aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2018-01-24 01:59:13 +0100
committerDimitri Sokolyuk <demon@dim13.org>2018-01-24 01:59:13 +0100
commit565751db4e5b8370c0a05d1998a91e6e20a19bb4 (patch)
tree59ab8649b3e01da4c61a6f70269aaddacdf2eba9
parent07584da73461b69043451ebe48fcac226202492a (diff)
remove context
-rw-r--r--cmd/eval/main.go10
-rw-r--r--cmd/j1e/main.go10
-rw-r--r--console/console.go26
-rw-r--r--core.go50
-rw-r--r--core_test.go10
5 files changed, 58 insertions, 48 deletions
diff --git a/cmd/eval/main.go b/cmd/eval/main.go
index 152824c..cd593a3 100644
--- a/cmd/eval/main.go
+++ b/cmd/eval/main.go
@@ -1,18 +1,16 @@
package main
import (
- "context"
-
"dim13.org/j1"
"dim13.org/j1/console"
)
func main() {
- vm := j1.New()
+ con := console.New()
+ defer con.Stop()
+ vm := j1.New(con)
if err := vm.LoadFile("testdata/j1e.bin"); err != nil {
panic(err)
}
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
- vm.Run(ctx, cancel, console.New(ctx))
+ vm.Run()
}
diff --git a/cmd/j1e/main.go b/cmd/j1e/main.go
index 8f31aeb..934d416 100644
--- a/cmd/j1e/main.go
+++ b/cmd/j1e/main.go
@@ -3,16 +3,14 @@ package main
//go:generate file2go -in ../../testdata/j1e.bin
import (
- "context"
-
"dim13.org/j1"
"dim13.org/j1/console"
)
func main() {
- vm := j1.New()
+ con := console.New()
+ defer con.Stop()
+ vm := j1.New(con)
vm.LoadBytes(J1eBin)
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
- vm.Run(ctx, cancel, console.New(ctx))
+ vm.Run()
}
diff --git a/console/console.go b/console/console.go
index 4fe9680..577e021 100644
--- a/console/console.go
+++ b/console/console.go
@@ -1,7 +1,6 @@
package console
import (
- "context"
"fmt"
"io"
"os"
@@ -11,36 +10,38 @@ type Console struct {
r io.Reader
w io.Writer
ich, och chan uint16
+ done chan struct{}
}
-func New(ctx context.Context) *Console {
+func New() *Console {
c := &Console{
- r: os.Stdin,
- w: os.Stdout,
- ich: make(chan uint16, 1),
- och: make(chan uint16, 1),
+ r: os.Stdin,
+ w: os.Stdout,
+ ich: make(chan uint16, 1),
+ och: make(chan uint16, 1),
+ done: make(chan struct{}),
}
- go c.read(ctx)
- go c.write(ctx)
+ go c.read()
+ go c.write()
return c
}
-func (c *Console) read(ctx context.Context) {
+func (c *Console) read() {
var v uint16
for {
fmt.Fscanf(c.r, "%c", &v)
select {
- case <-ctx.Done():
+ case <-c.done:
return
case c.ich <- v:
}
}
}
-func (c *Console) write(ctx context.Context) {
+func (c *Console) write() {
for {
select {
- case <-ctx.Done():
+ case <-c.done:
return
case v := <-c.och:
fmt.Fprintf(c.w, "%c", v)
@@ -51,3 +52,4 @@ func (c *Console) write(ctx context.Context) {
func (c *Console) Read() uint16 { return <-c.ich }
func (c *Console) Write(v uint16) { c.och <- v }
func (c *Console) Len() uint16 { return uint16(len(c.ich)) }
+func (c *Console) Stop() { close(c.done) }
diff --git a/core.go b/core.go
index 74355e5..5b08cd9 100644
--- a/core.go
+++ b/core.go
@@ -2,7 +2,6 @@ package j1
import (
"bytes"
- "context"
"encoding/binary"
"errors"
"fmt"
@@ -11,6 +10,8 @@ import (
const memSize = 0x4000
+var ErrStop = errors.New("stop")
+
type Console interface {
Read() uint16
Write(uint16)
@@ -24,11 +25,10 @@ type Core struct {
st0 uint16 // top of data stack
d, r stack // data and return stacks
tty Console // console i/o
- stop context.CancelFunc
}
-func New() *Core {
- return new(Core)
+func New(con Console) *Core {
+ return &Core{tty: con}
}
// Reset VM
@@ -54,20 +54,6 @@ func (c *Core) LoadFile(fname string) error {
return c.LoadBytes(data)
}
-// Run evaluates content of memory
-func (c *Core) Run(ctx context.Context, cancel context.CancelFunc, con Console) {
- c.stop = cancel
- c.tty = con
- for {
- select {
- case <-ctx.Done():
- return
- default:
- c.Eval(Decode(c.memory[c.pc]))
- }
- }
-}
-
func (c *Core) String() string {
s := fmt.Sprintf("\tPC=%0.4X ST=%0.4X\n", c.pc, c.st0)
s += fmt.Sprintf("\tD=%0.4X\n", c.d.dump())
@@ -75,7 +61,7 @@ func (c *Core) String() string {
return s
}
-func (c *Core) writeAt(addr, value uint16) {
+func (c *Core) writeAt(addr, value uint16) error {
if off := int(addr >> 1); off < memSize {
c.memory[addr>>1] = value
}
@@ -83,8 +69,9 @@ func (c *Core) writeAt(addr, value uint16) {
case 0xf000: // key
c.tty.Write(value)
case 0xf002: // bye
- c.stop()
+ return ErrStop
}
+ return nil
}
func (c *Core) readAt(addr uint16) uint16 {
@@ -100,7 +87,22 @@ func (c *Core) readAt(addr uint16) uint16 {
return 0
}
-func (c *Core) Eval(ins Instruction) {
+// Run evaluates content of memory
+func (c *Core) Run() {
+ for {
+ ins := c.Decode()
+ err := c.Eval(ins)
+ if err != nil {
+ return
+ }
+ }
+}
+
+func (c *Core) Decode() Instruction {
+ return Decode(c.memory[c.pc])
+}
+
+func (c *Core) Eval(ins Instruction) error {
c.pc++
switch v := ins.(type) {
case Lit:
@@ -121,7 +123,10 @@ func (c *Core) Eval(ins Instruction) {
c.pc = c.r.peek() >> 1
}
if v.NtoAtT {
- c.writeAt(c.st0, c.d.peek())
+ err := c.writeAt(c.st0, c.d.peek())
+ if err != nil {
+ return err
+ }
}
st0 := c.newST0(v.Opcode)
c.d.move(v.Ddir)
@@ -134,6 +139,7 @@ func (c *Core) Eval(ins Instruction) {
}
c.st0 = st0
}
+ return nil
}
var boolValue = map[bool]uint16{
diff --git a/core_test.go b/core_test.go
index be0773e..68229be 100644
--- a/core_test.go
+++ b/core_test.go
@@ -27,6 +27,12 @@ func cmp(t *testing.T, got, want Core) {
}
}
+type mocConsole struct{}
+
+func (m *mocConsole) Read() uint16 { return 0 }
+func (m *mocConsole) Write(uint16) {}
+func (m *mocConsole) Len() uint16 { return 0 }
+
func TestEval(t *testing.T) {
testCases := []struct {
ins []Instruction
@@ -112,7 +118,7 @@ func TestEval(t *testing.T) {
for _, tc := range testCases {
t.Run(fmt.Sprint(tc.ins), func(t *testing.T) {
- state := New()
+ state := New(&mocConsole{})
for _, ins := range tc.ins {
state.Eval(ins)
}
@@ -160,7 +166,7 @@ func TestNextST0(t *testing.T) {
func TestLoadBytes(t *testing.T) {
data := []byte{1, 2, 4, 8}
- j1 := New()
+ j1 := New(&mocConsole{})
if err := j1.LoadBytes(data); err != nil {
t.Fatal(err)
}