Skip to content

Commit

Permalink
implements selectany (#59)
Browse files Browse the repository at this point in the history
* implements selectany

* fixes names

* adds tests; create `nifcache` to store generated files
  • Loading branch information
ringabout authored Sep 11, 2024
1 parent 61b2468 commit a4852cf
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 31 deletions.
17 changes: 14 additions & 3 deletions src/nifc/codegen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

import std / [assertions, syncio, tables, sets, intsets, formatfloat, strutils]

Check warning on line 12 in src/nifc/codegen.nim

View workflow job for this annotation

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

imported and not used: 'formatfloat' [UnusedImport]

Check warning on line 12 in src/nifc/codegen.nim

View workflow job for this annotation

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

imported and not used: 'formatfloat' [UnusedImport]

Check warning on line 12 in src/nifc/codegen.nim

View workflow job for this annotation

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

imported and not used: 'formatfloat' [UnusedImport]
from std / strutils import parseBiggestInt, parseBiggestUInt, parseInt
from std / os import changeFileExt
from std / os import changeFileExt, splitFile, extractFileName

import .. / lib / [bitabs, packedtrees]
import mangler, nifc_model, cprelude
Expand Down Expand Up @@ -81,6 +81,9 @@ type
generatedTypes: IntSet
requestedSyms: HashSet[string]

State* = object
selects*: seq[string]

proc initGeneratedCode*(m: sink Module): GeneratedCode =
result = GeneratedCode(m: m, code: @[], tokens: initBiTable[Token, string]())
fillTokenTable(result.tokens)
Expand Down Expand Up @@ -174,6 +177,8 @@ proc genStrLit(c: var GeneratedCode; litId: StrId): Token =
let cstr = makeCString(c.m.lits.strings[litId])
result = c.tokens.getOrIncl cstr

include selectany

type
ProcFlag = enum
isSelectAny, isVarargs, isInline
Expand Down Expand Up @@ -335,9 +340,13 @@ proc genProcDecl(c: var GeneratedCode; t: Tree; n: NodePos; isExtern: bool) =
if isExtern:
c.code.setLen signatureBegin
else:
if isSelectAny in flags:
genRoutineGuardBegin(c, name)
c.add CurlyLe
genStmt c, t, prc.body
c.add CurlyRi
if isSelectAny in flags:
genRoutineGuardEnd(c)

proc genInclude(c: var GeneratedCode; t: Tree; n: NodePos) =
let lit = t[n.firstSon].litId
Expand Down Expand Up @@ -410,7 +419,7 @@ proc traverseCode(c: var GeneratedCode; t: Tree; n: NodePos) =
c.init.add c.code[i]
setLen c.code, oldLen

proc generateCode*(inp, outp: string; intmSize: int) =
proc generateCode*(s: var State, inp, outp: string; intmSize: int) =
var c = initGeneratedCode(load(inp))

var co = TypeOrder()
Expand All @@ -435,7 +444,9 @@ proc generateCode*(inp, outp: string; intmSize: int) =
f.f.close

if c.headerFile.len > 0:
var h = open(outp.changeFileExt(".h"), fmWrite)
let selectHeader = outp.changeFileExt(".h")
s.selects.add selectHeader
var h = open(selectHeader, fmWrite)
for x in items(c.headerFile):
write h, c.tokens[x]
h.close()
11 changes: 9 additions & 2 deletions src/nifc/nifc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,17 @@ proc handleCmdLine() =
quit "command takes a filename"
else:
let destExt = if action == "c": ".c" else: ".cpp"
var s = State()
createDir("nifcache")
for i in 0..<args.len:
let inp = args[i]
let outp = changeFileExt(inp, destExt)
generateCode inp, outp, bits
let outp = "nifcache" / splitFile(inp).name & destExt
generateCode s, inp, outp, bits
if s.selects.len > 0:
var h = open("nifcache/select_any.h", fmWrite)
for x in s.selects:
write h, "#include \"" & extractFileName(x) & "\"\n"
h.close()
else:
quit "Invalid action: " & action

Expand Down
2 changes: 2 additions & 0 deletions src/nifc/nifc_model.nim
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ type
types*: TypeGraph
defs*: Table[StrId, NodePos]
lits*: Literals
filename*: string

proc addAtom*[L](dest: var PackedTree[NifcKind]; kind: NifcKind; lit: L; info: PackedLineInfo) =
packedtrees.addAtom dest, kind, uint32(lit), info
Expand Down Expand Up @@ -216,6 +217,7 @@ proc load*(filename: string): Module =
var r = nifreader.open(filename)
discard nifreader.processDirectives(r)
result = parse(r)
result.filename = filename
r.close

proc memSizes*(m: Module) =
Expand Down
67 changes: 41 additions & 26 deletions src/nifc/selectany.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# See the file "license.txt", included in this
# distribution, for details about the copyright.

# imported from codegen.nim
# included from codegen.nim

##[
Expand Down Expand Up @@ -58,36 +58,51 @@ void genericProc() // always declare header
]##

proc genRoutineGuardBegin(c: var GeneratedCode; f: var CppFunc) =
let guardName = c.tokens[f.e.name] & "__" & $c.m.canonName
proc addHeadFile(c: var GeneratedCode; s: string) {.inline.} =
c.headerFile.add c.tokens.getOrIncl(s)

c.headerFile.add c.tokens.getOrIncl"""#ifndef """
c.headerFile.add f.e.name
c.headerFile.add "__impl"
c.headerFile.add NewLine
proc addHeadFile(c: var GeneratedCode; t: PredefinedToken) {.inline.} =
c.headerFile.add Token(t)

c.headerFile.add " #define "
c.headerFile.add f.e.name
c.headerFile.add "__impl"
c.headerFile.add NewLine
proc inclHeader(c: var GeneratedCode) =
let header = c.tokens.getOrIncl("\"select_any.h\"")
if not c.includedHeaders.containsOrIncl(int header):
c.includes.add Token(IncludeKeyword)
c.includes.add header
c.includes.add Token NewLine

c.headerFile.add " #define "
c.headerFile.add guardName
c.headerFile.add NewLine
proc genRoutineGuardBegin(c: var GeneratedCode; name: string) =
let guardName = name & "__" & mangle(c.m.filename.splitFile.name)

c.headerFile.add "#endif"
c.headerFile.add NewLine
inclHeader(c)

emit NewLine
emit "#ifdef "
emit guardName
emit NewLine
c.addHeadFile """#ifndef """
c.addHeadFile name
c.addHeadFile "__impl"
c.addHeadFile NewLine

c.addHeadFile " #define "
c.addHeadFile name
c.addHeadFile "__impl"
c.addHeadFile NewLine

c.addHeadFile " #define "
c.addHeadFile guardName
c.addHeadFile NewLine

c.addHeadFile "#endif"
c.addHeadFile NewLine

c.add NewLine
c.add "#ifdef "
c.add guardName
c.add NewLine


proc genRoutineGuardEnd(c: var GeneratedCode) =
emit "#else"
emit NewLine
emit Semicolon
emit "#endif"
emit NewLine
emit NewLine
c.add "#else"
c.add NewLine
c.add Semicolon
c.add "#endif"
c.add NewLine
c.add NewLine
21 changes: 21 additions & 0 deletions tests/nifc/selectany/t1.nif
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
(.nif24)
(stmts
(incl "<stdio.h>")

(proc :genericProc.c . (void) (pragmas (selectany)) (stmts
(call printf.c "hello %s" "file t1")
)
)

(proc :genericProc2.c . (void) (pragmas (selectany)) (stmts
(call printf.c "hello %s" "file t1")
)
)

(proc :main.c . (i -1 +90) . (stmts
(call printf.c "hello %s" "abc")
(call printf.c "hello %d" (suf +12 "i64"))
(ret +0)
))

)
15 changes: 15 additions & 0 deletions tests/nifc/selectany/t2.nif
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
(.nif24)
(stmts
(incl "<stdio.h>")
(proc :genericProc.c . (void) (pragmas (selectany)) (stmts
(call printf.c "hello %s" "file t2")
)
)

(proc :main.c . (i -1 +90) . (stmts
(call printf.c "hello %s" "abc")
(call printf.c "hello %d" (suf +12 "i64"))
(ret +0)
))

)
19 changes: 19 additions & 0 deletions tests/nifc/selectany/t3.nif
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
(.nif24)
(stmts
(incl "<stdio.h>")
(proc :genericProc.c . (void) (pragmas (selectany)) (stmts
(call printf.c "hello %s" "file t3")
)
)

(proc :genericProc2.c . (void) (pragmas (selectany)) (stmts
(call printf.c "hello %s" "file t3")
)
)

(proc :main.c . (i -1 +90) . (stmts
(call printf.c "hello %s" "abc")
(call printf.c "hello %d" (suf +12 "i64"))
(ret +0)
))
)
9 changes: 9 additions & 0 deletions tests/tester.nim
Original file line number Diff line number Diff line change
Expand Up @@ -217,3 +217,12 @@ proc testNifGram(overwrite: bool) =
removeFile rem

testNifGram(overwrite)

proc testNifc(overwrite: bool) =
exec "nim c src/nifc/nifc"
let t1 = "tests/nifc/selectany/t1.nif"
let t2 = "tests/nifc/selectany/t2.nif"
let t3 = "tests/nifc/selectany/t3.nif"
exec ("src" / "nifc" / "nifc").addFileExt(ExeExt) & " c" & " " & t1 & " " & t2 & " " & t3

testNifc(overwrite)

0 comments on commit a4852cf

Please sign in to comment.