Skip to content

Commit 0b0c7b4

Browse files
committed
encodes Nim PSym to NIF Symbol and SymbolDef
1 parent fc87850 commit 0b0c7b4

File tree

4 files changed

+163
-44
lines changed

4 files changed

+163
-44
lines changed

compiler/icnif/nifdecoder.nim

Lines changed: 73 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import std / [assertions, tables]
2-
import "../../dist/nimony/src/lib" / [bitabs, nifreader, nifstreams, nifcursors]
3-
import ".." / [ast, astalgo, idents, lineinfos, options, modulegraphs, pathutils]
1+
import std / [assertions, tables, parseutils]
2+
import "../../dist/nimony/src/lib" / [bitabs, nifreader, nifstreams, nifcursors, symparser]
3+
import ".." / [ast, astalgo, idents, lineinfos, options, modulegraphs, msgs, pathutils]
44
import enum2nif
55

66
type
77
DecodeContext = object
88
graph: ModuleGraph
9+
nifSymToPSym: Table[string, PSym] # foo.1.modsuffix -> PSym
910

1011
proc nodeKind(n: Cursor): TNodeKind {.inline.} =
1112
assert n.kind == ParLe
@@ -21,36 +22,87 @@ proc getSysType(typeKind: TTypeKind): PType =
2122
else:
2223
result = PType(itemId: ItemId(module: 0, item: typeKind.int32), kind: typeKind)
2324

25+
type
26+
SplittedNifSym = object
27+
name: string
28+
id: int
29+
module: string
30+
31+
proc splitNifSym(s: string): SplittedNifSym =
32+
result = SplittedNifSym()
33+
var i = s.len - 2
34+
var mp = -1
35+
while i > 0:
36+
if s[i] == '.':
37+
if s[i+1] in {'0'..'9'}:
38+
var id = 0
39+
discard parseutils.parseInt(s, id, i + 1)
40+
return SplittedNifSym(
41+
name: s.substr(0, i - 1),
42+
id: id,
43+
module: if mp < 0: "" else: s.substr(mp, s.high))
44+
else:
45+
mp = i + 1
46+
dec i
47+
2448
proc fromNif(c: var DecodeContext; n: var Cursor): PNode
2549

26-
proc fromNifLocal(c: var DecodeContext; n: var Cursor; kind: TNodeKind): PNode =
27-
result = newNodeI(kind, unknownLineInfo, 1)
28-
inc n
29-
assert n.nodeKind == nkIdentDefs
30-
result[0] = newNodeI(nkIdentDefs, unknownLineInfo, 3)
31-
inc n
50+
proc fromNifSymDef(c: var DecodeContext; n: var Cursor; kind: TNodeKind): PNode =
3251
assert n.nodeKind == nkSym
3352
let symKind = case kind:
3453
of nkVarSection: skVar
3554
of nkLetSection: skLet
55+
of nkImportStmt: skModule
3656
else: skConst
3757
inc n
38-
assert n.kind == Ident
39-
let ident = c.graph.cache.getIdent(pool.strings[n.litId])
58+
assert n.kind == SymbolDef
59+
let nifSym = pool.syms[n.symId]
60+
let symdef = nifSym.splitNifSym
61+
assert symdef.name.len != 0
62+
let ident = c.graph.cache.getIdent(symdef.name)
63+
inc n
64+
assert n.kind in {Ident, DotToken}, $n.kind
65+
let flags = if n.kind == Ident: pool.strings[n.litId].parseSymFlags else: {}
4066
inc n
41-
assert n.kind == IntLit
42-
let id = pool.integers[n.intId]
43-
result[0][0] = PSym(itemId: ItemId(module: 0, item: id.int32), kind: symKind, name: ident).newSymNode()
67+
var position = 0
68+
if symKind == skModule:
69+
assert n.kind == StringLit
70+
let path = pool.strings[n.litId].AbsoluteFile
71+
position = fileInfoIdx(c.graph.config, path).int
72+
else:
73+
assert n.kind == IntLit
74+
position = pool.integers[n.intId]
4475
inc n
76+
77+
let psym = PSym(itemId: ItemId(module: 0, item: symdef.id.int32), kind: symKind, name: ident, flags: flags, position: position)
78+
result = newSymNode(psym)
79+
let hasSym = c.nifSymToPSym.hasKeyOrPut(nifSym, psym)
80+
assert not hasSym
81+
4582
assert n.kind == ParRi
4683
inc n
84+
85+
proc fromNifLocal(c: var DecodeContext; n: var Cursor; kind: TNodeKind): PNode =
86+
result = newNodeI(kind, unknownLineInfo, 1)
87+
inc n
88+
assert n.nodeKind == nkIdentDefs
89+
result[0] = newNodeI(nkIdentDefs, unknownLineInfo, 3)
90+
inc n
91+
result[0][0] = fromNifSymDef(c, n, kind)
4792
result[0][1] = fromNif(c, n)
4893
result[0][2] = fromNif(c, n)
49-
assert n.kind == ParRi
94+
assert n.kind == ParRi # nkIdentDefs
5095
inc n
5196
assert n.kind == ParRi
5297
inc n
5398

99+
proc fromNifImport(c: var DecodeContext; n: var Cursor): PNode =
100+
result = newNode(nkImportStmt)
101+
inc n
102+
while n.kind != ParRi:
103+
result.add fromNifSymDef(c, n, nkImportStmt)
104+
inc n
105+
54106
proc fromNif(c: var DecodeContext; n: var Cursor): PNode =
55107
result = nil
56108
case n.kind:
@@ -60,6 +112,10 @@ proc fromNif(c: var DecodeContext; n: var Cursor): PNode =
60112
of IntLit:
61113
result = newIntTypeNode(pool.integers[n.intId], getSysType(tyInt))
62114
inc n
115+
of Symbol:
116+
let sym = c.nifSymToPSym[pool.syms[n.symId]]
117+
result = newSymNode(sym)
118+
inc n
63119
of ParLe:
64120
let kind = n.nodeKind
65121
case kind:
@@ -71,6 +127,8 @@ proc fromNif(c: var DecodeContext; n: var Cursor): PNode =
71127
inc n
72128
of nkVarSection, nkLetSection:
73129
result = fromNifLocal(c, n, kind)
130+
of nkImportStmt:
131+
result = fromNifImport(c, n)
74132
else:
75133
assert false, "Not yet implemented " & $kind
76134
else:

compiler/icnif/nifencoder.nim

Lines changed: 74 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,63 @@
1-
import std / [assertions]
2-
import ".." / [ast, astalgo, idents]
1+
import std / [assertions, tables]
2+
import ".." / [ast, astalgo, idents, lineinfos, msgs, options]
33
import "../../dist/nimony/src/lib" / nifbuilder
4+
import "../../dist/nimony/src/gear2" / modnames
45
import enum2nif
56

67
type
78
EncodeContext = object
89
b: Builder
10+
conf: ConfigRef
11+
toSuffix: Table[FileIndex, string]
12+
moduleToNifSuffix: Table[ItemId, string] # module PSym -> module suffix
913

10-
proc toNifSymDef(c: var EncodeContext; n: PNode) =
14+
proc modname(c: var EncodeContext; idx: FileIndex): string =
15+
# copied from ../nifgen.nim
16+
result = c.toSuffix.getOrDefault(idx)
17+
if result.len == 0:
18+
let fp = toFullPath(c.conf, idx)
19+
result = moduleSuffix(fp, cast[seq[string]](c.conf.searchPaths))
20+
c.toSuffix[idx] = result
21+
22+
proc toNifSym(c: var EncodeContext; sym: PSym): string =
23+
result = sym.name.s & '.' & $sym.itemId.item
24+
if sym.owner.kind == skModule:
25+
result.add '.'
26+
var modsuf = c.moduleToNifSuffix.getOrDefault(sym.owner.itemId)
27+
if modsuf.len == 0:
28+
modsuf = modname(c, sym.owner.position.FileIndex)
29+
c.moduleToNifSuffix[sym.owner.itemId] = modsuf
30+
result.add modsuf
31+
32+
proc symdefToNif(c: var EncodeContext; n: PNode) =
1133
assert n.kind == nkSym
1234
let sym = n.sym
1335
c.b.addTree toNifTag(n.kind)
14-
c.b.addIdent sym.name.s
15-
c.b.addIntLit sym.itemId.item
36+
var name = toNifSym(c, sym)
37+
c.b.addSymbolDef name
38+
if sym.flags == {}:
39+
c.b.addEmpty()
40+
else:
41+
var flags: string = ""
42+
genFlags(sym.flags, flags)
43+
c.b.addIdent flags
44+
if sym.kind == skModule:
45+
# position is module's FileIndex but it cannot be directly encoded
46+
# as the uniqueness of it can broke
47+
# if any import/include statements are changed.
48+
let path = toFullPath(c.conf, sym.position.FileIndex)
49+
c.b.addStrLit path
50+
else:
51+
c.b.addIntLit sym.position
52+
c.b.endTree()
53+
54+
proc toNifImport(c: var EncodeContext; n: PNode) =
55+
c.b.addTree toNifTag(n.kind)
56+
for i in 0 ..< n.len:
57+
assert n[i].kind == nkSym
58+
let sym = n[i].sym
59+
assert sym.kind == skModule
60+
symdefToNif(c, n[i])
1661
c.b.endTree()
1762

1863
proc toNif(c: var EncodeContext; n: PNode) =
@@ -24,10 +69,28 @@ proc toNif(c: var EncodeContext; n: PNode) =
2469
of nkIdentDefs:
2570
c.b.addTree toNifTag(n.kind)
2671
assert n.len == 3
27-
toNifSymDef(c, n[0])
72+
symdefToNif(c, n[0])
2873
toNif c, n[1]
2974
toNif c, n[2]
3075
c.b.endTree()
76+
of nkSym:
77+
when false:
78+
echo "nkSym: ", n.sym.name.s
79+
if n.sym.kind == skModule:
80+
echo "position = ", n.sym.position
81+
debug(n.sym)
82+
var o = n.sym.owner
83+
for i in 0 .. 20:
84+
if o == nil:
85+
break
86+
echo "owner ", i, ":"
87+
if o.kind == skModule:
88+
echo "position = ", o.position
89+
debug(o)
90+
o = o.owner
91+
c.b.addSymbol toNifSym(c, n.sym)
92+
of nkImportStmt:
93+
toNifImport(c, n)
3194
else:
3295
assert n.len > 0, $n.kind
3396
c.b.addTree toNifTag(n.kind)
@@ -37,20 +100,16 @@ proc toNif(c: var EncodeContext; n: PNode) =
37100

38101
proc saveNif(c: var EncodeContext; n: PNode) =
39102
c.b.addHeader "nim2", "nim2-ic-nif"
40-
c.b.addTree "stmts"
41-
assert n.kind == nkStmtList
42-
for i in 0 ..< n.len:
43-
toNif c, n[i]
44-
c.b.endTree()
103+
toNif c, n
45104

46-
proc saveNifFile*(module: PSym; n: PNode) =
105+
proc saveNifFile*(module: PSym; n: PNode; conf: ConfigRef) =
47106
let outfile = module.name.s & ".nif"
48-
var c = EncodeContext(b: nifbuilder.open(outfile))
107+
var c = EncodeContext(b: nifbuilder.open(outfile), conf: conf)
49108
saveNif(c, n)
50109
c.b.close()
51110

52-
proc saveNifToBuffer*(n: PNode): string =
53-
var c = EncodeContext(b: nifbuilder.open(100))
111+
proc saveNifToBuffer*(n: PNode; conf: ConfigRef): string =
112+
var c = EncodeContext(b: nifbuilder.open(100), conf: conf)
54113
saveNif(c, n)
55114
c.b.close()
56115
result = c.b.extract

compiler/pipelines.nim

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,9 @@ proc processPipelineModule*(graph: ModuleGraph; module: PSym; idgen: IdGenerator
187187
# encode the asts of specific modules to NIF files for debug or tests.
188188
if module.name.s.substr(0, 3) == "test":
189189
echo "saveNifFile: ", module.name.s
190-
echo "n:"
191-
debug(n)
192-
nifencoder.saveNifFile(module, semNode)
190+
echo "semNode:"
191+
debug(semNode)
192+
nifencoder.saveNifFile(module, semNode, graph.config)
193193

194194
closeParser(p)
195195
if s.kind != llsStdIn: break

tests/icnif/tencode.nim

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@ var graph = newModuleGraph(newIdentCache(), newConfigRef())
66

77
block:
88
const TestNif = """
9-
(.nif24)
10-
(.vendor "nim2")
11-
(.dialect "nim2-ic-nif")
12-
(stmts
13-
(var
14-
(identdefs
15-
(sym x +1) . +123))
16-
(var
17-
(identdefs
18-
(sym y +2) . +321)))"""
9+
(.nif24)
10+
(.vendor "nim2")
11+
(.dialect "nim2-ic-nif")
12+
(stmts
13+
(import
14+
(sym :testmod2.1 . "/home/nimdev/testnim/testmod2.nim"))
15+
(var
16+
(identdefs
17+
(sym :x.2.tesvp2f3v ueg +0) . +123))
18+
(var
19+
(identdefs
20+
(sym :y.3.tesvp2f3v g +0) . x.2.tesvp2f3v)))"""
1921

20-
assert loadNifFromBuffer(TestNif, graph).saveNifToBuffer() == TestNif
22+
assert loadNifFromBuffer(TestNif, graph).saveNifToBuffer(graph.config) == TestNif

0 commit comments

Comments
 (0)