Skip to content

Commit

Permalink
NIFC: follow scopes for precise typing information (#518)
Browse files Browse the repository at this point in the history
* NIFC: follow scopes for precise typing information

* NIFC: (addr arr) must produce &arr.a
  • Loading branch information
Araq authored Feb 12, 2025
1 parent 8cf3ac6 commit de8b01e
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 69 deletions.
67 changes: 0 additions & 67 deletions src/lib/programs.nim

This file was deleted.

10 changes: 9 additions & 1 deletion src/nifc/codegen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,9 @@ proc genParamPragmas(c: var GeneratedCode; n: var Cursor) =
proc genParam(c: var GeneratedCode; n: var Cursor) =
var d = takeParamDecl(n)
if d.name.kind == SymbolDef:
let name = mangle(pool.syms[d.name.symId])
let lit = d.name.symId
c.m.registerLocal(lit, d.typ)
let name = mangle(pool.syms[lit])
genType c, d.typ, name
genParamPragmas c, d.pragmas
else:
Expand Down Expand Up @@ -416,6 +418,7 @@ proc genVarDecl(c: var GeneratedCode; n: var Cursor; vk: VarKind; toExtern = fal
var d = takeVarDecl(n)
if d.name.kind == SymbolDef:
let lit = d.name.symId
c.m.registerLocal(lit, d.typ)
let name = mangle(pool.syms[lit])
let beforeDecl = c.code.len
if toExtern:
Expand Down Expand Up @@ -450,6 +453,7 @@ include genstmts


proc genProcDecl(c: var GeneratedCode; n: var Cursor; isExtern: bool) =
c.m.openScope()
let signatureBegin = c.code.len
var prc = takeProcDecl(n)

Expand Down Expand Up @@ -546,6 +550,7 @@ proc genProcDecl(c: var GeneratedCode; n: var Cursor; isExtern: bool) =
c.add CurlyRi
if isSelectAny in flags:
genRoutineGuardEnd(c)
c.m.closeScope()

proc genInclude(c: var GeneratedCode; n: var Cursor) =
inc n
Expand Down Expand Up @@ -641,6 +646,7 @@ proc generateCode*(s: var State, inp, outp: string; flags: set[GenFlag]) =
var m = load(inp)
m.config = s.config
var c = initGeneratedCode(m, flags)
c.m.openScope()

var co = TypeOrder()
traverseTypes(c.m, co)
Expand Down Expand Up @@ -685,3 +691,5 @@ proc generateCode*(s: var State, inp, outp: string; flags: set[GenFlag]) =
for x in items(c.headerFile):
write h, c.tokens[x]
h.close()

c.m.closeScope()
15 changes: 14 additions & 1 deletion src/nifc/genexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,18 @@ proc suffixConv(c: var GeneratedCode; value, suffix: Cursor) =
genx c, value
c.add ParRi

proc genAddr(c: var GeneratedCode; n: var Cursor) =
# If we take the address of an array expression, add the `.a` field access.
inc n
let arrType = getType(c.m, n)
c.add ParLe
c.add "&"
genx c, n
if arrType.typeKind == ArrayT and not c.m.isImportC(arrType):
c.add ".a"
c.add ParRi
skipParRi n

proc genx(c: var GeneratedCode; n: var Cursor) =
case n.exprKind
of NoExpr:
Expand Down Expand Up @@ -268,7 +280,8 @@ proc genx(c: var GeneratedCode; n: var Cursor) =
genx c, n
c.add ParRi
skipParRi n
of AddrC: unOp c, n, "&"
of AddrC:
genAddr c, n
of SizeofC:
c.add "sizeof"
c.add ParLe
Expand Down
2 changes: 2 additions & 0 deletions src/nifc/genstmts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,12 @@ proc genTryCpp(c: var GeneratedCode; n: var Cursor) =
proc genScope(c: var GeneratedCode; n: var Cursor) =
c.add CurlyLe
inc n
c.m.openScope()
while n.kind != ParRi:
c.genStmt n
skipParRi n
c.add CurlyRi
c.m.closeScope()

proc genBranchValue(c: var GeneratedCode; n: var Cursor) =
if n.kind in {IntLit, UIntLit, CharLit, Symbol} or n.exprKind in {TrueC, FalseC}:
Expand Down
14 changes: 14 additions & 0 deletions src/nifc/nifc_model.nim
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ type
pos*: int
kind*: NifcSym

TypeScope* {.acyclic.} = ref object
locals*: Table[SymId, Cursor]
parent*: TypeScope

Module* = object
src*: TokenBuf
types*: seq[int]
Expand All @@ -25,12 +29,22 @@ type
config*: ConfigRef
mem*: seq[TokenBuf] # for intermediate results such as computed types
builtinTypes*: Table[string, Cursor]
current*: TypeScope

proc bug*(msg: string) {.noreturn.} =
when defined(debug):
writeStackTrace()
quit "BUG: " & msg

proc registerLocal*(c: var Module; s: SymId; typ: Cursor) =
c.current.locals[s] = typ

proc openScope*(c: var Module) =
c.current = TypeScope(locals: initTable[SymId, Cursor](), parent: c.current)

proc closeScope*(c: var Module) =
c.current = c.current.parent

proc skipParRi*(n: var Cursor) =
# XXX: Give NIFC some better error reporting.
if n.kind == ParRi:
Expand Down
6 changes: 6 additions & 0 deletions src/nifc/typenav.nim
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ proc getType*(m: var Module; n: Cursor): Cursor =
of DotToken, Ident, SymbolDef:
result = createIntegralType(m, "(err)")
of Symbol:
var it {.cursor.} = m.current
while it != nil:
let res = it.locals.getOrDefault(n.symId)
if not cursorIsNil(res):
return res
it = it.parent
let d = m.defs.getOrDefault(n.symId)
if d.pos != 0:
result = getType(m, m.src.cursorAt(d.pos))
Expand Down

0 comments on commit de8b01e

Please sign in to comment.