예제 #1
0
파일: error.go 프로젝트: BiggerNoise/otto
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)
}
예제 #2
0
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))
}