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

implements {.compile.} #367

Closed
wants to merge 12 commits into from
Closed
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "vendor/mimalloc"]
path = vendor/mimalloc
url = https://github.com/microsoft/mimalloc
23 changes: 23 additions & 0 deletions lib/std/system/mimalloc.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{.compile("../../../vendor/mimalloc/src/static.c", "-Ivendor/mimalloc/include").}

type
csize_t* {.importc: "size_t", nodecl.} = uint

proc mi_malloc(size: csize_t): pointer {.importc: "mi_malloc".}
proc mi_calloc(nmemb: csize_t, size: csize_t): pointer {.importc: "mi_calloc".}
proc mi_realloc(pt: pointer, size: csize_t): pointer {.importc: "mi_realloc".}
proc mi_free(p: pointer) {.importc: "mi_free".}

proc mi_usable_size(p: pointer): csize_t {.importc: "mi_usable_size".}

proc alloc*(size: int): pointer =
result = mi_malloc(size.csize_t)

proc realloc*(p: pointer; size: int): pointer =
result = mi_realloc(p, size.csize_t)

proc dealloc*(p: pointer) =
mi_free(p)

proc allocatedSize*(p: pointer): int =
result = int mi_usable_size(p)
15 changes: 14 additions & 1 deletion src/hexer/expander.nim
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,13 @@ proc parsePragmas(e: var EContext; c: var Cursor): CollectedPragmas =
error e, "expected string literal or ident, but got: ", c
result.flags.incl Nodecl
inc c
of ImportC, ImportCpp, ExportC, Plugin:
of ImportC, ImportCpp:
inc c
expectStrLit e, c
result.externName = pool.strings[c.litId]
result.flags.incl pk
inc c
of ExportC, Plugin:
inc c
expectStrLit e, c
result.externName = pool.strings[c.litId]
Expand All @@ -479,6 +485,7 @@ proc parsePragmas(e: var EContext; c: var Cursor): CollectedPragmas =
inc c
expectStrLit e, c
result.header = c.litId
result.flags.incl Nodecl
inc c
of Align:
inc c
Expand Down Expand Up @@ -610,6 +617,10 @@ proc traverseProc(e: var EContext; c: var Cursor; mode: TraverseMode) =
swap dst, e.dest
if Nodecl in prag.flags or isGeneric:
discard "do not add to e.dest"
elif prag.flags * {ImportC, ImportCpp} != {}:
e.dest.add tagToken("imp", c.info)
e.dest.add dst
e.dest.addParRi()
else:
e.dest.add dst
if prag.header != StrId(0):
Expand Down Expand Up @@ -1082,6 +1093,8 @@ proc traverseStmt(e: var EContext; c: var Cursor; mode = TraverseAll) =
traverseTypeDecl e, c
of ContinueS, WhenS:
error e, "unreachable: ", c
of PragmasLineS:
skip c
of ClonerS, TracerS, DisarmerS, MoverS, DtorS:
skip c
else:
Expand Down
3 changes: 2 additions & 1 deletion src/hexer/xelim.nim
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,8 @@ proc trStmt(c: var Context; dest: var TokenBuf; n: var Cursor) =
trBlock c, dest, n, tar
of IterS, TemplateS, TypeS, EmitS, BreakS, ContinueS,
ForS, CmdS, IncludeS, ImportS, FromImportS, ImportExceptS,
ExportS, CommentS, ClonerS, TracerS, DisarmerS, MoverS, DtorS:
ExportS, CommentS, ClonerS, TracerS, DisarmerS, MoverS, DtorS,
PragmasLineS:
takeTree dest, n
of StmtsS:
copyInto(dest, n):
Expand Down
83 changes: 83 additions & 0 deletions src/nifler/bridge.nim
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,68 @@ proc addFloatLit*(b: var Builder; u: BiggestFloat; suffix: string) =
b.addFloatLit u
b.addStrLit suffix

proc toNif*(n, parent: PNode; c: var TranslationContext)

proc compilePathToNif(n, parent: PNode; info: TLineInfo; c: var TranslationContext) =
var modulePath = toFullPath(c.conf, info.fileIndex)
case n.kind
of nkStrLit, nkRStrLit, nkTripleStrLit:
let cfile = n.strVal
if isAbsolute(cfile):
toNif(n, parent, c)
else:
var path = parentDir(modulePath) / cfile
relLineInfo(n, parent, c)
c.b.addStrLit(path)
else:
toNif(n, parent, c)

proc handleCompileDeps(n: PNode, child: PNode; isCall: bool; hasCompile: var bool; c: var TranslationContext) =
if child.len > 0 and child[0].kind == nkIdent and
child[0].ident.s == "compile":
if not hasCompile:
c.deps.addTree(nodeKindTranslation(n.kind))
hasCompile = true

let oldLineInfoEnabled = c.lineInfoEnabled
c.lineInfoEnabled = false
let oldDepsEnabled = c.depsEnabled
swap c.b, c.deps
c.depsEnabled = false

c.b.addTree("kv")
if isCall:
if child.len == 3:
toNif(child[0], child, c)
c.b.addTree("tup")
compilePathToNif(child[1], child, n.info, c)
c.b.addStrLit("")
toNif(child[2], child, c)
c.b.endTree()
elif child.len == 2:
# format (file, obj, customArgs)
toNif(child[0], child, c)
c.b.addTree("tup")

case child[1].kind
of nkStrLit, nkRStrLit, nkTripleStrLit:
compilePathToNif(child[1], child, n.info, c)
c.b.addStrLit("")
of nkTupleConstr:
let tup = child[1]
if tup.len == 2:
compilePathToNif(tup[0], tup, n.info, c)
toNif(tup[1], tup, c)
else:
discard
c.b.addStrLit("")
c.b.endTree()
c.b.endTree()

c.depsEnabled = oldDepsEnabled
swap c.b, c.deps
c.lineInfoEnabled = oldLineInfoEnabled

proc toNif*(n, parent: PNode; c: var TranslationContext) =
case n.kind
of nkNone, nkEmpty:
Expand Down Expand Up @@ -594,6 +656,27 @@ proc toNif*(n, parent: PNode; c: var TranslationContext) =
toNif(n[i], n, c)
c.b.endTree()
c.depsEnabled = oldDepsEnabled
of nkPragma:
if c.depsEnabled:
var hasCompile = false
for i in 0..<n.len:
let child = n[i]
case child.kind
of nkExprColonExpr:
handleCompileDeps(n, child, false, hasCompile, c)
of nkCallKinds:
handleCompileDeps(n, child, true, hasCompile, c)
else:
discard
if hasCompile:
c.deps.endTree()

relLineInfo(n, parent, c)
c.b.addTree(nodeKindTranslation(n.kind))
for i in 0..<n.len:
toNif(n[i], n, c)
c.b.endTree()

else:
relLineInfo(n, parent, c)
c.b.addTree(nodeKindTranslation(n.kind))
Expand Down
41 changes: 41 additions & 0 deletions src/nimony/deps.nim
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ type
DoCompile, # like `nim c` but with nifler
DoRun # like `nim run`

Cfile = object
name, obj: string
customArgs: string

DepContext = object
forceRebuild: bool
cmd: Command
Expand All @@ -66,6 +70,7 @@ type
includeStack: seq[string]
processedModules: HashSet[string]
moduleFlags: set[ModuleFlag]
toCompile: seq[Cfile]

proc toPair(c: DepContext; f: string): FilePair =
FilePair(nimFile: f, modname: moduleSuffix(f, c.config.paths))
Expand Down Expand Up @@ -170,6 +175,33 @@ proc processFrom(c: var DepContext; it: var Cursor; current: Node) =
importSingleFile c, f.path, info, current, false
break

proc processCompile(c: var DepContext; it: var Cursor; current: Node) =
var compileObj = CFile()
inc it # skips pragmas
while it.kind != ParRi:
inc it # skips kv
inc it # skips compile
inc it # skips TupleConstrX
# (file, obj, customArgs)
let name = pool.strings[it.litId]
compileObj.name = name
inc it
if compileObj.obj.len == 0:
compileObj.obj = name
else:
compileObj.obj = pool.strings[it.litId]
compileObj.obj = splitFile(compileObj.obj).name & ".o"

inc it
compileObj.customArgs = pool.strings[it.litId]
inc it
inc it # TupleConstrX
inc it # kv
inc it # pragmas

c.toCompile.add compileObj


proc processDep(c: var DepContext; n: var Cursor; current: Node) =
case stmtKind(n)
of ImportS:
Expand All @@ -181,6 +213,8 @@ proc processDep(c: var DepContext; n: var Cursor; current: Node) =
of ExportS:
discard "ignore `export` statement"
skip n
of PragmasLineS:
processCompile c, n, current
else:
#echo "IGNORING ", toString(n, false)
skip n
Expand Down Expand Up @@ -259,10 +293,17 @@ proc generateMakefile(c: DepContext; commandLineArgs: string): string =
# The .exe file depends on all .o files:
if c.cmd in {DoCompile, DoRun}:
s.add "\n" & mescape(exeFile(c.rootNode.files[0])) & ":"
for cfile in c.toCompile:
s.add " " & mescape("nifcache" / cfile.obj)
for v in c.nodes:
s.add " " & mescape(objFile(v.files[0]))
s.add "\n\t$(CC) -o $@ $^"

for cfile in c.toCompile:
s.add "\n" & mescape("nifcache" / cfile.obj) & ": " & mescape(cfile.name) &
"\n\t$(CC) -c $(CFLAGS) $(CPPFLAGS) " &
cfile.customArgs & " $< -o $@"

# The .o files depend on all of their .c files:
s.add "\n%.o: %.c\n\t$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@"

Expand Down
1 change: 1 addition & 0 deletions src/nimony/nimony.nim
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ proc handleCmdLine() =
of FullProject:
createDir("nifcache")
createDir(binDir())
exec "git submodule update --init"
requiresTool "nifler", "src/nifler/nifler.nim", forceRebuild
requiresTool "nimsem", "src/nimony/nimsem.nim", forceRebuild
requiresTool "hexer", "src/hexer/hexer.nim", forceRebuild
Expand Down
1 change: 1 addition & 0 deletions src/nimony/nimony_model.nim
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type
DisarmerS = "disarmer"
MoverS = "mover"
DtorS = "dtor"
PragmasLineS = "pragmas"

SymKind* = enum
NoSym
Expand Down
2 changes: 2 additions & 0 deletions src/nimony/sem.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4644,6 +4644,8 @@ proc semExpr(c: var SemContext; it: var Item; flags: set[SemFlag] = {}) =
skip it.n
of ClonerS, TracerS, DisarmerS, MoverS, DtorS:
takeTree c, it.n
of PragmasLineS:
takeTree c, it.n
of FalseX, TrueX:
literalB c, it, c.types.boolType
of InfX, NegInfX, NanX:
Expand Down
3 changes: 3 additions & 0 deletions tests/nimony/sysbasics/foo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
int myFunc() {
return 12;
}
3 changes: 3 additions & 0 deletions tests/nimony/sysbasics/foo1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
int myFunc2() {
return 12;
}
8 changes: 8 additions & 0 deletions tests/nimony/sysbasics/tcompile.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{.compile: "foo.c".}
{.compile("foo.c", "-fno-strict-aliasing")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
{.compile("foo.c", "-fno-strict-aliasing")
{.compile("foo1.c", "-fno-strict-aliasing").}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


proc myFunc(): int {.importc: "myFunc".}
proc myFunc2(): int {.importc: "myFunc2".}

let s = myFunc()
let s2 = myFunc2()
1 change: 1 addition & 0 deletions vendor/mimalloc
Submodule mimalloc added at 97c304
Loading