importCompilerProc pragma introduced because the hacks for typeinfo.nim did not suffice
This commit is contained in:
parent
3e91b456e5
commit
3091bc4958
9 changed files with 96 additions and 38 deletions
|
|
@ -406,7 +406,8 @@ type
|
||||||
lfNoDecl, # do not declare it in C
|
lfNoDecl, # do not declare it in C
|
||||||
lfDynamicLib, # link symbol to dynamic library
|
lfDynamicLib, # link symbol to dynamic library
|
||||||
lfExportLib, # export symbol for dynamic library generation
|
lfExportLib, # export symbol for dynamic library generation
|
||||||
lfHeader # include header file for symbol
|
lfHeader, # include header file for symbol
|
||||||
|
lfImportCompilerProc # ``importc`` of a compilerproc
|
||||||
TStorageLoc* = enum
|
TStorageLoc* = enum
|
||||||
OnUnknown, # location is unknown (stack, heap or static)
|
OnUnknown, # location is unknown (stack, heap or static)
|
||||||
OnStack, # location is on hardware stack
|
OnStack, # location is on hardware stack
|
||||||
|
|
|
||||||
|
|
@ -1452,7 +1452,8 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
of mIncl, mExcl, mCard, mLtSet, mLeSet, mEqSet, mMulSet, mPlusSet, mMinusSet,
|
of mIncl, mExcl, mCard, mLtSet, mLeSet, mEqSet, mMulSet, mPlusSet, mMinusSet,
|
||||||
mInSet:
|
mInSet:
|
||||||
genSetOp(p, e, d, op)
|
genSetOp(p, e, d, op)
|
||||||
of mNewString, mNewStringOfCap, mCopyStr, mCopyStrLast, mExit, mCreateThread:
|
of mCreateThread: genCall(p, e, d)
|
||||||
|
of mNewString, mNewStringOfCap, mCopyStr, mCopyStrLast, mExit:
|
||||||
var opr = e.sons[0].sym
|
var opr = e.sons[0].sym
|
||||||
if lfNoDecl notin opr.loc.flags:
|
if lfNoDecl notin opr.loc.flags:
|
||||||
discard cgsym(p.module, opr.loc.r.ropeToStr)
|
discard cgsym(p.module, opr.loc.r.ropeToStr)
|
||||||
|
|
|
||||||
|
|
@ -666,9 +666,13 @@ proc genProcPrototype(m: BModule, sym: PSym) =
|
||||||
proc genProcNoForward(m: BModule, prc: PSym) =
|
proc genProcNoForward(m: BModule, prc: PSym) =
|
||||||
fillProcLoc(prc)
|
fillProcLoc(prc)
|
||||||
useHeader(m, prc)
|
useHeader(m, prc)
|
||||||
|
if lfImportCompilerProc in prc.loc.flags:
|
||||||
|
# dependency to a compilerproc:
|
||||||
|
discard cgsym(m, prc.name.s)
|
||||||
|
return
|
||||||
genProcPrototype(m, prc)
|
genProcPrototype(m, prc)
|
||||||
if lfNoDecl in prc.loc.Flags: return
|
if lfNoDecl in prc.loc.Flags: nil
|
||||||
if prc.typ.callConv == ccInline:
|
elif prc.typ.callConv == ccInline:
|
||||||
# We add inline procs to the calling module to enable C based inlining.
|
# We add inline procs to the calling module to enable C based inlining.
|
||||||
# This also means that a check with ``gGeneratedSyms`` is wrong, we need
|
# This also means that a check with ``gGeneratedSyms`` is wrong, we need
|
||||||
# a check for ``m.declaredThings``.
|
# a check for ``m.declaredThings``.
|
||||||
|
|
@ -676,7 +680,7 @@ proc genProcNoForward(m: BModule, prc: PSym) =
|
||||||
elif lfDynamicLib in prc.loc.flags:
|
elif lfDynamicLib in prc.loc.flags:
|
||||||
if not ContainsOrIncl(gGeneratedSyms, prc.id):
|
if not ContainsOrIncl(gGeneratedSyms, prc.id):
|
||||||
SymInDynamicLib(findPendingModule(m, prc), prc)
|
SymInDynamicLib(findPendingModule(m, prc), prc)
|
||||||
elif not (sfImportc in prc.flags):
|
elif sfImportc notin prc.flags:
|
||||||
if not ContainsOrIncl(gGeneratedSyms, prc.id):
|
if not ContainsOrIncl(gGeneratedSyms, prc.id):
|
||||||
genProcAux(findPendingModule(m, prc), prc)
|
genProcAux(findPendingModule(m, prc), prc)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ const
|
||||||
procPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
|
procPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
|
||||||
wMagic, wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader,
|
wMagic, wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader,
|
||||||
wCompilerProc, wPure, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge,
|
wCompilerProc, wPure, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge,
|
||||||
wBorrow, wExtern}
|
wBorrow, wExtern, wImportCompilerProc}
|
||||||
converterPragmas* = procPragmas
|
converterPragmas* = procPragmas
|
||||||
methodPragmas* = procPragmas
|
methodPragmas* = procPragmas
|
||||||
macroPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
|
macroPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
|
||||||
|
|
@ -80,6 +80,12 @@ proc MakeExternExport(s: PSym, extname: string) =
|
||||||
setExternName(s, extname)
|
setExternName(s, extname)
|
||||||
incl(s.flags, sfExportc)
|
incl(s.flags, sfExportc)
|
||||||
|
|
||||||
|
proc processImportCompilerProc(s: PSym, extname: string) =
|
||||||
|
setExternName(s, extname)
|
||||||
|
incl(s.flags, sfImportc)
|
||||||
|
excl(s.flags, sfForward)
|
||||||
|
incl(s.loc.flags, lfImportCompilerProc)
|
||||||
|
|
||||||
proc getStrLitNode(c: PContext, n: PNode): PNode =
|
proc getStrLitNode(c: PContext, n: PNode): PNode =
|
||||||
if n.kind != nkExprColonExpr:
|
if n.kind != nkExprColonExpr:
|
||||||
GlobalError(n.info, errStringLiteralExpected)
|
GlobalError(n.info, errStringLiteralExpected)
|
||||||
|
|
@ -401,6 +407,8 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
|
||||||
makeExternExport(sym, getOptionalStr(c, it, sym.name.s))
|
makeExternExport(sym, getOptionalStr(c, it, sym.name.s))
|
||||||
incl(sym.flags, sfUsed) # avoid wrong hints
|
incl(sym.flags, sfUsed) # avoid wrong hints
|
||||||
of wImportc: makeExternImport(sym, getOptionalStr(c, it, sym.name.s))
|
of wImportc: makeExternImport(sym, getOptionalStr(c, it, sym.name.s))
|
||||||
|
of wImportCompilerProc:
|
||||||
|
processImportCompilerProc(sym, getOptionalStr(c, it, sym.name.s))
|
||||||
of wExtern: setExternName(sym, expectStrLit(c, it))
|
of wExtern: setExternName(sym, expectStrLit(c, it))
|
||||||
of wAlign:
|
of wAlign:
|
||||||
if sym.typ == nil: invalidPragma(it)
|
if sym.typ == nil: invalidPragma(it)
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,9 @@ type
|
||||||
wWithout, wXor, wYield,
|
wWithout, wXor, wYield,
|
||||||
|
|
||||||
wColon, wColonColon, wEquals, wDot, wDotDot, wHat, wStar, wMinus,
|
wColon, wColonColon, wEquals, wDot, wDotDot, wHat, wStar, wMinus,
|
||||||
wMagic, wTypeCheck, wFinal, wProfiler, wObjChecks, wImportc, wExportc,
|
wMagic, wTypeCheck, wFinal, wProfiler, wObjChecks,
|
||||||
wExtern,
|
wImportCompilerProc,
|
||||||
|
wImportc, wExportc, wExtern,
|
||||||
wAlign, wNodecl, wPure, wVolatile, wRegister, wSideeffect, wHeader,
|
wAlign, wNodecl, wPure, wVolatile, wRegister, wSideeffect, wHeader,
|
||||||
wNosideeffect, wNoreturn, wMerge, wLib, wDynlib, wCompilerproc, wProcVar,
|
wNosideeffect, wNoreturn, wMerge, wLib, wDynlib, wCompilerproc, wProcVar,
|
||||||
wFatal, wError, wWarning, wHint, wLine, wPush, wPop, wDefine, wUndef,
|
wFatal, wError, wWarning, wHint, wLine, wPush, wPop, wDefine, wUndef,
|
||||||
|
|
@ -79,8 +80,8 @@ const
|
||||||
"yield",
|
"yield",
|
||||||
|
|
||||||
":", "::", "=", ".", "..", "^", "*", "-",
|
":", "::", "=", ".", "..", "^", "*", "-",
|
||||||
"magic", "typecheck", "final", "profiler", "objchecks", "importc",
|
"magic", "typecheck", "final", "profiler", "objchecks",
|
||||||
"exportc", "extern",
|
"importcompilerproc", "importc", "exportc", "extern",
|
||||||
"align", "nodecl", "pure", "volatile", "register", "sideeffect",
|
"align", "nodecl", "pure", "volatile", "register", "sideeffect",
|
||||||
"header", "nosideeffect", "noreturn", "merge", "lib", "dynlib",
|
"header", "nosideeffect", "noreturn", "merge", "lib", "dynlib",
|
||||||
"compilerproc", "procvar", "fatal", "error", "warning", "hint", "line",
|
"compilerproc", "procvar", "fatal", "error", "warning", "hint", "line",
|
||||||
|
|
|
||||||
6
koch.nim
6
koch.nim
|
|
@ -178,7 +178,11 @@ proc clean(args: string) =
|
||||||
|
|
||||||
proc tests(args: string) =
|
proc tests(args: string) =
|
||||||
exec("nimrod cc tests/tester")
|
exec("nimrod cc tests/tester")
|
||||||
exec("tests/tester")
|
exec("tests/tester reject")
|
||||||
|
exec("tests/tester compile")
|
||||||
|
exec("tests/tester examples")
|
||||||
|
exec("tests/tester run")
|
||||||
|
exec("tests/tester merge")
|
||||||
|
|
||||||
proc showHelp() =
|
proc showHelp() =
|
||||||
quit(HelpText % [NimrodVersion & repeatChar(44-len(NimrodVersion)),
|
quit(HelpText % [NimrodVersion & repeatChar(44-len(NimrodVersion)),
|
||||||
|
|
|
||||||
|
|
@ -60,12 +60,13 @@ type
|
||||||
const
|
const
|
||||||
GenericSeqSize = (2 * sizeof(int))
|
GenericSeqSize = (2 * sizeof(int))
|
||||||
|
|
||||||
proc genericAssign(dest, src: Pointer, mt: PNimType) {.importc.}
|
proc genericAssign(dest, src: Pointer, mt: PNimType) {.importCompilerProc.}
|
||||||
proc genericShallowAssign(dest, src: Pointer, mt: PNimType) {.importc.}
|
proc genericShallowAssign(dest, src: Pointer, mt: PNimType) {.
|
||||||
proc incrSeq(seq: PGenSeq, elemSize: int): PGenSeq {.importc, nodecl.}
|
importCompilerProc.}
|
||||||
proc newObj(typ: PNimType, size: int): pointer {.importc, nodecl.}
|
proc incrSeq(seq: PGenSeq, elemSize: int): PGenSeq {.importCompilerProc.}
|
||||||
proc newSeq(typ: PNimType, len: int): pointer {.importc.}
|
proc newObj(typ: PNimType, size: int): pointer {.importCompilerProc.}
|
||||||
proc objectInit(dest: Pointer, typ: PNimType) {.importc.}
|
proc newSeq(typ: PNimType, len: int): pointer {.importCompilerProc.}
|
||||||
|
proc objectInit(dest: Pointer, typ: PNimType) {.importCompilerProc.}
|
||||||
|
|
||||||
template `+!!`(a, b: expr): expr = cast[pointer](cast[TAddress](a) + b)
|
template `+!!`(a, b: expr): expr = cast[pointer](cast[TAddress](a) + b)
|
||||||
|
|
||||||
|
|
@ -228,7 +229,9 @@ iterator fields*(x: TAny): tuple[name: string, any: TAny] =
|
||||||
assert x.rawType.kind in {tyTuple, tyPureObject, tyObject}
|
assert x.rawType.kind in {tyTuple, tyPureObject, tyObject}
|
||||||
var p = x.value
|
var p = x.value
|
||||||
var t = x.rawType
|
var t = x.rawType
|
||||||
if x.rawType.kind == tyObject: t = cast[ptr PNimType](x.value)[]
|
# XXX BUG: does not work yet, however is questionable anyway
|
||||||
|
when false:
|
||||||
|
if x.rawType.kind == tyObject: t = cast[ptr PNimType](x.value)[]
|
||||||
var n = t.node
|
var n = t.node
|
||||||
var ret: seq[tuple[name: cstring, any: TAny]] = @[]
|
var ret: seq[tuple[name: cstring, any: TAny]] = @[]
|
||||||
fieldsAux(p, n, ret)
|
fieldsAux(p, n, ret)
|
||||||
|
|
@ -272,7 +275,9 @@ proc getFieldNode(p: pointer, n: ptr TNimNode,
|
||||||
proc `[]=`*(x: TAny, fieldName: string, value: TAny) =
|
proc `[]=`*(x: TAny, fieldName: string, value: TAny) =
|
||||||
## sets a field of `x`; `x` represents an object or a tuple.
|
## sets a field of `x`; `x` represents an object or a tuple.
|
||||||
var t = x.rawType
|
var t = x.rawType
|
||||||
if x.rawType.kind == tyObject: t = cast[ptr PNimType](x.value)[]
|
# XXX BUG: does not work yet, however is questionable anyway
|
||||||
|
when false:
|
||||||
|
if x.rawType.kind == tyObject: t = cast[ptr PNimType](x.value)[]
|
||||||
assert x.rawType.kind in {tyTuple, tyPureObject, tyObject}
|
assert x.rawType.kind in {tyTuple, tyPureObject, tyObject}
|
||||||
var n = getFieldNode(x.value, t.node, fieldname)
|
var n = getFieldNode(x.value, t.node, fieldname)
|
||||||
if n != nil:
|
if n != nil:
|
||||||
|
|
@ -284,7 +289,9 @@ proc `[]=`*(x: TAny, fieldName: string, value: TAny) =
|
||||||
proc `[]`*(x: TAny, fieldName: string): TAny =
|
proc `[]`*(x: TAny, fieldName: string): TAny =
|
||||||
## gets a field of `x`; `x` represents an object or a tuple.
|
## gets a field of `x`; `x` represents an object or a tuple.
|
||||||
var t = x.rawType
|
var t = x.rawType
|
||||||
if x.rawType.kind == tyObject: t = cast[ptr PNimType](x.value)[]
|
# XXX BUG: does not work yet, however is questionable anyway
|
||||||
|
when false:
|
||||||
|
if x.rawType.kind == tyObject: t = cast[ptr PNimType](x.value)[]
|
||||||
assert x.rawType.kind in {tyTuple, tyPureObject, tyObject}
|
assert x.rawType.kind in {tyTuple, tyPureObject, tyObject}
|
||||||
var n = getFieldNode(x.value, t.node, fieldname)
|
var n = getFieldNode(x.value, t.node, fieldname)
|
||||||
if n != nil:
|
if n != nil:
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,14 @@
|
||||||
## This program verifies Nimrod against the testcases.
|
## This program verifies Nimrod against the testcases.
|
||||||
|
|
||||||
import
|
import
|
||||||
parseutils, strutils, pegs, os, osproc, streams, parsecfg, browsers, json
|
parseutils, strutils, pegs, os, osproc, streams, parsecfg, browsers, json,
|
||||||
|
marshal
|
||||||
|
|
||||||
const
|
const
|
||||||
cmdTemplate = r"nimrod cc --hints:on $# $#"
|
cmdTemplate = r"nimrod cc --hints:on $# $#"
|
||||||
resultsFile = "testresults.html"
|
resultsFile = "testresults.html"
|
||||||
jsonFile = "testresults.json"
|
jsonFile = "testresults.json"
|
||||||
|
Usage = "usage: tester reject|compile|examples|run|merge [nimrod options]"
|
||||||
|
|
||||||
type
|
type
|
||||||
TTestAction = enum
|
TTestAction = enum
|
||||||
|
|
@ -141,6 +143,12 @@ proc initResults: TResults =
|
||||||
result.skipped = 0
|
result.skipped = 0
|
||||||
result.data = ""
|
result.data = ""
|
||||||
|
|
||||||
|
proc readResults(filename: string): TResults =
|
||||||
|
result = marshal.to[TResults](readFile(filename))
|
||||||
|
|
||||||
|
proc writeResults(filename: string, r: TResults) =
|
||||||
|
writeFile(filename, $$r)
|
||||||
|
|
||||||
proc `$`(x: TResults): string =
|
proc `$`(x: TResults): string =
|
||||||
result = ("Tests passed: $1 / $3 <br />\n" &
|
result = ("Tests passed: $1 / $3 <br />\n" &
|
||||||
"Tests skipped: $2 / $3 <br />\n") %
|
"Tests skipped: $2 / $3 <br />\n") %
|
||||||
|
|
@ -275,22 +283,45 @@ proc outputJSON(reject, compile, run: TResults) =
|
||||||
var s = pretty(doc)
|
var s = pretty(doc)
|
||||||
writeFile(jsonFile, s)
|
writeFile(jsonFile, s)
|
||||||
|
|
||||||
var options = ""
|
proc main(action: string) =
|
||||||
var rejectRes = initResults()
|
const
|
||||||
var compileRes = initResults()
|
compileJson = "compile.json"
|
||||||
var runRes = initResults()
|
runJson = "run.json"
|
||||||
|
rejectJson = "reject.json"
|
||||||
|
var options = ""
|
||||||
|
for i in 2.. paramCount():
|
||||||
|
add(options, " ")
|
||||||
|
add(options, paramStr(i))
|
||||||
|
|
||||||
for i in 1.. paramCount():
|
case action
|
||||||
add(options, " ")
|
of "reject":
|
||||||
add(options, paramStr(i))
|
var rejectRes = initResults()
|
||||||
|
reject(rejectRes, "tests/reject", options)
|
||||||
|
writeResults(rejectJson, rejectRes)
|
||||||
|
of "compile":
|
||||||
|
var compileRes = initResults()
|
||||||
|
compile(compileRes, "tests/accept/compile/t*.nim", options)
|
||||||
|
writeResults(compileJson, compileRes)
|
||||||
|
of "examples":
|
||||||
|
var compileRes = readResults(compileJson)
|
||||||
|
compileExample(compileRes, "lib/pure/*.nim", options)
|
||||||
|
compileExample(compileRes, "examples/*.nim", options)
|
||||||
|
compileExample(compileRes, "examples/gtk/*.nim", options)
|
||||||
|
writeResults(compileJson, compileRes)
|
||||||
|
of "run":
|
||||||
|
var runRes = initResults()
|
||||||
|
run(runRes, "tests/accept/run", options)
|
||||||
|
writeResults(runJson, runRes)
|
||||||
|
of "merge":
|
||||||
|
var rejectRes = readResults(rejectJson)
|
||||||
|
var compileRes = readResults(compileJson)
|
||||||
|
var runRes = readResults(runJson)
|
||||||
|
listResults(rejectRes, compileRes, runRes)
|
||||||
|
outputJSON(rejectRes, compileRes, runRes)
|
||||||
|
else:
|
||||||
|
quit usage
|
||||||
|
|
||||||
reject(rejectRes, "tests/reject", options)
|
if paramCount() == 0:
|
||||||
compile(compileRes, "tests/accept/compile/t*.nim", options)
|
quit usage
|
||||||
compileExample(compileRes, "lib/pure/*.nim", options)
|
main(paramStr(1))
|
||||||
compileExample(compileRes, "examples/*.nim", options)
|
|
||||||
compileExample(compileRes, "examples/gtk/*.nim", options)
|
|
||||||
run(runRes, "tests/accept/run", options)
|
|
||||||
listResults(rejectRes, compileRes, runRes)
|
|
||||||
outputJSON(rejectRes, compileRes, runRes)
|
|
||||||
openDefaultBrowser(resultsFile)
|
|
||||||
|
|
||||||
|
|
|
||||||
1
todo.txt
1
todo.txt
|
|
@ -3,6 +3,7 @@ High priority (version 0.8.12)
|
||||||
* test threads on windows; thread analysis needs to be even more restrictive!
|
* test threads on windows; thread analysis needs to be even more restrictive!
|
||||||
* implement message passing built-ins: channels/queues
|
* implement message passing built-ins: channels/queues
|
||||||
* bug: {:}.toTable[int, string]()
|
* bug: {:}.toTable[int, string]()
|
||||||
|
* test tester
|
||||||
|
|
||||||
|
|
||||||
version 0.9.0
|
version 0.9.0
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue