Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement converters in sigmatch #384

Closed
wants to merge 14 commits into from
2 changes: 1 addition & 1 deletion src/hexer/expander.nim
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,7 @@ proc traverseExpr(e: var EContext; c: var Cursor) =
inc nested
of TupleConstrX:
traverseTupleConstr e, c
of CmdX, CallStrLitX, InfixX, PrefixX:
of CmdX, CallStrLitX, InfixX, PrefixX, HcallX:
e.dest.add tagToken("call", c.info)
inc c
inc nested
Expand Down
112 changes: 95 additions & 17 deletions src/lib/nifindexes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

## Create an index file for a NIF file.

import std / [os, tables, assertions, syncio, formatfloat, sets]

Check warning on line 9 in src/lib/nifindexes.nim

View workflow job for this annotation

GitHub Actions / linux-amd64-nim-devel (master)

imported and not used: 'formatfloat' [UnusedImport]

Check warning on line 9 in src/lib/nifindexes.nim

View workflow job for this annotation

GitHub Actions / linux-amd64-nim-devel (master)

imported and not used: 'formatfloat' [UnusedImport]

Check warning on line 9 in src/lib/nifindexes.nim

View workflow job for this annotation

GitHub Actions / macos-amd64-nim-devel (master)

imported and not used: 'formatfloat' [UnusedImport]

Check warning on line 9 in src/lib/nifindexes.nim

View workflow job for this annotation

GitHub Actions / macos-amd64-nim-devel (master)

imported and not used: 'formatfloat' [UnusedImport]

Check warning on line 9 in src/lib/nifindexes.nim

View workflow job for this annotation

GitHub Actions / windows-amd64-nim-devel (master)

imported and not used: 'formatfloat' [UnusedImport]

Check warning on line 9 in src/lib/nifindexes.nim

View workflow job for this annotation

GitHub Actions / windows-amd64-nim-devel (master)

imported and not used: 'formatfloat' [UnusedImport]
import bitabs, lineinfos, nifreader, nifstreams, nifcursors, nifchecksums

#import std / [sha1]
Expand Down Expand Up @@ -99,9 +99,41 @@
else:
inc n

proc createIndex*(infile: string; buildChecksum: bool;
hookIndexMap: Table[string, seq[(SymId, SymId)]];
toBuild: TokenBuf) =
type IndexSections* = object
hooks*: Table[string, seq[(SymId, SymId)]]
converters*: seq[(SymId, SymId)]
toBuild*: TokenBuf

proc getSection(tag: TagId; values: seq[(SymId, SymId)]; symToOffsetMap: Table[SymId, int]): TokenBuf =
let KvT = registerTag "kv"

result = default(TokenBuf)
result.addParLe tag

for value in values:
let (key, sym) = value
let offset = symToOffsetMap[sym]
result.buildTree KvT, NoLineInfo:
result.add symToken(key, NoLineInfo)
result.add intToken(pool.integers.getOrIncl(offset), NoLineInfo)

result.addParRi()

proc getSymbolSection(tag: TagId; values: seq[(SymId, SymId)]): TokenBuf =
let KvT = registerTag "kv"

result = default(TokenBuf)
result.addParLe tag

for value in values:
let (key, sym) = value
result.buildTree KvT, NoLineInfo:
result.add symToken(key, NoLineInfo)
result.add symToken(sym, NoLineInfo)

result.addParRi()

proc createIndex*(infile: string; buildChecksum: bool; sections: IndexSections) =
let PublicT = registerTag "public"
let PrivateT = registerTag "private"
let KvT = registerTag "kv"
Expand Down Expand Up @@ -161,27 +193,24 @@
content.add toString(private)
content.add "\n"

for (key, values) in hookIndexMap.pairs:
var hookSectionBuf = default(TokenBuf)
for (key, values) in sections.hooks.pairs:
let tag = registerTag(key)
hookSectionBuf.addParLe tag

for value in values:
let (obj, sym) = value
let offset = symToOffsetMap[sym]
hookSectionBuf.buildTree KvT, NoLineInfo:
hookSectionBuf.add symToken(obj, NoLineInfo)
hookSectionBuf.add intToken(pool.integers.getOrIncl(offset), NoLineInfo)

hookSectionBuf.addParRi()
let hookSectionBuf = getSection(tag, values, symToOffsetMap)

content.add toString(hookSectionBuf)
content.add "\n"

if sections.converters.len != 0:
let ConverterT = registerTag "converter"
let converterSectionBuf = getSymbolSection(ConverterT, sections.converters)

content.add toString(converterSectionBuf)
content.add "\n"

let buildT = registerTag "build"
var buildBuf = createTokenBuf()
buildBuf.addParLe buildT
buildBuf.add toBuild
buildBuf.add sections.toBuild
buildBuf.addParRi
content.add toString(buildBuf)
content.add "\n"
Expand All @@ -198,7 +227,7 @@
writeFile(indexName, content)

proc createIndex*(infile: string; buildChecksum: bool) =
createIndex(infile, buildChecksum, initTable[string, seq[(SymId, SymId)]](), default(TokenBuf))
createIndex(infile, buildChecksum, IndexSections(hooks: initTable[string, seq[(SymId, SymId)]](), toBuild: default(TokenBuf)))

type
NifIndexEntry* = object
Expand All @@ -207,6 +236,7 @@
NifIndex* = object
public*, private*: Table[string, NifIndexEntry]
hooks*: Table[string, Table[string, NifIndexEntry]]
converters*: Table[string, string] # map of dest types to converter symbols
toBuild*: seq[(string, string, string)]

proc readSection(s: var Stream; tab: var Table[string, NifIndexEntry]; useAbsoluteOffset = false) =
Expand Down Expand Up @@ -252,6 +282,49 @@
assert false, "expected (kv) construct"
#t = next(s)

proc readSymbolSection(s: var Stream; tab: var Table[string, string]) =
let KvT = registerTag "kv"
var t = next(s)
var nested = 1
while t.kind != EofToken:
let info = t.info
if t.kind == ParLe:
inc nested
if t.tagId == KvT:
t = next(s)
var key: string
if t.kind == Symbol:
key = pool.syms[t.symId]
elif t.kind == Ident:
key = pool.strings[t.litId]
else:
raiseAssert "invalid (kv) construct: symbol expected"
t = next(s) # skip Symbol
var value: string
if t.kind == Symbol:
value = pool.syms[t.symId]
elif t.kind == Ident:
value = pool.strings[t.litId]
else:
raiseAssert "invalid (kv) construct: symbol expected"
t = next(s) # skip value symbol
tab[key] = value
if t.kind == ParRi:
t = next(s)
dec nested
else:
assert false, "invalid (kv) construct: ')' expected"
else:
assert false, "expected (kv) construct"
elif t.kind == ParRi:
dec nested
if nested == 0:
break
t = next(s)
else:
assert false, "expected (kv) construct"
#t = next(s)

proc readIndex*(indexName: string): NifIndex =
var s = nifstreams.open(indexName)
let res = processDirectives(s.r)
Expand All @@ -269,6 +342,8 @@

let hookSet = toHashSet([ClonerT, TracerT, DisarmerT, MoverT, DtorT])

let ConverterT = registerTag "converter"

result = default(NifIndex)
var t = next(s)
if t.tag == IndexT:
Expand All @@ -288,6 +363,9 @@
result.hooks[tagName] = initTable[string, NifIndexEntry]()
readSection(s, result.hooks[tagName])
t = next(s)
if t.tag == ConverterT:
readSymbolSection(s, result.converters)
t = next(s)

let BuildT = registerTag "build"
if t.tag == BuildT:
Expand Down
3 changes: 2 additions & 1 deletion src/nimony/nimony_model.nim
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ type
CallStrLitX = "callstrlit"
InfixX = "infix"
PrefixX = "prefix"
HcallX = "hcall" # hidden converter call
CmdX = "cmd"
InfX = "inf"
NegInfX = "neginf"
Expand Down Expand Up @@ -334,7 +335,7 @@ template `==`*(n: Cursor; s: string): bool = n.kind == ParLe and pool.tags[n.tag

const
RoutineKinds* = {ProcY, FuncY, IterY, TemplateY, MacroY, ConverterY, MethodY}
CallKinds* = {CallX, CallStrLitX, CmdX, PrefixX, InfixX}
CallKinds* = {CallX, CallStrLitX, CmdX, PrefixX, InfixX, HcallX}
ConvKinds* = {HconvX, ConvX, OconvX, DconvX, CastX}

proc addParLe*(dest: var TokenBuf; kind: TypeKind|SymKind|ExprKind|StmtKind|SubstructureKind; info = NoLineInfo) =
Expand Down
10 changes: 10 additions & 0 deletions src/nimony/programs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ proc load*(suffix: string): NifModule =

proc loadInterface*(suffix: string; iface: var Iface;
module: SymId; importTab: var OrderedTable[StrId, seq[SymId]];
converters: var Table[SymId, seq[SymId]];
marker: var PackedSet[StrId]; negateMarker: bool) =
let m = load(suffix)
for k, _ in m.index.public:
Expand All @@ -63,6 +64,15 @@ proc loadInterface*(suffix: string; iface: var Iface;
if not symMarked:
# mark that this module contains the identifier `strId`:
importTab.mgetOrPut(strId, @[]).add(module)
for k, v in m.index.converters:
var name = v
extractBasename(name)
let nameId = pool.strings.getOrIncl(name)
# check that the converter is imported, slow but better to be slow here:
if nameId in importTab and module in importTab[nameId]:
let key = pool.syms.getOrIncl(k)
let val = pool.syms.getOrIncl(v)
converters.mgetOrPut(key, @[]).add(val)

proc error*(msg: string; c: Cursor) {.noreturn.} =
when defined(debug):
Expand Down
Loading
Loading