@@ 19,7 19,7 @@
"program": "cmd/rhumb/main.go",
"args": [
"line",
- "foo := 1; bar .= 1"
+ "foo .= 10; bar .= 3; foo ** bar // 6"
]
}
@@ 24,6 24,24 @@ func locateScopeLabel(
return
}
+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) popStack() (popped Word) {
idx := len(vm.stack) - 1
popped = vm.stack[idx]
@@ 31,6 49,22 @@ func (vm *VirtualMachine) popStack() (popped Word) {
return
}
+func (vm *VirtualMachine) gatherTwoInts() (val1, val2 uint32) {
+ stackVal2 := vm.popStack()
+ stackVal1 := vm.popStack()
+ if stackVal1.IsAddr() {
+ val1 = vm.heap[stackVal1.AsAddr()].AsInt()
+ } else if stackVal1.IsInt() {
+ val1 = stackVal1.AsInt()
+ }
+ if stackVal2.IsAddr() {
+ val2 = vm.heap[stackVal2.AsAddr()].AsInt()
+ } else if stackVal2.IsInt() {
+ val2 = stackVal2.AsInt()
+ }
+ return
+}
+
func (vm *VirtualMachine) assignLabel() {
valWord := vm.popStack()
addrWord := vm.popStack()
@@ 38,56 72,58 @@ func (vm *VirtualMachine) assignLabel() {
}
func (vm *VirtualMachine) addTwoInts() {
- val2 := vm.heap[vm.popStack().AsAddr()].AsInt()
- val1 := vm.heap[vm.popStack().AsAddr()].AsInt()
+ val1, val2 := vm.gatherTwoInts()
vm.stack = append(vm.stack, WordFromInt(val1+val2))
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()
+ val1, val2 := vm.gatherTwoInts()
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()
+ val1, val2 := vm.gatherTwoInts()
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()
+ val1, val2 := vm.gatherTwoInts()
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
+func (vm *VirtualMachine) expTwoInts() {
+ val1, val2 := vm.gatherTwoInts()
+ vm.stack = append(vm.stack, WordFromInt(expBySquaring(val1, val2)))
+ logAddedToStack(vm.stack, fmt.Sprint(val1, " ^ ", val2))
+}
+
+func (vm *VirtualMachine) beginRoutine() {
+ vm.scope = append(vm.scope, make(map[string]int))
+ vm.stack = append(vm.stack, Word(TAG_MRK_STL))
+}
+
+func (vm *VirtualMachine) endRoutine() {
+ // TODO: try to delete things?
+ vm.scope = vm.scope[:len(vm.scope)-1]
+ for back := len(vm.stack); back > 0; back-- {
+ if vm.stack[back].IsSentinel() {
+ last := vm.stack[len(vm.stack)-1]
+ vm.stack = vm.stack[:back]
+ vm.stack[back] = last
}
}
- 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))
+func (vm *VirtualMachine) beginMap() {
+
+}
+
+func (vm *VirtualMachine) endMap() {
+
}
/* Phase 2
@@ 97,6 97,15 @@ func (vm *VirtualMachine) SubmitOuterRequest(ir InstrRef) {
vm.divTwoInts()
case "^^":
vm.expTwoInts()
+ case "[[":
+ vm.beginMap()
+ case "]]":
+ vm.endMap()
+ case "((":
+ vm.beginRoutine()
+ case "))":
+ vm.endRoutine()
+
default:
panic("Not a valid outer operator")
}
@@ 87,17 87,18 @@ func WordFromRune(r rune) Word { return Word(TAG_LIT_RNE | uint64(r)) }
func WordFromSym(a int) Word { return Word(TAG_LIT_SYM | uint64(a)) }
func WordFromAddr(a int) Word { return Word(TAG_ADDRESS | uint64(a)) }
-func (w Word) IsNAN() bool { return uint64(w) == TAG_LIT_NAN }
-func (w Word) IsTrue() bool { return uint64(w) == TAG_LIT_TRU }
-func (w Word) IsFalse() bool { return uint64(w) == TAG_LIT_FLS }
-func (w Word) IsBool() bool { return w.IsTrue() || w.IsFalse() }
-func (w Word) IsEmpty() bool { return uint64(w) == TAG_LIT_ETY }
-func (w Word) IsInt() bool { return uint64(w)&TAG_LIT_INT == TAG_LIT_INT }
-func (w Word) IsRune() bool { return uint64(w)&TAG_LIT_RNE == TAG_LIT_RNE }
-func (w Word) IsSym() bool { return uint64(w)&TAG_LIT_SYM == TAG_LIT_SYM }
-func (w Word) IsFloat() bool { return uint64(w)&TAG_SLT_NAN != TAG_SLT_NAN }
-func (w Word) IsMark() bool { return uint64(w)&TAG_OBJ_MAP == TAG_OBJ_MAP }
-func (w Word) IsAddr() bool { return uint64(w)&TAG_ADDRESS == TAG_ADDRESS }
+func (w Word) IsFloat() bool { return uint64(w)&TAG_SLT_NAN != TAG_SLT_NAN }
+func (w Word) IsAddr() bool { return uint64(w)&TAG_ADDRESS == TAG_ADDRESS }
+func (w Word) IsNAN() bool { return uint64(w) == TAG_LIT_NAN }
+func (w Word) IsTrue() bool { return uint64(w) == TAG_LIT_TRU }
+func (w Word) IsFalse() bool { return uint64(w) == TAG_LIT_FLS }
+func (w Word) IsBool() bool { return w.IsTrue() || w.IsFalse() }
+func (w Word) IsEmpty() bool { return uint64(w) == TAG_LIT_ETY }
+func (w Word) IsInt() bool { return uint64(w)&TAG_LIT_INT == TAG_LIT_INT }
+func (w Word) IsRune() bool { return uint64(w)&TAG_LIT_RNE == TAG_LIT_RNE }
+func (w Word) IsSym() bool { return uint64(w)&TAG_LIT_SYM == TAG_LIT_SYM }
+func (w Word) IsSentinel() bool { return uint64(w)&TAG_MRK_STL == TAG_MRK_STL }
+func (w Word) IsMark() bool { return uint64(w)&TAG_OBJ_MAP == TAG_OBJ_MAP }
func (w Word) isMrkT(t uint64) bool { return uint64(w)&TAG_ALLMARK == t }
func (w Word) IsMap() bool { return w.isMrkT(TAG_OBJ_MAP) }