aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2018-01-07 00:43:28 +0100
committerDimitri Sokolyuk <demon@dim13.org>2018-01-07 00:43:28 +0100
commit6fe6679b816cedbe1f007a1f036cc55ae9214492 (patch)
tree968241eaa55ef17f923d428ac26d7153bf392220
parente995ee3c0b77708aa2b6f04a7c86a4ed4684d96a (diff)
...
-rw-r--r--console.go30
-rw-r--r--eval.go52
-rw-r--r--eval_test.go14
3 files changed, 63 insertions, 33 deletions
diff --git a/console.go b/console.go
new file mode 100644
index 0000000..a29c4ad
--- /dev/null
+++ b/console.go
@@ -0,0 +1,30 @@
+package j1
+
+import (
+ "bufio"
+ "os"
+)
+
+type Console struct {
+ r *bufio.Reader
+ w *bufio.Writer
+}
+
+func NewConsole() *Console {
+ return &Console{
+ r: bufio.NewReader(os.Stdin),
+ w: bufio.NewWriter(os.Stdout),
+ }
+}
+
+func (c *Console) Read(p []byte) (int, error) {
+ return c.r.Read(p)
+}
+
+func (c *Console) Write(p []byte) (int, error) {
+ n, err := c.w.Write(p)
+ if err != nil {
+ return 0, err
+ }
+ return n, c.w.Flush()
+}
diff --git a/eval.go b/eval.go
index 4bc9b79..363f3f2 100644
--- a/eval.go
+++ b/eval.go
@@ -6,14 +6,8 @@ import (
"fmt"
"io"
"io/ioutil"
- "os"
)
-type Console struct {
- io.Reader
- io.Writer
-}
-
// J1 Forth processor VM
type J1 struct {
pc uint16 // 13 bit
@@ -27,7 +21,7 @@ type J1 struct {
}
func New() *J1 {
- return &J1{console: Console{Reader: os.Stdin, Writer: os.Stdout}}
+ return &J1{console: NewConsole()}
}
// Reset VM
@@ -61,45 +55,51 @@ func (j1 *J1) Eval() {
return
}
j1.eval(ins)
- fmt.Printf("%4d %v\n%v\n", n, ins, j1)
+ //fmt.Printf("%4d %v %v\n", n, ins, j1)
}
}
func (j1 *J1) String() string {
- var rstack [32]uint16
- for i, v := range j1.rstack {
- rstack[i] = v << 1
- }
- s := fmt.Sprintf("\tPC=%0.4X ST=%0.4X\n", j1.pc<<1, j1.st0)
+ s := fmt.Sprintf("\tPC=%0.4X ST=%0.4X\n", j1.pc, j1.st0)
s += fmt.Sprintf("\tD=%0.4X\n", j1.dstack[:j1.dsp+1])
- s += fmt.Sprintf("\tR=%0.4X\n", rstack[:j1.rsp+1])
+ s += fmt.Sprintf("\tR=%0.4X", j1.rstack[:j1.rsp+1])
return s
}
+func (j1 *J1) push(v uint16) {
+ j1.dsp++
+ j1.dstack[j1.dsp] = j1.st0
+ j1.st0 = v
+}
+
+func (j1 *J1) pop() uint16 {
+ v := j1.st0
+ j1.st0 = j1.dstack[j1.dsp]
+ j1.dsp--
+ return v
+}
+
func (j1 *J1) eval(ins Instruction) {
j1.pc++
switch v := ins.(type) {
case Lit:
- j1.dsp++
- j1.dstack[j1.dsp] = j1.st0
- j1.st0 = v.Value()
+ j1.push(v.Value())
case Jump:
j1.pc = v.Value()
case Call:
j1.rsp++
- j1.rstack[j1.rsp] = j1.pc
+ j1.rstack[j1.rsp] = j1.pc << 1
j1.pc = v.Value()
case Cond:
- if j1.st0 == 0 {
+ if j1.pop() == 0 {
j1.pc = v.Value()
}
- j1.st0 = j1.dstack[j1.dsp] // N
- j1.dsp--
case ALU:
if v.RtoPC {
- j1.pc = j1.rstack[j1.rsp]
+ j1.pc = j1.rstack[j1.rsp] >> 1
}
st0 := j1.newST0(v.Opcode)
+ n := j1.dstack[j1.dsp]
j1.dsp += v.Ddir
j1.rsp += v.Rdir
if v.TtoN {
@@ -111,11 +111,11 @@ func (j1 *J1) eval(ins Instruction) {
if v.NtoAtT {
switch j1.st0 {
case 0xf000: // key
- fmt.Fprintf(j1.console, "%c", j1.dstack[j1.dsp])
+ fmt.Fprintf(j1.console, "%c", n)
case 0xf002: // bye
j1.rsp = 0
default:
- j1.memory[j1.st0] = j1.dstack[j1.dsp]
+ j1.memory[j1.st0>>1] = n
}
}
j1.st0 = st0
@@ -124,7 +124,7 @@ func (j1 *J1) eval(ins Instruction) {
func bool2int(b bool) uint16 {
if b {
- return 1
+ return ^uint16(0)
}
return 0
}
@@ -165,7 +165,7 @@ func (j1 *J1) newST0(opcode uint16) uint16 {
case 0xf001: // ?rx
return 1
default:
- return j1.memory[T]
+ return j1.memory[T>>1]
}
case opNlshiftT: // N<<T
return N << (T & 0xf)
diff --git a/eval_test.go b/eval_test.go
index 9aacf09..1686287 100644
--- a/eval_test.go
+++ b/eval_test.go
@@ -46,7 +46,7 @@ func TestEval(t *testing.T) {
},
{
ins: []Instruction{Call(0xff)},
- end: J1{pc: 0xff, rstack: [0x20]uint16{0x00, 0x01}, rsp: 1},
+ end: J1{pc: 0xff, rstack: [0x20]uint16{0x00, 0x02}, rsp: 1},
},
{
ins: []Instruction{Lit(0xff)},
@@ -86,7 +86,7 @@ func TestEval(t *testing.T) {
},
{ // ;
ins: []Instruction{Call(10), Call(20), ALU{Opcode: opT, RtoPC: true, Rdir: -1}},
- end: J1{pc: 11, rsp: 1, rstack: [0x20]uint16{0, 1, 11}},
+ end: J1{pc: 11, rsp: 1, rstack: [0x20]uint16{0, 2, 22}},
},
{ // >r
ins: []Instruction{Lit(10), ALU{Opcode: opN, TtoR: true, Ddir: -1, Rdir: 1}},
@@ -94,7 +94,7 @@ func TestEval(t *testing.T) {
},
{ // r>
ins: []Instruction{Lit(10), Call(20), ALU{Opcode: opR, TtoN: true, TtoR: true, Ddir: 1, Rdir: -1}},
- end: J1{pc: 21, st0: 2, dsp: 2, dstack: [0x20]uint16{0, 0, 10}, rsp: 0, rstack: [0x20]uint16{10, 2}},
+ end: J1{pc: 21, st0: 4, dsp: 2, dstack: [0x20]uint16{0, 0, 10}, rsp: 0, rstack: [0x20]uint16{10, 4}},
},
{ // r@
ins: []Instruction{Lit(10), ALU{Opcode: opR, TtoN: true, TtoR: true, Ddir: 1}},
@@ -135,16 +135,16 @@ func TestNextST0(t *testing.T) {
{ins: ALU{Opcode: opTxorN}, st0: 0x44, state: J1{st0: 0xff, dstack: [0x20]uint16{0, 0xaa, 0xbb}, dsp: 2}},
{ins: ALU{Opcode: opNotT}, st0: 0xff55, state: J1{st0: 0xaa}},
{ins: ALU{Opcode: opNeqT}, st0: 0x00, state: J1{st0: 0xff, dstack: [0x20]uint16{0, 0xaa, 0xbb}, dsp: 2}},
- {ins: ALU{Opcode: opNeqT}, st0: 0x01, state: J1{st0: 0xff, dstack: [0x20]uint16{0, 0xaa, 0xff}, dsp: 2}},
- {ins: ALU{Opcode: opNleT}, st0: 0x01, state: J1{st0: 0xff, dstack: [0x20]uint16{0, 0xaa, 0xbb}, dsp: 2}},
+ {ins: ALU{Opcode: opNeqT}, st0: 0xffff, state: J1{st0: 0xff, dstack: [0x20]uint16{0, 0xaa, 0xff}, dsp: 2}},
+ {ins: ALU{Opcode: opNleT}, st0: 0xffff, state: J1{st0: 0xff, dstack: [0x20]uint16{0, 0xaa, 0xbb}, dsp: 2}},
{ins: ALU{Opcode: opNleT}, st0: 0x00, state: J1{st0: 0xff, dstack: [0x20]uint16{0, 0xaa, 0xff}, dsp: 2}},
{ins: ALU{Opcode: opNrshiftT}, st0: 0x3f, state: J1{st0: 0x02, dstack: [0x20]uint16{0, 0xaa, 0xff}, dsp: 2}},
{ins: ALU{Opcode: opTminus1}, st0: 0x54, state: J1{st0: 0x55}},
{ins: ALU{Opcode: opR}, st0: 0x5, state: J1{rstack: [0x20]uint16{0, 0x05}, rsp: 1}},
- {ins: ALU{Opcode: opAtT}, st0: 0x5, state: J1{st0: 0x01, memory: [0x4000]uint16{0, 5, 10}}},
+ {ins: ALU{Opcode: opAtT}, st0: 0x0, state: J1{st0: 0x01, memory: [0x4000]uint16{0, 5, 10}}},
{ins: ALU{Opcode: opNlshiftT}, st0: 0x3fc, state: J1{st0: 0x02, dstack: [0x20]uint16{0, 0xaa, 0xff}, dsp: 2}},
{ins: ALU{Opcode: opDepth}, st0: 0x305, state: J1{rsp: 3, dsp: 5}},
- {ins: ALU{Opcode: opNuleT}, st0: 0x01, state: J1{st0: 0xff, dstack: [0x20]uint16{0, 0xaa, 0xbb}, dsp: 2}},
+ {ins: ALU{Opcode: opNuleT}, st0: 0xffff, state: J1{st0: 0xff, dstack: [0x20]uint16{0, 0xaa, 0xbb}, dsp: 2}},
{ins: ALU{Opcode: opNuleT}, st0: 0x00, state: J1{st0: 0xff, dstack: [0x20]uint16{0, 0xaa, 0xff}, dsp: 2}},
}
for _, tc := range testCases {