aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2017-06-17 15:06:56 +0200
committerDimitri Sokolyuk <demon@dim13.org>2017-06-17 15:06:56 +0200
commit5b734a8aa3a02c87012e90f9c97b71914c776214 (patch)
tree4b252b05bfc384a96e28dd6e54bca44bddc90522
parent5b10c8a1a3f14beafe5e9b47663bc5dc67bb6409 (diff)
Compile
-rw-r--r--eval.go13
-rw-r--r--parse.go33
-rw-r--r--parse_test.go3
3 files changed, 33 insertions, 16 deletions
diff --git a/eval.go b/eval.go
index eedffd4..da962f5 100644
--- a/eval.go
+++ b/eval.go
@@ -27,10 +27,17 @@ func (vm *J1) Reset() {
vm.rsp = 0
}
+// Depth of stacks
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] }
+
+// T is top of the data stack
+func (vm *J1) T() uint16 { return vm.st0 }
+
+// N is sendond element in data stack
+func (vm *J1) N() uint16 { return vm.dstack[vm.dsp] }
+
+// R is top of return stack
+func (vm *J1) R() uint16 { return vm.rstack[vm.rsp] }
// LoadBytes into memory
func (vm *J1) LoadBytes(data []byte) error {
diff --git a/parse.go b/parse.go
index 336ce5a..bf96844 100644
--- a/parse.go
+++ b/parse.go
@@ -11,7 +11,7 @@ func Decode(v uint16) Instruction {
return newJump(v)
case v&(7<<13) == 1<<13:
return newCond(v)
- case v&(7<<13) == 1<<14:
+ case v&(7<<13) == 2<<13:
return newCall(v)
case v&(7<<13) == 3<<13:
return newALU(v)
@@ -23,35 +23,40 @@ func Decode(v uint16) Instruction {
type Instruction interface {
String() string
Value() uint16
+ Compile() uint16
}
// Lit is a literal
type Lit uint16
-func newLit(v uint16) Lit { return Lit(v &^ uint16(1<<15)) }
-func (v Lit) String() string { return fmt.Sprintf("LIT %0.4X", uint16(v)) }
-func (v Lit) Value() uint16 { return uint16(v) }
+func newLit(v uint16) Lit { return Lit(v &^ uint16(1<<15)) }
+func (v Lit) String() string { return fmt.Sprintf("LIT %0.4X", uint16(v)) }
+func (v Lit) Value() uint16 { return uint16(v) }
+func (v Lit) Compile() uint16 { return v.Value() | (1 << 15) }
// Jump is an unconditional branch
type Jump uint16
-func newJump(v uint16) Jump { return Jump(v &^ uint16(7<<13)) }
-func (v Jump) String() string { return fmt.Sprintf("UBRANCH %0.4X", uint16(v<<1)) }
-func (v Jump) Value() uint16 { return uint16(v) }
+func newJump(v uint16) Jump { return Jump(v &^ uint16(7<<13)) }
+func (v Jump) String() string { return fmt.Sprintf("UBRANCH %0.4X", uint16(v<<1)) }
+func (v Jump) Value() uint16 { return uint16(v) }
+func (v Jump) Compile() uint16 { return v.Value() }
// Cond is a conditional branch
type Cond uint16
-func newCond(v uint16) Cond { return Cond(v &^ uint16(7<<13)) }
-func (v Cond) String() string { return fmt.Sprintf("0BRANCH %0.4X", uint16(v<<1)) }
-func (v Cond) Value() uint16 { return uint16(v) }
+func newCond(v uint16) Cond { return Cond(v &^ uint16(7<<13)) }
+func (v Cond) String() string { return fmt.Sprintf("0BRANCH %0.4X", uint16(v<<1)) }
+func (v Cond) Value() uint16 { return uint16(v) }
+func (v Cond) Compile() uint16 { return v.Value() | (1 << 13) }
// Call procedure
type Call uint16
-func newCall(v uint16) Call { return Call(v &^ uint16(7<<13)) }
-func (v Call) String() string { return fmt.Sprintf("CALL %0.4X", uint16(v<<1)) }
-func (v Call) Value() uint16 { return uint16(v) }
+func newCall(v uint16) Call { return Call(v &^ uint16(7<<13)) }
+func (v Call) String() string { return fmt.Sprintf("CALL %0.4X", uint16(v<<1)) }
+func (v Call) Value() uint16 { return uint16(v) }
+func (v Call) Compile() uint16 { return v.Value() | (2 << 13) }
// ALU instruction
type ALU struct {
@@ -95,6 +100,8 @@ func (v ALU) Value() uint16 {
return ret
}
+func (v ALU) Compile() uint16 { return v.Value() | (3 << 13) }
+
func expand(v uint16) int8 {
if v&2 != 0 {
v |= 0xfc
diff --git a/parse_test.go b/parse_test.go
index 168032f..e69774b 100644
--- a/parse_test.go
+++ b/parse_test.go
@@ -39,6 +39,9 @@ func TestDecode(t *testing.T) {
if ins != tc.ins {
t.Errorf("got %v, want %v", ins, tc.ins)
}
+ if v := ins.Compile(); v != tc.bin {
+ t.Errorf("got %v, want %v", v, tc.bin)
+ }
})
}
}