From db0f786777e7fb046f05344170c2a9bb9a8c6a76 Mon Sep 17 00:00:00 2001 From: Jonas Franz Date: Mon, 25 May 2020 18:24:15 +0200 Subject: [PATCH] Improve IO --- hal/command_line_io.go | 26 ++++++++++++++++++++++++++ hal/instructions.go | 9 ++++----- hal/mock_io.go | 32 ++++++++++++++++++++++++++++++++ hal/module.go | 13 +++++++++++-- hal_test.go | 18 +++++++++++++----- 5 files changed, 86 insertions(+), 12 deletions(-) create mode 100644 hal/command_line_io.go create mode 100644 hal/mock_io.go diff --git a/hal/command_line_io.go b/hal/command_line_io.go new file mode 100644 index 0000000..9073502 --- /dev/null +++ b/hal/command_line_io.go @@ -0,0 +1,26 @@ +package hal + +import ( + "fmt" +) + +func NewCommandLineIO(index int) *CommandLineIO { + return &CommandLineIO{ + index: index, + } +} + +type CommandLineIO struct { + index int +} + +func (io *CommandLineIO) Read() (result float64, err error) { + fmt.Printf("Input[%d]: ", io.index) + _, err = fmt.Scanf("%f", &result) + return +} + +func (io *CommandLineIO) Write(output float64) error { + fmt.Printf("Output[%d]: %f\n", io.index, output) + return nil +} diff --git a/hal/instructions.go b/hal/instructions.go index e87ca3a..c6fd640 100644 --- a/hal/instructions.go +++ b/hal/instructions.go @@ -82,20 +82,19 @@ var InstructionOut = &Instruction{ if len(module.IO) <= index { return fmt.Errorf("index %d exceeds IO size of %d", index, len(module.IO)) } - module.IO[int64(operand)] = module.accumulator - return nil + return module.IO[int64(operand)].Write(module.accumulator) }, } var InstructionIn = &Instruction{ Name: "IN", - ExecuteWithOperand: func(module *Module, operand float64) error { + ExecuteWithOperand: func(module *Module, operand float64) (err error) { index := int(operand) if len(module.IO) <= index { return fmt.Errorf("index %d exceeds IO size of %d", index, len(module.IO)) } - module.accumulator = module.IO[index] - return nil + module.accumulator, err = module.IO[index].Read() + return }, } diff --git a/hal/mock_io.go b/hal/mock_io.go new file mode 100644 index 0000000..de35643 --- /dev/null +++ b/hal/mock_io.go @@ -0,0 +1,32 @@ +package hal + +import "fmt" + +func NewMockIO(inputs ...float64) *MockIO { + return &MockIO{ + Inputs: inputs, + } +} + +type MockIO struct { + currentInputIndex int + Inputs []float64 + Outputs []float64 +} + +func (io *MockIO) increaseInputIndex() { + io.currentInputIndex++ +} + +func (io *MockIO) Read() (float64, error) { + if len(io.Inputs) <= io.currentInputIndex { + return 0, fmt.Errorf("no mock data for index %d", io.currentInputIndex) + } + defer io.increaseInputIndex() + return io.Inputs[io.currentInputIndex], nil +} + +func (io *MockIO) Write(output float64) error { + io.Outputs = append(io.Outputs, output) + return nil +} diff --git a/hal/module.go b/hal/module.go index 342b951..11ca62c 100644 --- a/hal/module.go +++ b/hal/module.go @@ -6,11 +6,16 @@ const maxInstructions = 1000 type Program map[int64]*ProgrammedInstruction +type IO interface { + Read() (float64, error) + Write(output float64) error +} + type Module struct { accumulator float64 programStorage Program register []float64 - IO []float64 + IO []IO isStopped bool debugEnabled bool @@ -70,10 +75,14 @@ func NewHALModule(program Program, registerSize uint64, ioSize uint64, debug boo if registerSize <= 10 { return nil, fmt.Errorf("register size must be greater then 10 [ registerSize = %d ]", registerSize) } + ios := make([]IO, ioSize) + for index, _ := range ios { + ios[index] = NewCommandLineIO(index) + } return &Module{ programStorage: program, register: make([]float64, registerSize), - IO: make([]float64, ioSize), + IO: ios, debugEnabled: debug, }, nil } diff --git a/hal_test.go b/hal_test.go index efdd4cf..f80dd99 100644 --- a/hal_test.go +++ b/hal_test.go @@ -37,7 +37,7 @@ func TestMax(t *testing.T) { input := []string{ "00 IN 0", "01 STORE 1", - "02 IN 1", + "02 IN 0", "03 STORE 2", "04 SUB 1", "05 JUMPPOS 9", @@ -55,13 +55,15 @@ func TestMax(t *testing.T) { module, err := hal.NewHALModule(program, 256, 2, false) assert.NoError(t, err) - module.IO[0] = 10 - module.IO[1] = 15 + module.IO[0] = hal.NewMockIO(10, 15) + outputMock := hal.NewMockIO() + module.IO[1] = outputMock err = module.Run() assert.NoError(t, err) - assert.Equal(t, float64(15), module.IO[1]) + assert.Len(t, outputMock.Outputs, 1) + assert.Equal(t, float64(15), outputMock.Outputs[0]) } func TestNewton1(t *testing.T) { @@ -109,12 +111,18 @@ func TestNewton1(t *testing.T) { program, err := parser.ParseProgram(input) assert.NoError(t, err) - module, err := hal.NewHALModule(program, 256, 2, false) + module, err := hal.NewHALModule(program, 256, 1, false) assert.NoError(t, err) + outputMock := hal.NewMockIO() + module.IO[0] = outputMock + err = module.Run() assert.NoError(t, err) + assert.Len(t, outputMock.Outputs, 1) + assert.Equal(t, float64(15), outputMock.Outputs[0]) + assert.Equal(t, calculateNewton(1), module.IO[1]) }