|
|
@@ -53,14 +53,8 @@ func (vm *VM) Run() error {
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- case code.OpAdd:
|
|
|
- right := vm.pop()
|
|
|
- left := vm.pop()
|
|
|
- leftValue := left.(*object.Integer).Value
|
|
|
- rightValue := right.(*object.Integer).Value
|
|
|
-
|
|
|
- result := leftValue + rightValue
|
|
|
- err := vm.push(&object.Integer{Value: result})
|
|
|
+ case code.OpAdd, code.OpSub, code.OpMul, code.OpDiv:
|
|
|
+ err := vm.executeBinaryOperation(op)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
@@ -89,6 +83,44 @@ func (vm *VM) pop() object.Object {
|
|
|
return o
|
|
|
}
|
|
|
|
|
|
+func (vm *VM) executeBinaryOperation(op code.Opcode) error {
|
|
|
+ right := vm.pop()
|
|
|
+ left := vm.pop()
|
|
|
+
|
|
|
+ leftType := left.Type()
|
|
|
+ rightType := right.Type()
|
|
|
+ if leftType == object.IntegerObj && rightType == object.IntegerObj {
|
|
|
+ return vm.executeBinaryIntegerOperation(op, left, right)
|
|
|
+ }
|
|
|
+
|
|
|
+ return fmt.Errorf("unsupported types of binary operation: %s %s", leftType, rightType)
|
|
|
+}
|
|
|
+
|
|
|
func (vm *VM) LastPopStackElem() object.Object {
|
|
|
return vm.stack[vm.sp]
|
|
|
}
|
|
|
+
|
|
|
+func (vm *VM) executeBinaryIntegerOperation(
|
|
|
+ op code.Opcode,
|
|
|
+ left, right object.Object,
|
|
|
+) error {
|
|
|
+ leftValue := left.(*object.Integer).Value
|
|
|
+ rightValue := right.(*object.Integer).Value
|
|
|
+
|
|
|
+ var result int64
|
|
|
+
|
|
|
+ switch op {
|
|
|
+ case code.OpAdd:
|
|
|
+ result = leftValue + rightValue
|
|
|
+ case code.OpSub:
|
|
|
+ result = leftValue - rightValue
|
|
|
+ case code.OpMul:
|
|
|
+ result = leftValue * rightValue
|
|
|
+ case code.OpDiv:
|
|
|
+ result = leftValue / rightValue
|
|
|
+ default:
|
|
|
+ return fmt.Errorf("unknown integer operator: %d", op)
|
|
|
+ }
|
|
|
+
|
|
|
+ return vm.push(&object.Integer{Value: result})
|
|
|
+}
|