From 9203a1742e83cccccb5c44c08c82a1f7bb4733a9 Mon Sep 17 00:00:00 2001 From: Tristan Morgan Date: Thu, 22 Aug 2024 15:26:03 +1000 Subject: [PATCH] OpVec - vector multiply --- parser/execute.go | 10 ++++++++++ parser/execute_test.go | 6 +++++- parser/instruction.go | 1 + parser/instruction_test.go | 4 ++++ parser/print.go | 9 +++++++-- parser/print_test.go | 5 ++++- parser/tokenise.go | 8 ++++++++ parser/tokenise_test.go | 11 +++++++++++ 8 files changed, 50 insertions(+), 4 deletions(-) diff --git a/parser/execute.go b/parser/execute.go index 24f463c..b3c414d 100644 --- a/parser/execute.go +++ b/parser/execute.go @@ -82,6 +82,16 @@ func Execute[T Number](data []T, program []Instruction, reader io.ByteReader, wr data[secondPtr] += data[dataPtr] data[dataPtr] = 0 pc++ + case opVec: + factor := program[pc+2].operand + dataVal := data[dataPtr] * T(factor) + firstPtr := (operand + dataPtr) & DataMask + data[firstPtr] += dataVal + secondPtr := (program[pc+1].operand + dataPtr) & DataMask + data[secondPtr] += dataVal + data[dataPtr] = 0 + pc++ + pc++ case opNoop: continue default: diff --git a/parser/execute_test.go b/parser/execute_test.go index 4b0c69d..500568a 100644 --- a/parser/execute_test.go +++ b/parser/execute_test.go @@ -28,12 +28,16 @@ func TestExecuteSmall(t *testing.T) { {opOut, 1}, {opIn, 1}, {opMovN, 2}, + {opAddDp, 1}, + {opVec, 2}, + {opNoop, 3}, + {opNoop, 2}, } startdata := make([]int, 65536) outputBuf := bufio.NewWriter(&bufferWriter{}) inputBuf := bufio.NewReader(strings.NewReader("no input.")) data := Execute(startdata, program, inputBuf, outputBuf)[:10] - want := []int{0, 0, 0, 0, 10, -100, 0, 0, 0, 0} + want := []int{0, 0, 0, 0, 0, -100, 20, 20, 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 b1fcce5..c1ec544 100644 --- a/parser/instruction.go +++ b/parser/instruction.go @@ -23,6 +23,7 @@ const ( opSkip opMulVal opDupVal + opVec ) var instMap = map[byte]Instruction{ diff --git a/parser/instruction_test.go b/parser/instruction_test.go index 99f0878..00ed84d 100644 --- a/parser/instruction_test.go +++ b/parser/instruction_test.go @@ -21,6 +21,7 @@ var opName = map[Opcode]string{ opSkip: "skp", opMulVal: "mul", opDupVal: "dup", + opVec: "vec", } func (inst Instruction) String() string { @@ -84,6 +85,7 @@ func TestIsZeroOp(t *testing.T) { {opMovN, 1}, {opMulVal, 1}, {opDupVal, 1}, + {opVec, 1}, } want := []bool{ true, @@ -100,6 +102,7 @@ func TestIsZeroOp(t *testing.T) { true, true, true, + true, } for idx, val := range program { @@ -123,6 +126,7 @@ func TestSameOp(t *testing.T) { opSkip, opMulVal, opDupVal, + opVec, } for row, rval := range opsList { diff --git a/parser/print.go b/parser/print.go index 745cfce..1d28b6c 100644 --- a/parser/print.go +++ b/parser/print.go @@ -20,7 +20,7 @@ func repeatDirection(neg, pos string, vect int) string { return strings.Repeat(neg, abs(vect)) } -func instPrint(inst, lastInst Instruction) string { +func instPrint(inst, lastInst, lastlastInst Instruction) string { switch inst.operator { case opAddDp: return repeatDirection("<", ">", inst.operand) @@ -52,6 +52,9 @@ func instPrint(inst, lastInst Instruction) string { return "[-" + repeatDirection("<", ">", lastInst.operand) + multiplier + repeatDirection(">", "<", lastInst.operand) + "]" } else if lastInst.operator == opDupVal { return "[-" + repeatDirection("<", ">", lastInst.operand) + "+" + repeatDirection("<", ">", inst.operand-lastInst.operand) + "+" + repeatDirection(">", "<", inst.operand) + "]" + } else if lastlastInst.operator == opVec { + multiplier := repeatDirection("-", "+", inst.operand) + return "[-" + repeatDirection("<", ">", lastlastInst.operand) + multiplier + repeatDirection("<", ">", lastInst.operand-lastlastInst.operand) + multiplier + repeatDirection(">", "<", lastInst.operand) + "]" } return "" default: @@ -65,17 +68,19 @@ func Print(program []Instruction, writer *bufio.Writer) { startLoop := NewInstruction('[') endLoop := NewInstruction(']') lastInst := NewInstruction('!') + lastlastInst := NewInstruction('!') for _, inst := range program { if inst.SameOp(endLoop) { depth-- } - printout := instPrint(inst, lastInst) + printout := instPrint(inst, lastInst, lastlastInst) if printout != "" { fmt.Fprintln(writer, strings.Repeat("\t", depth), printout) } if inst.SameOp(startLoop) { depth++ } + lastlastInst = lastInst lastInst = inst } writer.Flush() diff --git a/parser/print_test.go b/parser/print_test.go index e8745b5..352b4e7 100644 --- a/parser/print_test.go +++ b/parser/print_test.go @@ -22,6 +22,9 @@ func TestPrint(t *testing.T) { {opNoop, 2}, {opDupVal, 1}, {opNoop, 2}, + {opVec, 1}, + {opNoop, 2}, + {opNoop, 3}, {opJmpNz, 5}, {opAddDp, 2}, {opOut, 1}, @@ -31,7 +34,7 @@ func TestPrint(t *testing.T) { outputBuf := bufio.NewWriter(&buf) Print(program, outputBuf) got := buf.String() - want := " >>>>>\n [-]\n +++++\n [->>+<<]\n [\n\t ,\n\t [<<<]\n\t ++\n\t [->>++<<]\n\t [->+>+<<]\n ]\n >>\n .\n [->>-<<]\n" + want := " >>>>>\n [-]\n +++++\n [->>+<<]\n [\n\t ,\n\t [<<<]\n\t ++\n\t [->>++<<]\n\t [->+>+<<]\n\t [->+++>+++<<]\n ]\n >>\n .\n [->>-<<]\n" if !reflect.DeepEqual(got, want) { t.Errorf("got %v want %v", got, want) diff --git a/parser/tokenise.go b/parser/tokenise.go index 5c7ffac..05847ce 100644 --- a/parser/tokenise.go +++ b/parser/tokenise.go @@ -93,6 +93,14 @@ func Tokenise(input io.ByteReader) (program []Instruction, err error) { program = append(program, Instruction{opDupVal, pointers[0]}) pc++ program = append(program, Instruction{opNoop, pointers[1]}) + } else if ok && factors[0] == factors[1] { + pc = jmpPc + program = program[:pc] + program = append(program, Instruction{opVec, pointers[0]}) + pc++ + program = append(program, Instruction{opNoop, pointers[1]}) + pc++ + program = append(program, Instruction{opNoop, factors[1]}) } } } diff --git a/parser/tokenise_test.go b/parser/tokenise_test.go index 64f5c25..86b659e 100644 --- a/parser/tokenise_test.go +++ b/parser/tokenise_test.go @@ -82,6 +82,17 @@ func TestTokenise(t *testing.T) { {opMovN, 1}, }, }, + { + "op_vec", + ">[->>+++>+++<<<]", + []Instruction{ + {opNoop, 0}, + {opAddDp, 1}, + {opVec, 2}, + {opNoop, 3}, + {opNoop, 3}, + }, + }, { "op_dup", ">[->>+>+<<<]>[>>+<<-<<+>>]",