Skip to content

Commit c16c667

Browse files
committed
supports object types partially
1 parent ac90f02 commit c16c667

File tree

5 files changed

+91
-16
lines changed

5 files changed

+91
-16
lines changed

compiler/icnif/nifdecoder.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ proc fromNifSymDef(c: var DecodeContext; n: var Cursor; kind: TNodeKind): PNode
7575
of nkLetSection: skLet
7676
of nkImportStmt: skModule
7777
of nkEnumTy: skEnumField
78+
of nkRecList: skField
7879
else: skConst
7980
incExpect n, SymbolDef
8081
let nifSymId = n.symId

compiler/icnif/nifdecodertypes.nim

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ proc getSysTypeSym(c: var DecodeContext; typeKind: TTypeKind): PSym =
1212
var typ = newType(typeKind, c.idgen, nil)
1313
typ.sym = result
1414
result.typ = typ
15+
if typeKind == tyString:
16+
var charSym = getSysTypeSym(c, tyChar)
17+
result.typ.add charSym.typ
1518
c.sysTypes[typeKind] = result
1619

1720
proc getSysType(c: var DecodeContext; typeKind: TTypeKind): PType =
@@ -72,15 +75,25 @@ proc fromNifTypeImpl(c: var DecodeContext; n: var Cursor; kind: TTypeKind; res:
7275
sym.sym.typ = res
7376
res.n.add sym
7477
inc n
78+
res.addAllowNil nil
7579
of tyFromExpr:
7680
res.n = fromNif(c, n)
7781
of tyStatic:
7882
res.addAllowNil fromNifType(c, n)
7983
res.n = fromNif(c, n)
8084
of tyObject:
81-
# inheritance:
82-
res.addAllowNil fromNifType(c, n)
83-
res.n = fromNif(c, n)
85+
# TODO: inheritance:
86+
if n.kind == DotToken:
87+
res.addAllowNil nil
88+
inc n
89+
else:
90+
res.addAllowNil fromNifType(c, n)
91+
res.n = newNode(nkRecList)
92+
while n.kind != ParRi:
93+
var sym = fromNifSymDef(c, n, nkRecList)
94+
res.n.add sym
95+
sym.sym.typ = fromNifType(c, n)
96+
inc n
8497
else:
8598
while n.kind != ParRi:
8699
res.addAllowNil fromNifType(c, n)

compiler/icnif/nifencodertypes.nim

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,19 @@ proc toNif(c: var EncodeContext; t: PType; isTypeSection = false) =
225225
of tyPointer: atom c, t
226226
of tyString: atom c, t
227227
of tyCstring: atom c, t
228-
of tyObject: symToNif c, t.sym
228+
of tyObject:
229+
if isTypeSection:
230+
c.typeHead t:
231+
# TODO: inheritance:
232+
c.b.addEmpty
233+
for son in t.n:
234+
symdefToNif c, son
235+
if son.typ == nil:
236+
c.b.addEmpty
237+
else:
238+
toNif c, son.typ
239+
else:
240+
symToNif c, t.sym
229241
of tyForward: atom c, t
230242
of tyError: atom c, t
231243
of tyBuiltInTypeClass:

tests/icnif/tencode_node2node.nim

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,26 +58,61 @@ proc sem(graph: ModuleGraph; path: AbsoluteFile): PNode =
5858

5959
const SysTypeKinds = {tyBool, tyChar, tyString, tyInt .. tyUInt64}
6060

61+
type
62+
# Nim's AST has cycles that causes infinite recursive loop in eql procs.
63+
# this is used to prevent that happen.
64+
EqlContext = object
65+
nodeStack: seq[PNode]
66+
#symStack: seq[PSym]
67+
typStack: seq[PType]
68+
6169
# Compare PType, PSym and PNode but ignores fields nifencoder and nifdecoder doesn't support
6270
# Assumes `x` is generated by sem.nim and `y` is decoded by icnif/nifdecoder.
6371
# So `eql(x, y) == eql(y, x)` is not always true.
64-
proc eql(x, y: PType): bool =
72+
proc eql(x, y: PNode; c: var EqlContext): bool
73+
74+
proc eql(x, y: PType; c: var EqlContext): bool =
6575
if x == nil and y == nil:
6676
result = true
6777
elif x == nil or y == nil:
78+
echo "type is missing"
6879
result = false
69-
elif x.kind == y.kind:
70-
result = true
71-
else:
80+
elif x.kind != y.kind:
7281
echo "type kind mismatch: ", x.kind, "/", y.kind
7382
result = false
83+
elif x.flags != y.flags:
84+
echo "flag mismatch: ", x.flags, "/", y.flags
85+
result = false
86+
else:
87+
if c.typStack.len != 0:
88+
for i in countDown(c.typStack.len - 1, 0):
89+
if x == c.typStack[i]:
90+
# echo "cycle is detected in PType"
91+
return true
92+
c.typStack.add x
93+
if not eql(x.n, y.n, c):
94+
echo "type.n mismatch"
95+
result = false
96+
elif x.kidsLen != y.kidsLen:
97+
echo "type kidsLen mismatch"
98+
result = false
99+
else:
100+
result = true
101+
for i in 0 ..< x.kidsLen:
102+
if not eql(x[i], y[i], c):
103+
echo "type kids mismatch: "
104+
debug(x[i])
105+
debug(y[i])
106+
result = false
107+
break
108+
discard c.typStack.pop
74109

75-
proc eql(x, y: PSym): bool =
110+
proc eql(x, y: PSym; c: var EqlContext): bool =
76111
if x == nil and y == nil:
77112
result = true
78113
elif x == nil or y == nil:
79114
result = false
80-
elif x.kind == y.kind and eql(x.typ, y.typ) and x.name.s == y.name.s:
115+
elif x.kind == y.kind and eql(x.typ, y.typ, c) and x.name.s == y.name.s:
81116
if (x.itemId.item == y.itemId.item and x.disamb == y.disamb and x.flags == y.flags) or (x.kind == skType and x.typ.kind in SysTypeKinds):
82117
if x.owner == nil and y.owner == nil:
83118
result = true
@@ -100,15 +135,21 @@ proc eql(x, y: PSym): bool =
100135
else:
101136
result = false
102137

103-
proc eql(x, y: PNode): bool =
138+
proc eql(x, y: PNode; c: var EqlContext): bool =
104139
if x == nil and y == nil:
105140
result = true
106141
elif x == nil or y == nil:
107142
result = false
108143
elif x.kind == y.kind and x.safeLen == y.safeLen and x.flags == y.flags:
144+
if c.nodeStack.len != 0:
145+
for i in countDown(c.nodeStack.len - 1, 0):
146+
if x == c.nodeStack[i]:
147+
# echo "cycle is detected in PNode"
148+
return true
149+
c.nodeStack.add x
109150
case x.kind:
110151
of nkSym:
111-
result = eql(x.sym, y.sym)
152+
result = eql(x.sym, y.sym, c)
112153
if not result:
113154
echo "Symbol mismatch:"
114155
debug(x.sym)
@@ -119,22 +160,23 @@ proc eql(x, y: PNode): bool =
119160
result = sameValue(x, y)
120161
of nkIdentDefs:
121162
assert x.len == 3 and y.len == 3
122-
if eql(x[0], y[0]) and eql(x[2], y[2]):
163+
if eql(x[0], y[0], c) and eql(x[2], y[2], c):
123164
result = y[1].kind == nkEmpty and y[0].sym.typ != nil
124165
else:
125166
result = false
126167
of nkTypeDef:
127168
assert x.len == 3 and y.len == 3
128-
if eql(x[0], y[0]) and eql(x[1], y[1]):
169+
if eql(x[0], y[0], c) and eql(x[1], y[1], c):
129170
result = y[2].kind == nkEmpty and y[0].sym.typ != nil
130171
else:
131172
result = false
132173
else:
133174
result = true
134175
for i in 0 ..< x.safeLen:
135-
if not eql(x[i], y[i]):
176+
if not eql(x[i], y[i], c):
136177
result = false
137178
break
179+
discard c.nodeStack.pop
138180
else:
139181
result = false
140182

@@ -143,13 +185,15 @@ proc testNifEncDec(graph: ModuleGraph; src: string) =
143185
let n = sem(graph, fullPath)
144186
let nif = saveNifToBuffer(n, graph.config)
145187
#debug(n)
188+
#debug(n[0][0][0].typ)
146189
#echo nif
147190

148191
# Don't reuse the ModuleGraph used for semcheck when load NIF.
149192
var graphForLoad = newModuleGraph(newIdentCache(), newConfigRefForTest())
150193
let n2 = loadNifFromBuffer(nif, fullPath, graphForLoad)
151194
#debug(n2)
152-
assert eql(n, n2)
195+
var c = EqlContext()
196+
assert eql(n, n2, c)
153197

154198
var conf = newConfigRefForTest()
155199
var cache = newIdentCache()

tests/icnif/testcode/modtesttypesections.nim

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ type
55
Y
66
TestDistinct = distinct int
77

8+
TestObject = object
9+
x*: int
10+
y: int
11+
812
var x: TestInt
913
var testEnum: TestEnum
1014
var testEnum1 = X
1115
var testDistinct: TestDistinct
16+
var testObject: TestObject

0 commit comments

Comments
 (0)