-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexpr.nim
122 lines (112 loc) · 2.91 KB
/
expr.nim
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
import macros
var ignore: seq[NimNode]
proc addIfNewSym(s: var seq[NimNode], x: NimNode): int =
let sx = $x
for i in 0..<ignore.len:
if ignore[i].eqIdent sx: return -1
for i in 0..<s.len:
if s[i].eqIdent sx: return i
result = s.len
s.add x
proc cpNimNode(x: NimNode): NimNode =
result = newNimNode(x.kind)
case x.kind
of nnkCharLit..nnkUInt64Lit:
result.intVal = x.intVal
of nnkFloatLit..nnkFloat64Lit:
result.floatVal = x.floatVal
of nnkStrLit..nnkTripleStrLit:
result.strVal = x.strVal
of nnkIdent:
#result.ident = ident(x.repr)
result = newIdentNode($x)
of {nnkSym,nnkOpenSymChoice}:
#echo "got sym"
#quit -1
#result = newIdentNode($x)
result = x.copy
else:
discard
proc getVars*(v: var seq[NimNode], x,a: NimNode): NimNode =
proc recurse(it: NimNode, vars: var seq[NimNode], a: NimNode): NimNode =
var r0 = 0
var r1 = it.len - 1
case it.kind
of {nnkSym, nnkIdent}:
let i = vars.addIfNewSym(it)
if i>=0:
let ii = newLit(i)
return newCall(a,ii)
of nnkCallKinds: r0 = 1
of nnkDotExpr: r1 = 0
of {nnkVarSection,nnkLetSection}:
result = it.cpNimNode
for c in it:
result.add c.cpNimNode
for i in 0..(c.len-3):
ignore.add c[i]
result[^1].add c[i].cpNimNode
result[^1].add c[^2].cpNimNode
result[^1].add recurse(c[^1], vars, a)
return
else: discard
#echo it.treerepr
result = it.cpNimNode
for i in 0..<r0:
result.add it[i].cpNimNode
for i in r0..r1:
result.add recurse(it[i], vars, a)
for i in (r1+1)..<it.len:
result.add it[i].cpNimNode
ignore.newSeq(0)
result = recurse(x, v, a)
macro packVarsStmt*(x: untyped, f: untyped): auto =
#echo x.treerepr
var v = newSeq[NimNode](0)
let a = ident("foo")
let e = getVars(v, x, a)
var p = newStmtList()
for vs in v:
p.add newCall(f,vs)
result = p
#echo result.treerepr
macro packVars*(x: untyped, f: untyped): auto =
#echo x.treerepr
var v = newSeq[NimNode](0)
let a = ident("foo")
let e = getVars(v, x, a)
var p = newPar()
if v.len==0:
p.add newNimNode(nnkExprColonExpr).add(ident("Field0"),newLit(1))
elif v.len==1:
let vi = ident($v[0])
p.add newNimNode(nnkExprColonExpr).add(ident("Field0"),newCall(f,vi))
else:
for vs in v:
p.add newCall(f,vs)
result = p
#echo result.treerepr
macro substVars*(x: untyped, a: untyped): auto =
#echo x.treerepr
var v = newSeq[NimNode](0)
let e = getVars(v, x, a)
result = e
#echo result.treerepr
when isMainModule:
template test(x) =
template getref(t: untyped): untyped = addr(t)
let v = packVars(x,getref)
proc foo(xx: type(v)) =
template deref(i: int): untyped = xx[i][]
substVars(x, deref)
foo(v)
macro dump(x: typed): auto =
echo x.repr
x
var x,y,z: float
dump:
test:
x = 1
y = 2
z = x + y
echo x, y, z