refers imported symbols like Nimony

This commit is contained in:
demotomohiro
2025-11-04 17:16:10 +09:00
parent ab13900fad
commit 54aa552fb6
5 changed files with 114 additions and 46 deletions

View File

@@ -0,0 +1,19 @@
import std/[tables]
import ".." / [ast, lineinfos, msgs, options]
import "../../dist/nimony/src/gear2" / modnames
proc modname(moduleToNifSuffix: var Table[FileIndex, string]; module: PSym; conf: ConfigRef): string =
assert module.kind == skModule
let idx: FileIndex = module.position.FileIndex
# copied from ../nifgen.nim
result = moduleToNifSuffix.getOrDefault(idx)
if result.len == 0:
let fp = toFullPath(conf, idx)
result = moduleSuffix(fp, cast[seq[string]](conf.searchPaths))
moduleToNifSuffix[idx] = result
#echo result, " -> ", fp
proc toNifSym*(sym: PSym; moduleToNifSuffix: var Table[FileIndex, string]; conf: ConfigRef): string =
let module = sym.originatingModule
result = sym.name.s & '.' & $sym.disamb & '.' & modname(moduleToNifSuffix, module, conf)

View File

@@ -1,14 +1,19 @@
import std / [assertions, tables]
import "../../dist/nimony/src/lib" / [bitabs, nifreader, nifstreams, nifcursors, lineinfos]
import ".." / [ast, idents, lineinfos, options, modules, modulegraphs, msgs, pathutils]
import enum2nif, icniftags
import enum2nif, icniftags, nifbasics
type
NifProgram* = ref object
nifSymIdToPSym: Table[SymId, PSym]
moduleToNifSuffix: Table[FileIndex, string] # FileIndex (PSym.position) -> module suffix
DecodeContext = object
graph: ModuleGraph
symbols: Table[ItemId, PSym]
types: Table[ItemId, PType]
modules: Table[int, FileIndex] # maps module id in NIF to FileIndex of the module
prog: NifProgram
proc nodeKind(n: Cursor): TNodeKind {.inline.} =
assert n.kind == ParLe
@@ -160,6 +165,11 @@ proc fromNifSymDef(c: var DecodeContext; n: var Cursor): PSym =
result.instantiatedFrom = c.fromNifSymbol n
skipParRi n
if sfExported in flags or kind == skModule:
let nifSym = toNifSym(result, c.prog.moduleToNifSuffix, c.graph.config)
let symId = pool.syms.getOrIncl(nifSym)
c.prog.nifSymIdToPSym[symId] = result
proc fromNifTypeDef(c: var DecodeContext; n: var Cursor): PType =
expectTag n, typeIdTag
inc n
@@ -207,6 +217,14 @@ proc fromNifSymbol(c: var DecodeContext; n: var Cursor): PSym =
if n.kind == DotToken:
result = nil
inc n
elif n.kind == Symbol:
if n.symId notin c.prog.nifSymIdToPSym:
# TODO: Support import statement and remove this branch
#echo pool.syms[n.symId], " is not found"
result = nil
else:
result = c.prog.nifSymIdToPSym[n.symId]
inc n
else:
expect n, ParLe
if n.tagId == symIdTag:
@@ -333,26 +351,26 @@ proc fromNif(c: var DecodeContext; n: var Cursor): PNode =
else:
assert false, "Not yet implemented " & $n.kind
proc loadNif(stream: var Stream; graph: ModuleGraph): PNode =
proc loadNif(stream: var Stream; graph: ModuleGraph; prog: NifProgram): PNode =
discard processDirectives(stream.r)
var buf = fromStream(stream)
var n = beginRead(buf)
var c = DecodeContext(graph: graph)
var c = DecodeContext(graph: graph, prog: prog)
result = fromNif(c, n)
endRead(buf)
proc loadNifFile*(infile: AbsoluteFile; graph: ModuleGraph): PNode =
proc loadNifFile*(infile: AbsoluteFile; graph: ModuleGraph; prog: NifProgram): PNode =
var stream = nifstreams.open(infile.string)
result = loadNif(stream, graph)
result = loadNif(stream, graph, prog)
stream.close
proc loadNifFromBuffer*(strbuf: sink string; graph: ModuleGraph): PNode =
proc loadNifFromBuffer*(strbuf: sink string; graph: ModuleGraph; prog: NifProgram): PNode =
var stream = nifstreams.openFromBuffer(strbuf)
result = loadNif(stream, graph)
result = loadNif(stream, graph, prog)
when isMainModule:
import std/cmdline

View File

@@ -1,18 +1,21 @@
import std / [assertions, sets]
import std / [assertions, sets, tables]
import ".." / [ast, idents, lineinfos, msgs, options]
import "../../dist/nimony/src/lib" / [bitabs, nifstreams, nifcursors, lineinfos]
import enum2nif, icniftags
import enum2nif, icniftags, nifbasics
type
EncodeContext = object
conf: ConfigRef
currentModule: PSym
decodedSyms: HashSet[ItemId]
decodedTypes: HashSet[ItemId]
decodedFileIndices: HashSet[FileIndex]
dest: TokenBuf
moduleToNifSuffix: Table[FileIndex, string] # FileIndex (PSym.position) -> module suffix
proc initEncodeContext(conf: ConfigRef): EncodeContext =
proc initEncodeContext(conf: ConfigRef; currentModule: PSym): EncodeContext =
result = EncodeContext(conf: conf,
currentModule: currentModule,
dest: createTokenBuf())
template buildTree(dest: var TokenBuf; tag: TagId; body: untyped) =
@@ -110,6 +113,9 @@ proc toNifDef(c: var EncodeContext; typ: PType) =
proc toNif(c: var EncodeContext; sym: PSym) =
if sym == nil:
c.dest.addDotToken()
elif sym.owner != nil and sym.originatingModule != c.currentModule:
let nifSym = toNifSym(sym, c.moduleToNifSuffix, c.conf)
c.dest.addSymUse(pool.syms.getOrIncl(nifSym), NoLineInfo)
else:
if not c.decodedSyms.containsOrIncl(sym.itemId):
c.toNifDef sym
@@ -201,11 +207,11 @@ proc saveNif(c: var EncodeContext; n: PNode): string =
result = "(.nif24)\n" & toString(c.dest)
proc saveNifFile*(module: PSym; n: PNode; conf: ConfigRef) =
proc saveNifFile*(n: PNode; conf: ConfigRef; module: PSym) =
let outfile = module.name.s & ".nif"
var c = initEncodeContext(conf)
var c = initEncodeContext(conf, module)
writeFile outfile, saveNif(c, n)
proc saveNifToBuffer*(n: PNode; conf: ConfigRef): string =
var c = initEncodeContext(conf)
proc saveNifToBuffer*(n: PNode; conf: ConfigRef; module: PSym): string =
var c = initEncodeContext(conf, module)
result = saveNif(c, n)