bitwise operators and boolean operators
Some checks failed
Test / build (push) Waiting to run
Build / build (push) Has been cancelled

This commit is contained in:
Chuck Smith
2024-03-23 10:00:02 -04:00
parent cbb430b47d
commit ef8c8f8f04
13 changed files with 427 additions and 188 deletions

View File

@@ -112,7 +112,8 @@ func (vm *VM) Run() error {
return err
}
case code.OpAdd, code.OpSub, code.OpMul, code.OpDiv, code.OpMod:
case code.OpAdd, code.OpSub, code.OpMul, code.OpDiv, code.OpMod, code.OpOr,
code.OpAnd, code.OpBitwiseOR, code.OpBitwiseXOR, code.OpBitwiseAND:
err := vm.executeBinaryOperation(op)
if err != nil {
return err
@@ -139,8 +140,14 @@ func (vm *VM) Run() error {
return err
}
case code.OpBang:
err := vm.executeBangOperator()
case code.OpNot:
err := vm.executeNotOperator()
if err != nil {
return err
}
case code.OpBitwiseNOT:
err := vm.executeBitwiseNotOperator()
if err != nil {
return err
}
@@ -516,18 +523,38 @@ func (vm *VM) executeBinaryOperation(op code.Opcode) error {
left := vm.pop()
leftType := left.Type()
rightRight := right.Type()
rightType := right.Type()
switch {
case leftType == object.INTEGER_OBJ && rightRight == object.INTEGER_OBJ:
case leftType == object.BOOLEAN_OBJ && rightType == object.BOOLEAN_OBJ:
return vm.executeBinaryBooleanOperation(op, left, right)
case leftType == object.INTEGER_OBJ && rightType == object.INTEGER_OBJ:
return vm.executeBinaryIntegerOperation(op, left, right)
case leftType == object.STRING_OBJ && rightRight == object.STRING_OBJ:
case leftType == object.STRING_OBJ && rightType == object.STRING_OBJ:
return vm.executeBinaryStringOperation(op, left, right)
default:
return fmt.Errorf("unsupported types for binary operation: %s %s", leftType, rightRight)
return fmt.Errorf("unsupported types for binary operation: %s %s", leftType, rightType)
}
}
func (vm *VM) executeBinaryBooleanOperation(op code.Opcode, left, right object.Object) error {
leftValue := left.(*object.Boolean).Value
rightValue := right.(*object.Boolean).Value
var result bool
switch op {
case code.OpOr:
result = leftValue || rightValue
case code.OpAnd:
result = leftValue && rightValue
default:
return fmt.Errorf("unknown boolean operator: %d", op)
}
return vm.push(&object.Boolean{Value: result})
}
func (vm *VM) executeBinaryIntegerOperation(op code.Opcode, left, right object.Object) error {
leftValue := left.(*object.Integer).Value
rightValue := right.(*object.Integer).Value
@@ -545,6 +572,12 @@ func (vm *VM) executeBinaryIntegerOperation(op code.Opcode, left, right object.O
result = leftValue / rightValue
case code.OpMod:
result = leftValue % rightValue
case code.OpBitwiseOR:
result = leftValue | rightValue
case code.OpBitwiseXOR:
result = leftValue ^ rightValue
case code.OpBitwiseAND:
result = leftValue & rightValue
default:
return fmt.Errorf("unknown integer operator: %d", op)
@@ -604,7 +637,15 @@ func (vm *VM) executeIntegerComparison(op code.Opcode, left, right object.Object
}
}
func (vm *VM) executeBangOperator() error {
func (vm *VM) executeBitwiseNotOperator() error {
operand := vm.pop()
if i, ok := operand.(*object.Integer); ok {
return vm.push(&object.Integer{Value: ^i.Value})
}
return fmt.Errorf("expected int got=%T", operand)
}
func (vm *VM) executeNotOperator() error {
operand := vm.pop()
switch operand {
@@ -622,12 +663,11 @@ func (vm *VM) executeBangOperator() error {
func (vm *VM) executeMinusOperator() error {
operand := vm.pop()
if operand.Type() != object.INTEGER_OBJ {
return fmt.Errorf("unsupported type for negation: %s", operand.Type())
if i, ok := operand.(*object.Integer); ok {
return vm.push(&object.Integer{Value: -i.Value})
}
value := operand.(*object.Integer).Value
return vm.push(&object.Integer{Value: -value})
return fmt.Errorf("expected int got=%T", operand)
}
func (vm *VM) executeCall(numArgs int) error {