From 383fbca27ef4f4e0b5eae0e0e02029fe644248ac Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 17 Jan 2014 08:47:51 +0100 Subject: better tester --- tests/macro/tmacro1.nim | 23 ---------- tests/macro/tmacro2.nim | 28 ------------ tests/macro/tmacro3.nim | 31 ------------- tests/macro/tmacro4.nim | 19 -------- tests/macro/tmacro5.nim | 59 ------------------------- tests/macro/tmacroaspragma.nim | 8 ---- tests/macro/tmacrogenerics.nim | 39 ----------------- tests/macro/tmacros1.nim | 31 ------------- tests/macro/tmacrostmt.nim | 26 ----------- tests/macro/tmacrotypes.nim | 12 ------ tests/macro/tnimrodnode_for_runtime.nim | 13 ------ tests/macro/tprintf.nim | 16 ------- tests/macro/tquotewords.nim | 26 ----------- tests/macro/trecmacro.nim | 14 ------ tests/macro/tstringinterp.nim | 74 -------------------------------- tests/macro/tvtable.nim | 74 -------------------------------- tests/macros/tmacro1.nim | 23 ++++++++++ tests/macros/tmacro2.nim | 28 ++++++++++++ tests/macros/tmacro3.nim | 31 +++++++++++++ tests/macros/tmacro4.nim | 19 ++++++++ tests/macros/tmacro5.nim | 59 +++++++++++++++++++++++++ tests/macros/tmacroaspragma.nim | 8 ++++ tests/macros/tmacrogenerics.nim | 39 +++++++++++++++++ tests/macros/tmacros1.nim | 31 +++++++++++++ tests/macros/tmacrostmt.nim | 26 +++++++++++ tests/macros/tmacrotypes.nim | 12 ++++++ tests/macros/tnimrodnode_for_runtime.nim | 13 ++++++ tests/macros/tprintf.nim | 16 +++++++ tests/macros/tquotewords.nim | 26 +++++++++++ tests/macros/trecmacro.nim | 14 ++++++ tests/macros/tstringinterp.nim | 74 ++++++++++++++++++++++++++++++++ tests/macros/tvtable.nim | 74 ++++++++++++++++++++++++++++++++ tests/testament/backend.nim | 6 +-- tests/testament/htmlgen.nim | 50 +++++++++++---------- tests/testament/tester.nim | 8 +++- 35 files changed, 529 insertions(+), 521 deletions(-) delete mode 100644 tests/macro/tmacro1.nim delete mode 100644 tests/macro/tmacro2.nim delete mode 100644 tests/macro/tmacro3.nim delete mode 100644 tests/macro/tmacro4.nim delete mode 100644 tests/macro/tmacro5.nim delete mode 100644 tests/macro/tmacroaspragma.nim delete mode 100644 tests/macro/tmacrogenerics.nim delete mode 100644 tests/macro/tmacros1.nim delete mode 100644 tests/macro/tmacrostmt.nim delete mode 100644 tests/macro/tmacrotypes.nim delete mode 100644 tests/macro/tnimrodnode_for_runtime.nim delete mode 100644 tests/macro/tprintf.nim delete mode 100644 tests/macro/tquotewords.nim delete mode 100644 tests/macro/trecmacro.nim delete mode 100644 tests/macro/tstringinterp.nim delete mode 100644 tests/macro/tvtable.nim create mode 100644 tests/macros/tmacro1.nim create mode 100644 tests/macros/tmacro2.nim create mode 100644 tests/macros/tmacro3.nim create mode 100644 tests/macros/tmacro4.nim create mode 100644 tests/macros/tmacro5.nim create mode 100644 tests/macros/tmacroaspragma.nim create mode 100644 tests/macros/tmacrogenerics.nim create mode 100644 tests/macros/tmacros1.nim create mode 100644 tests/macros/tmacrostmt.nim create mode 100644 tests/macros/tmacrotypes.nim create mode 100644 tests/macros/tnimrodnode_for_runtime.nim create mode 100644 tests/macros/tprintf.nim create mode 100644 tests/macros/tquotewords.nim create mode 100644 tests/macros/trecmacro.nim create mode 100644 tests/macros/tstringinterp.nim create mode 100644 tests/macros/tvtable.nim (limited to 'tests') diff --git a/tests/macro/tmacro1.nim b/tests/macro/tmacro1.nim deleted file mode 100644 index 3a67c2611..000000000 --- a/tests/macro/tmacro1.nim +++ /dev/null @@ -1,23 +0,0 @@ -import macros - -from uri import `/` - -macro test*(a: stmt): stmt {.immediate.} = - var nodes: tuple[a, b: int] - nodes.a = 4 - nodes[1] = 45 - - type - TTypeEx = object - x, y: int - case b: bool - of false: nil - of true: z: float - - var t: TTypeEx - t.b = true - t.z = 4.5 - -test: - "hi" - diff --git a/tests/macro/tmacro2.nim b/tests/macro/tmacro2.nim deleted file mode 100644 index 8515322d5..000000000 --- a/tests/macro/tmacro2.nim +++ /dev/null @@ -1,28 +0,0 @@ -discard """ - output: "ta-da Your value sir: 'HE!!!!o Wor!!d'" -""" - -import macros, strutils - -proc testBlock(): string {.compileTime.} = - block myBlock: - while true: - echo "inner block" - break myBlock - echo "outer block" - result = "ta-da" - -macro mac(n: expr): expr = - let n = callsite() - expectKind(n, nnkCall) - expectLen(n, 2) - expectKind(n[1], nnkStrLit) - var s: string = n[1].strVal - s = s.replace("l", "!!") - result = newStrLitNode("Your value sir: '$#'" % [s]) - -const s = testBlock() -const t = mac("HEllo World") -echo s, " ", t - - diff --git a/tests/macro/tmacro3.nim b/tests/macro/tmacro3.nim deleted file mode 100644 index 162212326..000000000 --- a/tests/macro/tmacro3.nim +++ /dev/null @@ -1,31 +0,0 @@ -discard """ - output: "" -""" - -import macros - -type - TA = tuple[a: int] - PA = ref TA - -macro test*(a: stmt): stmt {.immediate.} = - var val: PA - new(val) - val.a = 4 - -test: - "hi" - -macro test2*(a: stmt): stmt {.immediate.} = - proc testproc(recurse: int) = - echo "Thats weird" - var o : PNimrodNode = nil - echo " no its not!" - o = newNimNode(nnkNone) - if recurse > 0: - testproc(recurse - 1) - testproc(5) - -test2: - "hi" - diff --git a/tests/macro/tmacro4.nim b/tests/macro/tmacro4.nim deleted file mode 100644 index 10a23b159..000000000 --- a/tests/macro/tmacro4.nim +++ /dev/null @@ -1,19 +0,0 @@ -discard """ - output: "after" -""" - -import - macros, strutils - -macro test_macro*(n: stmt): stmt {.immediate.} = - result = newNimNode(nnkStmtList) - var ass : PNimrodNode = newNimNode(nnkAsgn) - add(ass, newIdentNode("str")) - add(ass, newStrLitNode("after")) - add(result, ass) -when isMainModule: - var str: string = "before" - test_macro(str): - var i : integer = 123 - echo str - diff --git a/tests/macro/tmacro5.nim b/tests/macro/tmacro5.nim deleted file mode 100644 index 39324e497..000000000 --- a/tests/macro/tmacro5.nim +++ /dev/null @@ -1,59 +0,0 @@ -import macros,json - -var decls{.compileTime.}: seq[PNimrodNode] = @[] -var impls{.compileTime.}: seq[PNimrodNode] = @[] - -macro importImpl_forward(name, returns): stmt {.immediate.} = - result = newNimNode(nnkEmpty) - var func_name = newNimNode(nnkAccQuoted) - func_name.add newIdentNode("import") - func_name.add name - - var res = newNimNode(nnkProcDef) - res.add newNimNode(nnkPostfix) - res[0].add newIdentNode("*") - res[0].add func_name - res.add newNimNode(nnkEmpty) - res.add newNimNode(nnkEmpty) - res.add newNimNode(nnkFormalParams) - res[3].add returns - var p1 = newNimNode(nnkIdentDefs) - p1.add newIdentNode("dat") - p1.add newIdentNOde("PJsonNode") - p1.add newNimNode(nnkEmpty) - res[3].add p1 - var p2 = newNimNode(nnkIdentDefs) - p2.add newIdentNode("errors") - p2.add newNimNode(nnkVarTy) - p2.add newNimNode(nnkEmpty) - p2[1].add newNimNode(nnkBracketExpr) - p2[1][0].add newIdentNode("seq") - p2[1][0].add newIdentNode("string") - res[3].add p2 - - res.add newNimNode(nnkEmpty) - res.add newNimNode(nnkEmpty) - res.add newNimNode(nnkEmpty) - - decls.add res - echo(repr(res)) - -macro importImpl(name, returns: expr, body: stmt): stmt {.immediate.} = - #var res = getAST(importImpl_forward(name, returns)) - discard getAST(importImpl_forward(name, returns)) - var res = copyNimTree(decls[decls.high]) - res[6] = body - echo repr(res) - impls.add res - -macro okayy:stmt = - result = newNimNode(nnkStmtList) - for node in decls: result.add node - for node in impls: result.add node - -importimpl(Item, int): - echo 42 -importImpl(Foo, int16): - echo 77 - -okayy \ No newline at end of file diff --git a/tests/macro/tmacroaspragma.nim b/tests/macro/tmacroaspragma.nim deleted file mode 100644 index 0e5c352b3..000000000 --- a/tests/macro/tmacroaspragma.nim +++ /dev/null @@ -1,8 +0,0 @@ -import macros - -macro foo(x: stmt): stmt = - echo treerepr(callsite()) - result = newNimNode(nnkStmtList) - -proc zoo() {.foo.} = echo "hi" - diff --git a/tests/macro/tmacrogenerics.nim b/tests/macro/tmacrogenerics.nim deleted file mode 100644 index 5ae59e0da..000000000 --- a/tests/macro/tmacrogenerics.nim +++ /dev/null @@ -1,39 +0,0 @@ -discard """ - file: "tmacrogenerics.nim" - msg: ''' -instantiation 1 with int and float -instantiation 2 with float and string -instantiation 3 with string and string -counter: 3 -''' - output: "int\nfloat\nint\nstring" -""" - -import typetraits, macros - -var counter {.compileTime.} = 0 - -macro makeBar(A, B: typedesc): typedesc = - inc counter - echo "instantiation ", counter, " with ", A.name, " and ", B.name - result = A - -type - Bar[T, U] = makeBar(T, U) - -var bb1: Bar[int, float] -var bb2: Bar[float, string] -var bb3: Bar[int, float] -var bb4: Bar[string, string] - -proc match(a: int) = echo "int" -proc match(a: string) = echo "string" -proc match(a: float) = echo "float" - -match(bb1) -match(bb2) -match(bb3) -match(bb4) - -static: - echo "counter: ", counter diff --git a/tests/macro/tmacros1.nim b/tests/macro/tmacros1.nim deleted file mode 100644 index 3c814ad6d..000000000 --- a/tests/macro/tmacros1.nim +++ /dev/null @@ -1,31 +0,0 @@ -discard """ - output: "Got: 'nnkCall' hi" -""" - -import - macros, strutils - -macro outterMacro*(n: stmt): stmt {.immediate.} = - let n = callsite() - var j : string = "hi" - proc innerProc(i: int): string = - echo "Using arg ! " & n.repr - result = "Got: '" & $n.kind & "' " & $j - var callNode = n[0] - expectKind(n, TNimrodNodeKind.nnkCall) - if n.len != 3 or n[1].kind != TNimrodNodeKind.nnkIdent: - error("Macro " & callNode.repr & - " requires the ident passed as parameter (eg: " & callNode.repr & - "(the_name_you_want)): statements.") - result = newNimNode(TNimrodNodeKind.nnkStmtList) - var ass : PNimrodNode = newNimNode(nnkAsgn) - ass.add(newIdentNode(n[1].ident)) - ass.add(newStrLitNode(innerProc(4))) - result.add(ass) - -var str: string -outterMacro(str): - "hellow" -echo str - - diff --git a/tests/macro/tmacrostmt.nim b/tests/macro/tmacrostmt.nim deleted file mode 100644 index d9c70197d..000000000 --- a/tests/macro/tmacrostmt.nim +++ /dev/null @@ -1,26 +0,0 @@ -import macros -macro case_token(n: stmt): stmt {.immediate.} = - # creates a lexical analyzer from regular expressions - # ... (implementation is an exercise for the reader :-) - nil - -case_token: # this colon tells the parser it is a macro statement -of r"[A-Za-z_]+[A-Za-z_0-9]*": - return tkIdentifier -of r"0-9+": - return tkInteger -of r"[\+\-\*\?]+": - return tkOperator -else: - return tkUnknown - -case_token: inc i - -#bug #488 - -macro foo: stmt = - var exp = newCall("whatwhat", newIntLitNode(1)) - if compiles(getAst(exp)): return exp - else: echo "Does not compute!" - -foo() diff --git a/tests/macro/tmacrotypes.nim b/tests/macro/tmacrotypes.nim deleted file mode 100644 index 7697dba27..000000000 --- a/tests/macro/tmacrotypes.nim +++ /dev/null @@ -1,12 +0,0 @@ -import macros, typetraits - -macro checkType(ex, expected: expr): stmt {.immediate.} = - var t = ex.typ - assert t.name == expected.strVal - -proc voidProc = echo "hello" -proc intProc(a, b): int = 10 - -checkType(voidProc(), "void") -checkType(intProc(10, 20.0), "int") -checkType(noproc(10, 20.0), "Error Type") diff --git a/tests/macro/tnimrodnode_for_runtime.nim b/tests/macro/tnimrodnode_for_runtime.nim deleted file mode 100644 index e73c8430f..000000000 --- a/tests/macro/tnimrodnode_for_runtime.nim +++ /dev/null @@ -1,13 +0,0 @@ -discard """ - output: "bla" - disabled: true -""" - -import macros -proc makeMacro: PNimrodNode = - result = nil - -var p = makeMacro() - -echo "bla" - diff --git a/tests/macro/tprintf.nim b/tests/macro/tprintf.nim deleted file mode 100644 index c8fb51cdc..000000000 --- a/tests/macro/tprintf.nim +++ /dev/null @@ -1,16 +0,0 @@ -discard """ - file: "tprintf.nim" - output: "Andreas Rumpf" -""" -# Test a printf proc - -proc printf(file: TFile, args: openarray[string]) = - var i = 0 - while i < args.len: - write(file, args[i]) - inc(i) - -printf(stdout, ["Andreas ", "Rumpf\n"]) -#OUT Andreas Rumpf - - diff --git a/tests/macro/tquotewords.nim b/tests/macro/tquotewords.nim deleted file mode 100644 index 76b8d8af7..000000000 --- a/tests/macro/tquotewords.nim +++ /dev/null @@ -1,26 +0,0 @@ -discard """ - file: "tquotewords.nim" - output: "thisanexample" -""" -# Test an idea I recently had: - -import macros - -macro quoteWords(n: expr): expr {.immediate.} = - let n = callsite() - result = newNimNode(nnkBracket, n) - for i in 1..n.len-1: - expectKind(n[i], nnkIdent) - result.add(toStrLit(n[i])) - -const - myWordList = quoteWords(this, an, example) - -var s = "" -for w in items(myWordList): - s.add(w) - -echo s #OUT thisanexample - - - diff --git a/tests/macro/trecmacro.nim b/tests/macro/trecmacro.nim deleted file mode 100644 index 28b6db530..000000000 --- a/tests/macro/trecmacro.nim +++ /dev/null @@ -1,14 +0,0 @@ -discard """ - file: "trecmacro.nim" - line: 8 - errormsg: "recursive dependency: 'dump'" -""" - -macro dump(n: stmt): stmt = - dump(n) - if kind(n) == nnkNone: - nil - else: - hint($kind(n)) - for i in countUp(0, len(n)-1): - nil diff --git a/tests/macro/tstringinterp.nim b/tests/macro/tstringinterp.nim deleted file mode 100644 index f030213e0..000000000 --- a/tests/macro/tstringinterp.nim +++ /dev/null @@ -1,74 +0,0 @@ -discard """ - file: "tstringinterp.nim" - output: "Hello Alice, 64 | Hello Bob, 10$" -""" - -import macros, parseutils, strutils - -proc concat(strings: varargs[string]): string = - result = newString(0) - for s in items(strings): result.add(s) - -template ProcessInterpolations(e: expr) = - var s = e[1].strVal - for f in interpolatedFragments(s): - case f.kind - of ikStr: addString(f.value) - of ikDollar: addDollar() - of ikVar, ikExpr: addExpr(newCall("$", parseExpr(f.value))) - -macro formatStyleInterpolation(e: expr): expr = - let e = callsite() - var - formatString = "" - arrayNode = newNimNode(nnkBracket) - idx = 1 - - proc addString(s: string) = - formatString.add(s) - - proc addExpr(e: PNimrodNode) = - arrayNode.add(e) - formatString.add("$" & $(idx)) - inc idx - - proc addDollar() = - formatString.add("$$") - - ProcessInterpolations(e) - - result = parseExpr("\"x\" % [y]") - result[1].strVal = formatString - result[2] = arrayNode - -macro concatStyleInterpolation(e: expr): expr = - let e = callsite() - var args: seq[PNimrodNode] - newSeq(args, 0) - - proc addString(s: string) = args.add(newStrLitNode(s)) - proc addExpr(e: PNimrodNode) = args.add(e) - proc addDollar() = args.add(newStrLitNode"$") - - ProcessInterpolations(e) - - result = newCall("concat", args) - -### - -proc sum(a, b, c: int): int = - return (a + b + c) - -var - alice = "Alice" - bob = "Bob" - a = 10 - b = 20 - c = 34 - -var - s1 = concatStyleInterpolation"Hello ${alice}, ${sum(a, b, c)}" - s2 = formatStyleInterpolation"Hello ${bob}, ${sum(alice.len, bob.len, 2)}$$" - -write(stdout, s1 & " | " & s2) - diff --git a/tests/macro/tvtable.nim b/tests/macro/tvtable.nim deleted file mode 100644 index 51894618c..000000000 --- a/tests/macro/tvtable.nim +++ /dev/null @@ -1,74 +0,0 @@ -discard """ - output: ''' -OBJ 1 foo -10 -OBJ 1 bar -OBJ 2 foo -5 -OBJ 2 bar -''' -""" - -type - # these are the signatures of the virtual procs for each type - fooProc[T] = proc (o: var T): int - barProc[T] = proc (o: var T) - - # an untyped table to store the proc pointers - # it's also possible to use a strongly typed tuple here - VTable = array[0..1, pointer] - - TBase = object {.inheritable.} - vtbl: ptr VTable - - TUserObject1 = object of TBase - x: int - - TUserObject2 = object of TBase - y: int - -proc foo(o: var TUserObject1): int = - echo "OBJ 1 foo" - return 10 - -proc bar(o: var TUserObject1) = - echo "OBJ 1 bar" - -proc foo(o: var TUserObject2): int = - echo "OBJ 2 foo" - return 5 - -proc bar(o: var TUserObject2) = - echo "OBJ 2 bar" - -proc getVTable(T: typedesc): ptr VTable = - # pay attention to what's going on here - # this will initialize the vtable for each type at program start-up - # - # fooProc[T](foo) is a type coercion - it looks for a proc named foo - # matching the signature fooProc[T] (e.g. proc (o: var TUserObject1): int) - var vtbl {.global.} = [ - cast[pointer](fooProc[T](foo)), - cast[pointer](barProc[T](bar)) - ] - - return vtbl.addr - -proc create(T: typedesc): T = - result.vtbl = getVTable(T) - -proc baseFoo(o: var TBase): int = - return cast[fooProc[TBase]](o.vtbl[0]) (o) - -proc baseBar(o: var TBase) = - cast[barProc[TBase]](o.vtbl[1]) (o) - -var a = TUserObject1.create -var b = TUserObject2.create - -echo a.baseFoo -a.baseBar - -echo b.baseFoo -b.baseBar - diff --git a/tests/macros/tmacro1.nim b/tests/macros/tmacro1.nim new file mode 100644 index 000000000..3a67c2611 --- /dev/null +++ b/tests/macros/tmacro1.nim @@ -0,0 +1,23 @@ +import macros + +from uri import `/` + +macro test*(a: stmt): stmt {.immediate.} = + var nodes: tuple[a, b: int] + nodes.a = 4 + nodes[1] = 45 + + type + TTypeEx = object + x, y: int + case b: bool + of false: nil + of true: z: float + + var t: TTypeEx + t.b = true + t.z = 4.5 + +test: + "hi" + diff --git a/tests/macros/tmacro2.nim b/tests/macros/tmacro2.nim new file mode 100644 index 000000000..8515322d5 --- /dev/null +++ b/tests/macros/tmacro2.nim @@ -0,0 +1,28 @@ +discard """ + output: "ta-da Your value sir: 'HE!!!!o Wor!!d'" +""" + +import macros, strutils + +proc testBlock(): string {.compileTime.} = + block myBlock: + while true: + echo "inner block" + break myBlock + echo "outer block" + result = "ta-da" + +macro mac(n: expr): expr = + let n = callsite() + expectKind(n, nnkCall) + expectLen(n, 2) + expectKind(n[1], nnkStrLit) + var s: string = n[1].strVal + s = s.replace("l", "!!") + result = newStrLitNode("Your value sir: '$#'" % [s]) + +const s = testBlock() +const t = mac("HEllo World") +echo s, " ", t + + diff --git a/tests/macros/tmacro3.nim b/tests/macros/tmacro3.nim new file mode 100644 index 000000000..162212326 --- /dev/null +++ b/tests/macros/tmacro3.nim @@ -0,0 +1,31 @@ +discard """ + output: "" +""" + +import macros + +type + TA = tuple[a: int] + PA = ref TA + +macro test*(a: stmt): stmt {.immediate.} = + var val: PA + new(val) + val.a = 4 + +test: + "hi" + +macro test2*(a: stmt): stmt {.immediate.} = + proc testproc(recurse: int) = + echo "Thats weird" + var o : PNimrodNode = nil + echo " no its not!" + o = newNimNode(nnkNone) + if recurse > 0: + testproc(recurse - 1) + testproc(5) + +test2: + "hi" + diff --git a/tests/macros/tmacro4.nim b/tests/macros/tmacro4.nim new file mode 100644 index 000000000..10a23b159 --- /dev/null +++ b/tests/macros/tmacro4.nim @@ -0,0 +1,19 @@ +discard """ + output: "after" +""" + +import + macros, strutils + +macro test_macro*(n: stmt): stmt {.immediate.} = + result = newNimNode(nnkStmtList) + var ass : PNimrodNode = newNimNode(nnkAsgn) + add(ass, newIdentNode("str")) + add(ass, newStrLitNode("after")) + add(result, ass) +when isMainModule: + var str: string = "before" + test_macro(str): + var i : integer = 123 + echo str + diff --git a/tests/macros/tmacro5.nim b/tests/macros/tmacro5.nim new file mode 100644 index 000000000..39324e497 --- /dev/null +++ b/tests/macros/tmacro5.nim @@ -0,0 +1,59 @@ +import macros,json + +var decls{.compileTime.}: seq[PNimrodNode] = @[] +var impls{.compileTime.}: seq[PNimrodNode] = @[] + +macro importImpl_forward(name, returns): stmt {.immediate.} = + result = newNimNode(nnkEmpty) + var func_name = newNimNode(nnkAccQuoted) + func_name.add newIdentNode("import") + func_name.add name + + var res = newNimNode(nnkProcDef) + res.add newNimNode(nnkPostfix) + res[0].add newIdentNode("*") + res[0].add func_name + res.add newNimNode(nnkEmpty) + res.add newNimNode(nnkEmpty) + res.add newNimNode(nnkFormalParams) + res[3].add returns + var p1 = newNimNode(nnkIdentDefs) + p1.add newIdentNode("dat") + p1.add newIdentNOde("PJsonNode") + p1.add newNimNode(nnkEmpty) + res[3].add p1 + var p2 = newNimNode(nnkIdentDefs) + p2.add newIdentNode("errors") + p2.add newNimNode(nnkVarTy) + p2.add newNimNode(nnkEmpty) + p2[1].add newNimNode(nnkBracketExpr) + p2[1][0].add newIdentNode("seq") + p2[1][0].add newIdentNode("string") + res[3].add p2 + + res.add newNimNode(nnkEmpty) + res.add newNimNode(nnkEmpty) + res.add newNimNode(nnkEmpty) + + decls.add res + echo(repr(res)) + +macro importImpl(name, returns: expr, body: stmt): stmt {.immediate.} = + #var res = getAST(importImpl_forward(name, returns)) + discard getAST(importImpl_forward(name, returns)) + var res = copyNimTree(decls[decls.high]) + res[6] = body + echo repr(res) + impls.add res + +macro okayy:stmt = + result = newNimNode(nnkStmtList) + for node in decls: result.add node + for node in impls: result.add node + +importimpl(Item, int): + echo 42 +importImpl(Foo, int16): + echo 77 + +okayy \ No newline at end of file diff --git a/tests/macros/tmacroaspragma.nim b/tests/macros/tmacroaspragma.nim new file mode 100644 index 000000000..0e5c352b3 --- /dev/null +++ b/tests/macros/tmacroaspragma.nim @@ -0,0 +1,8 @@ +import macros + +macro foo(x: stmt): stmt = + echo treerepr(callsite()) + result = newNimNode(nnkStmtList) + +proc zoo() {.foo.} = echo "hi" + diff --git a/tests/macros/tmacrogenerics.nim b/tests/macros/tmacrogenerics.nim new file mode 100644 index 000000000..5ae59e0da --- /dev/null +++ b/tests/macros/tmacrogenerics.nim @@ -0,0 +1,39 @@ +discard """ + file: "tmacrogenerics.nim" + msg: ''' +instantiation 1 with int and float +instantiation 2 with float and string +instantiation 3 with string and string +counter: 3 +''' + output: "int\nfloat\nint\nstring" +""" + +import typetraits, macros + +var counter {.compileTime.} = 0 + +macro makeBar(A, B: typedesc): typedesc = + inc counter + echo "instantiation ", counter, " with ", A.name, " and ", B.name + result = A + +type + Bar[T, U] = makeBar(T, U) + +var bb1: Bar[int, float] +var bb2: Bar[float, string] +var bb3: Bar[int, float] +var bb4: Bar[string, string] + +proc match(a: int) = echo "int" +proc match(a: string) = echo "string" +proc match(a: float) = echo "float" + +match(bb1) +match(bb2) +match(bb3) +match(bb4) + +static: + echo "counter: ", counter diff --git a/tests/macros/tmacros1.nim b/tests/macros/tmacros1.nim new file mode 100644 index 000000000..3c814ad6d --- /dev/null +++ b/tests/macros/tmacros1.nim @@ -0,0 +1,31 @@ +discard """ + output: "Got: 'nnkCall' hi" +""" + +import + macros, strutils + +macro outterMacro*(n: stmt): stmt {.immediate.} = + let n = callsite() + var j : string = "hi" + proc innerProc(i: int): string = + echo "Using arg ! " & n.repr + result = "Got: '" & $n.kind & "' " & $j + var callNode = n[0] + expectKind(n, TNimrodNodeKind.nnkCall) + if n.len != 3 or n[1].kind != TNimrodNodeKind.nnkIdent: + error("Macro " & callNode.repr & + " requires the ident passed as parameter (eg: " & callNode.repr & + "(the_name_you_want)): statements.") + result = newNimNode(TNimrodNodeKind.nnkStmtList) + var ass : PNimrodNode = newNimNode(nnkAsgn) + ass.add(newIdentNode(n[1].ident)) + ass.add(newStrLitNode(innerProc(4))) + result.add(ass) + +var str: string +outterMacro(str): + "hellow" +echo str + + diff --git a/tests/macros/tmacrostmt.nim b/tests/macros/tmacrostmt.nim new file mode 100644 index 000000000..d9c70197d --- /dev/null +++ b/tests/macros/tmacrostmt.nim @@ -0,0 +1,26 @@ +import macros +macro case_token(n: stmt): stmt {.immediate.} = + # creates a lexical analyzer from regular expressions + # ... (implementation is an exercise for the reader :-) + nil + +case_token: # this colon tells the parser it is a macro statement +of r"[A-Za-z_]+[A-Za-z_0-9]*": + return tkIdentifier +of r"0-9+": + return tkInteger +of r"[\+\-\*\?]+": + return tkOperator +else: + return tkUnknown + +case_token: inc i + +#bug #488 + +macro foo: stmt = + var exp = newCall("whatwhat", newIntLitNode(1)) + if compiles(getAst(exp)): return exp + else: echo "Does not compute!" + +foo() diff --git a/tests/macros/tmacrotypes.nim b/tests/macros/tmacrotypes.nim new file mode 100644 index 000000000..7697dba27 --- /dev/null +++ b/tests/macros/tmacrotypes.nim @@ -0,0 +1,12 @@ +import macros, typetraits + +macro checkType(ex, expected: expr): stmt {.immediate.} = + var t = ex.typ + assert t.name == expected.strVal + +proc voidProc = echo "hello" +proc intProc(a, b): int = 10 + +checkType(voidProc(), "void") +checkType(intProc(10, 20.0), "int") +checkType(noproc(10, 20.0), "Error Type") diff --git a/tests/macros/tnimrodnode_for_runtime.nim b/tests/macros/tnimrodnode_for_runtime.nim new file mode 100644 index 000000000..e73c8430f --- /dev/null +++ b/tests/macros/tnimrodnode_for_runtime.nim @@ -0,0 +1,13 @@ +discard """ + output: "bla" + disabled: true +""" + +import macros +proc makeMacro: PNimrodNode = + result = nil + +var p = makeMacro() + +echo "bla" + diff --git a/tests/macros/tprintf.nim b/tests/macros/tprintf.nim new file mode 100644 index 000000000..c8fb51cdc --- /dev/null +++ b/tests/macros/tprintf.nim @@ -0,0 +1,16 @@ +discard """ + file: "tprintf.nim" + output: "Andreas Rumpf" +""" +# Test a printf proc + +proc printf(file: TFile, args: openarray[string]) = + var i = 0 + while i < args.len: + write(file, args[i]) + inc(i) + +printf(stdout, ["Andreas ", "Rumpf\n"]) +#OUT Andreas Rumpf + + diff --git a/tests/macros/tquotewords.nim b/tests/macros/tquotewords.nim new file mode 100644 index 000000000..76b8d8af7 --- /dev/null +++ b/tests/macros/tquotewords.nim @@ -0,0 +1,26 @@ +discard """ + file: "tquotewords.nim" + output: "thisanexample" +""" +# Test an idea I recently had: + +import macros + +macro quoteWords(n: expr): expr {.immediate.} = + let n = callsite() + result = newNimNode(nnkBracket, n) + for i in 1..n.len-1: + expectKind(n[i], nnkIdent) + result.add(toStrLit(n[i])) + +const + myWordList = quoteWords(this, an, example) + +var s = "" +for w in items(myWordList): + s.add(w) + +echo s #OUT thisanexample + + + diff --git a/tests/macros/trecmacro.nim b/tests/macros/trecmacro.nim new file mode 100644 index 000000000..28b6db530 --- /dev/null +++ b/tests/macros/trecmacro.nim @@ -0,0 +1,14 @@ +discard """ + file: "trecmacro.nim" + line: 8 + errormsg: "recursive dependency: 'dump'" +""" + +macro dump(n: stmt): stmt = + dump(n) + if kind(n) == nnkNone: + nil + else: + hint($kind(n)) + for i in countUp(0, len(n)-1): + nil diff --git a/tests/macros/tstringinterp.nim b/tests/macros/tstringinterp.nim new file mode 100644 index 000000000..f030213e0 --- /dev/null +++ b/tests/macros/tstringinterp.nim @@ -0,0 +1,74 @@ +discard """ + file: "tstringinterp.nim" + output: "Hello Alice, 64 | Hello Bob, 10$" +""" + +import macros, parseutils, strutils + +proc concat(strings: varargs[string]): string = + result = newString(0) + for s in items(strings): result.add(s) + +template ProcessInterpolations(e: expr) = + var s = e[1].strVal + for f in interpolatedFragments(s): + case f.kind + of ikStr: addString(f.value) + of ikDollar: addDollar() + of ikVar, ikExpr: addExpr(newCall("$", parseExpr(f.value))) + +macro formatStyleInterpolation(e: expr): expr = + let e = callsite() + var + formatString = "" + arrayNode = newNimNode(nnkBracket) + idx = 1 + + proc addString(s: string) = + formatString.add(s) + + proc addExpr(e: PNimrodNode) = + arrayNode.add(e) + formatString.add("$" & $(idx)) + inc idx + + proc addDollar() = + formatString.add("$$") + + ProcessInterpolations(e) + + result = parseExpr("\"x\" % [y]") + result[1].strVal = formatString + result[2] = arrayNode + +macro concatStyleInterpolation(e: expr): expr = + let e = callsite() + var args: seq[PNimrodNode] + newSeq(args, 0) + + proc addString(s: string) = args.add(newStrLitNode(s)) + proc addExpr(e: PNimrodNode) = args.add(e) + proc addDollar() = args.add(newStrLitNode"$") + + ProcessInterpolations(e) + + result = newCall("concat", args) + +### + +proc sum(a, b, c: int): int = + return (a + b + c) + +var + alice = "Alice" + bob = "Bob" + a = 10 + b = 20 + c = 34 + +var + s1 = concatStyleInterpolation"Hello ${alice}, ${sum(a, b, c)}" + s2 = formatStyleInterpolation"Hello ${bob}, ${sum(alice.len, bob.len, 2)}$$" + +write(stdout, s1 & " | " & s2) + diff --git a/tests/macros/tvtable.nim b/tests/macros/tvtable.nim new file mode 100644 index 000000000..51894618c --- /dev/null +++ b/tests/macros/tvtable.nim @@ -0,0 +1,74 @@ +discard """ + output: ''' +OBJ 1 foo +10 +OBJ 1 bar +OBJ 2 foo +5 +OBJ 2 bar +''' +""" + +type + # these are the signatures of the virtual procs for each type + fooProc[T] = proc (o: var T): int + barProc[T] = proc (o: var T) + + # an untyped table to store the proc pointers + # it's also possible to use a strongly typed tuple here + VTable = array[0..1, pointer] + + TBase = object {.inheritable.} + vtbl: ptr VTable + + TUserObject1 = object of TBase + x: int + + TUserObject2 = object of TBase + y: int + +proc foo(o: var TUserObject1): int = + echo "OBJ 1 foo" + return 10 + +proc bar(o: var TUserObject1) = + echo "OBJ 1 bar" + +proc foo(o: var TUserObject2): int = + echo "OBJ 2 foo" + return 5 + +proc bar(o: var TUserObject2) = + echo "OBJ 2 bar" + +proc getVTable(T: typedesc): ptr VTable = + # pay attention to what's going on here + # this will initialize the vtable for each type at program start-up + # + # fooProc[T](foo) is a type coercion - it looks for a proc named foo + # matching the signature fooProc[T] (e.g. proc (o: var TUserObject1): int) + var vtbl {.global.} = [ + cast[pointer](fooProc[T](foo)), + cast[pointer](barProc[T](bar)) + ] + + return vtbl.addr + +proc create(T: typedesc): T = + result.vtbl = getVTable(T) + +proc baseFoo(o: var TBase): int = + return cast[fooProc[TBase]](o.vtbl[0]) (o) + +proc baseBar(o: var TBase) = + cast[barProc[TBase]](o.vtbl[1]) (o) + +var a = TUserObject1.create +var b = TUserObject2.create + +echo a.baseFoo +a.baseBar + +echo b.baseFoo +b.baseBar + diff --git a/tests/testament/backend.nim b/tests/testament/backend.nim index 87ac10b1f..bc1f92eba 100644 --- a/tests/testament/backend.nim +++ b/tests/testament/backend.nim @@ -49,10 +49,10 @@ proc createDb() = # """, []) type - MachineId* = distinct int64 + MachineId = distinct int64 CommitId = distinct int64 -proc `$`*(id: MachineId): string {.borrow.} +proc `$`(id: MachineId): string {.borrow.} proc `$`(id: CommitId): string {.borrow.} var @@ -61,7 +61,7 @@ var proc `()`(cmd: string{lit}): string = cmd.execProcess.string.strip -proc getMachine*: MachineId = +proc getMachine: MachineId = var name = "hostname"() if name.len == 0: name = when defined(posix): getenv"HOSTNAME".string diff --git a/tests/testament/htmlgen.nim b/tests/testament/htmlgen.nim index e42b88070..bc2d8bd37 100644 --- a/tests/testament/htmlgen.nim +++ b/tests/testament/htmlgen.nim @@ -109,42 +109,46 @@ div.tabContent.hide { display: none; } proc td(s: string): string = result = "" & s.substr(0, 200).XMLEncode & "" -proc generateHtml*(filename: string) = +proc getCommit(db: TDbConn, c: int): string = + var commit = c + for thisCommit in db.rows(sql"select id from [Commit] order by id desc"): + if commit == 0: result = thisCommit[0] + inc commit + if result.isNil: + quit "cannot determine commit " & $c + +proc generateHtml*(filename: string, commit: int) = const selRow = """select name, category, target, action, expected, given, result - from TestResult - where [commit] = ? and machine = ? - order by category""" + from TestResult + where [commit] = ? and machine = ? + order by category""" var db = open(connection="testament.db", user="testament", password="", database="testament") + # search for proper commit: + let lastCommit = db.getCommit(commit) + var outfile = open(filename, fmWrite) outfile.write(HtmlBegin) - let thisMachine = backend.getMachine() - outfile.write() - let machine = db.getRow(sql"select name, os, cpu from machine where id = ?", - thisMachine) - outfile.write("

$#

" % machine.join(" ")) + let commit = db.getValue(sql"select hash from [Commit] where id = ?", + lastCommit) + let branch = db.getValue(sql"select branch from [Commit] where id = ?", + lastCommit) + outfile.write("

$# $#

" % [branch, commit]) + # generate navigation: outfile.write("""") - for thisCommit in db.rows(sql"select id from [Commit] order by id desc"): - let lastCommit = thisCommit[0] - outfile.write("""
""" % lastCommit) + for currentMachine in db.rows(sql"select id from Machine order by id"): + let m = currentMachine[0] + outfile.write("""
""" % m) outfile.write(TableHeader) - for row in db.rows(sql(selRow), lastCommit, thisMachine): + for row in db.rows(sql(selRow), lastCommit, m): outfile.write("") for x in row: outfile.write(x.td) diff --git a/tests/testament/tester.nim b/tests/testament/tester.nim index 8abea8224..54a6de2d0 100644 --- a/tests/testament/tester.nim +++ b/tests/testament/tester.nim @@ -22,7 +22,9 @@ const Command: all run all tests c|category run all the tests of a certain category - html generate $1 from the database + html [commit] generate $1 from the database; uses the latest + commit or a specific one (use -1 for the commit + before latest etc) Arguments: arguments are passed to the compiler Options: @@ -254,7 +256,9 @@ proc main() = p.next processCategory(r, cat, p.cmdLineRest.string) of "html": - generateHtml(resultsFile) + var commit = 0 + discard parseInt(p.cmdLineRest.string, commit) + generateHtml(resultsFile, commit) else: quit usage -- cgit 1.4.1-2-gfad0