From a1e10543a4f23356898b0dec65650f8e50d9d2c5 Mon Sep 17 00:00:00 2001 From: Tristan Morgan Date: Mon, 25 Mar 2024 15:11:13 +1100 Subject: [PATCH] Tweak tokenise. --- README.md | 30 ++++++++++++++++++++++++------ parser/tokenise.go | 17 +++++++++-------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 950f56b..96d46f6 100644 --- a/README.md +++ b/README.md @@ -6,16 +6,34 @@ BFG is an optimised [Brainfuck](https://esolangs.org/wiki/Brainfuck) interpreter Uses signed ints for data (platform specific 32/64), memory wraps around at 65535, EOF returns -1. +Buffered output flushes on newline, 200 chars or input. + ## Optimisations -[-] is replaced with a blind set 0 command +Operates with a instruction parse then execute pattern. + + * loop start/end are calculated up front. + * [-] is replaced with a blind set 0 command + * repeat ++++ or --- are replaced with a single addition/subtraction + * addition/subtraction after zero does a blind set. + * repeat >>> or <<< are replaced with a single pointer jump + * [>>>] and [<<<] are merged into a skip instruction. + * [>>+<<-] and [->>+<<] merged into a move instruction. + +for performance comparison see no_optimisation branch. -repeat ++++ or --- are replaced with a single addition/subtraction +## Usage -addition/subtraction after zero does a blind set. + Usage: + bf [option] source.bf [input] + + Options: + -version + display version -repeat >>> or <<< are replaced with a single pointer jump +May use - as source to read program from STDIN and output is STDOUT -[>>+<<-] and [->>+<<] merged into a move instruction. + +++++++++[>++++++++>++++++++++++>++++>++++++++++++>+++++++++++>+<<<<<<-]>---.>++ + .----.+++++.++++++++++.>----.<-----.>>----.+.<<-.>.<<---.>-.>>>--.<.+++++.<<<+++ + +.>+++.>>>++.<---.<+.>>>+. -buffered output prints on newline, 200 chars or input. diff --git a/parser/tokenise.go b/parser/tokenise.go index c896f28..f7a233a 100644 --- a/parser/tokenise.go +++ b/parser/tokenise.go @@ -18,28 +18,29 @@ func Tokenise(input io.ByteReader) (program []Instruction, err error) { } else if err != nil { return nil, errors.New("tokenisation read error") } - program = append(program, NewInstruction(chr)) - switch program[pc].operator { + instruction := NewInstruction(chr) + program = append(program, instruction) + switch instruction.operator { case opNoop: program = program[:pc] pc-- case opAddDp: - if program[pc-1].SameOp(program[pc]) { - program[pc-1].operand += program[pc].operand + if program[pc-1].SameOp(instruction) { + program[pc-1].operand += instruction.operand program = program[:pc] pc-- } case opAddVal: - if program[pc-1].SameOp(program[pc]) { - program[pc-1].operand += program[pc].operand + if program[pc-1].SameOp(instruction) { + program[pc-1].operand += instruction.operand program = program[:pc] pc-- } else if program[pc-1].operator == opSetVal { - program[pc-1].operand += program[pc].operand + program[pc-1].operand += instruction.operand program = program[:pc] pc-- } else if program[pc-1].operator == opJmpNz { - operand := program[pc].operand + operand := instruction.operand program = program[:pc] program = append(program, Instruction{opSetVal, operand}) }