From 7345dcb617db629ccf5a89540a301ecb5e8a0a1f Mon Sep 17 00:00:00 2001 From: Tristan Morgan Date: Mon, 14 Oct 2024 10:04:27 +1100 Subject: [PATCH] Implement an iterator for byte to Instruction convertion. --- go.mod | 2 +- parser/instruction.go | 21 +++++++++++++++++++++ parser/instruction_test.go | 7 +++++-- parser/tokenise.go | 9 +-------- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index c031d70..0134041 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ module github.com/tristanmorgan/bfg -go 1.22.0 +go 1.23.0 diff --git a/parser/instruction.go b/parser/instruction.go index c1ec544..31d5ce2 100644 --- a/parser/instruction.go +++ b/parser/instruction.go @@ -1,5 +1,10 @@ package parser +import ( + "io" + "iter" +) + // Instruction structure for intermediate program type Instruction struct { operator Opcode @@ -37,6 +42,22 @@ var instMap = map[byte]Instruction{ ']': {opJmpNz, 0}, } +// Instructions returns an iterator of the instructions. +func Instructions(input io.ByteReader) iter.Seq[Instruction] { + return func(yield func(Instruction) bool) { + + for { + chr, err := input.ReadByte() + if err == io.EOF { + break + } + if !yield(NewInstruction(chr)) { + return + } + } + } +} + // NewInstruction created from a sourcecode byte func NewInstruction(chr byte) Instruction { return instMap[chr] diff --git a/parser/instruction_test.go b/parser/instruction_test.go index 00ed84d..7f18bde 100644 --- a/parser/instruction_test.go +++ b/parser/instruction_test.go @@ -1,8 +1,10 @@ package parser import ( + "bufio" "fmt" "reflect" + "strings" "testing" "unsafe" ) @@ -57,15 +59,16 @@ func TestNewInstruction(t *testing.T) { {opJmpNz, 0}, } - for idx, val := range []byte(sourceCode) { + idx := 0 + for got := range Instructions(bufio.NewReader(strings.NewReader(sourceCode))) { t.Run(program[idx].String(), func(t *testing.T) { - got := NewInstruction(val) want := program[idx] if !reflect.DeepEqual(got, want) { t.Errorf("got %v want %v", got, want) } }) + idx++ } } diff --git a/parser/tokenise.go b/parser/tokenise.go index 36118f3..25201d5 100644 --- a/parser/tokenise.go +++ b/parser/tokenise.go @@ -11,14 +11,7 @@ func Tokenise(input io.ByteReader) (program []Instruction, err error) { jmpStack := make([]int, 0) program = append(program, Instruction{opNoop, 0}) pc++ - for { - chr, err := input.ReadByte() - if err == io.EOF { - break - } else if err != nil { - return nil, errors.New("tokenisation read error") - } - instruction := NewInstruction(chr) + for instruction := range Instructions(input) { program = append(program, instruction) switch instruction.operator { case opNoop: