From 565751db4e5b8370c0a05d1998a91e6e20a19bb4 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Wed, 24 Jan 2018 01:59:13 +0100 Subject: remove context --- cmd/eval/main.go | 10 ++++------ cmd/j1e/main.go | 10 ++++------ console/console.go | 26 ++++++++++++++------------ core.go | 50 ++++++++++++++++++++++++++++---------------------- core_test.go | 10 ++++++++-- 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) } -- cgit v1.2.3