From d1ac3b5e930a83b78c5ad871a97e13242983df96 Mon Sep 17 00:00:00 2001 From: Tristan Morgan Date: Mon, 25 Mar 2024 09:53:57 +1100 Subject: [PATCH] Implement opSkip. --- parser/execute.go | 4 ++++ parser/execute_test.go | 5 +++-- parser/instruction.go | 2 ++ parser/instruction_test.go | 1 + parser/tokenise.go | 5 +++++ parser/tokenise_test.go | 8 ++++++++ 6 files changed, 23 insertions(+), 2 deletions(-) diff --git a/parser/execute.go b/parser/execute.go index c92c207..266f87a 100644 --- a/parser/execute.go +++ b/parser/execute.go @@ -41,6 +41,10 @@ func Execute(program []Instruction, reader io.ByteReader, writer *bufio.Writer) } else if err != nil { break } + case opSkip: + for data[dataPtr] != 0 { + dataPtr = (operand + dataPtr) & dataMask + } case opJmpZ: if data[dataPtr] == 0 { pc = operand diff --git a/parser/execute_test.go b/parser/execute_test.go index 84321e1..ef1e8e1 100644 --- a/parser/execute_test.go +++ b/parser/execute_test.go @@ -29,7 +29,8 @@ func TestExecuteSmall(t *testing.T) { func TestTokeniseExecuteSmall(t *testing.T) { program, _ := Tokenise(bufio.NewReader(strings.NewReader( - `+> >+> >+> >+> > + `>>>>>>>>>> +<+< <+< <+< <+ [>>] >++++++++ [ < @@ -40,7 +41,7 @@ func TestTokeniseExecuteSmall(t *testing.T) { outputBuf := bufio.NewWriter(os.Stdout) inputBuf := bufio.NewReader(strings.NewReader("no input.")) data := Execute(program, inputBuf, outputBuf)[:10] - want := []int{170, 0, 0, 0, 0, 0, 0, 0, 0, 0} + want := []int{0, 0, 0, 170, 0, 0, 0, 0, 0, 0} if !reflect.DeepEqual(data, want) { t.Errorf("got %v want %v", data, want) diff --git a/parser/instruction.go b/parser/instruction.go index c107309..14ccb1e 100644 --- a/parser/instruction.go +++ b/parser/instruction.go @@ -23,6 +23,7 @@ const ( opJmpZ opJmpNz opMove + opSkip ) // String representation of Instruction @@ -37,6 +38,7 @@ func (inst Instruction) String() string { "jmpz", "jmpnz", "mov", + "skip", } return fmt.Sprintf("%s:%v", opName[inst.operator], inst.operand) } diff --git a/parser/instruction_test.go b/parser/instruction_test.go index 147204e..99e85e7 100644 --- a/parser/instruction_test.go +++ b/parser/instruction_test.go @@ -43,6 +43,7 @@ func TestSameOp(t *testing.T) { opJmpZ, opJmpNz, opMove, + opSkip, } for row, rval := range opsList { diff --git a/parser/tokenise.go b/parser/tokenise.go index 4ccf695..c896f28 100644 --- a/parser/tokenise.go +++ b/parser/tokenise.go @@ -57,6 +57,11 @@ func Tokenise(input io.ByteReader) (program []Instruction, err error) { pc = jmpPc program = program[:pc] program = append(program, Instruction{opSetVal, 0}) + } else if pc-jmpPc == 2 && program[pc-1].operator == opAddDp { + offset := program[pc-1].operand + pc = jmpPc + program = program[:pc] + program = append(program, Instruction{opSkip, offset}) } else if pc-jmpPc == 5 && program[pc-4].Complement(program[pc-2]) && program[pc-3].Complement(program[pc-1]) { diff --git a/parser/tokenise_test.go b/parser/tokenise_test.go index fdf8baf..5010dd3 100644 --- a/parser/tokenise_test.go +++ b/parser/tokenise_test.go @@ -43,6 +43,14 @@ func TestTokenise(t *testing.T) { Instruction{opAddVal, -4}, }, }, + { + "op_skip", + "[>>>>>]", + []Instruction{ + Instruction{opNoop, 0}, + Instruction{opSkip, 5}, + }, + }, { "op_move", "[->>+<<][<<<+>>>-]",