aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Dessaux2023-01-07 11:10:04 +0100
committerJulien Dessaux2023-01-07 11:10:04 +0100
commit7d6ed4697e9c006b07a5029ea89ecd2198fe9d75 (patch)
tree1610a6ba6a088ba1ffa530a626f99635cc7654d2
parentFixed stack duplicate behaviour (diff)
downloadnimfunge98-7d6ed4697e9c006b07a5029ea89ecd2198fe9d75.tar.gz
nimfunge98-7d6ed4697e9c006b07a5029ea89ecd2198fe9d75.tar.bz2
nimfunge98-7d6ed4697e9c006b07a5029ea89ecd2198fe9d75.zip
Fix several bugs #11.1.3
The load function was too clever, simplified it by using Set This uncovered an initialization bug in Set and a mishandling of Blank
-rw-r--r--examples/empty.b980
-rw-r--r--examples/invalid.b982
-rw-r--r--src/field.nim133
-rw-r--r--tests/field.nim2
4 files changed, 52 insertions, 85 deletions
diff --git a/examples/empty.b98 b/examples/empty.b98
deleted file mode 100644
index e69de29..0000000
--- a/examples/empty.b98
+++ /dev/null
diff --git a/examples/invalid.b98 b/examples/invalid.b98
deleted file mode 100644
index 0a9f039..0000000
--- a/examples/invalid.b98
+++ /dev/null
@@ -1,2 +0,0 @@
-
-@
diff --git a/src/field.nim b/src/field.nim
index e94dba7..71eaf2c 100644
--- a/src/field.nim
+++ b/src/field.nim
@@ -66,84 +66,10 @@ func Get*(f: Field, x, y: int): int =
func IsIn*(f: Field, x, y: int): bool =
return x >= f.x and y >= f.y and x < f.x+f.lx and y < f.y+f.lines.len
-proc Load*(filename: string): ref Field =
- var file: File
- if not open(file, filename):
- return nil
- defer: file.close()
- var f: ref Field
- new(f)
- var l: ptr Line
- var leadingSpaces = 0
- var trailingSpaces = 0
- var data: array[4096, char]
- var lastReadIsCR = false
- while true:
- let n = file.readChars(data)
- if n <= 0:
- if f.lines.len == 0:
- if l == nil: # we got en empty file!
- return nil
- f.x = l.x
- if l != nil:
- if f.lx < l.columns.len+l.x-f.x:
- f.lx = l.columns.len+l.x-f.x
- break
- var i = 0
- while i < n:
- if data[i] == char(12):
- inc i
- continue
- if lastReadIsCR and data[i] == '\n':
- inc i
- lastReadIsCR = false
- continue
- if data[i] == '\n' or data[i] == '\r':
- if f.lines.len == 0:
- return nil
- if f.lines.len == 1:
- f.x = l.x
- if l != nil:
- if f.x > l.x:
- f.x = l.x
- if f.lx < l.columns.len+l.x-f.x:
- f.lx = l.columns.len+l.x-f.x
- else:
- f.lines.add(Line())
- l = nil
- trailingSpaces = 0
- if data[i] == '\r':
- if i+1 < n and data[i+1] == '\n':
- inc i
- else:
- lastReadIsCR = true
- else:
- if data[i] == ' ':
- if l == nil: # trim leading spaces
- inc leadingSpaces
- else:
- inc trailingSpaces
- else:
- if l == nil:
- f.lines.add(Line())
- l = addr f.lines[^1]
- l.x = leadingSpaces
- leadingSpaces = 0
- if trailingSpaces > 0:
- let oldL = l.columns.len
- l.columns.setlen(oldL+trailingSpaces+1)
- for j in oldL..<l.columns.len-1:
- l.columns[j] = int(' ')
- l.columns[^1] = int(data[i])
- trailingSpaces = 0
- else:
- l.columns.add(int(data[i]))
- inc i
- return f
-
func Set*(f: var Field, x, y, v: int) =
if v == int(' '):
f.Blank(x, y)
+ return
elif y >= f.y:
if y < f.y+f.lines.len: # the line exists
var l = addr f.lines[y-f.y]
@@ -179,13 +105,19 @@ func Set*(f: var Field, x, y, v: int) =
f.lx = f.lx + f.x - x
f.x = x
else: # append lines
- f.lines.setlen(y-f.y+1)
- f.lines[y-f.y] = Line(x: x, columns: @[v])
- if f.x > x:
- f.lx = f.lx + f.x - x
+ if f.lines.len == 0: # is it the first line of the field
+ f.lines.setlen(1)
f.x = x
- if f.lx < x-f.x+1:
- f.lx = x-f.x+1
+ f.y = y
+ f.lx = 1
+ else:
+ f.lines.setlen(y-f.y+1)
+ if f.x > x:
+ f.lx = f.lx + f.x - x
+ f.x = x
+ if f.lx < x-f.x+1:
+ f.lx = x-f.x+1
+ f.lines[y-f.y] = Line(x: x, columns: @[v])
else: # prepend lines
var newlines = newSeq[Line](f.lines.len+f.y-y)
newlines[0] = Line(x: x, columns: @[v])
@@ -199,6 +131,45 @@ func Set*(f: var Field, x, y, v: int) =
if f.lx < x-f.x+1:
f.lx = x-f.x+1
+proc Load*(filename: string): ref Field =
+ var file: File
+ if not open(file, filename):
+ return nil
+ defer: file.close()
+ var f: ref Field
+ new(f)
+ var lastReadIsCR = false
+ var x = 0
+ var y = 0
+ while true:
+ var data: array[4096, char]
+ let n = file.readChars(data)
+ if n <= 0:
+ break
+ var i = 0
+ while i < n:
+ if lastReadIsCR:
+ lastReadIsCR = false
+ if data[i] == '\n':
+ inc i
+ continue
+ if data[i] == char(12):
+ discard
+ elif data[i] == '\r':
+ x = 0
+ inc y
+ lastReadIsCR = true
+ elif data[i] == '\n':
+ x = 0
+ inc y
+ #elif data[i] == ' ':
+ # inc x
+ else:
+ f[].Set(x, y, int(data[i]))
+ inc x
+ inc i
+ return f
+
func Step*(f: Field, v: tuple[x, y: int], d: tuple[x, y: int]): (int, int) =
var x = v.x + d.x
var y = v.y + d.y
diff --git a/tests/field.nim b/tests/field.nim
index e386e37..00b6c19 100644
--- a/tests/field.nim
+++ b/tests/field.nim
@@ -106,8 +106,6 @@ suite "Field":
check minimal.IsIn(1, 0) == false
test "Load":
check Load("nonexistant") == nil
- check Load("examples/invalid.b98") == nil
- check Load("examples/empty.b98") == nil
check Load("examples/minimal.b98")[] == Field(lx: 1, lines: @[Line(columns: @['@'].cols)])
let hello = Field(lx: 24, lines: @[Line(columns: @['6', '4', '+', '"', '!', 'd', 'l', 'r', 'o', 'W', ' ', ',', 'o', 'l', 'l', 'e', 'H', '"', '>', ':', '#', ',', '_', '@'].cols)])
check Load("examples/hello.b98")[] == hello