1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
import macros
macro case_token(n: varargs[untyped]): untyped =
# 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() =
var exp = newCall("whatwhat", newIntLitNode(1))
if compiles(getAst(exp)):
return exp
else: echo "Does not compute! (test OK)"
foo()
#------------------------------------
# bug #8287
type MyString = distinct string
proc `$` (c: MyString): string {.borrow.}
proc `!!` (c: cstring): int =
c.len
proc f(name: MyString): int =
!! $ name
macro repr_and_parse(fn: typed) =
let fn_impl = fn.getImpl
fn_impl.name = genSym(nskProc, $fn_impl.name)
echo fn_impl.repr
result = parseStmt(fn_impl.repr)
macro repr_to_string(fn: typed): string =
let fn_impl = fn.getImpl
result = newStrLitNode(fn_impl.repr)
repr_and_parse(f)
#------------------------------------
# bugs #8343 and #8344
proc one_if_proc(x, y : int): int =
if x < y: result = x
else: result = y
proc test_block(x, y : int): int =
block label:
result = x
result = y
#------------------------------------
# bugs #8348
template `>`(x, y: untyped): untyped =
## "is greater" operator. This is the same as ``y < x``.
y < x
proc test_cond_stmtlist(x, y: int): int =
result = x
if x > y:
result = x
#------------------------------------
# bug #8762
proc t2(a, b: int): int =
`+`(a, b)
#------------------------------------
# bug #8761
proc fn1(x, y: int):int =
2 * (x + y)
proc fn2(x, y: float): float =
(y + 2 * x) / (x - y)
proc fn3(x, y: int): bool =
(((x and 3) div 4) or (x mod (y xor -1))) == 0 or y notin [1,2]
proc fn4(x: int): int =
if x mod 2 == 0: return x + 2
else: return 0
proc fn5(a, b: float): float =
result = - a * a / (b * b)
proc `{}`(x: seq[float], i: int, j: int): float =
x[i + 0 * j]
proc `{}=`(x: var seq[float], i: int, val: float) =
x[i] = val
proc fn6() =
var a = @[1.0, 2.0]
let z = a{0, 1}
a{2} = 5.0
#------------------------------------
# bug #10807
proc fn_unsafeaddr(x: int): int =
cast[int](unsafeAddr(x))
static:
let fn1s = "proc fn1(x, y: int): int =\n result = 2 * (x + y)\n"
let fn2s = "proc fn2(x, y: float): float =\n result = (y + 2 * x) / (x - y)\n"
let fn3s = "proc fn3(x, y: int): bool =\n result = ((x and 3) div 4 or x mod (y xor -1)) == 0 or not contains([1, 2], y)\n"
let fn4s = "proc fn4(x: int): int =\n if x mod 2 == 0:\n return x + 2\n else:\n return 0\n"
let fn5s = "proc fn5(a, b: float): float =\n result = -a * a / (b * b)\n"
let fn6s = "proc fn6() =\n var a = @[1.0, 2.0]\n let z = a{0, 1}\n a{2} = 5.0\n"
let fnAddr = "proc fn_unsafeaddr(x: int): int =\n result = cast[int](addr(x))\n"
doAssert fn1.repr_to_string == fn1s
doAssert fn2.repr_to_string == fn2s
doAssert fn3.repr_to_string == fn3s
doAssert fn4.repr_to_string == fn4s
doAssert fn5.repr_to_string == fn5s
doAssert fn6.repr_to_string == fn6s
doAssert fn_unsafeaddr.repr_to_string == fnAddr
#------------------------------------
# bug #8763
type
A {.pure.} = enum
X, Y
B {.pure.} = enum
X, Y
proc test_pure_enums(a: B) =
case a
of B.X: echo B.X
of B.Y: echo B.Y
repr_and_parse(one_if_proc)
repr_and_parse(test_block)
repr_and_parse(test_cond_stmtlist)
repr_and_parse(t2)
repr_and_parse(test_pure_enums)
|