func (self *_parser) errorUnexpectedToken(tkn token.Token) error { switch tkn { case token.EOF: return self.error(file.Idx(0), err_UnexpectedEndOfInput) } value := tkn.String() switch tkn { case token.BOOLEAN, token.NULL: value = self.literal case token.IDENTIFIER: return self.error(self.idx, "Unexpected identifier") case token.KEYWORD: // TODO Might be a future reserved word return self.error(self.idx, "Unexpected reserved word") case token.NUMBER: return self.error(self.idx, "Unexpected number") case token.STRING: return self.error(self.idx, "Unexpected string") } return self.error(self.idx, err_UnexpectedToken, value) }
func (self *_runtime) calculateComparison(comparator token.Token, left Value, right Value) bool { // FIXME Use strictEqualityComparison? // TODO This might be redundant now (with regards to evaluateComparison) x := left.resolve() y := right.resolve() kindEqualKind := false result := true negate := false switch comparator { case token.LESS: result = lessThanTable[0][calculateLessThan(x, y, true)] case token.GREATER: result = lessThanTable[1][calculateLessThan(y, x, false)] case token.LESS_OR_EQUAL: result = lessThanTable[2][calculateLessThan(y, x, false)] case token.GREATER_OR_EQUAL: result = lessThanTable[3][calculateLessThan(x, y, true)] case token.STRICT_NOT_EQUAL: negate = true fallthrough case token.STRICT_EQUAL: if x.kind != y.kind { result = false } else { kindEqualKind = true } case token.NOT_EQUAL: negate = true fallthrough case token.EQUAL: if x.kind == y.kind { kindEqualKind = true } else if x.kind <= valueNull && y.kind <= valueNull { result = true } else if x.kind <= valueNull || y.kind <= valueNull { result = false } else if x.kind <= valueString && y.kind <= valueString { result = x.float64() == y.float64() } else if x.kind == valueBoolean { result = self.calculateComparison(token.EQUAL, toValue_float64(x.float64()), y) } else if y.kind == valueBoolean { result = self.calculateComparison(token.EQUAL, x, toValue_float64(y.float64())) } else if x.kind == valueObject { result = self.calculateComparison(token.EQUAL, toPrimitive(x), y) } else if y.kind == valueObject { result = self.calculateComparison(token.EQUAL, x, toPrimitive(y)) } else { panic(hereBeDragons("Unable to test for equality: %v ==? %v", x, y)) } default: panic(fmt.Errorf("Unknown comparator %s", comparator.String())) } if kindEqualKind { switch x.kind { case valueUndefined, valueNull: result = true case valueNumber: x := x.float64() y := y.float64() if math.IsNaN(x) || math.IsNaN(y) { result = false } else { result = x == y } case valueString: result = x.string() == y.string() case valueBoolean: result = x.bool() == y.bool() case valueObject: result = x._object() == y._object() default: goto ERROR } } if negate { result = !result } return result ERROR: panic(hereBeDragons("%v (%v) %s %v (%v)", x, x.kind, comparator, y, y.kind)) }