rewrote field data structure for simplicity

This commit is contained in:
Julien Dessaux 2021-09-17 00:44:35 +02:00
parent 4bacbc2375
commit 7458dd8aa8
2 changed files with 86 additions and 69 deletions

View file

@ -1,7 +1,6 @@
package field package field
import ( import (
"bytes"
"io" "io"
) )
@ -16,15 +15,17 @@ import (
// y|2,147,483,647 // y|2,147,483,647
type Field struct { type Field struct {
firstLineIndex int x int
length int y int
lines []Line lx int
ly int
lines []Line
} }
type Line struct { type Line struct {
firstColumnIndex int x int
length int l int
columns []byte columns []int
} }
func LoadFile(fd io.Reader) (*Field, error) { func LoadFile(fd io.Reader) (*Field, error) {
@ -35,11 +36,14 @@ func LoadFile(fd io.Reader) (*Field, error) {
data := make([]byte, 4096) data := make([]byte, 4096)
if n, errRead := fd.Read(data); errRead != nil { if n, errRead := fd.Read(data); errRead != nil {
if errRead == io.EOF { if errRead == io.EOF {
if f.length == 0 && l.length == 0 { if f.ly == 0 && l.l == 0 {
return nil, newDecodeError("No instruction on the first line of the file produces an unusable program in Befunge98") return nil, newDecodeError("No instruction on the first line of the file produces an unusable program in Befunge98")
} }
if l.length > 0 { if l.l > 0 {
f.length++ f.ly++
if f.lx < l.l {
f.lx = l.l
}
f.lines = append(f.lines, *l) f.lines = append(f.lines, *l)
} }
break break
@ -49,10 +53,13 @@ func LoadFile(fd io.Reader) (*Field, error) {
} else { } else {
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
if data[i] == '\n' || data[i] == '\r' { if data[i] == '\n' || data[i] == '\r' {
if f.length == 0 && l.length == 0 { if f.ly == 0 && l.l == 0 {
return nil, newDecodeError("No instruction on the first line of the file produces an unusable program in Befunge98") return nil, newDecodeError("No instruction on the first line of the file produces an unusable program in Befunge98")
} }
f.length++ f.ly++
if f.lx < l.l {
f.lx = l.l
}
f.lines = append(f.lines, *l) f.lines = append(f.lines, *l)
l = new(Line) l = new(Line)
trailingSpaces = 0 trailingSpaces = 0
@ -60,17 +67,18 @@ func LoadFile(fd io.Reader) (*Field, error) {
i++ i++
} }
} else { } else {
if l.length == 0 && data[i] == ' ' { if l.l == 0 && data[i] == ' ' {
l.firstColumnIndex++ // trim leading spaces l.x++ // trim leading spaces
} else { } else {
if data[i] == ' ' { if data[i] == ' ' {
trailingSpaces++ trailingSpaces++
} else { } else {
l.columns = append(l.columns, bytes.Repeat([]byte{' '}, trailingSpaces)...) for j := 0; j < trailingSpaces; j++ {
l.length += trailingSpaces l.columns = append(l.columns, ' ')
}
l.l += trailingSpaces + 1
trailingSpaces = 0 trailingSpaces = 0
l.length++ l.columns = append(l.columns, int(data[i]))
l.columns = append(l.columns, data[i])
} }
} }
} }

View file

@ -6,108 +6,117 @@ import (
"testing" "testing"
"testing/iotest" "testing/iotest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestLoadFile(t *testing.T) { func TestLoadFile(t *testing.T) {
// minimal b98 file // minimal b98 file
minimalField := Field{ minimalField := Field{
firstLineIndex: 0, x: 0,
length: 1, y: 0,
lx: 1,
ly: 1,
lines: []Line{ lines: []Line{
Line{ Line{
firstColumnIndex: 0, x: 0,
length: 1, l: 1,
columns: []byte{'@'}, columns: []int{'@'},
}, },
}, },
} }
// hello b98 file // hello b98 file
helloField := Field{ helloField := Field{
firstLineIndex: 0, x: 0,
length: 1, y: 0,
lx: 24,
ly: 1,
lines: []Line{ lines: []Line{
Line{ Line{
firstColumnIndex: 0, x: 0,
length: 24, l: 24,
columns: []byte{'6', '4', '+', '"', '!', 'd', 'l', 'r', 'o', 'W', ' ', ',', 'o', 'l', 'l', 'e', 'H', '"', '>', ':', '#', ',', '_', '@'}, columns: []int{'6', '4', '+', '"', '!', 'd', 'l', 'r', 'o', 'W', ' ', ',', 'o', 'l', 'l', 'e', 'H', '"', '>', ':', '#', ',', '_', '@'},
}, },
}, },
} }
// factorial b98 file // factorial b98 file
factorialField := Field{ factorialField := Field{
firstLineIndex: 0, x: 0,
length: 2, y: 0,
lx: 15,
ly: 2,
lines: []Line{ lines: []Line{
Line{ Line{
firstColumnIndex: 0, x: 0,
length: 15, l: 15,
columns: []byte{'&', '>', ':', '1', '-', ':', 'v', ' ', 'v', ' ', '*', '_', '$', '.', '@'}, columns: []int{'&', '>', ':', '1', '-', ':', 'v', ' ', 'v', ' ', '*', '_', '$', '.', '@'},
}, },
Line{ Line{
firstColumnIndex: 1, x: 1,
length: 11, l: 11,
columns: []byte{'^', ' ', ' ', ' ', ' ', '_', '$', '>', '\\', ':', '^'}, columns: []int{'^', ' ', ' ', ' ', ' ', '_', '$', '>', '\\', ':', '^'},
}, },
}, },
} }
// dna b98 file // dna b98 file
dnaField := Field{ dnaField := Field{
firstLineIndex: 0, x: 0,
length: 8, y: 0,
lx: 7,
ly: 8,
lines: []Line{ lines: []Line{
Line{ Line{
firstColumnIndex: 0, x: 0,
length: 7, l: 7,
columns: []byte{'7', '^', 'D', 'N', '>', 'v', 'A'}, columns: []int{'7', '^', 'D', 'N', '>', 'v', 'A'},
}, },
Line{ Line{
firstColumnIndex: 0, x: 0,
length: 7, l: 7,
columns: []byte{'v', '_', '#', 'v', '?', ' ', 'v'}, columns: []int{'v', '_', '#', 'v', '?', ' ', 'v'},
}, },
Line{ Line{
firstColumnIndex: 0, x: 0,
length: 7, l: 7,
columns: []byte{'7', '^', '<', '"', '"', '"', '"'}, columns: []int{'7', '^', '<', '"', '"', '"', '"'},
}, },
Line{ Line{
firstColumnIndex: 0, x: 0,
length: 7, l: 7,
columns: []byte{'3', ' ', ' ', 'A', 'C', 'G', 'T'}, columns: []int{'3', ' ', ' ', 'A', 'C', 'G', 'T'},
}, },
Line{ Line{
firstColumnIndex: 0, x: 0,
length: 7, l: 7,
columns: []byte{'9', '0', '!', '"', '"', '"', '"'}, columns: []int{'9', '0', '!', '"', '"', '"', '"'},
}, },
Line{ Line{
firstColumnIndex: 0, x: 0,
length: 7, l: 7,
columns: []byte{'4', '*', ':', '>', '>', '>', 'v'}, columns: []int{'4', '*', ':', '>', '>', '>', 'v'},
}, },
Line{ Line{
firstColumnIndex: 0, x: 0,
length: 7, l: 7,
columns: []byte{'+', '8', '^', '-', '1', ',', '<'}, columns: []int{'+', '8', '^', '-', '1', ',', '<'},
}, },
Line{ Line{
firstColumnIndex: 0, x: 0,
length: 7, l: 7,
columns: []byte{'>', ' ', ',', '+', ',', '@', ')'}, columns: []int{'>', ' ', ',', '+', ',', '@', ')'},
}, },
}, },
} }
// \r\n file b98 file // \r\n file b98 file
rnField := Field{ rnField := Field{
firstLineIndex: 0, x: 0,
length: 1, y: 0,
lx: 24,
ly: 1,
lines: []Line{ lines: []Line{
Line{ Line{
firstColumnIndex: 0, x: 0,
length: 24, l: 24,
columns: []byte{'6', '4', '+', '"', '!', 'd', 'l', 'r', 'o', 'W', ' ', ',', 'o', 'l', 'l', 'e', 'H', '"', '>', ':', '#', ',', '_', '@'}, columns: []int{'6', '4', '+', '"', '!', 'd', 'l', 'r', 'o', 'W', ' ', ',', 'o', 'l', 'l', 'e', 'H', '"', '>', ':', '#', ',', '_', '@'},
}, },
}, },
} }
@ -148,7 +157,7 @@ func TestLoadFile(t *testing.T) {
} else { } else {
require.NoError(t, err) require.NoError(t, err)
} }
assert.Equal(t, tc.expected, valid, "Invalid value") require.Equal(t, tc.expected, valid, "Invalid value")
}) })
} }
} }