aboutsummaryrefslogtreecommitdiff
path: root/eval.go
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2017-06-17 13:57:58 +0200
committerDimitri Sokolyuk <demon@dim13.org>2017-06-17 13:57:58 +0200
commit5b10c8a1a3f14beafe5e9b47663bc5dc67bb6409 (patch)
treea107d8a06fb36fb27ec0b084feae355d80cc0d44 /eval.go
parent34b234fc5a66d646bee90370e149abc5b15e35c9 (diff)
Add value
Diffstat (limited to 'eval.go')
-rw-r--r--eval.go60
1 files changed, 32 insertions, 28 deletions
diff --git a/eval.go b/eval.go
index c3891c3..eedffd4 100644
--- a/eval.go
+++ b/eval.go
@@ -10,10 +10,10 @@ import (
// J1 Forth processor VM
type J1 struct {
- dsp uint16 // 5 bit data stack pointer
- st0 uint16 // top of data stack
pc uint16 // 13 bit
- rsp uint16 // 5 bit retrun stack pointer
+ st0 uint16 // top of data stack
+ dsp int8 // 5 bit data stack pointer
+ rsp int8 // 5 bit retrun stack pointer
dstack [0x20]uint16 // data stack
rstack [0x20]uint16 // deturn stack
memory [0x8000]uint16 // memory
@@ -21,12 +21,17 @@ type J1 struct {
// Reset VM
func (vm *J1) Reset() {
- vm.dsp = 0
- vm.st0 = 0
vm.pc = 0
+ vm.st0 = 0
+ vm.dsp = 0
vm.rsp = 0
}
+func (vm *J1) Depth() uint16 { return (uint16(vm.rsp) << 8) | uint16(vm.dsp) }
+func (vm *J1) T() uint16 { return vm.st0 }
+func (vm *J1) N() uint16 { return vm.dstack[vm.dsp] }
+func (vm *J1) R() uint16 { return vm.rstack[vm.rsp] }
+
// LoadBytes into memory
func (vm *J1) LoadBytes(data []byte) error {
size := len(data) >> 1
@@ -79,17 +84,17 @@ func (vm *J1) eval(ins Instruction) {
vm.pc++
vm.dsp++
vm.dstack[vm.dsp] = vm.st0
- vm.st0 = uint16(v)
+ vm.st0 = v.Value()
case Jump:
- vm.pc = uint16(v)
+ vm.pc = v.Value()
case Call:
vm.rsp++
vm.rstack[vm.rsp] = vm.pc + 1
- vm.pc = uint16(v)
+ vm.pc = v.Value()
case Cond:
vm.pc++
if vm.st0 == 0 {
- vm.pc = uint16(v)
+ vm.pc = v.Value()
}
vm.st0 = vm.dstack[vm.dsp] // N
vm.dsp--
@@ -102,8 +107,8 @@ func (vm *J1) eval(ins Instruction) {
if v.NtoAtT {
vm.memory[vm.st0] = vm.dstack[vm.dsp]
}
- vm.dsp = uint16(int8(vm.dsp) + v.Ddir)
- vm.rsp = uint16(int8(vm.rsp) + v.Rdir)
+ vm.dsp += v.Ddir
+ vm.rsp += v.Rdir
if v.TtoR {
vm.rstack[vm.rsp] = vm.st0
}
@@ -115,46 +120,45 @@ func (vm *J1) eval(ins Instruction) {
}
func (vm *J1) newST0(v ALU) uint16 {
- T, N, R := vm.st0, vm.dstack[vm.dsp], vm.rstack[vm.rsp]
switch v.Opcode {
case opT: // T
- return T
+ return vm.T()
case opN: // N
- return N
+ return vm.N()
case opTplusN: // T+N
- return T + N
+ return vm.T() + vm.N()
case opTandN: // T&N
- return T & N
+ return vm.T() & vm.N()
case opTorN: // T|N
- return T | N
+ return vm.T() | vm.N()
case opTxorN: // T^N
- return T ^ N
+ return vm.T() ^ vm.N()
case opNotT: // ~T
- return ^T
+ return ^vm.T()
case opNeqT: // N==T
- if N == T {
+ if vm.N() == vm.T() {
return 1
}
return 0
case opNleT: // N<T
- if int16(N) < int16(T) {
+ if int16(vm.N()) < int16(vm.T()) {
return 1
}
return 0
case opNrshiftT: // N>>T
- return N >> (T & 0xf)
+ return vm.N() >> (vm.T() & 0xf)
case opTminus1: // T-1
- return T - 1
+ return vm.T() - 1
case opR: // R (rT)
- return R
+ return vm.R()
case opAtT: // [T]
- return vm.memory[T]
+ return vm.memory[vm.T()]
case opNlshiftT: // N<<T
- return N << (T & 0xf)
+ return vm.N() << (vm.T() & 0xf)
case opDepth: // depth (dsp)
- return (vm.rsp << 8) | vm.dsp
+ return vm.Depth()
case opNuleT: // Nu<T
- if N < T {
+ if vm.N() < vm.T() {
return 1
}
return 0