Skip to content

Commit

Permalink
README.md format tweak and try multiply operation.
Browse files Browse the repository at this point in the history
  • Loading branch information
tristanmorgan committed Apr 29, 2024
1 parent 76e4205 commit e0242bb
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 8 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Operates with a instruction parse then execute pattern.
* repeat >>> or <<< are replaced with a single pointer jump
* [>>>] and [<<<] are merged into a skip instruction.
* [>>+<<-] and [->>+<<] merged into a move instruction.
* [<+++++>-] is converted to a Multiply instruction.

for performance comparison see no_optimisation branch.

Expand All @@ -33,7 +34,7 @@ for performance comparison see no_optimisation branch.

Options:
-dump
dump parsed program
dump parsed program
-eight
eight bit execution
-version
Expand Down
6 changes: 6 additions & 0 deletions parser/execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ func Execute[T Number](data []T, program []Instruction, reader io.ByteReader, wr
destPtr := (operand + dataPtr) & DataMask
data[destPtr] += data[dataPtr]
data[dataPtr] = 0
case opMulVal:
destPtr := (operand + dataPtr) & DataMask
factor := program[pc+1].operand
data[destPtr] += data[dataPtr] * T(factor)
data[dataPtr] = 0
pc++
case opNoop:
continue
default:
Expand Down
4 changes: 3 additions & 1 deletion parser/execute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ func TestExecuteSmall(t *testing.T) {
{opAddVal, 5},
{opMove, 2},
{opAddDp, 2},
{opMulVal, -1},
{opNoop, 2},
}
startdata := make([]int, 65536)
outputBuf := bufio.NewWriter(os.Stdout)
inputBuf := bufio.NewReader(strings.NewReader("no input."))
data := Execute(startdata, program, inputBuf, outputBuf)[:10]
want := []int{0, 0, 0, 0, 0, 0, 0, 5, 0, 0}
want := []int{0, 0, 0, 0, 0, 0, 10, 0, 0, 0}

if !reflect.DeepEqual(data, want) {
t.Errorf("got %v want %v", data, want)
Expand Down
2 changes: 2 additions & 0 deletions parser/instruction.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const (
opJmpNz
opMove
opSkip
opMulVal
)

// String representation of Instruction
Expand All @@ -39,6 +40,7 @@ func (inst Instruction) String() string {
"jnz",
"mov",
"skp",
"mul",
}
return fmt.Sprintf("%s: %v", opName[inst.operator], inst.operand)
}
Expand Down
2 changes: 1 addition & 1 deletion parser/instruction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func TestSameOp(t *testing.T) {
opJmpNz,
opMove,
opSkip,
opMulVal,
}

for row, rval := range opsList {
Expand Down Expand Up @@ -83,5 +84,4 @@ func TestComplement(t *testing.T) {
})
}
}

}
22 changes: 17 additions & 5 deletions parser/tokenise.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func Tokenise(input io.ByteReader) (program []Instruction, err error) {
program[pc-1].operand += instruction.operand
program = program[:pc]
pc--
} else if program[pc-1].operator == opJmpNz {
} else if program[pc-1].SameOp(NewInstruction(']')) {
operand := instruction.operand
program = program[:pc]
program = append(program, Instruction{opSetVal, operand})
Expand All @@ -51,25 +51,37 @@ func Tokenise(input io.ByteReader) (program []Instruction, err error) {
jmpStack = jmpStack[:len(jmpStack)-1]
program[pc].operand = jmpPc
program[jmpPc].operand = pc
if pc-jmpPc == 2 && program[pc-1].operator == opAddVal {
if pc-jmpPc == 2 && program[pc-1].SameOp(NewInstruction('+')) {
pc = jmpPc
program = program[:pc]
program = append(program, Instruction{opSetVal, 0})
} else if pc-jmpPc == 2 && program[pc-1].operator == opAddDp {
} else if pc-jmpPc == 2 && program[pc-1].SameOp(NewInstruction('>')) {
offset := program[pc-1].operand
pc = jmpPc
program = program[:pc]
program = append(program, Instruction{opSkip, offset})
} else if pc-jmpPc == 5 &&
} else if pc-jmpPc == 5 && // [<<<+>>>-] or [-<<<+>>>]
program[pc-4].Complement(program[pc-2]) &&
program[pc-3].Complement(program[pc-1]) {
offset := program[pc-4].operand
if program[pc-3].operator == opAddDp {
if program[pc-3].SameOp(NewInstruction('>')) {
offset = program[pc-3].operand
}
pc = jmpPc
program = program[:pc]
program = append(program, Instruction{opMove, offset})
} else if pc-jmpPc == 5 && // [<<++++>>-]
program[pc-4].Complement(program[pc-2]) &&
program[pc-3].SameOp(NewInstruction('+')) &&
program[pc-1].SameOp(NewInstruction('-')) &&
program[pc-1].operand == -1 {
offset := program[pc-4].operand
factor := program[pc-3].operand
pc = jmpPc
program = program[:pc]
program = append(program, Instruction{opMulVal, offset})
pc++
program = append(program, Instruction{opNoop, factor})
}
}
pc++
Expand Down
9 changes: 9 additions & 0 deletions parser/tokenise_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ func TestTokenise(t *testing.T) {
{opAddDp, 2},
},
},
{
"op_mul",
" [<++++++>-]",
[]Instruction{
Instruction{opNoop, 0},
Instruction{opMulVal, -1}, // dest value pointer
Instruction{opNoop, 6}, // multiplication factor
},
},
{
"op_dp",
">>>>>>><<<<<<>",
Expand Down

0 comments on commit e0242bb

Please sign in to comment.