From 65cd45f823c5b6d5221f515d0b07d6c171adb84e Mon Sep 17 00:00:00 2001 From: Jonas Franz Date: Mon, 18 May 2020 20:53:46 +0200 Subject: [PATCH] Implement START and STOP --- example.hal | 2 ++ hal/instructions.go | 11 +++++------ hal/module.go | 19 ++++++++++++++++--- parser/program_parser.go | 4 ++-- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/example.hal b/example.hal index e69de29..b40c4c3 100644 --- a/example.hal +++ b/example.hal @@ -0,0 +1,2 @@ +0 START +1 STOP \ No newline at end of file diff --git a/hal/instructions.go b/hal/instructions.go index 627cfec..ceed661 100644 --- a/hal/instructions.go +++ b/hal/instructions.go @@ -1,7 +1,6 @@ package hal import ( - "fmt" "strings" ) @@ -10,15 +9,14 @@ type ProgrammedInstruction struct { Operand float64 } -func (pi *ProgrammedInstruction) Execute(module *Module) error { +func (pi *ProgrammedInstruction) Execute(module *Module) { if pi.Instruction.ExecuteWithOperand != nil { pi.Instruction.ExecuteWithOperand(module, pi.Operand) } else if pi.Instruction.Execute != nil { pi.Instruction.Execute(module) } else { - return fmt.Errorf("instruction is not implemented") + panic("instruction is not implemented") } - return nil } type Instruction struct { @@ -46,14 +44,15 @@ var instructions = []*Instruction{ var InstructionStart = &Instruction{ Name: "START", Execute: func(module *Module) { - // TODO implement + // actually not required + module.isStopped = false }, } var InstructionStop = &Instruction{ Name: "STOP", Execute: func(module *Module) { - // TODO implement + module.isStopped = true }, } diff --git a/hal/module.go b/hal/module.go index 05b6b50..09ded49 100644 --- a/hal/module.go +++ b/hal/module.go @@ -2,12 +2,15 @@ package hal import "fmt" +const maxInstructions = 1000 + type Program map[int64]*ProgrammedInstruction type Module struct { Accumulator float64 ProgramStorage Program Register []float64 + isStopped bool } func (h *Module) ProgramCounter() int64 { @@ -18,13 +21,23 @@ func (h *Module) increaseProgramCounter() { h.Register[0]++ } -func (h *Module) Step() error { +func (h *Module) Step() { instruction := h.ProgramStorage[h.ProgramCounter()] h.increaseProgramCounter() if instruction == nil { - return fmt.Errorf("instruction not found for program counter = %d", h.ProgramCounter()) + return + } + instruction.Execute(h) +} + +func (h *Module) Run() error { + for !h.isStopped && h.ProgramCounter() <= maxInstructions { + h.Step() + } + if h.ProgramCounter() > maxInstructions { + return fmt.Errorf("module exceeded max instructions without being stopped") } - return instruction.Execute(h) + return nil } func NewHALModule(program Program, registerSize uint64) (*Module, error) { diff --git a/parser/program_parser.go b/parser/program_parser.go index 0026c58..563cb86 100644 --- a/parser/program_parser.go +++ b/parser/program_parser.go @@ -13,7 +13,7 @@ func ParseProgram(input []string) (hal.Program, error) { program := make(hal.Program) for index, line := range input { args := strings.Split(line, " ") - if len(args) == 0 { + if len(args) <= 1 { continue } lineNumber, err := strconv.ParseInt(args[0], 10, 64) @@ -39,7 +39,7 @@ func parseInstruction(args []string) (*hal.ProgrammedInstruction, error) { programmedInstruction := &hal.ProgrammedInstruction{ Instruction: instruction, } - if len(args) == 1 { + if len(args) == 2 { operand, err := strconv.ParseFloat(args[1], 64) if err != nil { return nil, fmt.Errorf("error while parsing operand for instruction '%s': %v", args[0], err)