M internal/generator/visitor.go => internal/generator/visitor.go +26 -4
@@ 202,7 202,18 @@ func (v *RhumbVisitor) VisitComparative(ctx *parser.ComparativeContext) interfac
func (v *RhumbVisitor) VisitMultiplicative(ctx *parser.MultiplicativeContext) interface{} {
fmt.Println("multiply:", ctx.GetText())
- return v.VisitChildren(ctx)
+ exprs := ctx.AllExpression()
+ for i := range exprs {
+ exprs[i].Accept(v)
+ }
+ mulOp := ctx.MultiplicativeOp()
+ v.vm.WriteCodeToMain(
+ mulOp.GetStart().GetLine(),
+ vm.NewInstrRef(vm.RefLabel, mulOp.GetText(), nil),
+ // FIXME: re-implement as NewInnerRequest
+ vm.NewOuterRequest,
+ )
+ return nil
}
func (v *RhumbVisitor) VisitAdditive(ctx *parser.AdditiveContext) interface{} {
@@ 258,7 269,18 @@ func (v *RhumbVisitor) VisitSelector(ctx *parser.SelectorContext) interface{} {
func (v *RhumbVisitor) VisitPower(ctx *parser.PowerContext) interface{} {
fmt.Println("power:", ctx.GetText())
- return v.VisitChildren(ctx)
+ exprs := ctx.AllExpression()
+ for i := range exprs {
+ exprs[i].Accept(v)
+ }
+ powOp := ctx.ExponentiationOp()
+ v.vm.WriteCodeToMain(
+ powOp.GetStart().GetLine(),
+ vm.NewInstrRef(vm.RefLabel, powOp.GetText(), nil),
+ // FIXME: re-implement as NewInnerRequest
+ vm.NewOuterRequest,
+ )
+ return nil
}
func (v *RhumbVisitor) VisitMap(ctx *parser.MapContext) interface{} {
@@ 476,8 498,8 @@ func (v *RhumbVisitor) VisitNumericalNegate(ctx *parser.NumericalNegateContext)
return v.VisitChildren(ctx)
}
-func (v *RhumbVisitor) VisitBindBase(ctx *parser.BindBaseContext) interface{} {
- fmt.Println("bind-base:", ctx.GetText())
+func (v *RhumbVisitor) VisitOuterScope(ctx *parser.OuterScopeContext) interface{} {
+ fmt.Println("outer-scope:", ctx.GetText())
return v.VisitChildren(ctx)
}
M internal/vm/primitives.go => internal/vm/primitives.go +49 -8
@@ 1,15 1,10 @@
package vm
-import "fmt"
+import (
+ "fmt"
+)
/* Phase 1
- * _.=_
- * _:=_
- * _++_
- * _--_
- * _**_
- * _^^_
- * _//_
* _+/_
* _-/_
*/
@@ 49,6 44,52 @@ func (vm *VirtualMachine) addTwoInts() {
logAddedToStack(vm.stack, fmt.Sprint(val1, " + ", val2))
}
+func (vm *VirtualMachine) subTwoInts() {
+ val2 := vm.heap[vm.popStack().AsAddr()].AsInt()
+ val1 := vm.heap[vm.popStack().AsAddr()].AsInt()
+ vm.stack = append(vm.stack, WordFromInt(val1-val2))
+ logAddedToStack(vm.stack, fmt.Sprint(val1, " - ", val2))
+}
+
+func (vm *VirtualMachine) mulTwoInts() {
+ val2 := vm.heap[vm.popStack().AsAddr()].AsInt()
+ val1 := vm.heap[vm.popStack().AsAddr()].AsInt()
+ vm.stack = append(vm.stack, WordFromInt(val1*val2))
+ logAddedToStack(vm.stack, fmt.Sprint(val1, " x ", val2))
+}
+
+func (vm *VirtualMachine) divTwoInts() {
+ val2 := vm.heap[vm.popStack().AsAddr()].AsInt()
+ val1 := vm.heap[vm.popStack().AsAddr()].AsInt()
+ vm.stack = append(vm.stack, WordFromInt(val1/val2))
+ logAddedToStack(vm.stack, fmt.Sprint(val1, " / ", val2))
+}
+
+func expBySquaring(x, n uint32) uint32 {
+ if n == 0 {
+ return 1
+ }
+ var y uint32 = 1
+ for n > 1 {
+ if n%2 == 0 {
+ x = x * x
+ n = n / 2
+ } else {
+ y = x * y
+ x = x * x
+ n = (n - 1) / 2
+ }
+ }
+ return x * y
+}
+
+func (vm *VirtualMachine) expTwoInts() {
+ val2 := vm.heap[vm.popStack().AsAddr()].AsInt()
+ val1 := vm.heap[vm.popStack().AsAddr()].AsInt()
+ vm.stack = append(vm.stack, WordFromInt(expBySquaring(val1, val2)))
+ logAddedToStack(vm.stack, fmt.Sprint(val1, " ^ ", val2))
+}
+
/* Phase 2
* _.._
* _::_s
M internal/vm/vm.go => internal/vm/vm.go +8 -0
@@ 89,6 89,14 @@ func (vm *VirtualMachine) SubmitOuterRequest(ir InstrRef) {
vm.assignLabel()
case "++":
vm.addTwoInts()
+ case "--":
+ vm.subTwoInts()
+ case "**":
+ vm.mulTwoInts()
+ case "//":
+ vm.divTwoInts()
+ case "^^":
+ vm.expTwoInts()
default:
panic("Not a valid outer operator")
}