summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xcompiler/ast.nim3
-rwxr-xr-xcompiler/ccgexprs.nim3
-rwxr-xr-xcompiler/cgen.nim12
-rwxr-xr-xcompiler/pragmas.nim10
-rwxr-xr-xcompiler/wordrecg.nim9
-rwxr-xr-xkoch.nim6
-rw-r--r--lib/core/typeinfo.nim25
-rwxr-xr-xtests/tester.nim65
-rwxr-xr-xtodo.txt1
9 files changed, 96 insertions, 38 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 905576655..69269be84 100755
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -406,7 +406,8 @@ type
     lfNoDecl,                 # do not declare it in C
     lfDynamicLib,             # link symbol to dynamic library
     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 
     OnUnknown,                # location is unknown (stack, heap or static)
     OnStack,                  # location is on hardware stack
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 38cfafcfa..88284e9fb 100755
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -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,
      mInSet:
     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
     if lfNoDecl notin opr.loc.flags:
       discard cgsym(p.module, opr.loc.r.ropeToStr)
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 60c052d5d..02fcce980 100755
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -666,17 +666,21 @@ proc genProcPrototype(m: BModule, sym: PSym) =
 proc genProcNoForward(m: BModule, prc: PSym) = 
   fillProcLoc(prc)
   useHeader(m, prc)
+  if lfImportCompilerProc in prc.loc.flags:
+    # dependency to a compilerproc:
+    discard cgsym(m, prc.name.s)
+    return
   genProcPrototype(m, prc)
-  if lfNoDecl in prc.loc.Flags: return 
-  if prc.typ.callConv == ccInline: 
+  if lfNoDecl in prc.loc.Flags: nil
+  elif prc.typ.callConv == ccInline:
     # 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
     # a check for ``m.declaredThings``.
     if not ContainsOrIncl(m.declaredThings, prc.id): genProcAux(m, prc)
-  elif lfDynamicLib in prc.loc.flags: 
+  elif lfDynamicLib in prc.loc.flags:
     if not ContainsOrIncl(gGeneratedSyms, prc.id): 
       SymInDynamicLib(findPendingModule(m, prc), prc)
-  elif not (sfImportc in prc.flags): 
+  elif sfImportc notin prc.flags: 
     if not ContainsOrIncl(gGeneratedSyms, prc.id): 
       genProcAux(findPendingModule(m, prc), prc)
   
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index 7ca980dcc..754a88fda 100755
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -22,7 +22,7 @@ const
   procPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, 
     wMagic, wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, 
     wCompilerProc, wPure, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge, 
-    wBorrow, wExtern}
+    wBorrow, wExtern, wImportCompilerProc}
   converterPragmas* = procPragmas
   methodPragmas* = procPragmas
   macroPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, 
@@ -80,6 +80,12 @@ proc MakeExternExport(s: PSym, extname: string) =
   setExternName(s, extname)
   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 =
   if n.kind != nkExprColonExpr: 
     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))
             incl(sym.flags, sfUsed) # avoid wrong hints
           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 wAlign: 
             if sym.typ == nil: invalidPragma(it)
diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim
index 088972e0e..5335c2ccf 100755
--- a/compiler/wordrecg.nim
+++ b/compiler/wordrecg.nim
@@ -33,8 +33,9 @@ type
     wWithout, wXor, wYield,
     
     wColon, wColonColon, wEquals, wDot, wDotDot, wHat, wStar, wMinus, 
-    wMagic, wTypeCheck, wFinal, wProfiler, wObjChecks, wImportc, wExportc, 
-    wExtern,
+    wMagic, wTypeCheck, wFinal, wProfiler, wObjChecks,
+    wImportCompilerProc,
+    wImportc, wExportc, wExtern,
     wAlign, wNodecl, wPure, wVolatile, wRegister, wSideeffect, wHeader, 
     wNosideeffect, wNoreturn, wMerge, wLib, wDynlib, wCompilerproc, wProcVar, 
     wFatal, wError, wWarning, wHint, wLine, wPush, wPop, wDefine, wUndef, 
@@ -79,8 +80,8 @@ const
     "yield",
 
     ":", "::", "=", ".", "..", "^", "*", "-",
-    "magic", "typecheck", "final", "profiler", "objchecks", "importc", 
-    "exportc", "extern",
+    "magic", "typecheck", "final", "profiler", "objchecks", 
+    "importcompilerproc", "importc", "exportc", "extern",
     "align", "nodecl", "pure", "volatile", "register", "sideeffect", 
     "header", "nosideeffect", "noreturn", "merge", "lib", "dynlib", 
     "compilerproc", "procvar", "fatal", "error", "warning", "hint", "line", 
diff --git a/koch.nim b/koch.nim
index 29fa86cb3..8faee0cc7 100755
--- a/koch.nim
+++ b/koch.nim
@@ -178,7 +178,11 @@ proc clean(args: string) =
 
 proc tests(args: string) =
   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() = 
   quit(HelpText % [NimrodVersion & repeatChar(44-len(NimrodVersion)), 
diff --git a/lib/core/typeinfo.nim b/lib/core/typeinfo.nim
index 9de3fde16..3434cd9d4 100644
--- a/lib/core/typeinfo.nim
+++ b/lib/core/typeinfo.nim
@@ -60,12 +60,13 @@ type
 const
   GenericSeqSize = (2 * sizeof(int))
 
-proc genericAssign(dest, src: Pointer, mt: PNimType) {.importc.}
-proc genericShallowAssign(dest, src: Pointer, mt: PNimType) {.importc.}
-proc incrSeq(seq: PGenSeq, elemSize: int): PGenSeq {.importc, nodecl.}
-proc newObj(typ: PNimType, size: int): pointer {.importc, nodecl.}
-proc newSeq(typ: PNimType, len: int): pointer {.importc.}
-proc objectInit(dest: Pointer, typ: PNimType) {.importc.}
+proc genericAssign(dest, src: Pointer, mt: PNimType) {.importCompilerProc.}
+proc genericShallowAssign(dest, src: Pointer, mt: PNimType) {.
+  importCompilerProc.}
+proc incrSeq(seq: PGenSeq, elemSize: int): PGenSeq {.importCompilerProc.}
+proc newObj(typ: PNimType, size: int): pointer {.importCompilerProc.}
+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)
 
@@ -228,7 +229,9 @@ iterator fields*(x: TAny): tuple[name: string, any: TAny] =
   assert x.rawType.kind in {tyTuple, tyPureObject, tyObject}
   var p = x.value
   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 ret: seq[tuple[name: cstring, any: TAny]] = @[]
   fieldsAux(p, n, ret)
@@ -272,7 +275,9 @@ proc getFieldNode(p: pointer, n: ptr TNimNode,
 proc `[]=`*(x: TAny, fieldName: string, value: TAny) =
   ## sets a field of `x`; `x` represents an object or a tuple.
   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}
   var n = getFieldNode(x.value, t.node, fieldname)
   if n != nil:
@@ -284,7 +289,9 @@ proc `[]=`*(x: TAny, fieldName: string, value: TAny) =
 proc `[]`*(x: TAny, fieldName: string): TAny =
   ## gets a field of `x`; `x` represents an object or a tuple.
   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}
   var n = getFieldNode(x.value, t.node, fieldname)
   if n != nil:
diff --git a/tests/tester.nim b/tests/tester.nim
index 5908b8e29..3883969b9 100755
--- a/tests/tester.nim
+++ b/tests/tester.nim
@@ -10,12 +10,14 @@
 ## This program verifies Nimrod against the testcases.
 
 import
-  parseutils, strutils, pegs, os, osproc, streams, parsecfg, browsers, json
+  parseutils, strutils, pegs, os, osproc, streams, parsecfg, browsers, json,
+  marshal
 
 const
   cmdTemplate = r"nimrod cc --hints:on $# $#"
   resultsFile = "testresults.html"
   jsonFile = "testresults.json"
+  Usage = "usage: tester reject|compile|examples|run|merge [nimrod options]"
 
 type
   TTestAction = enum
@@ -141,6 +143,12 @@ proc initResults: TResults =
   result.skipped = 0
   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 = 
   result = ("Tests passed: $1 / $3 <br />\n" &
             "Tests skipped: $2 / $3 <br />\n") %
@@ -275,22 +283,45 @@ proc outputJSON(reject, compile, run: TResults) =
   var s = pretty(doc)
   writeFile(jsonFile, s)
   
-var options = ""
-var rejectRes = initResults()
-var compileRes = initResults()
-var runRes = initResults()
+proc main(action: string) =
+  const 
+    compileJson = "compile.json"
+    runJson = "run.json"
+    rejectJson = "reject.json"
+  var options = ""
+  for i in 2.. paramCount():
+    add(options, " ")
+    add(options, paramStr(i))
   
-for i in 1.. paramCount():
-  add(options, " ")
-  add(options, paramStr(i))
+  case action
+  of "reject":
+    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)
-compile(compileRes, "tests/accept/compile/t*.nim", options)
-compileExample(compileRes, "lib/pure/*.nim", options)
-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)
+if paramCount() == 0:
+  quit usage
+main(paramStr(1))
 
diff --git a/todo.txt b/todo.txt
index 3308309c7..384f493ea 100755
--- a/todo.txt
+++ b/todo.txt
@@ -3,6 +3,7 @@ High priority (version 0.8.12)
 * test threads on windows; thread analysis needs to be even more restrictive!
 * implement message passing built-ins: channels/queues
 * bug: {:}.toTable[int, string]()
+* test tester
 
 
 version 0.9.0