diff options
Diffstat (limited to 'tests/showoff')
-rw-r--r-- | tests/showoff/tdrdobbs_examples.nim | 134 | ||||
-rw-r--r-- | tests/showoff/tformatopt.nim | 57 | ||||
-rw-r--r-- | tests/showoff/tgenericmacrotypes.nim | 55 | ||||
-rw-r--r-- | tests/showoff/thello2.nim | 11 | ||||
-rw-r--r-- | tests/showoff/thtml1.nim | 11 | ||||
-rw-r--r-- | tests/showoff/thtml2.nim | 37 | ||||
-rw-r--r-- | tests/showoff/tonce.nim | 22 | ||||
-rw-r--r-- | tests/showoff/tquasiquote.nim | 14 |
8 files changed, 341 insertions, 0 deletions
diff --git a/tests/showoff/tdrdobbs_examples.nim b/tests/showoff/tdrdobbs_examples.nim new file mode 100644 index 000000000..c61e177dc --- /dev/null +++ b/tests/showoff/tdrdobbs_examples.nim @@ -0,0 +1,134 @@ +discard """ + output: '''108 +11 -1 1936 +0.4 +true +truefalse''' +""" + +proc `++`(x: var int; y: int = 1; z: int = 0) = + x = x + y + z + +var g = 70 +++g +g ++ 7 +g.`++`(10, 20) +echo g + + +#let lv = stdin.readline +#var vv = stdin.readline +#vv = "abc" # valid, reassignment allowed +#lv = "abc" # fails at compile time + +#proc square(x: int): int = x*x + +template square(x: int): int = + # ensure 'x' is only evaluated once: + let y = x + y * y + +proc mostSignificantBit(n: int): int = + # naive algorithm: + var n = n + while n != 0: + n = n shr 1 + result += 1 + result -= 1 + +const msb3999 = mostSignificantBit(3999) + +echo msb3999, " ", mostSignificantBit(0), " ", square(44) + +proc filter[T](a: openArray[T], predicate: proc (x: T): bool): seq[T] = + result = @[] # @[] constructs the empty seq + for x in a: + if predicate(x): result.add(x) + +proc map[T, S](a: openArray[T], fn: proc (x: T): S): seq[S] = + newSeq(result, a.len) + for i in 0 ..< a.len: result[i] = fn(a[i]) + + +type + FormulaKind = enum + fkVar, ## element is a variable like 'X' + fkLit, ## element is a literal like 0.1 + fkAdd, ## element is an addition operation + fkMul, ## element is a multiplication operation + fkExp ## element is an exponentiation operation + +type + Formula = ref object + case kind: FormulaKind + of fkVar: name: string + of fkLit: value: float + of fkAdd, fkMul, fkExp: left, right: Formula + +from math import pow + +proc evaluate(n: Formula, varToVal: proc (name: string): float): float = + case n.kind + of fkVar: varToVal(n.name) + of fkLit: n.value + of fkAdd: evaluate(n.left, varToVal) + evaluate(n.right, varToVal) + of fkMul: evaluate(n.left, varToVal) * evaluate(n.right, varToVal) + of fkExp: pow(evaluate(n.left, varToVal), evaluate(n.right, varToVal)) + +echo evaluate(Formula(kind: fkLit, value: 0.4), nil) + +proc isPolyTerm(n: Formula): bool = + n.kind == fkMul and n.left.kind == fkLit and (let e = n.right; + e.kind == fkExp and e.left.kind == fkVar and e.right.kind == fkLit) + +proc isPolynomial(n: Formula): bool = + isPolyTerm(n) or + (n.kind == fkAdd and isPolynomial(n.left) and isPolynomial(n.right)) + +let myFormula = Formula(kind: fkMul, + left: Formula(kind: fkLit, value: 2.0), + right: Formula(kind: fkExp, + left: Formula(kind: fkVar, name: "x"), + right: Formula(kind: fkLit, value: 5.0))) + +echo isPolyTerm(myFormula) + +proc pat2kind(pattern: string): FormulaKind = + case pattern + of "^": fkExp + of "*": fkMul + of "+": fkAdd + of "x": fkVar + of "c": fkLit + else: fkVar # no error reporting for reasons of simplicity + +import macros + +proc matchAgainst(n, pattern: NimNode): NimNode {.compileTime.} = + template `@`(current, field: untyped): untyped = + newDotExpr(current, newIdentNode(astToStr(field))) + + template `==@`(n, pattern: untyped): untyped = + newCall("==", n@kind, newIdentNode($pat2kind($pattern.ident))) + + case pattern.kind + of CallNodes: + result = newCall("and", + n ==@ pattern[0], + matchAgainst(n@left, pattern[1])) + if pattern.len == 3: + result = newCall("and", result.copy, + matchAgainst(n@right, pattern[2])) + of nnkIdent: + result = n ==@ pattern + of nnkPar: + result = matchAgainst(n, pattern[0]) + else: + error "invalid pattern" + +macro `=~` (n: Formula, pattern: untyped): bool = + result = matchAgainst(n, pattern) + +proc isPolyTerm2(n: Formula): bool = n =~ c * x^c + +echo isPolyTerm2(myFormula), isPolyTerm2(Formula(kind: fkLit, value: 0.7)) diff --git a/tests/showoff/tformatopt.nim b/tests/showoff/tformatopt.nim new file mode 100644 index 000000000..420dd026b --- /dev/null +++ b/tests/showoff/tformatopt.nim @@ -0,0 +1,57 @@ +discard """ + output: '''(a: 3 +b: 4 +s: abc +)''' +""" + +import macros + +proc invalidFormatString() = + echo "invalidFormatString" + +template formatImpl(handleChar: untyped) = + var i = 0 + while i < f.len: + if f[i] == '$': + case f[i+1] + of '1'..'9': + var j = 0 + i += 1 + while f[i] in {'0'..'9'}: + j = j * 10 + ord(f[i]) - ord('0') + i += 1 + result.add(a[j-1]) + else: + invalidFormatString() + else: + result.add(handleChar(f[i])) + i += 1 + +proc `%`*(f: string, a: openArray[string]): string = + template identity(x: untyped): untyped = x + result = "" + formatImpl(identity) + +macro optFormat{`%`(f, a)}(f: string{lit}, a: openArray[string]): untyped = + result = newNimNode(nnkBracket) + let f = f.strVal + formatImpl(newLit) + result = nestList(newIdentNode("&"), result) + +template optAdd1{x = y; add(x, z)}(x, y, z: string) = + x = y & z + +proc `/&` [T: object](x: T): string = + result = "(" + for name, value in fieldPairs(x): + result.add("$1: $2\n" % [name, $value]) + result.add(")") + +type + MyObject = object + a, b: int + s: string + +let obj = MyObject(a: 3, b: 4, s: "abc") +echo(/&obj) diff --git a/tests/showoff/tgenericmacrotypes.nim b/tests/showoff/tgenericmacrotypes.nim new file mode 100644 index 000000000..cc07f4355 --- /dev/null +++ b/tests/showoff/tgenericmacrotypes.nim @@ -0,0 +1,55 @@ +# issue #7974 + +import macros + +macro genTypeA(arg: typed): untyped = + if arg.typeKind != ntyTypeDesc: + error("expected typedesc", arg) + + result = arg.getTypeInst[1] + +macro genTypeB(arg: typed): untyped = + if arg.typeKind != ntyTypeDesc: + error("expected typedesc", arg) + + + let typeSym = arg.getTypeInst[1] + result = + nnkTupleTy.newTree( + nnkIdentDefs.newTree( + ident"a", typeSym, newEmptyNode() + ) + ) + +type + # this is the trivial case, MyTypeA[T] is basically just T, nothing else. But it works. + MyTypeA[T] = genTypeA(T) + # in this case I generate `tuple[a: T]`. This this is something the compiler does not want + MyTypeB[T] = genTypeB(T) + +# these are just alias types for int32 and float32, nothing really happens, but it works +var a1: MyTypeA[int32] +doAssert a1 is MyTypeA[int32] +doAssert a1 is int32 +a1 = 0'i32 +var a2: MyTypeA[float32] +doAssert a2 is MyTypeA[float32] +doAssert a2 is float32 +a2 = 0'f32 +var a3: MyTypeA[float32] +doAssert a3 is MyTypeA[float32] +doAssert a3 is float32 +a3 = 0'f32 + +var b1: MyTypeB[int32] # cannot generate VM code fur tuple[a: int32] +doAssert b1 is MyTypeB[int32] +doAssert b1 is tuple[a: int32] +b1 = (a: 0'i32) +var b2: MyTypeB[float32] +doAssert b2 is MyTypeB[float32] +doAssert b2 is tuple[a: float32] +b2 = (a: 0'f32) +var b3: MyTypeB[float32] +doAssert b3 is MyTypeB[float32] +doAssert b3 is tuple[a: float32] +b3 = (a: 0'f32) diff --git a/tests/showoff/thello2.nim b/tests/showoff/thello2.nim new file mode 100644 index 000000000..3ccb4e3be --- /dev/null +++ b/tests/showoff/thello2.nim @@ -0,0 +1,11 @@ +discard """ + output: '''(a: 3, b: 4, s: "abc")''' +""" + +type + MyObject = object + a, b: int + s: string + +let obj = MyObject(a: 3, b: 4, s: "abc") +echo obj diff --git a/tests/showoff/thtml1.nim b/tests/showoff/thtml1.nim new file mode 100644 index 000000000..fe0cd3b1e --- /dev/null +++ b/tests/showoff/thtml1.nim @@ -0,0 +1,11 @@ +discard """ + output: "<br>" +""" + +template htmlTag(tag: untyped) = + proc tag(): string = "<" & astToStr(tag) & ">" + +htmlTag(br) +htmlTag(html) + +echo br() diff --git a/tests/showoff/thtml2.nim b/tests/showoff/thtml2.nim new file mode 100644 index 000000000..dcf6534a5 --- /dev/null +++ b/tests/showoff/thtml2.nim @@ -0,0 +1,37 @@ +discard """ + output: "<html><head><title>now look at this</title></head><body><ul><li>Nim is quite capable</li></ul></body></html>" +""" + +import strutils + +template html(name, matter: untyped) = + proc name(): string = + result = "<html>" + matter + result.add("</html>") + +template nestedTag(tag: untyped) = + template tag(matter: untyped) = + result.add("<" & astToStr(tag) & ">") + matter + result.add("</" & astToStr(tag) & ">") + +template simpleTag(tag: untyped) = + template tag(matter: untyped) = + result.add("<$1>$2</$1>" % [astToStr(tag), matter]) + +nestedTag body +nestedTag head +nestedTag ul +simpleTag title +simpleTag li + + +html mainPage: + head: + title "now look at this" + body: + ul: + li "Nim is quite capable" + +echo mainPage() diff --git a/tests/showoff/tonce.nim b/tests/showoff/tonce.nim new file mode 100644 index 000000000..ed2684dcf --- /dev/null +++ b/tests/showoff/tonce.nim @@ -0,0 +1,22 @@ +discard """ + output: '''first call of p +some call of p +new instantiation +some call of p''' +""" + +template once(body) = + var x {.global.} = false + if not x: + x = true + body + +proc p() = + once: + echo "first call of p" + echo "some call of p" + +p() +once: + echo "new instantiation" +p() diff --git a/tests/showoff/tquasiquote.nim b/tests/showoff/tquasiquote.nim new file mode 100644 index 000000000..404712a02 --- /dev/null +++ b/tests/showoff/tquasiquote.nim @@ -0,0 +1,14 @@ +discard """ + outputsub: '''tquasiquote.nim(14, 8): Check failed: 1 > 2''' +""" + +import macros + +macro check(ex: untyped): untyped = + var info = ex.lineInfo + var expString = ex.toStrLit + result = quote do: + if not `ex`: + echo `info`, ": Check failed: ", `expString` + +check 1 > 2 |