renamed writeln to writeLine in tests

This commit is contained in:
patrick dw 2015-06-19 01:34:34 -05:00
commit 69e15ac32f
39 changed files with 456 additions and 456 deletions

View file

@ -11,8 +11,8 @@ type
proc len(x: TMyType): int {.inline.} = return x.len proc len(x: TMyType): int {.inline.} = return x.len
proc x(s: TMyType, len: int) = proc x(s: TMyType, len: int) =
writeln(stdout, len(s)) writeLine(stdout, len(s))
var var
m: TMyType m: TMyType

View file

@ -10,6 +10,6 @@ import mambsym1, times
var var
v = mDec #ERROR_MSG ambiguous identifier v = mDec #ERROR_MSG ambiguous identifier
writeln(stdout, ord(v)) writeLine(stdout, ord(v))

View file

@ -22,10 +22,10 @@ proc test() =
b = a # perform a deep copy here! b = a # perform a deep copy here!
b.seq = @["xyz", "huch", "was", "soll"] b.seq = @["xyz", "huch", "was", "soll"]
writeln(stdout, len(a.seq)) writeLine(stdout, len(a.seq))
writeln(stdout, a.seq[3]) writeLine(stdout, a.seq[3])
writeln(stdout, len(b.seq)) writeLine(stdout, len(b.seq))
writeln(stdout, b.seq[3]) writeLine(stdout, b.seq[3])
writeln(stdout, b.y) writeLine(stdout, b.y)
test() test()

View file

@ -16,8 +16,8 @@ proc main() =
p = find(example, "=") p = find(example, "=")
a = substr(example, 0, p-1) a = substr(example, 0, p-1)
b = substr(example, p+1) b = substr(example, p+1)
writeln(stdout, a & '=' & b) writeLine(stdout, a & '=' & b)
#writeln(stdout, b) #writeLine(stdout, b)
main() main()
#OUT TEMP=C:\Programs\xyz\bin #OUT TEMP=C:\Programs\xyz\bin

View file

@ -13,7 +13,7 @@ type
proc forw: int {. .} proc forw: int {. .}
proc lier(): int {.raises: [IO2Error].} = proc lier(): int {.raises: [IO2Error].} =
writeln stdout, "arg" writeLine stdout, "arg"
proc forw: int = proc forw: int =
raise newException(IOError, "arg") raise newException(IOError, "arg")

View file

@ -13,7 +13,7 @@ type
proc forw: int {.raises: [].} proc forw: int {.raises: [].}
proc lier(): int {.raises: [IOError].} = proc lier(): int {.raises: [IOError].} =
writeln stdout, "arg" writeLine stdout, "arg"
proc forw: int = proc forw: int =
raise newException(IOError, "arg") raise newException(IOError, "arg")

View file

@ -12,7 +12,7 @@ type
EIO2 = ref object of EIO EIO2 = ref object of EIO
proc raiser(): int {.tags: [TObj, FWriteIO].} = proc raiser(): int {.tags: [TObj, FWriteIO].} =
writeln stdout, "arg" writeLine stdout, "arg"
var o: TObjB var o: TObjB
o.fn = raiser o.fn = raiser

View file

@ -15,7 +15,7 @@ proc q() {.tags: [FIO].} =
nil nil
proc raiser(): int = proc raiser(): int =
writeln stdout, "arg" writeLine stdout, "arg"
if true: if true:
q() q()

View file

@ -63,12 +63,12 @@ proc caseTree(lvl: int = 0): PCaseNode =
if lvl == 3: result = newCaseNode("data item") if lvl == 3: result = newCaseNode("data item")
else: result = newCaseNode(caseTree(lvl+1), caseTree(lvl+1)) else: result = newCaseNode(caseTree(lvl+1), caseTree(lvl+1))
proc finalizeBNode(n: TBNode) = writeln(stdout, n.data) proc finalizeBNode(n: TBNode) = writeLine(stdout, n.data)
proc finalizeNode(n: PNode) = proc finalizeNode(n: PNode) =
assert(n != nil) assert(n != nil)
write(stdout, "finalizing: ") write(stdout, "finalizing: ")
if isNil(n.data): writeln(stdout, "nil!") if isNil(n.data): writeLine(stdout, "nil!")
else: writeln(stdout, n.data) else: writeLine(stdout, n.data)
var var
id: int = 1 id: int = 1
@ -82,7 +82,7 @@ proc buildTree(depth = 1): PNode =
inc(id) inc(id)
proc returnTree(): PNode = proc returnTree(): PNode =
writeln(stdout, "creating id: " & $id) writeLine(stdout, "creating id: " & $id)
new(result, finalizeNode) new(result, finalizeNode)
result.data = $id result.data = $id
new(result.le, finalizeNode) new(result.le, finalizeNode)
@ -92,26 +92,26 @@ proc returnTree(): PNode =
inc(id) inc(id)
# now create a cycle: # now create a cycle:
writeln(stdout, "creating id (cyclic): " & $id) writeLine(stdout, "creating id (cyclic): " & $id)
var cycle: PNode var cycle: PNode
new(cycle, finalizeNode) new(cycle, finalizeNode)
cycle.data = $id cycle.data = $id
cycle.le = cycle cycle.le = cycle
cycle.ri = cycle cycle.ri = cycle
inc(id) inc(id)
#writeln(stdout, "refcount: " & $refcount(cycle)) #writeLine(stdout, "refcount: " & $refcount(cycle))
#writeln(stdout, "refcount le: " & $refcount(cycle.le)) #writeLine(stdout, "refcount le: " & $refcount(cycle.le))
#writeln(stdout, "refcount ri: " & $refcount(cycle.ri)) #writeLine(stdout, "refcount ri: " & $refcount(cycle.ri))
proc printTree(t: PNode) = proc printTree(t: PNode) =
if t == nil: return if t == nil: return
writeln(stdout, "printing") writeLine(stdout, "printing")
writeln(stdout, t.data) writeLine(stdout, t.data)
printTree(t.le) printTree(t.le)
printTree(t.ri) printTree(t.ri)
proc unsureNew(result: var PNode) = proc unsureNew(result: var PNode) =
writeln(stdout, "creating unsure id: " & $id) writeLine(stdout, "creating unsure id: " & $id)
new(result, finalizeNode) new(result, finalizeNode)
result.data = $id result.data = $id
new(result.le, finalizeNode) new(result.le, finalizeNode)
@ -176,7 +176,7 @@ proc main() =
var s: seq[string] = @[] var s: seq[string] = @[]
for i in 1..100: for i in 1..100:
add s, "hohoho" # test reallocation add s, "hohoho" # test reallocation
writeln(stdout, s[89]) writeLine(stdout, s[89])
write(stdout, "done!\n") write(stdout, "done!\n")
var var
@ -184,7 +184,7 @@ var
s: string s: string
s = "" s = ""
s = "" s = ""
writeln(stdout, repr(caseTree())) writeLine(stdout, repr(caseTree()))
father.t.data = @["ha", "lets", "stress", "it"] father.t.data = @["ha", "lets", "stress", "it"]
father.t.data = @["ha", "lets", "stress", "it"] father.t.data = @["ha", "lets", "stress", "it"]
var t = buildTree() var t = buildTree()
@ -199,5 +199,5 @@ GC_fullCollect()
# the M&S GC fails with this call and it's unclear why. Definitely something # the M&S GC fails with this call and it's unclear why. Definitely something
# we need to fix! # we need to fix!
GC_fullCollect() GC_fullCollect()
writeln(stdout, GC_getStatistics()) writeLine(stdout, GC_getStatistics())
write(stdout, "finished\n") write(stdout, "finished\n")

View file

@ -15,7 +15,7 @@ if find(root, "world"):
for str in items(root): for str in items(root):
stdout.write(str) stdout.write(str)
else: else:
stdout.writeln("BUG") stdout.writeLine("BUG")
var var
r2: PBinaryTree[int] r2: PBinaryTree[int]

View file

@ -92,7 +92,7 @@ when isMainModule:
for str in items(root): for str in items(root):
stdout.write(str) stdout.write(str)
else: else:
stdout.writeln("BUG") stdout.writeLine("BUG")
var var
r2: PBinaryTree[int] r2: PBinaryTree[int]

View file

@ -37,25 +37,25 @@ proc clean[T: SomeOrdinal|SomeNumber](o: var T) {.inline.} = discard
proc clean[T: string|seq](o: var T) {.inline.} = proc clean[T: string|seq](o: var T) {.inline.} =
o = nil o = nil
proc clean[T,D] (o: ref TItem[T,D]) {.inline.} = proc clean[T,D] (o: ref TItem[T,D]) {.inline.} =
when (D is string) : when (D is string) :
o.value = nil o.value = nil
else : else :
o.val_set = false o.val_set = false
proc isClean[T,D] (it: ref TItem[T,D]): bool {.inline.} = proc isClean[T,D] (it: ref TItem[T,D]): bool {.inline.} =
when (D is string) : when (D is string) :
return it.value == nil return it.value == nil
else : else :
return not it.val_set return not it.val_set
proc isClean[T,D](n: PNode[T,D], x: int): bool {.inline.} = proc isClean[T,D](n: PNode[T,D], x: int): bool {.inline.} =
when (D is string): when (D is string):
return n.slots[x].value == nil return n.slots[x].value == nil
else: else:
return not n.slots[x].val_set return not n.slots[x].val_set
proc setItem[T,D](Akey: T, Avalue: D, ANode: PNode[T,D]): ref TItem[T,D] {.inline.} = proc setItem[T,D](Akey: T, Avalue: D, ANode: PNode[T,D]): ref TItem[T,D] {.inline.} =
new(result) new(result)
result.key = Akey result.key = Akey
result.value = Avalue result.value = Avalue
@ -72,8 +72,8 @@ template binSearchImpl *(docmp: expr) {.immediate.} =
var H = haystack.len -1 var H = haystack.len -1
while result <= H : while result <= H :
var I {.inject.} = (result + H) shr 1 var I {.inject.} = (result + H) shr 1
var SW = docmp var SW = docmp
if SW < 0: result = I + 1 if SW < 0: result = I + 1
else: else:
H = I - 1 H = I - 1
if SW == 0 : bFound = true if SW == 0 : bFound = true
@ -85,14 +85,14 @@ proc bSearch[T,D] (haystack: PNode[T,D], needle:T): int {.inline.} =
proc DeleteItem[T,D] (n: PNode[T,D], x: int): PNode[T,D] {.inline.} = proc DeleteItem[T,D] (n: PNode[T,D], x: int): PNode[T,D] {.inline.} =
var w = n.slots[x] var w = n.slots[x]
if w.node != nil : if w.node != nil :
clean(w) clean(w)
return n return n
dec(n.count) dec(n.count)
if n.count > 0 : if n.count > 0 :
for i in countup(x, n.count -1) : n.slots[i] = n.slots[i + 1] for i in countup(x, n.count -1) : n.slots[i] = n.slots[i + 1]
n.slots[n.count] = nil n.slots[n.count] = nil
case n.count case n.count
of cLen1 : setLen(n.slots, cLen1) of cLen1 : setLen(n.slots, cLen1)
of cLen2 : setLen(n.slots, cLen2) of cLen2 : setLen(n.slots, cLen2)
of cLen3 : setLen(n.slots, cLen3) of cLen3 : setLen(n.slots, cLen3)
@ -106,7 +106,7 @@ proc DeleteItem[T,D] (n: PNode[T,D], x: int): PNode[T,D] {.inline.} =
n.slots = nil n.slots = nil
n.left = nil n.left = nil
proc internalDelete[T,D] (ANode: PNode[T,D], key: T, Avalue: var D): PNode[T,D] = proc internalDelete[T,D] (ANode: PNode[T,D], key: T, Avalue: var D): PNode[T,D] =
var Path: array[0..20, RPath[T,D]] var Path: array[0..20, RPath[T,D]]
var n = ANode var n = ANode
result = n result = n
@ -126,20 +126,20 @@ proc internalDelete[T,D] (ANode: PNode[T,D], key: T, Avalue: var D): PNode[T,D]
n = n.slots[x].node n = n.slots[x].node
else : else :
n = nil n = nil
else : else :
dec(x) dec(x)
if isClean(n, x) : return if isClean(n, x) : return
Avalue = n.slots[x].value Avalue = n.slots[x].value
var n2 = DeleteItem(n, x) var n2 = DeleteItem(n, x)
dec(h) dec(h)
while (n2 != n) and (h >=0) : while (n2 != n) and (h >=0) :
n = n2 n = n2
var w = addr Path[h] var w = addr Path[h]
x = w.Xi -1 x = w.Xi -1
if x >= 0 : if x >= 0 :
if (n == nil) and isClean(w.Nd, x) : if (n == nil) and isClean(w.Nd, x) :
n = w.Nd n = w.Nd
n.slots[x].node = nil n.slots[x].node = nil
n2 = DeleteItem(n, x) n2 = DeleteItem(n, x)
else : else :
w.Nd.slots[x].node = n w.Nd.slots[x].node = n
@ -161,7 +161,7 @@ proc internalFind[T,D] (n: PNode[T,D], key: T): ref TItem[T,D] {.inline.} =
wn = wn.left wn = wn.left
else : else :
x = (-x) -1 x = (-x) -1
if x < wn.count : if x < wn.count :
wn = wn.slots[x].node wn = wn.slots[x].node
else : else :
return nil return nil
@ -171,7 +171,7 @@ proc internalFind[T,D] (n: PNode[T,D], key: T): ref TItem[T,D] {.inline.} =
return nil return nil
proc traceTree[T,D](root: PNode[T,D]) = proc traceTree[T,D](root: PNode[T,D]) =
proc traceX(x: int) = proc traceX(x: int) =
write stdout, "(" write stdout, "("
write stdout, x write stdout, x
write stdout, ") " write stdout, ") "
@ -184,7 +184,7 @@ proc traceTree[T,D](root: PNode[T,D]) =
proc traceln(space: string) = proc traceln(space: string) =
writeln stdout, "" writeLine stdout, ""
write stdout, space write stdout, space
proc doTrace(n: PNode[T,D], level: int) = proc doTrace(n: PNode[T,D], level: int) =
@ -192,7 +192,7 @@ proc traceTree[T,D](root: PNode[T,D]) =
traceln(space) traceln(space)
write stdout, "node: " write stdout, "node: "
if n == nil: if n == nil:
writeln stdout, "is empty" writeLine stdout, "is empty"
return return
write stdout, n.count write stdout, n.count
write stdout, " elements: " write stdout, " elements: "
@ -204,7 +204,7 @@ proc traceTree[T,D](root: PNode[T,D]) =
if el != nil and not isClean(el): if el != nil and not isClean(el):
traceln(space) traceln(space)
traceX(i) traceX(i)
if i >= n.count: if i >= n.count:
write stdout, "error " write stdout, "error "
else: else:
traceEl(el) traceEl(el)
@ -219,14 +219,14 @@ proc traceTree[T,D](root: PNode[T,D]) =
else : write stdout, el.key else : write stdout, el.key
if el.node != nil: doTrace(el.node, level +1) if el.node != nil: doTrace(el.node, level +1)
else : write stdout, " empty " else : write stdout, " empty "
writeln stdout,"" writeLine stdout,""
doTrace(root, 0) doTrace(root, 0)
proc InsertItem[T,D](APath: RPath[T,D], ANode:PNode[T,D], Akey: T, Avalue: D) = proc InsertItem[T,D](APath: RPath[T,D], ANode:PNode[T,D], Akey: T, Avalue: D) =
var x = - APath.Xi var x = - APath.Xi
inc(APath.Nd.count) inc(APath.Nd.count)
case APath.Nd.count case APath.Nd.count
of cLen1: setLen(APath.Nd.slots, cLen2) of cLen1: setLen(APath.Nd.slots, cLen2)
of cLen2: setLen(APath.Nd.slots, cLen3) of cLen2: setLen(APath.Nd.slots, cLen3)
of cLen3: setLen(APath.Nd.slots, cLenCenter) of cLen3: setLen(APath.Nd.slots, cLenCenter)
@ -286,7 +286,7 @@ proc internalPut[T,D](ANode: ref TNode[T,D], Akey: T, Avalue: D, Oldvalue: var D
if x <= 0 : if x <= 0 :
Path[h].Nd = n Path[h].Nd = n
Path[h].Xi = x Path[h].Xi = x
inc(h) inc(h)
if x == 0 : if x == 0 :
n = n.left n = n.left
else : else :
@ -337,40 +337,40 @@ proc CleanTree[T,D](n: PNode[T,D]): PNode[T,D] =
proc VisitAllNodes[T,D](n: PNode[T,D], visit: proc(n: PNode[T,D]): PNode[T,D] {.closure.} ): PNode[T,D] = proc VisitAllNodes[T,D](n: PNode[T,D], visit: proc(n: PNode[T,D]): PNode[T,D] {.closure.} ): PNode[T,D] =
if n != nil : if n != nil :
if n.left != nil : if n.left != nil :
n.left = VisitAllNodes(n.left, visit) n.left = VisitAllNodes(n.left, visit)
for i in 0 .. n.count - 1 : for i in 0 .. n.count - 1 :
var w = n.slots[i] var w = n.slots[i]
if w.node != nil : if w.node != nil :
w.node = VisitAllNodes(w.node, visit) w.node = VisitAllNodes(w.node, visit)
return visit(n) return visit(n)
return nil return nil
proc VisitAllNodes[T,D](n: PNode[T,D], visit: proc(n: PNode[T,D]) {.closure.} ) = proc VisitAllNodes[T,D](n: PNode[T,D], visit: proc(n: PNode[T,D]) {.closure.} ) =
if n != nil: if n != nil:
if n.left != nil : if n.left != nil :
VisitAllNodes(n.left, visit) VisitAllNodes(n.left, visit)
for i in 0 .. n.count - 1 : for i in 0 .. n.count - 1 :
var w = n.slots[i] var w = n.slots[i]
if w.node != nil : if w.node != nil :
VisitAllNodes(w.node, visit) VisitAllNodes(w.node, visit)
visit(n) visit(n)
proc VisitAll[T,D](n: PNode[T,D], visit: proc(Akey: T, Avalue: D) {.closure.} ) = proc VisitAll[T,D](n: PNode[T,D], visit: proc(Akey: T, Avalue: D) {.closure.} ) =
if n != nil: if n != nil:
if n.left != nil : if n.left != nil :
VisitAll(n.left, visit) VisitAll(n.left, visit)
for i in 0 .. n.count - 1 : for i in 0 .. n.count - 1 :
var w = n.slots[i] var w = n.slots[i]
if not w.isClean : if not w.isClean :
visit(w.key, w.value) visit(w.key, w.value)
if w.node != nil : if w.node != nil :
VisitAll(w.node, visit) VisitAll(w.node, visit)
proc VisitAll[T,D](n: PNode[T,D], visit: proc(Akey: T, Avalue: var D):bool {.closure.} ): PNode[T,D] = proc VisitAll[T,D](n: PNode[T,D], visit: proc(Akey: T, Avalue: var D):bool {.closure.} ): PNode[T,D] =
if n != nil: if n != nil:
var n1 = n.left var n1 = n.left
if n1 != nil : if n1 != nil :
var n2 = VisitAll(n1, visit) var n2 = VisitAll(n1, visit)
if n1 != n2 : if n1 != n2 :
n.left = n2 n.left = n2
var i = 0 var i = 0
@ -395,7 +395,7 @@ iterator keys* [T,D] (n: PNode[T,D]): T =
var level = 0 var level = 0
var nd = n var nd = n
var i = -1 var i = -1
while true : while true :
if i < nd.count : if i < nd.count :
Path[level].Nd = nd Path[level].Nd = nd
Path[level].Xi = i Path[level].Xi = i
@ -471,4 +471,4 @@ when isMainModule:
test() test()

View file

@ -50,8 +50,8 @@ proc main*(infile: string, a, b: int, someverylongnamewithtype = 0,
# this should be an error! # this should be an error!
if initBaseLexer(L, infile, 30): nil if initBaseLexer(L, infile, 30): nil
else: else:
writeln(stdout, "could not open: " & infile) writeLine(stdout, "could not open: " & infile)
writeln(stdout, "Success!") writeLine(stdout, "Success!")
call(3, # we use 3 call(3, # we use 3
12, # we use 12 12, # we use 12
43) # we use 43 43) # we use 43

View file

@ -18,7 +18,7 @@ macro debug(n: varargs[expr]): stmt =
# add a call to the statement list that writes ": " # add a call to the statement list that writes ": "
add(result, newCall("write", newIdentNode("stdout"), newStrLitNode(": "))) add(result, newCall("write", newIdentNode("stdout"), newStrLitNode(": ")))
# add a call to the statement list that writes the expressions value: # add a call to the statement list that writes the expressions value:
add(result, newCall("writeln", newIdentNode("stdout"), n[i])) add(result, newCall("writeLine", newIdentNode("stdout"), n[i]))
var var
a: array [0..10, int] a: array [0..10, int]

View file

@ -7,8 +7,8 @@ var
i: int i: int
params = paramCount() params = paramCount()
i = 0 i = 0
writeln(stdout, "This exe: " & getAppFilename()) writeLine(stdout, "This exe: " & getAppFilename())
writeln(stdout, "Number of parameters: " & $params) writeLine(stdout, "Number of parameters: " & $params)
while i <= params: while i <= params:
writeln(stdout, paramStr(i)) writeLine(stdout, paramStr(i))
i = i + 1 i = i + 1

View file

@ -1,3 +1,3 @@
# test the new endian magic # test the new endian magic
writeln(stdout, repr(system.cpuEndian)) writeLine(stdout, repr(system.cpuEndian))

View file

@ -22,7 +22,7 @@ macro macrotest(n: expr): stmt {.immediate.} =
result = newNimNode(nnkStmtList, n) result = newNimNode(nnkStmtList, n)
for i in 2..n.len-1: for i in 2..n.len-1:
result.add(newCall("write", n[1], n[i])) result.add(newCall("write", n[1], n[i]))
result.add(newCall("writeln", n[1], newStrLitNode(""))) result.add(newCall("writeLine", n[1], newStrLitNode("")))
macro debug(n: expr): stmt {.immediate.} = macro debug(n: expr): stmt {.immediate.} =
let n = callsite() let n = callsite()
@ -30,7 +30,7 @@ macro debug(n: expr): stmt {.immediate.} =
for i in 1..n.len-1: for i in 1..n.len-1:
result.add(newCall("write", newIdentNode("stdout"), toStrLit(n[i]))) result.add(newCall("write", newIdentNode("stdout"), toStrLit(n[i])))
result.add(newCall("write", newIdentNode("stdout"), newStrLitNode(": "))) result.add(newCall("write", newIdentNode("stdout"), newStrLitNode(": ")))
result.add(newCall("writeln", newIdentNode("stdout"), n[i])) result.add(newCall("writeLine", newIdentNode("stdout"), n[i]))
macrotest(stdout, "finally", 4, 5, "variable", "argument lists") macrotest(stdout, "finally", 4, 5, "variable", "argument lists")
macrotest(stdout) macrotest(stdout)
@ -38,7 +38,7 @@ macrotest(stdout)
#GC_disable() #GC_disable()
echo("This was compiled by Nim version " & system.NimVersion) echo("This was compiled by Nim version " & system.NimVersion)
writeln(stdout, "Hello", " World", "!") writeLine(stdout, "Hello", " World", "!")
echo(["a", "b", "c", "d"].len) echo(["a", "b", "c", "d"].len)
for x in items(["What's", "your", "name", "?", ]): for x in items(["What's", "your", "name", "?", ]):

View file

@ -8,8 +8,8 @@ proc main() =
a, b: TTime a, b: TTime
a = getLastModificationTime(paramStr(1)) a = getLastModificationTime(paramStr(1))
b = getLastModificationTime(paramStr(2)) b = getLastModificationTime(paramStr(2))
writeln(stdout, $a) writeLine(stdout, $a)
writeln(stdout, $b) writeLine(stdout, $b)
if a < b: if a < b:
write(stdout, "$2 is newer than $1\n" % [paramStr(1), paramStr(2)]) write(stdout, "$2 is newer than $1\n" % [paramStr(1), paramStr(2)])
else: else:

View file

@ -24,10 +24,10 @@ var size = parseInt (paramStr (1))
var bit = 128 var bit = 128
var byteAcc = 0 var byteAcc = 0
stdout.writeln ("P4") stdout.writeLine ("P4")
stdout.write ($size) stdout.write ($size)
stdout.write (" ") stdout.write (" ")
stdout.writeln ($size) stdout.writeLine ($size)
var fsize = float (size) var fsize = float (size)
for y in 0 .. size-1: for y in 0 .. size-1:

View file

@ -9,4 +9,4 @@ var
x = 1 x = 1
y = high(int) y = high(int)
writeln(stdout, $ ( x +% y ) ) writeLine(stdout, $ ( x +% y ) )

View file

@ -2,141 +2,141 @@ discard """
file: "tvarnums.nim" file: "tvarnums.nim"
output: "Success!" output: "Success!"
""" """
# Test variable length binary integers # Test variable length binary integers
import import
strutils strutils
type type
TBuffer = array [0..10, int8] TBuffer = array [0..10, int8]
proc toVarNum(x: int32, b: var TBuffer) = proc toVarNum(x: int32, b: var TBuffer) =
# encoding: first bit indicates end of number (0 if at end) # encoding: first bit indicates end of number (0 if at end)
# second bit of the first byte denotes the sign (1 --> negative) # second bit of the first byte denotes the sign (1 --> negative)
var a = x var a = x
if x != low(x): if x != low(x):
# low(int) is a special case, # low(int) is a special case,
# because abs() does not work here! # because abs() does not work here!
# we leave x as it is and use the check >% instead of > # we leave x as it is and use the check >% instead of >
# for low(int) this is needed and positive numbers are not affected # for low(int) this is needed and positive numbers are not affected
# anyway # anyway
a = abs(x) a = abs(x)
# first 6 bits: # first 6 bits:
b[0] = toU8(ord(a >% 63'i32) shl 7 or (ord(x < 0'i32) shl 6) or (int(a) and 63)) b[0] = toU8(ord(a >% 63'i32) shl 7 or (ord(x < 0'i32) shl 6) or (int(a) and 63))
a = a shr 6'i32 # skip first 6 bits a = a shr 6'i32 # skip first 6 bits
var i = 1 var i = 1
while a != 0'i32: while a != 0'i32:
b[i] = toU8(ord(a >% 127'i32) shl 7 or (int(a) and 127)) b[i] = toU8(ord(a >% 127'i32) shl 7 or (int(a) and 127))
inc(i) inc(i)
a = a shr 7'i32 a = a shr 7'i32
proc toVarNum64(x: int64, b: var TBuffer) = proc toVarNum64(x: int64, b: var TBuffer) =
# encoding: first bit indicates end of number (0 if at end) # encoding: first bit indicates end of number (0 if at end)
# second bit of the first byte denotes the sign (1 --> negative) # second bit of the first byte denotes the sign (1 --> negative)
var a = x var a = x
if x != low(x): if x != low(x):
# low(int) is a special case, # low(int) is a special case,
# because abs() does not work here! # because abs() does not work here!
# we leave x as it is and use the check >% instead of > # we leave x as it is and use the check >% instead of >
# for low(int) this is needed and positive numbers are not affected # for low(int) this is needed and positive numbers are not affected
# anyway # anyway
a = abs(x) a = abs(x)
# first 6 bits: # first 6 bits:
b[0] = toU8(ord(a >% 63'i64) shl 7 or (ord(x < 0'i64) shl 6) or int(a and 63)) b[0] = toU8(ord(a >% 63'i64) shl 7 or (ord(x < 0'i64) shl 6) or int(a and 63))
a = a shr 6 # skip first 6 bits a = a shr 6 # skip first 6 bits
var i = 1 var i = 1
while a != 0'i64: while a != 0'i64:
b[i] = toU8(ord(a >% 127'i64) shl 7 or int(a and 127)) b[i] = toU8(ord(a >% 127'i64) shl 7 or int(a and 127))
inc(i) inc(i)
a = a shr 7 a = a shr 7
proc toNum64(b: TBuffer): int64 = proc toNum64(b: TBuffer): int64 =
# treat first byte different: # treat first byte different:
result = ze64(b[0]) and 63 result = ze64(b[0]) and 63
var var
i = 0 i = 0
Shift = 6'i64 Shift = 6'i64
while (ze(b[i]) and 128) != 0: while (ze(b[i]) and 128) != 0:
inc(i) inc(i)
result = result or ((ze64(b[i]) and 127) shl Shift) result = result or ((ze64(b[i]) and 127) shl Shift)
inc(Shift, 7) inc(Shift, 7)
if (ze(b[0]) and 64) != 0: # sign bit set? if (ze(b[0]) and 64) != 0: # sign bit set?
result = not result +% 1 result = not result +% 1
# this is the same as ``- result`` # this is the same as ``- result``
# but gives no overflow error for low(int) # but gives no overflow error for low(int)
proc toNum(b: TBuffer): int32 = proc toNum(b: TBuffer): int32 =
# treat first byte different: # treat first byte different:
result = ze(b[0]) and 63 result = ze(b[0]) and 63
var var
i = 0 i = 0
Shift = 6'i32 Shift = 6'i32
while (ze(b[i]) and 128) != 0: while (ze(b[i]) and 128) != 0:
inc(i) inc(i)
result = result or ((int32(ze(b[i])) and 127'i32) shl Shift) result = result or ((int32(ze(b[i])) and 127'i32) shl Shift)
Shift = Shift + 7'i32 Shift = Shift + 7'i32
if (ze(b[0]) and (1 shl 6)) != 0: # sign bit set? if (ze(b[0]) and (1 shl 6)) != 0: # sign bit set?
result = (not result) +% 1'i32 result = (not result) +% 1'i32
# this is the same as ``- result`` # this is the same as ``- result``
# but gives no overflow error for low(int) # but gives no overflow error for low(int)
proc toBinary(x: int64): string = proc toBinary(x: int64): string =
result = newString(64) result = newString(64)
for i in 0..63: for i in 0..63:
result[63-i] = chr((int(x shr i) and 1) + ord('0')) result[63-i] = chr((int(x shr i) and 1) + ord('0'))
proc t64(i: int64) = proc t64(i: int64) =
var var
b: TBuffer b: TBuffer
toVarNum64(i, b) toVarNum64(i, b)
var x = toNum64(b) var x = toNum64(b)
if x != i: if x != i:
writeln(stdout, $i) writeLine(stdout, $i)
writeln(stdout, toBinary(i)) writeLine(stdout, toBinary(i))
writeln(stdout, toBinary(x)) writeLine(stdout, toBinary(x))
proc t32(i: int32) = proc t32(i: int32) =
var var
b: TBuffer b: TBuffer
toVarNum(i, b) toVarNum(i, b)
var x = toNum(b) var x = toNum(b)
if x != i: if x != i:
writeln(stdout, toBinary(i)) writeLine(stdout, toBinary(i))
writeln(stdout, toBinary(x)) writeLine(stdout, toBinary(x))
proc tm(i: int32) = proc tm(i: int32) =
var var
b: TBuffer b: TBuffer
toVarNum64(i, b) toVarNum64(i, b)
var x = toNum(b) var x = toNum(b)
if x != i: if x != i:
writeln(stdout, toBinary(i)) writeLine(stdout, toBinary(i))
writeln(stdout, toBinary(x)) writeLine(stdout, toBinary(x))
t32(0) t32(0)
t32(1) t32(1)
t32(-1) t32(-1)
t32(-100_000) t32(-100_000)
t32(100_000) t32(100_000)
t32(low(int32)) t32(low(int32))
t32(high(int32)) t32(high(int32))
t64(low(int64)) t64(low(int64))
t64(high(int64)) t64(high(int64))
t64(0) t64(0)
t64(-1) t64(-1)
t64(1) t64(1)
t64(1000_000) t64(1000_000)
t64(-1000_000) t64(-1000_000)
tm(0) tm(0)
tm(1) tm(1)
tm(-1) tm(-1)
tm(-100_000) tm(-100_000)
tm(100_000) tm(100_000)
tm(low(int32)) tm(low(int32))
tm(high(int32)) tm(high(int32))
writeln(stdout, "Success!") #OUT Success! writeLine(stdout, "Success!") #OUT Success!

View file

@ -9,7 +9,7 @@ type
proc getPoint( p: var TPoint2d) = proc getPoint( p: var TPoint2d) =
{.breakpoint.} {.breakpoint.}
writeln(stdout, p.x) writeLine(stdout, p.x)
var var
p: TPoint3d p: TPoint3d

View file

@ -8,17 +8,17 @@ import macros
type type
TFigure = object of RootObj # abstract base class: TFigure = object of RootObj # abstract base class:
draw: proc (my: var TFigure) {.nimcall.} # concrete classes implement this draw: proc (my: var TFigure) {.nimcall.} # concrete classes implement this
proc init(f: var TFigure) = proc init(f: var TFigure) =
f.draw = nil f.draw = nil
type type
TCircle = object of TFigure TCircle = object of TFigure
radius: int radius: int
proc drawCircle(my: var TCircle) = stdout.writeln("o " & $my.radius)
proc init(my: var TCircle) = proc drawCircle(my: var TCircle) = stdout.writeLine("o " & $my.radius)
proc init(my: var TCircle) =
init(TFigure(my)) # call base constructor init(TFigure(my)) # call base constructor
my.radius = 5 my.radius = 5
my.draw = cast[proc (my: var TFigure) {.nimcall.}](drawCircle) my.draw = cast[proc (my: var TFigure) {.nimcall.}](drawCircle)
@ -29,13 +29,13 @@ type
proc drawRectangle(my: var TRectangle) = stdout.write("[]") proc drawRectangle(my: var TRectangle) = stdout.write("[]")
proc init(my: var TRectangle) = proc init(my: var TRectangle) =
init(TFigure(my)) # call base constructor init(TFigure(my)) # call base constructor
my.width = 5 my.width = 5
my.height = 10 my.height = 10
my.draw = cast[proc (my: var TFigure) {.nimcall.}](drawRectangle) my.draw = cast[proc (my: var TFigure) {.nimcall.}](drawRectangle)
macro `!` (n: expr): stmt {.immediate.} = macro `!` (n: expr): stmt {.immediate.} =
let n = callsite() let n = callsite()
result = newNimNode(nnkCall, n) result = newNimNode(nnkCall, n)
var dot = newNimNode(nnkDotExpr, n) var dot = newNimNode(nnkDotExpr, n)
@ -60,16 +60,16 @@ type
FHost: int # cannot be accessed from the outside of the module FHost: int # cannot be accessed from the outside of the module
# the `F` prefix is a convention to avoid clashes since # the `F` prefix is a convention to avoid clashes since
# the accessors are named `host` # the accessors are named `host`
proc `host=`*(s: var TSocket, value: int) {.inline.} = proc `host=`*(s: var TSocket, value: int) {.inline.} =
## setter of hostAddr ## setter of hostAddr
s.FHost = value s.FHost = value
proc host*(s: TSocket): int {.inline.} = proc host*(s: TSocket): int {.inline.} =
## getter of hostAddr ## getter of hostAddr
return s.FHost return s.FHost
var var
s: TSocket s: TSocket
s.host = 34 # same as `host=`(s, 34) s.host = 34 # same as `host=`(s, 34)
stdout.write(s.host) stdout.write(s.host)
@ -81,6 +81,6 @@ var
init(r) init(r)
init(c) init(c)
r!draw r!draw
c!draw() c!draw()
#OUT 34[]o 5 #OUT 34[]o 5

View file

@ -2,20 +2,20 @@ discard """
file: "toverflw.nim" file: "toverflw.nim"
output: "the computation overflowed" output: "the computation overflowed"
""" """
# Tests nim's ability to detect overflows # Tests nim's ability to detect overflows
{.push overflowChecks: on.} {.push overflowChecks: on.}
var var
a, b: int a, b: int
a = high(int) a = high(int)
b = -2 b = -2
try: try:
writeln(stdout, b - a) writeLine(stdout, b - a)
except OverflowError: except OverflowError:
writeln(stdout, "the computation overflowed") writeLine(stdout, "the computation overflowed")
{.pop.} # overflow check {.pop.} # overflow check
#OUT the computation overflowed #OUT the computation overflowed

View file

@ -58,7 +58,7 @@ for x in low(TAZ) .. high(TAZ):
for x in low(TTokTypeRange) .. high(TTokTypeRange): for x in low(TTokTypeRange) .. high(TTokTypeRange):
if x in tokTypes: if x in tokTypes:
discard discard
#writeln(stdout, "the token '$1' is in the set" % repr(x)) #writeLine(stdout, "the token '$1' is in the set" % repr(x))
#OUT Ha ein F ist in s! #OUT Ha ein F ist in s!

View file

@ -2,6 +2,6 @@
proc main() = proc main() =
for line in lines("thello.nim"): for line in lines("thello.nim"):
writeln(stdout, line) writeLine(stdout, line)
main() main()

View file

@ -3,24 +3,24 @@
import import
parseopt parseopt
proc writeHelp() = proc writeHelp() =
writeln(stdout, "Usage: tparsopt [options] filename [options]") writeLine(stdout, "Usage: tparsopt [options] filename [options]")
proc writeVersion() =
writeLine(stdout, "Version: 1.0.0")
proc writeVersion() =
writeln(stdout, "Version: 1.0.0")
var var
filename = "" filename = ""
for kind, key, val in getopt(): for kind, key, val in getopt():
case kind case kind
of cmdArgument: of cmdArgument:
filename = key filename = key
of cmdLongOption, cmdShortOption: of cmdLongOption, cmdShortOption:
case key case key
of "help", "h": writeHelp() of "help", "h": writeHelp()
of "version", "v": writeVersion() of "version", "v": writeVersion()
else: else:
writeln(stdout, "Unknown command line option: ", key, ": ", val) writeLine(stdout, "Unknown command line option: ", key, ": ", val)
of cmdEnd: assert(false) # cannot happen of cmdEnd: assert(false) # cannot happen
if filename == "": if filename == "":
# no filename has been given, so we show the help: # no filename has been given, so we show the help:

View file

@ -24,7 +24,7 @@ when useUnicode:
const const
InlineThreshold = 5 ## number of leaves; -1 to disable inlining InlineThreshold = 5 ## number of leaves; -1 to disable inlining
MaxSubpatterns* = 10 ## defines the maximum number of subpatterns that MaxSubpatterns* = 10 ## defines the maximum number of subpatterns that
## can be captured. More subpatterns cannot be captured! ## can be captured. More subpatterns cannot be captured!
type type
TPegKind = enum TPegKind = enum
@ -80,12 +80,12 @@ type
of pkBackRef..pkBackRefIgnoreStyle: index: range[0..MaxSubpatterns] of pkBackRef..pkBackRefIgnoreStyle: index: range[0..MaxSubpatterns]
else: sons: seq[TNode] else: sons: seq[TNode]
PNonTerminal* = ref TNonTerminal PNonTerminal* = ref TNonTerminal
TPeg* = TNode ## type that represents a PEG TPeg* = TNode ## type that represents a PEG
proc term*(t: string): TPeg {.rtl, extern: "npegs$1Str".} = proc term*(t: string): TPeg {.rtl, extern: "npegs$1Str".} =
## constructs a PEG from a terminal string ## constructs a PEG from a terminal string
if t.len != 1: if t.len != 1:
result.kind = pkTerminal result.kind = pkTerminal
result.term = t result.term = t
else: else:
@ -109,7 +109,7 @@ proc term*(t: char): TPeg {.rtl, extern: "npegs$1Char".} =
assert t != '\0' assert t != '\0'
result.kind = pkChar result.kind = pkChar
result.ch = t result.ch = t
proc charSet*(s: set[char]): TPeg {.rtl, extern: "npegs$1".} = proc charSet*(s: set[char]): TPeg {.rtl, extern: "npegs$1".} =
## constructs a PEG from a character set `s` ## constructs a PEG from a character set `s`
assert '\0' notin s assert '\0' notin s
@ -120,31 +120,31 @@ proc charSet*(s: set[char]): TPeg {.rtl, extern: "npegs$1".} =
proc len(a: TPeg): int {.inline.} = return a.sons.len proc len(a: TPeg): int {.inline.} = return a.sons.len
proc add(d: var TPeg, s: TPeg) {.inline.} = add(d.sons, s) proc add(d: var TPeg, s: TPeg) {.inline.} = add(d.sons, s)
proc copyPeg(a: TPeg): TPeg = proc copyPeg(a: TPeg): TPeg =
result.kind = a.kind result.kind = a.kind
case a.kind case a.kind
of pkEmpty..pkWhitespace: discard of pkEmpty..pkWhitespace: discard
of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle: of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle:
result.term = a.term result.term = a.term
of pkChar, pkGreedyRepChar: of pkChar, pkGreedyRepChar:
result.ch = a.ch result.ch = a.ch
of pkCharChoice, pkGreedyRepSet: of pkCharChoice, pkGreedyRepSet:
new(result.charChoice) new(result.charChoice)
result.charChoice[] = a.charChoice[] result.charChoice[] = a.charChoice[]
of pkNonTerminal: result.nt = a.nt of pkNonTerminal: result.nt = a.nt
of pkBackRef..pkBackRefIgnoreStyle: of pkBackRef..pkBackRefIgnoreStyle:
result.index = a.index result.index = a.index
else: else:
result.sons = a.sons result.sons = a.sons
proc addChoice(dest: var TPeg, elem: TPeg) = proc addChoice(dest: var TPeg, elem: TPeg) =
var L = dest.len-1 var L = dest.len-1
if L >= 0 and dest.sons[L].kind == pkCharChoice: if L >= 0 and dest.sons[L].kind == pkCharChoice:
# caution! Do not introduce false aliasing here! # caution! Do not introduce false aliasing here!
case elem.kind case elem.kind
of pkCharChoice: of pkCharChoice:
dest.sons[L] = charSet(dest.sons[L].charChoice[] + elem.charChoice[]) dest.sons[L] = charSet(dest.sons[L].charChoice[] + elem.charChoice[])
of pkChar: of pkChar:
dest.sons[L] = charSet(dest.sons[L].charChoice[] + {elem.ch}) dest.sons[L] = charSet(dest.sons[L].charChoice[] + {elem.ch})
else: add(dest, elem) else: add(dest, elem)
else: add(dest, elem) else: add(dest, elem)
@ -168,12 +168,12 @@ proc `/`*(a: varargs[TPeg]): TPeg {.
proc addSequence(dest: var TPeg, elem: TPeg) = proc addSequence(dest: var TPeg, elem: TPeg) =
var L = dest.len-1 var L = dest.len-1
if L >= 0 and dest.sons[L].kind == pkTerminal: if L >= 0 and dest.sons[L].kind == pkTerminal:
# caution! Do not introduce false aliasing here! # caution! Do not introduce false aliasing here!
case elem.kind case elem.kind
of pkTerminal: of pkTerminal:
dest.sons[L] = term(dest.sons[L].term & elem.term) dest.sons[L] = term(dest.sons[L].term & elem.term)
of pkChar: of pkChar:
dest.sons[L] = term(dest.sons[L].term & elem.ch) dest.sons[L] = term(dest.sons[L].term & elem.ch)
else: add(dest, elem) else: add(dest, elem)
else: add(dest, elem) else: add(dest, elem)
@ -182,7 +182,7 @@ proc sequence*(a: varargs[TPeg]): TPeg {.
rtl, extern: "npegs$1".} = rtl, extern: "npegs$1".} =
## constructs a sequence with all the PEGs from `a` ## constructs a sequence with all the PEGs from `a`
multipleOp(pkSequence, addSequence) multipleOp(pkSequence, addSequence)
proc `?`*(a: TPeg): TPeg {.rtl, extern: "npegsOptional".} = proc `?`*(a: TPeg): TPeg {.rtl, extern: "npegsOptional".} =
## constructs an optional for the PEG `a` ## constructs an optional for the PEG `a`
if a.kind in {pkOption, pkGreedyRep, pkGreedyAny, pkGreedyRepChar, if a.kind in {pkOption, pkGreedyRep, pkGreedyAny, pkGreedyRepChar,
@ -217,12 +217,12 @@ proc `!*`*(a: TPeg): TPeg {.rtl, extern: "npegsSearch".} =
result.kind = pkSearch result.kind = pkSearch
result.sons = @[a] result.sons = @[a]
proc `!*\`*(a: TPeg): TPeg {.rtl, proc `!*\`*(a: TPeg): TPeg {.rtl,
extern: "npgegsCapturedSearch".} = extern: "npgegsCapturedSearch".} =
## constructs a "captured search" for the PEG `a` ## constructs a "captured search" for the PEG `a`
result.kind = pkCapturedSearch result.kind = pkCapturedSearch
result.sons = @[a] result.sons = @[a]
when false: when false:
proc contains(a: TPeg, k: TPegKind): bool = proc contains(a: TPeg, k: TPegKind): bool =
if a.kind == k: return true if a.kind == k: return true
@ -238,7 +238,7 @@ when false:
proc `+`*(a: TPeg): TPeg {.rtl, extern: "npegsGreedyPosRep".} = proc `+`*(a: TPeg): TPeg {.rtl, extern: "npegsGreedyPosRep".} =
## constructs a "greedy positive repetition" with the PEG `a` ## constructs a "greedy positive repetition" with the PEG `a`
return sequence(a, *a) return sequence(a, *a)
proc `&`*(a: TPeg): TPeg {.rtl, extern: "npegsAndPredicate".} = proc `&`*(a: TPeg): TPeg {.rtl, extern: "npegsAndPredicate".} =
## constructs an "and predicate" with the PEG `a` ## constructs an "and predicate" with the PEG `a`
result.kind = pkAndPredicate result.kind = pkAndPredicate
@ -261,33 +261,33 @@ proc newLine*: TPeg {.inline.} =
## constructs the PEG `newline`:idx: (``\n``) ## constructs the PEG `newline`:idx: (``\n``)
result.kind = pkNewline result.kind = pkNewline
proc UnicodeLetter*: TPeg {.inline.} = proc UnicodeLetter*: TPeg {.inline.} =
## constructs the PEG ``\letter`` which matches any Unicode letter. ## constructs the PEG ``\letter`` which matches any Unicode letter.
result.kind = pkLetter result.kind = pkLetter
proc UnicodeLower*: TPeg {.inline.} =
## constructs the PEG ``\lower`` which matches any Unicode lowercase letter.
result.kind = pkLower
proc UnicodeUpper*: TPeg {.inline.} = proc UnicodeLower*: TPeg {.inline.} =
## constructs the PEG ``\lower`` which matches any Unicode lowercase letter.
result.kind = pkLower
proc UnicodeUpper*: TPeg {.inline.} =
## constructs the PEG ``\upper`` which matches any Unicode lowercase letter. ## constructs the PEG ``\upper`` which matches any Unicode lowercase letter.
result.kind = pkUpper result.kind = pkUpper
proc UnicodeTitle*: TPeg {.inline.} = proc UnicodeTitle*: TPeg {.inline.} =
## constructs the PEG ``\title`` which matches any Unicode title letter. ## constructs the PEG ``\title`` which matches any Unicode title letter.
result.kind = pkTitle result.kind = pkTitle
proc UnicodeWhitespace*: TPeg {.inline.} = proc UnicodeWhitespace*: TPeg {.inline.} =
## constructs the PEG ``\white`` which matches any Unicode ## constructs the PEG ``\white`` which matches any Unicode
## whitespace character. ## whitespace character.
result.kind = pkWhitespace result.kind = pkWhitespace
proc startAnchor*: TPeg {.inline.} = proc startAnchor*: TPeg {.inline.} =
## constructs the PEG ``^`` which matches the start of the input. ## constructs the PEG ``^`` which matches the start of the input.
result.kind = pkStartAnchor result.kind = pkStartAnchor
proc endAnchor*: TPeg {.inline.} = proc endAnchor*: TPeg {.inline.} =
## constructs the PEG ``$`` which matches the end of the input. ## constructs the PEG ``$`` which matches the end of the input.
result = !any() result = !any()
proc capture*(a: TPeg): TPeg {.rtl, extern: "npegsCapture".} = proc capture*(a: TPeg): TPeg {.rtl, extern: "npegsCapture".} =
@ -296,21 +296,21 @@ proc capture*(a: TPeg): TPeg {.rtl, extern: "npegsCapture".} =
result.sons = @[a] result.sons = @[a]
proc backref*(index: range[1..MaxSubPatterns]): TPeg {. proc backref*(index: range[1..MaxSubPatterns]): TPeg {.
rtl, extern: "npegs$1".} = rtl, extern: "npegs$1".} =
## constructs a back reference of the given `index`. `index` starts counting ## constructs a back reference of the given `index`. `index` starts counting
## from 1. ## from 1.
result.kind = pkBackRef result.kind = pkBackRef
result.index = index-1 result.index = index-1
proc backrefIgnoreCase*(index: range[1..MaxSubPatterns]): TPeg {. proc backrefIgnoreCase*(index: range[1..MaxSubPatterns]): TPeg {.
rtl, extern: "npegs$1".} = rtl, extern: "npegs$1".} =
## constructs a back reference of the given `index`. `index` starts counting ## constructs a back reference of the given `index`. `index` starts counting
## from 1. Ignores case for matching. ## from 1. Ignores case for matching.
result.kind = pkBackRefIgnoreCase result.kind = pkBackRefIgnoreCase
result.index = index-1 result.index = index-1
proc backrefIgnoreStyle*(index: range[1..MaxSubPatterns]): TPeg {. proc backrefIgnoreStyle*(index: range[1..MaxSubPatterns]): TPeg {.
rtl, extern: "npegs$1".}= rtl, extern: "npegs$1".}=
## constructs a back reference of the given `index`. `index` starts counting ## constructs a back reference of the given `index`. `index` starts counting
## from 1. Ignores style for matching. ## from 1. Ignores style for matching.
result.kind = pkBackRefIgnoreStyle result.kind = pkBackRefIgnoreStyle
@ -320,7 +320,7 @@ proc spaceCost(n: TPeg): int =
case n.kind case n.kind
of pkEmpty: discard of pkEmpty: discard
of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle, pkChar, of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle, pkChar,
pkGreedyRepChar, pkCharChoice, pkGreedyRepSet, pkGreedyRepChar, pkCharChoice, pkGreedyRepSet,
pkAny..pkWhitespace, pkGreedyAny: pkAny..pkWhitespace, pkGreedyAny:
result = 1 result = 1
of pkNonTerminal: of pkNonTerminal:
@ -332,7 +332,7 @@ proc spaceCost(n: TPeg): int =
if result >= InlineThreshold: break if result >= InlineThreshold: break
proc nonterminal*(n: PNonTerminal): TPeg {. proc nonterminal*(n: PNonTerminal): TPeg {.
rtl, extern: "npegs$1".} = rtl, extern: "npegs$1".} =
## constructs a PEG that consists of the nonterminal symbol ## constructs a PEG that consists of the nonterminal symbol
assert n != nil assert n != nil
if ntDeclared in n.flags and spaceCost(n.rule) < InlineThreshold: if ntDeclared in n.flags and spaceCost(n.rule) < InlineThreshold:
@ -353,7 +353,7 @@ proc newNonTerminal*(name: string, line, column: int): PNonTerminal {.
template letters*: expr = template letters*: expr =
## expands to ``charset({'A'..'Z', 'a'..'z'})`` ## expands to ``charset({'A'..'Z', 'a'..'z'})``
charset({'A'..'Z', 'a'..'z'}) charset({'A'..'Z', 'a'..'z'})
template digits*: expr = template digits*: expr =
## expands to ``charset({'0'..'9'})`` ## expands to ``charset({'0'..'9'})``
charset({'0'..'9'}) charset({'0'..'9'})
@ -361,11 +361,11 @@ template digits*: expr =
template whitespace*: expr = template whitespace*: expr =
## expands to ``charset({' ', '\9'..'\13'})`` ## expands to ``charset({' ', '\9'..'\13'})``
charset({' ', '\9'..'\13'}) charset({' ', '\9'..'\13'})
template identChars*: expr = template identChars*: expr =
## expands to ``charset({'a'..'z', 'A'..'Z', '0'..'9', '_'})`` ## expands to ``charset({'a'..'z', 'A'..'Z', '0'..'9', '_'})``
charset({'a'..'z', 'A'..'Z', '0'..'9', '_'}) charset({'a'..'z', 'A'..'Z', '0'..'9', '_'})
template identStartChars*: expr = template identStartChars*: expr =
## expands to ``charset({'A'..'Z', 'a'..'z', '_'})`` ## expands to ``charset({'A'..'Z', 'a'..'z', '_'})``
charset({'a'..'z', 'A'..'Z', '_'}) charset({'a'..'z', 'A'..'Z', '_'})
@ -374,14 +374,14 @@ template ident*: expr =
## same as ``[a-zA-Z_][a-zA-z_0-9]*``; standard identifier ## same as ``[a-zA-Z_][a-zA-z_0-9]*``; standard identifier
sequence(charset({'a'..'z', 'A'..'Z', '_'}), sequence(charset({'a'..'z', 'A'..'Z', '_'}),
*charset({'a'..'z', 'A'..'Z', '0'..'9', '_'})) *charset({'a'..'z', 'A'..'Z', '0'..'9', '_'}))
template natural*: expr = template natural*: expr =
## same as ``\d+`` ## same as ``\d+``
+digits +digits
# ------------------------- debugging ----------------------------------------- # ------------------------- debugging -----------------------------------------
proc esc(c: char, reserved = {'\0'..'\255'}): string = proc esc(c: char, reserved = {'\0'..'\255'}): string =
case c case c
of '\b': result = "\\b" of '\b': result = "\\b"
of '\t': result = "\\t" of '\t': result = "\\t"
@ -396,38 +396,38 @@ proc esc(c: char, reserved = {'\0'..'\255'}): string =
elif c < ' ' or c >= '\128': result = '\\' & $ord(c) elif c < ' ' or c >= '\128': result = '\\' & $ord(c)
elif c in reserved: result = '\\' & c elif c in reserved: result = '\\' & c
else: result = $c else: result = $c
proc singleQuoteEsc(c: char): string = return "'" & esc(c, {'\''}) & "'" proc singleQuoteEsc(c: char): string = return "'" & esc(c, {'\''}) & "'"
proc singleQuoteEsc(str: string): string = proc singleQuoteEsc(str: string): string =
result = "'" result = "'"
for c in items(str): add result, esc(c, {'\''}) for c in items(str): add result, esc(c, {'\''})
add result, '\'' add result, '\''
proc charSetEscAux(cc: set[char]): string = proc charSetEscAux(cc: set[char]): string =
const reserved = {'^', '-', ']'} const reserved = {'^', '-', ']'}
result = "" result = ""
var c1 = 0 var c1 = 0
while c1 <= 0xff: while c1 <= 0xff:
if chr(c1) in cc: if chr(c1) in cc:
var c2 = c1 var c2 = c1
while c2 < 0xff and chr(succ(c2)) in cc: inc(c2) while c2 < 0xff and chr(succ(c2)) in cc: inc(c2)
if c1 == c2: if c1 == c2:
add result, esc(chr(c1), reserved) add result, esc(chr(c1), reserved)
elif c2 == succ(c1): elif c2 == succ(c1):
add result, esc(chr(c1), reserved) & esc(chr(c2), reserved) add result, esc(chr(c1), reserved) & esc(chr(c2), reserved)
else: else:
add result, esc(chr(c1), reserved) & '-' & esc(chr(c2), reserved) add result, esc(chr(c1), reserved) & '-' & esc(chr(c2), reserved)
c1 = c2 c1 = c2
inc(c1) inc(c1)
proc charSetEsc(cc: set[char]): string = proc charSetEsc(cc: set[char]): string =
if card(cc) >= 128+64: if card(cc) >= 128+64:
result = "[^" & charSetEscAux({'\1'..'\xFF'} - cc) & ']' result = "[^" & charSetEscAux({'\1'..'\xFF'} - cc) & ']'
else: else:
result = '[' & charSetEscAux(cc) & ']' result = '[' & charSetEscAux(cc) & ']'
proc toStrAux(r: TPeg, res: var string) = proc toStrAux(r: TPeg, res: var string) =
case r.kind case r.kind
of pkEmpty: add(res, "()") of pkEmpty: add(res, "()")
of pkAny: add(res, '.') of pkAny: add(res, '.')
@ -491,25 +491,25 @@ proc toStrAux(r: TPeg, res: var string) =
toStrAux(r.sons[0], res) toStrAux(r.sons[0], res)
of pkCapture: of pkCapture:
add(res, '{') add(res, '{')
toStrAux(r.sons[0], res) toStrAux(r.sons[0], res)
add(res, '}') add(res, '}')
of pkBackRef: of pkBackRef:
add(res, '$') add(res, '$')
add(res, $r.index) add(res, $r.index)
of pkBackRefIgnoreCase: of pkBackRefIgnoreCase:
add(res, "i$") add(res, "i$")
add(res, $r.index) add(res, $r.index)
of pkBackRefIgnoreStyle: of pkBackRefIgnoreStyle:
add(res, "y$") add(res, "y$")
add(res, $r.index) add(res, $r.index)
of pkRule: of pkRule:
toStrAux(r.sons[0], res) toStrAux(r.sons[0], res)
add(res, " <- ") add(res, " <- ")
toStrAux(r.sons[1], res) toStrAux(r.sons[1], res)
of pkList: of pkList:
for i in 0 .. high(r.sons): for i in 0 .. high(r.sons):
toStrAux(r.sons[i], res) toStrAux(r.sons[i], res)
add(res, "\n") add(res, "\n")
of pkStartAnchor: of pkStartAnchor:
add(res, '^') add(res, '^')
@ -526,8 +526,8 @@ type
ml: int ml: int
origStart: int origStart: int
proc bounds*(c: TCaptures, proc bounds*(c: TCaptures,
i: range[0..MaxSubpatterns-1]): tuple[first, last: int] = i: range[0..MaxSubpatterns-1]): tuple[first, last: int] =
## returns the bounds ``[first..last]`` of the `i`'th capture. ## returns the bounds ``[first..last]`` of the `i`'th capture.
result = c.matches[i] result = c.matches[i]
@ -547,7 +547,7 @@ when not useUnicode:
proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {. proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
rtl, extern: "npegs$1".} = rtl, extern: "npegs$1".} =
## low-level matching proc that implements the PEG interpreter. Use this ## low-level matching proc that implements the PEG interpreter. Use this
## for maximum efficiency (every other PEG operation ends up calling this ## for maximum efficiency (every other PEG operation ends up calling this
## proc). ## proc).
## Returns -1 if it does not match, else the length of the match ## Returns -1 if it does not match, else the length of the match
@ -561,7 +561,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
result = runeLenAt(s, start) result = runeLenAt(s, start)
else: else:
result = -1 result = -1
of pkLetter: of pkLetter:
if s[start] != '\0': if s[start] != '\0':
var a: Rune var a: Rune
result = start result = start
@ -570,7 +570,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
else: result = -1 else: result = -1
else: else:
result = -1 result = -1
of pkLower: of pkLower:
if s[start] != '\0': if s[start] != '\0':
var a: Rune var a: Rune
result = start result = start
@ -579,7 +579,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
else: result = -1 else: result = -1
else: else:
result = -1 result = -1
of pkUpper: of pkUpper:
if s[start] != '\0': if s[start] != '\0':
var a: Rune var a: Rune
result = start result = start
@ -588,16 +588,16 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
else: result = -1 else: result = -1
else: else:
result = -1 result = -1
of pkTitle: of pkTitle:
if s[start] != '\0': if s[start] != '\0':
var a: Rune var a: Rune
result = start result = start
fastRuneAt(s, result, a) fastRuneAt(s, result, a)
if isTitle(a): dec(result, start) if isTitle(a): dec(result, start)
else: result = -1 else: result = -1
else: else:
result = -1 result = -1
of pkWhitespace: of pkWhitespace:
if s[start] != '\0': if s[start] != '\0':
var a: Rune var a: Rune
result = start result = start
@ -661,7 +661,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
when false: echo "leave: ", p.nt.name when false: echo "leave: ", p.nt.name
if result < 0: c.ml = oldMl if result < 0: c.ml = oldMl
of pkSequence: of pkSequence:
var oldMl = c.ml var oldMl = c.ml
result = 0 result = 0
assert(not isNil(p.sons)) assert(not isNil(p.sons))
for i in 0..high(p.sons): for i in 0..high(p.sons):
@ -744,11 +744,11 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
#else: silently ignore the capture #else: silently ignore the capture
else: else:
c.ml = idx c.ml = idx
of pkBackRef..pkBackRefIgnoreStyle: of pkBackRef..pkBackRefIgnoreStyle:
if p.index >= c.ml: return -1 if p.index >= c.ml: return -1
var (a, b) = c.matches[p.index] var (a, b) = c.matches[p.index]
var n: TPeg var n: TPeg
n.kind = succ(pkTerminal, ord(p.kind)-ord(pkBackRef)) n.kind = succ(pkTerminal, ord(p.kind)-ord(pkBackRef))
n.term = s.substr(a, b) n.term = s.substr(a, b)
result = rawMatch(s, n, start, c) result = rawMatch(s, n, start, c)
of pkStartAnchor: of pkStartAnchor:
@ -769,7 +769,7 @@ proc match*(s: string, pattern: TPeg, matches: var openarray[string],
for i in 0..c.ml-1: for i in 0..c.ml-1:
matches[i] = substr(s, c.matches[i][0], c.matches[i][1]) matches[i] = substr(s, c.matches[i][0], c.matches[i][1])
proc match*(s: string, pattern: TPeg, proc match*(s: string, pattern: TPeg,
start = 0): bool {.rtl, extern: "npegs$1".} = start = 0): bool {.rtl, extern: "npegs$1".} =
## returns ``true`` if ``s`` matches the ``pattern`` beginning from ``start``. ## returns ``true`` if ``s`` matches the ``pattern`` beginning from ``start``.
var c: TCaptures var c: TCaptures
@ -789,7 +789,7 @@ proc matchLen*(s: string, pattern: TPeg, matches: var openarray[string],
for i in 0..c.ml-1: for i in 0..c.ml-1:
matches[i] = substr(s, c.matches[i][0], c.matches[i][1]) matches[i] = substr(s, c.matches[i][0], c.matches[i][1])
proc matchLen*(s: string, pattern: TPeg, proc matchLen*(s: string, pattern: TPeg,
start = 0): int {.rtl, extern: "npegs$1".} = start = 0): int {.rtl, extern: "npegs$1".} =
## the same as ``match``, but it returns the length of the match, ## the same as ``match``, but it returns the length of the match,
## if there is no match, -1 is returned. Note that a match length ## if there is no match, -1 is returned. Note that a match length
@ -808,11 +808,11 @@ proc find*(s: string, pattern: TPeg, matches: var openarray[string],
if matchLen(s, pattern, matches, i) >= 0: return i if matchLen(s, pattern, matches, i) >= 0: return i
return -1 return -1
# could also use the pattern here: (!P .)* P # could also use the pattern here: (!P .)* P
proc findBounds*(s: string, pattern: TPeg, matches: var openarray[string], proc findBounds*(s: string, pattern: TPeg, matches: var openarray[string],
start = 0): tuple[first, last: int] {. start = 0): tuple[first, last: int] {.
rtl, extern: "npegs$1Capture".} = rtl, extern: "npegs$1Capture".} =
## returns the starting position and end position of ``pattern`` in ``s`` ## returns the starting position and end position of ``pattern`` in ``s``
## and the captured ## and the captured
## substrings in the array ``matches``. If it does not match, nothing ## substrings in the array ``matches``. If it does not match, nothing
## is written into ``matches`` and (-1,0) is returned. ## is written into ``matches`` and (-1,0) is returned.
@ -820,40 +820,40 @@ proc findBounds*(s: string, pattern: TPeg, matches: var openarray[string],
var L = matchLen(s, pattern, matches, i) var L = matchLen(s, pattern, matches, i)
if L >= 0: return (i, i+L-1) if L >= 0: return (i, i+L-1)
return (-1, 0) return (-1, 0)
proc find*(s: string, pattern: TPeg, proc find*(s: string, pattern: TPeg,
start = 0): int {.rtl, extern: "npegs$1".} = start = 0): int {.rtl, extern: "npegs$1".} =
## returns the starting position of ``pattern`` in ``s``. If it does not ## returns the starting position of ``pattern`` in ``s``. If it does not
## match, -1 is returned. ## match, -1 is returned.
for i in start .. s.len-1: for i in start .. s.len-1:
if matchLen(s, pattern, i) >= 0: return i if matchLen(s, pattern, i) >= 0: return i
return -1 return -1
iterator findAll*(s: string, pattern: TPeg, start = 0): string = iterator findAll*(s: string, pattern: TPeg, start = 0): string =
## yields all matching captures of pattern in `s`. ## yields all matching captures of pattern in `s`.
var matches: array[0..MaxSubpatterns-1, string] var matches: array[0..MaxSubpatterns-1, string]
var i = start var i = start
while i < s.len: while i < s.len:
var L = matchLen(s, pattern, matches, i) var L = matchLen(s, pattern, matches, i)
if L < 0: break if L < 0: break
for k in 0..MaxSubPatterns-1: for k in 0..MaxSubPatterns-1:
if isNil(matches[k]): break if isNil(matches[k]): break
yield matches[k] yield matches[k]
inc(i, L) inc(i, L)
proc findAll*(s: string, pattern: TPeg, start = 0): seq[string] {. proc findAll*(s: string, pattern: TPeg, start = 0): seq[string] {.
rtl, extern: "npegs$1".} = rtl, extern: "npegs$1".} =
## returns all matching captures of pattern in `s`. ## returns all matching captures of pattern in `s`.
## If it does not match, @[] is returned. ## If it does not match, @[] is returned.
accumulateResult(findAll(s, pattern, start)) accumulateResult(findAll(s, pattern, start))
template `=~`*(s: string, pattern: TPeg): expr = template `=~`*(s: string, pattern: TPeg): expr =
## This calls ``match`` with an implicit declared ``matches`` array that ## This calls ``match`` with an implicit declared ``matches`` array that
## can be used in the scope of the ``=~`` call: ## can be used in the scope of the ``=~`` call:
## ##
## .. code-block:: nim ## .. code-block:: nim
## ##
## if line =~ peg"\s* {\w+} \s* '=' \s* {\w+}": ## if line =~ peg"\s* {\w+} \s* '=' \s* {\w+}":
## # matches a key=value pair: ## # matches a key=value pair:
## echo("Key: ", matches[0]) ## echo("Key: ", matches[0])
## echo("Value: ", matches[1]) ## echo("Value: ", matches[1])
@ -864,7 +864,7 @@ template `=~`*(s: string, pattern: TPeg): expr =
## echo("comment: ", matches[0]) ## echo("comment: ", matches[0])
## else: ## else:
## echo("syntax error") ## echo("syntax error")
## ##
when not declaredInScope(matches): when not declaredInScope(matches):
var matches {.inject.}: array[0..MaxSubpatterns-1, string] var matches {.inject.}: array[0..MaxSubpatterns-1, string]
match(s, pattern, matches) match(s, pattern, matches)
@ -934,10 +934,10 @@ proc replace*(s: string, sub: TPeg, by = ""): string {.
addf(result, by, caps) addf(result, by, caps)
inc(i, x) inc(i, x)
add(result, substr(s, i)) add(result, substr(s, i))
proc parallelReplace*(s: string, subs: varargs[ proc parallelReplace*(s: string, subs: varargs[
tuple[pattern: TPeg, repl: string]]): string {. tuple[pattern: TPeg, repl: string]]): string {.
rtl, extern: "npegs$1".} = rtl, extern: "npegs$1".} =
## Returns a modified copy of `s` with the substitutions in `subs` ## Returns a modified copy of `s` with the substitutions in `subs`
## applied in parallel. ## applied in parallel.
result = "" result = ""
@ -954,8 +954,8 @@ proc parallelReplace*(s: string, subs: varargs[
add(result, s[i]) add(result, s[i])
inc(i) inc(i)
# copy the rest: # copy the rest:
add(result, substr(s, i)) add(result, substr(s, i))
proc transformFile*(infile, outfile: string, proc transformFile*(infile, outfile: string,
subs: varargs[tuple[pattern: TPeg, repl: string]]) {. subs: varargs[tuple[pattern: TPeg, repl: string]]) {.
rtl, extern: "npegs$1".} = rtl, extern: "npegs$1".} =
@ -972,7 +972,7 @@ proc transformFile*(infile, outfile: string,
quit("cannot open for writing: " & outfile) quit("cannot open for writing: " & outfile)
else: else:
quit("cannot open for reading: " & infile) quit("cannot open for reading: " & infile)
iterator split*(s: string, sep: TPeg): string = iterator split*(s: string, sep: TPeg): string =
## Splits the string `s` into substrings. ## Splits the string `s` into substrings.
## ##
@ -981,7 +981,7 @@ iterator split*(s: string, sep: TPeg): string =
## ##
## .. code-block:: nim ## .. code-block:: nim
## for word in split("00232this02939is39an22example111", peg"\d+"): ## for word in split("00232this02939is39an22example111", peg"\d+"):
## writeln(stdout, word) ## writeLine(stdout, word)
## ##
## Results in: ## Results in:
## ##
@ -1044,14 +1044,14 @@ type
tkBackref, ## '$' tkBackref, ## '$'
tkDollar, ## '$' tkDollar, ## '$'
tkHat ## '^' tkHat ## '^'
TToken {.final.} = object ## a token TToken {.final.} = object ## a token
kind: TTokKind ## the type of the token kind: TTokKind ## the type of the token
modifier: TModifier modifier: TModifier
literal: string ## the parsed (string) literal literal: string ## the parsed (string) literal
charset: set[char] ## if kind == tkCharSet charset: set[char] ## if kind == tkCharSet
index: int ## if kind == tkBackref index: int ## if kind == tkBackref
TPegLexer {.inheritable.} = object ## the lexer object. TPegLexer {.inheritable.} = object ## the lexer object.
bufpos: int ## the current position within the buffer bufpos: int ## the current position within the buffer
buf: cstring ## the buffer itself buf: cstring ## the buffer itself
@ -1081,7 +1081,7 @@ proc HandleLF(L: var TPegLexer, pos: int): int =
result = pos+1 result = pos+1
L.lineStart = result L.lineStart = result
proc init(L: var TPegLexer, input, filename: string, line = 1, col = 0) = proc init(L: var TPegLexer, input, filename: string, line = 1, col = 0) =
L.buf = input L.buf = input
L.bufpos = 0 L.bufpos = 0
L.lineNumber = line L.lineNumber = line
@ -1089,69 +1089,69 @@ proc init(L: var TPegLexer, input, filename: string, line = 1, col = 0) =
L.lineStart = 0 L.lineStart = 0
L.filename = filename L.filename = filename
proc getColumn(L: TPegLexer): int {.inline.} = proc getColumn(L: TPegLexer): int {.inline.} =
result = abs(L.bufpos - L.lineStart) + L.colOffset result = abs(L.bufpos - L.lineStart) + L.colOffset
proc getLine(L: TPegLexer): int {.inline.} = proc getLine(L: TPegLexer): int {.inline.} =
result = L.linenumber result = L.linenumber
proc errorStr(L: TPegLexer, msg: string, line = -1, col = -1): string = proc errorStr(L: TPegLexer, msg: string, line = -1, col = -1): string =
var line = if line < 0: getLine(L) else: line var line = if line < 0: getLine(L) else: line
var col = if col < 0: getColumn(L) else: col var col = if col < 0: getColumn(L) else: col
result = "$1($2, $3) Error: $4" % [L.filename, $line, $col, msg] result = "$1($2, $3) Error: $4" % [L.filename, $line, $col, msg]
proc handleHexChar(c: var TPegLexer, xi: var int) = proc handleHexChar(c: var TPegLexer, xi: var int) =
case c.buf[c.bufpos] case c.buf[c.bufpos]
of '0'..'9': of '0'..'9':
xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('0')) xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('0'))
inc(c.bufpos) inc(c.bufpos)
of 'a'..'f': of 'a'..'f':
xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('a') + 10) xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('a') + 10)
inc(c.bufpos) inc(c.bufpos)
of 'A'..'F': of 'A'..'F':
xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('A') + 10) xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('A') + 10)
inc(c.bufpos) inc(c.bufpos)
else: discard else: discard
proc getEscapedChar(c: var TPegLexer, tok: var TToken) = proc getEscapedChar(c: var TPegLexer, tok: var TToken) =
inc(c.bufpos) inc(c.bufpos)
case c.buf[c.bufpos] case c.buf[c.bufpos]
of 'r', 'R', 'c', 'C': of 'r', 'R', 'c', 'C':
add(tok.literal, '\c') add(tok.literal, '\c')
inc(c.bufpos) inc(c.bufpos)
of 'l', 'L': of 'l', 'L':
add(tok.literal, '\L') add(tok.literal, '\L')
inc(c.bufpos) inc(c.bufpos)
of 'f', 'F': of 'f', 'F':
add(tok.literal, '\f') add(tok.literal, '\f')
inc(c.bufpos) inc(c.bufpos)
of 'e', 'E': of 'e', 'E':
add(tok.literal, '\e') add(tok.literal, '\e')
inc(c.bufpos) inc(c.bufpos)
of 'a', 'A': of 'a', 'A':
add(tok.literal, '\a') add(tok.literal, '\a')
inc(c.bufpos) inc(c.bufpos)
of 'b', 'B': of 'b', 'B':
add(tok.literal, '\b') add(tok.literal, '\b')
inc(c.bufpos) inc(c.bufpos)
of 'v', 'V': of 'v', 'V':
add(tok.literal, '\v') add(tok.literal, '\v')
inc(c.bufpos) inc(c.bufpos)
of 't', 'T': of 't', 'T':
add(tok.literal, '\t') add(tok.literal, '\t')
inc(c.bufpos) inc(c.bufpos)
of 'x', 'X': of 'x', 'X':
inc(c.bufpos) inc(c.bufpos)
var xi = 0 var xi = 0
handleHexChar(c, xi) handleHexChar(c, xi)
handleHexChar(c, xi) handleHexChar(c, xi)
if xi == 0: tok.kind = tkInvalid if xi == 0: tok.kind = tkInvalid
else: add(tok.literal, chr(xi)) else: add(tok.literal, chr(xi))
of '0'..'9': of '0'..'9':
var val = ord(c.buf[c.bufpos]) - ord('0') var val = ord(c.buf[c.bufpos]) - ord('0')
inc(c.bufpos) inc(c.bufpos)
var i = 1 var i = 1
while (i <= 3) and (c.buf[c.bufpos] in {'0'..'9'}): while (i <= 3) and (c.buf[c.bufpos] in {'0'..'9'}):
val = val * 10 + ord(c.buf[c.bufpos]) - ord('0') val = val * 10 + ord(c.buf[c.bufpos]) - ord('0')
inc(c.bufpos) inc(c.bufpos)
inc(i) inc(i)
@ -1164,32 +1164,32 @@ proc getEscapedChar(c: var TPegLexer, tok: var TToken) =
else: else:
add(tok.literal, c.buf[c.bufpos]) add(tok.literal, c.buf[c.bufpos])
inc(c.bufpos) inc(c.bufpos)
proc skip(c: var TPegLexer) = proc skip(c: var TPegLexer) =
var pos = c.bufpos var pos = c.bufpos
var buf = c.buf var buf = c.buf
while true: while true:
case buf[pos] case buf[pos]
of ' ', '\t': of ' ', '\t':
inc(pos) inc(pos)
of '#': of '#':
while not (buf[pos] in {'\c', '\L', '\0'}): inc(pos) while not (buf[pos] in {'\c', '\L', '\0'}): inc(pos)
of '\c': of '\c':
pos = HandleCR(c, pos) pos = HandleCR(c, pos)
buf = c.buf buf = c.buf
of '\L': of '\L':
pos = HandleLF(c, pos) pos = HandleLF(c, pos)
buf = c.buf buf = c.buf
else: else:
break # EndOfFile also leaves the loop break # EndOfFile also leaves the loop
c.bufpos = pos c.bufpos = pos
proc getString(c: var TPegLexer, tok: var TToken) = proc getString(c: var TPegLexer, tok: var TToken) =
tok.kind = tkStringLit tok.kind = tkStringLit
var pos = c.bufPos + 1 var pos = c.bufPos + 1
var buf = c.buf var buf = c.buf
var quote = buf[pos-1] var quote = buf[pos-1]
while true: while true:
case buf[pos] case buf[pos]
of '\\': of '\\':
c.bufpos = pos c.bufpos = pos
@ -1200,13 +1200,13 @@ proc getString(c: var TPegLexer, tok: var TToken) =
break break
elif buf[pos] == quote: elif buf[pos] == quote:
inc(pos) inc(pos)
break break
else: else:
add(tok.literal, buf[pos]) add(tok.literal, buf[pos])
inc(pos) inc(pos)
c.bufpos = pos c.bufpos = pos
proc getDollar(c: var TPegLexer, tok: var TToken) = proc getDollar(c: var TPegLexer, tok: var TToken) =
var pos = c.bufPos + 1 var pos = c.bufPos + 1
var buf = c.buf var buf = c.buf
if buf[pos] in {'0'..'9'}: if buf[pos] in {'0'..'9'}:
@ -1218,8 +1218,8 @@ proc getDollar(c: var TPegLexer, tok: var TToken) =
else: else:
tok.kind = tkDollar tok.kind = tkDollar
c.bufpos = pos c.bufpos = pos
proc getCharSet(c: var TPegLexer, tok: var TToken) = proc getCharSet(c: var TPegLexer, tok: var TToken) =
tok.kind = tkCharSet tok.kind = tkCharSet
tok.charset = {} tok.charset = {}
var pos = c.bufPos + 1 var pos = c.bufPos + 1
@ -1242,7 +1242,7 @@ proc getCharSet(c: var TPegLexer, tok: var TToken) =
of '\C', '\L', '\0': of '\C', '\L', '\0':
tok.kind = tkInvalid tok.kind = tkInvalid
break break
else: else:
ch = buf[pos] ch = buf[pos]
inc(pos) inc(pos)
incl(tok.charset, ch) incl(tok.charset, ch)
@ -1262,18 +1262,18 @@ proc getCharSet(c: var TPegLexer, tok: var TToken) =
of '\C', '\L', '\0': of '\C', '\L', '\0':
tok.kind = tkInvalid tok.kind = tkInvalid
break break
else: else:
ch2 = buf[pos] ch2 = buf[pos]
inc(pos) inc(pos)
for i in ord(ch)+1 .. ord(ch2): for i in ord(ch)+1 .. ord(ch2):
incl(tok.charset, chr(i)) incl(tok.charset, chr(i))
c.bufpos = pos c.bufpos = pos
if caret: tok.charset = {'\1'..'\xFF'} - tok.charset if caret: tok.charset = {'\1'..'\xFF'} - tok.charset
proc getSymbol(c: var TPegLexer, tok: var TToken) = proc getSymbol(c: var TPegLexer, tok: var TToken) =
var pos = c.bufpos var pos = c.bufpos
var buf = c.buf var buf = c.buf
while true: while true:
add(tok.literal, buf[pos]) add(tok.literal, buf[pos])
inc(pos) inc(pos)
if buf[pos] notin strutils.IdentChars: break if buf[pos] notin strutils.IdentChars: break
@ -1289,7 +1289,7 @@ proc getBuiltin(c: var TPegLexer, tok: var TToken) =
tok.kind = tkEscaped tok.kind = tkEscaped
getEscapedChar(c, tok) # may set tok.kind to tkInvalid getEscapedChar(c, tok) # may set tok.kind to tkInvalid
proc getTok(c: var TPegLexer, tok: var TToken) = proc getTok(c: var TPegLexer, tok: var TToken) =
tok.kind = tkInvalid tok.kind = tkInvalid
tok.modifier = modNone tok.modifier = modNone
setlen(tok.literal, 0) setlen(tok.literal, 0)
@ -1304,11 +1304,11 @@ proc getTok(c: var TPegLexer, tok: var TToken) =
else: else:
tok.kind = tkCurlyLe tok.kind = tkCurlyLe
add(tok.literal, '{') add(tok.literal, '{')
of '}': of '}':
tok.kind = tkCurlyRi tok.kind = tkCurlyRi
inc(c.bufpos) inc(c.bufpos)
add(tok.literal, '}') add(tok.literal, '}')
of '[': of '[':
getCharset(c, tok) getCharset(c, tok)
of '(': of '(':
tok.kind = tkParLe tok.kind = tkParLe
@ -1318,7 +1318,7 @@ proc getTok(c: var TPegLexer, tok: var TToken) =
tok.kind = tkParRi tok.kind = tkParRi
inc(c.bufpos) inc(c.bufpos)
add(tok.literal, ')') add(tok.literal, ')')
of '.': of '.':
tok.kind = tkAny tok.kind = tkAny
inc(c.bufpos) inc(c.bufpos)
add(tok.literal, '.') add(tok.literal, '.')
@ -1326,16 +1326,16 @@ proc getTok(c: var TPegLexer, tok: var TToken) =
tok.kind = tkAnyRune tok.kind = tkAnyRune
inc(c.bufpos) inc(c.bufpos)
add(tok.literal, '_') add(tok.literal, '_')
of '\\': of '\\':
getBuiltin(c, tok) getBuiltin(c, tok)
of '\'', '"': getString(c, tok) of '\'', '"': getString(c, tok)
of '$': getDollar(c, tok) of '$': getDollar(c, tok)
of '\0': of '\0':
tok.kind = tkEof tok.kind = tkEof
tok.literal = "[EOF]" tok.literal = "[EOF]"
of 'a'..'z', 'A'..'Z', '\128'..'\255': of 'a'..'z', 'A'..'Z', '\128'..'\255':
getSymbol(c, tok) getSymbol(c, tok)
if c.buf[c.bufpos] in {'\'', '"'} or if c.buf[c.bufpos] in {'\'', '"'} or
c.buf[c.bufpos] == '$' and c.buf[c.bufpos+1] in {'0'..'9'}: c.buf[c.bufpos] == '$' and c.buf[c.bufpos+1] in {'0'..'9'}:
case tok.literal case tok.literal
of "i": tok.modifier = modIgnoreCase of "i": tok.modifier = modIgnoreCase
@ -1383,7 +1383,7 @@ proc getTok(c: var TPegLexer, tok: var TToken) =
tok.kind = tkAt tok.kind = tkAt
inc(c.bufpos) inc(c.bufpos)
add(tok.literal, '@') add(tok.literal, '@')
if c.buf[c.bufpos] == '@': if c.buf[c.bufpos] == '@':
tok.kind = tkCurlyAt tok.kind = tkCurlyAt
inc(c.bufpos) inc(c.bufpos)
add(tok.literal, '@') add(tok.literal, '@')
@ -1402,7 +1402,7 @@ proc arrowIsNextTok(c: TPegLexer): bool =
result = c.buf[pos] == '<' and c.buf[pos+1] == '-' result = c.buf[pos] == '<' and c.buf[pos+1] == '-'
# ----------------------------- parser ---------------------------------------- # ----------------------------- parser ----------------------------------------
type type
EInvalidPeg* = object of ValueError ## raised if an invalid EInvalidPeg* = object of ValueError ## raised if an invalid
## PEG has been detected ## PEG has been detected
@ -1420,7 +1420,7 @@ proc pegError(p: TPegParser, msg: string, line = -1, col = -1) =
e.msg = errorStr(p, msg, line, col) e.msg = errorStr(p, msg, line, col)
raise e raise e
proc getTok(p: var TPegParser) = proc getTok(p: var TPegParser) =
getTok(p, p.tok) getTok(p, p.tok)
if p.tok.kind == tkInvalid: pegError(p, "invalid token") if p.tok.kind == tkInvalid: pegError(p, "invalid token")
@ -1470,7 +1470,7 @@ proc builtin(p: var TPegParser): TPeg =
of "white": result = UnicodeWhitespace() of "white": result = UnicodeWhitespace()
else: pegError(p, "unknown built-in: " & p.tok.literal) else: pegError(p, "unknown built-in: " & p.tok.literal)
proc token(terminal: TPeg, p: TPegParser): TPeg = proc token(terminal: TPeg, p: TPegParser): TPeg =
if p.skip.kind == pkEmpty: result = terminal if p.skip.kind == pkEmpty: result = terminal
else: result = sequence(p.skip, terminal) else: result = sequence(p.skip, terminal)
@ -1491,7 +1491,7 @@ proc primary(p: var TPegParser): TPeg =
else: discard else: discard
case p.tok.kind case p.tok.kind
of tkIdentifier: of tkIdentifier:
if p.identIsVerbatim: if p.identIsVerbatim:
var m = p.tok.modifier var m = p.tok.modifier
if m == modNone: m = p.modifier if m == modNone: m = p.modifier
result = modifiedTerm(p.tok.literal, m).token(p) result = modifiedTerm(p.tok.literal, m).token(p)
@ -1534,17 +1534,17 @@ proc primary(p: var TPegParser): TPeg =
of tkEscaped: of tkEscaped:
result = term(p.tok.literal[0]).token(p) result = term(p.tok.literal[0]).token(p)
getTok(p) getTok(p)
of tkDollar: of tkDollar:
result = endAnchor() result = endAnchor()
getTok(p) getTok(p)
of tkHat: of tkHat:
result = startAnchor() result = startAnchor()
getTok(p) getTok(p)
of tkBackref: of tkBackref:
var m = p.tok.modifier var m = p.tok.modifier
if m == modNone: m = p.modifier if m == modNone: m = p.modifier
result = modifiedBackRef(p.tok.index, m).token(p) result = modifiedBackRef(p.tok.index, m).token(p)
if p.tok.index < 0 or p.tok.index > p.captures: if p.tok.index < 0 or p.tok.index > p.captures:
pegError(p, "invalid back reference index: " & $p.tok.index) pegError(p, "invalid back reference index: " & $p.tok.index)
getTok(p) getTok(p)
else: else:
@ -1568,7 +1568,7 @@ proc seqExpr(p: var TPegParser): TPeg =
while true: while true:
case p.tok.kind case p.tok.kind
of tkAmp, tkNot, tkAt, tkStringLit, tkCharset, tkParLe, tkCurlyLe, of tkAmp, tkNot, tkAt, tkStringLit, tkCharset, tkParLe, tkCurlyLe,
tkAny, tkAnyRune, tkBuiltin, tkEscaped, tkDollar, tkBackref, tkAny, tkAnyRune, tkBuiltin, tkEscaped, tkDollar, tkBackref,
tkHat, tkCurlyAt: tkHat, tkCurlyAt:
result = sequence(result, primary(p)) result = sequence(result, primary(p))
of tkIdentifier: of tkIdentifier:
@ -1582,7 +1582,7 @@ proc parseExpr(p: var TPegParser): TPeg =
while p.tok.kind == tkBar: while p.tok.kind == tkBar:
getTok(p) getTok(p)
result = result / seqExpr(p) result = result / seqExpr(p)
proc parseRule(p: var TPegParser): PNonTerminal = proc parseRule(p: var TPegParser): PNonTerminal =
if p.tok.kind == tkIdentifier and arrowIsNextTok(p): if p.tok.kind == tkIdentifier and arrowIsNextTok(p):
result = getNonTerminal(p, p.tok.literal) result = getNonTerminal(p, p.tok.literal)
@ -1596,7 +1596,7 @@ proc parseRule(p: var TPegParser): PNonTerminal =
incl(result.flags, ntDeclared) # NOW inlining may be attempted incl(result.flags, ntDeclared) # NOW inlining may be attempted
else: else:
pegError(p, "rule expected, but found: " & p.tok.literal) pegError(p, "rule expected, but found: " & p.tok.literal)
proc rawParse(p: var TPegParser): TPeg = proc rawParse(p: var TPegParser): TPeg =
## parses a rule or a PEG expression ## parses a rule or a PEG expression
while p.tok.kind == tkBuiltin: while p.tok.kind == tkBuiltin:
@ -1649,20 +1649,20 @@ proc peg*(pattern: string): TPeg =
## peg"{\ident} \s* '=' \s* {.*}" ## peg"{\ident} \s* '=' \s* {.*}"
result = parsePeg(pattern, "pattern") result = parsePeg(pattern, "pattern")
proc escapePeg*(s: string): string = proc escapePeg*(s: string): string =
## escapes `s` so that it is matched verbatim when used as a peg. ## escapes `s` so that it is matched verbatim when used as a peg.
result = "" result = ""
var inQuote = false var inQuote = false
for c in items(s): for c in items(s):
case c case c
of '\0'..'\31', '\'', '"', '\\': of '\0'..'\31', '\'', '"', '\\':
if inQuote: if inQuote:
result.add('\'') result.add('\'')
inQuote = false inQuote = false
result.add("\\x") result.add("\\x")
result.add(toHex(ord(c), 2)) result.add(toHex(ord(c), 2))
else: else:
if not inQuote: if not inQuote:
result.add('\'') result.add('\'')
inQuote = true inQuote = true
result.add(c) result.add(c)
@ -1675,27 +1675,27 @@ when isMainModule:
doAssert(not match("W_HI_L", peg"\y 'while'")) doAssert(not match("W_HI_L", peg"\y 'while'"))
doAssert(not match("W_HI_Le", peg"\y v'while'")) doAssert(not match("W_HI_Le", peg"\y v'while'"))
doAssert match("W_HI_Le", peg"y'while'") doAssert match("W_HI_Le", peg"y'while'")
doAssert($ +digits == $peg"\d+") doAssert($ +digits == $peg"\d+")
doAssert "0158787".match(peg"\d+") doAssert "0158787".match(peg"\d+")
doAssert "ABC 0232".match(peg"\w+\s+\d+") doAssert "ABC 0232".match(peg"\w+\s+\d+")
doAssert "ABC".match(peg"\d+ / \w+") doAssert "ABC".match(peg"\d+ / \w+")
for word in split("00232this02939is39an22example111", peg"\d+"): for word in split("00232this02939is39an22example111", peg"\d+"):
writeln(stdout, word) writeLine(stdout, word)
doAssert matchLen("key", ident) == 3 doAssert matchLen("key", ident) == 3
var pattern = sequence(ident, *whitespace, term('='), *whitespace, ident) var pattern = sequence(ident, *whitespace, term('='), *whitespace, ident)
doAssert matchLen("key1= cal9", pattern) == 11 doAssert matchLen("key1= cal9", pattern) == 11
var ws = newNonTerminal("ws", 1, 1) var ws = newNonTerminal("ws", 1, 1)
ws.rule = *whitespace ws.rule = *whitespace
var expr = newNonTerminal("expr", 1, 1) var expr = newNonTerminal("expr", 1, 1)
expr.rule = sequence(capture(ident), *sequence( expr.rule = sequence(capture(ident), *sequence(
nonterminal(ws), term('+'), nonterminal(ws), nonterminal(expr))) nonterminal(ws), term('+'), nonterminal(ws), nonterminal(expr)))
var c: TCaptures var c: TCaptures
var s = "a+b + c +d+e+f" var s = "a+b + c +d+e+f"
doAssert rawMatch(s, expr.rule, 0, c) == len(s) doAssert rawMatch(s, expr.rule, 0, c) == len(s)
@ -1716,7 +1716,7 @@ when isMainModule:
doAssert matches[0] == "abc" doAssert matches[0] == "abc"
else: else:
doAssert false doAssert false
var g2 = peg"""S <- A B / C D var g2 = peg"""S <- A B / C D
A <- 'a'+ A <- 'a'+
B <- 'b'+ B <- 'b'+
@ -1733,10 +1733,10 @@ when isMainModule:
doAssert matches[0] == "a" doAssert matches[0] == "a"
else: else:
doAssert false doAssert false
block: block:
var matches: array[0..2, string] var matches: array[0..2, string]
if match("abcdefg", peg"c {d} ef {g}", matches, 2): if match("abcdefg", peg"c {d} ef {g}", matches, 2):
doAssert matches[0] == "d" doAssert matches[0] == "d"
doAssert matches[1] == "g" doAssert matches[1] == "g"
else: else:
@ -1744,13 +1744,13 @@ when isMainModule:
for x in findAll("abcdef", peg"{.}", 3): for x in findAll("abcdef", peg"{.}", 3):
echo x echo x
if "f(a, b)" =~ peg"{[0-9]+} / ({\ident} '(' {@} ')')": if "f(a, b)" =~ peg"{[0-9]+} / ({\ident} '(' {@} ')')":
doAssert matches[0] == "f" doAssert matches[0] == "f"
doAssert matches[1] == "a, b" doAssert matches[1] == "a, b"
else: else:
doAssert false doAssert false
doAssert match("eine übersicht und außerdem", peg"(\letter \white*)+") doAssert match("eine übersicht und außerdem", peg"(\letter \white*)+")
# ß is not a lower cased letter?! # ß is not a lower cased letter?!
doAssert match("eine übersicht und auerdem", peg"(\lower \white*)+") doAssert match("eine übersicht und auerdem", peg"(\lower \white*)+")
@ -1762,7 +1762,7 @@ when isMainModule:
"var1<-keykey;var2<-key2key2") "var1<-keykey;var2<-key2key2")
doAssert match("prefix/start", peg"^start$", 7) doAssert match("prefix/start", peg"^start$", 7)
# tricky test to check for false aliasing: # tricky test to check for false aliasing:
block: block:
var a = term"key" var a = term"key"

View file

@ -9,8 +9,8 @@ when not defined(windows):
discard uname(u) discard uname(u)
writeln(stdout, u.sysname) writeLine(stdout, u.sysname)
writeln(stdout, u.nodename) writeLine(stdout, u.nodename)
writeln(stdout, u.release) writeLine(stdout, u.release)
writeln(stdout, u.machine) writeLine(stdout, u.machine)

View file

@ -9,7 +9,7 @@ type
var val = {a, b} var val = {a, b}
stdout.write(repr(val)) stdout.write(repr(val))
stdout.writeln(repr({'a'..'z', 'A'..'Z'})) stdout.writeLine(repr({'a'..'z', 'A'..'Z'}))
type type
TObj {.pure, inheritable.} = object TObj {.pure, inheritable.} = object

View file

@ -26,7 +26,7 @@ q[] = p
s = @[q, q, q, q] s = @[q, q, q, q]
writeln(stdout, repr(p)) writeLine(stdout, repr(p))
writeln(stdout, repr(q)) writeLine(stdout, repr(q))
writeln(stdout, repr(s)) writeLine(stdout, repr(s))
writeln(stdout, repr(en4)) writeLine(stdout, repr(en4))

View file

@ -1,12 +1,12 @@
import strtabs import strtabs
var tab = newStringTable({"key1": "val1", "key2": "val2"}, var tab = newStringTable({"key1": "val1", "key2": "val2"},
modeStyleInsensitive) modeStyleInsensitive)
for i in 0..80: for i in 0..80:
tab["key_" & $i] = "value" & $i tab["key_" & $i] = "value" & $i
for key, val in pairs(tab): for key, val in pairs(tab):
writeln(stdout, key, ": ", val) writeLine(stdout, key, ": ", val)
writeln(stdout, "length of table ", $tab.len) writeLine(stdout, "length of table ", $tab.len)
writeln(stdout, `%`("$key1 = $key2; ${PATH}", tab, {useEnvironment})) writeLine(stdout, `%`("$key1 = $key2; ${PATH}", tab, {useEnvironment}))

View file

@ -5,9 +5,9 @@ import
proc main(filter: string) = proc main(filter: string) =
for filename in walkFiles(filter): for filename in walkFiles(filter):
writeln(stdout, filename) writeLine(stdout, filename)
for key, val in envPairs(): for key, val in envPairs():
writeln(stdout, key & '=' & val) writeLine(stdout, key & '=' & val)
main("*.nim") main("*.nim")

View file

@ -15,10 +15,10 @@ var abclev = levB
template tstLev(abclev: TLev) = template tstLev(abclev: TLev) =
bind tstempl.abclev, `%` bind tstempl.abclev, `%`
writeln(stdout, "global = $1, arg = $2, test = $3" % [ writeLine(stdout, "global = $1, arg = $2, test = $3" % [
$tstempl.abclev, $abclev, $(tstempl.abclev == abclev)]) $tstempl.abclev, $abclev, $(tstempl.abclev == abclev)])
# evaluates to true, but must be false # evaluates to true, but must be false
tstLev(levA) tstLev(levA)
writeln(stdout, $abclev) writeLine(stdout, $abclev)

View file

@ -13,8 +13,8 @@ template withOpenFile(f: expr, filename: string, mode: TFileMode,
quit("cannot open for writing: " & filename) quit("cannot open for writing: " & filename)
withOpenFile(txt, "ttempl3.txt", fmWrite): withOpenFile(txt, "ttempl3.txt", fmWrite):
writeln(txt, "line 1") writeLine(txt, "line 1")
txt.writeln("line 2") txt.writeLine("line 2")
var var
myVar: array[0..1, int] myVar: array[0..1, int]

View file

@ -137,11 +137,11 @@ proc doScenario(script: string, output: Stream, mode: TRunMode, verbose: bool):
if line.strip.len == 0: continue if line.strip.len == 0: continue
if line.startsWith("#"): if line.startsWith("#"):
output.writeln line output.writeLine line
continue continue
elif line.startsWith(">"): elif line.startsWith(">"):
s.doCommand(line.substr(1).strip) s.doCommand(line.substr(1).strip)
output.writeln line, "\n", if verbose: s.lastOutput else: "" output.writeLine line, "\n", if verbose: s.lastOutput else: ""
else: else:
var expectMatch = true var expectMatch = true
var pattern = s.replaceVars(line) var pattern = s.replaceVars(line)
@ -153,9 +153,9 @@ proc doScenario(script: string, output: Stream, mode: TRunMode, verbose: bool):
s.lastOutput.find(re(pattern, flags = {reStudy})) != -1 s.lastOutput.find(re(pattern, flags = {reStudy})) != -1
if expectMatch == actualMatch: if expectMatch == actualMatch:
output.writeln "SUCCESS ", line output.writeLine "SUCCESS ", line
else: else:
output.writeln "FAILURE ", line output.writeLine "FAILURE ", line
result = false result = false
iterator caasTestsRunner*(filter = "", verbose = false): tuple[test, iterator caasTestsRunner*(filter = "", verbose = false): tuple[test,

View file

@ -138,7 +138,7 @@ proc generateHtml*(filename: string, commit: int; onlyFailing: bool) =
# generate navigation: # generate navigation:
outfile.write("""<ul id="tabs">""") outfile.write("""<ul id="tabs">""")
for m in db.rows(sql"select id, name, os, cpu from Machine order by id"): for m in db.rows(sql"select id, name, os, cpu from Machine order by id"):
outfile.writeln """<li><a href="#$#">$#: $#, $#</a></li>""" % m outfile.writeLine """<li><a href="#$#">$#: $#, $#</a></li>""" % m
outfile.write("</ul>") outfile.write("</ul>")
for currentMachine in db.rows(sql"select id from Machine order by id"): for currentMachine in db.rows(sql"select id from Machine order by id"):
@ -195,7 +195,7 @@ proc generateJson*(filename: string, commit: int) =
let machine = $backend.getMachine(db) let machine = $backend.getMachine(db)
let data = db.getRow(sql(selRow), lastCommit, machine) let data = db.getRow(sql(selRow), lastCommit, machine)
outfile.writeln("""{"total": $#, "passed": $#, "skipped": $#""" % data) outfile.writeLine("""{"total": $#, "passed": $#, "skipped": $#""" % data)
let results = newJArray() let results = newJArray()
for row in db.rows(sql(selResults), lastCommit): for row in db.rows(sql(selResults), lastCommit):
@ -208,7 +208,7 @@ proc generateJson*(filename: string, commit: int) =
obj["expected"] = %row[5] obj["expected"] = %row[5]
obj["given"] = %row[6] obj["given"] = %row[6]
results.add(obj) results.add(obj)
outfile.writeln(""", "results": """) outfile.writeLine(""", "results": """)
outfile.write(results.pretty) outfile.write(results.pretty)
if not previousCommit.isNil: if not previousCommit.isNil:
@ -220,9 +220,9 @@ proc generateJson*(filename: string, commit: int) =
obj["old"] = %row[1] obj["old"] = %row[1]
obj["new"] = %row[2] obj["new"] = %row[2]
diff.add obj diff.add obj
outfile.writeln(""", "diff": """) outfile.writeLine(""", "diff": """)
outfile.writeln(diff.pretty) outfile.writeLine(diff.pretty)
outfile.writeln "}" outfile.writeLine "}"
close(db) close(db)
close(outfile) close(outfile)

View file

@ -3,7 +3,7 @@ discard """
""" """
proc f(x: varargs[string, `$`]) = discard proc f(x: varargs[string, `$`]) = discard
template optF{f(x)}(x: varargs[expr]) = template optF{f(x)}(x: varargs[expr]) =
writeln(stdout, x) writeLine(stdout, x)
f 1, 2, false, 3, "ha" f 1, 2, false, 3, "ha"

View file

@ -7,13 +7,13 @@ discard """
template optWrite{ template optWrite{
write(f, x) write(f, x)
((write|writeln){w})(f, y) ((write|writeLine){w})(f, y)
}(x, y: varargs[expr], f, w: expr) = }(x, y: varargs[expr], f, w: expr) =
w(f, "|", x, y, "|") w(f, "|", x, y, "|")
if true: if true:
echo "0" echo "0"
write stdout, "1" write stdout, "1"
writeln stdout, "2" writeLine stdout, "2"
write stdout, "3" write stdout, "3"
echo "4" echo "4"