mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 09:24:36 +00:00
JS codegen enhancements; still unusable
This commit is contained in:
@@ -546,11 +546,12 @@ proc genTryStmt(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
if i > 1: app(epart, '}' & tnl)
|
||||
else:
|
||||
orExpr = nil
|
||||
useMagic(p, "isObj")
|
||||
for j in countup(0, blen - 2):
|
||||
if (n.sons[i].sons[j].kind != nkType):
|
||||
InternalError(n.info, "genTryStmt")
|
||||
if orExpr != nil: app(orExpr, "||")
|
||||
appf(orExpr, "($1.exc.m_type == $2)",
|
||||
appf(orExpr, "isObj($1.exc.m_type, $2)",
|
||||
[safePoint, genTypeInfo(p, n.sons[i].sons[j].typ)])
|
||||
if i > 1: app(epart, "else ")
|
||||
appf(epart, "if ($1.exc && $2) {$n", [safePoint, orExpr])
|
||||
@@ -791,7 +792,7 @@ proc genSwap(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
gen(p, n.sons[2], b)
|
||||
inc(p.unique)
|
||||
var tmp = ropef("Tmp$1", [toRope(p.unique)])
|
||||
case mapType(n.sons[1].typ)
|
||||
case mapType(skipTypes(n.sons[1].typ, abstractVar))
|
||||
of etyBaseIndex:
|
||||
inc(p.unique)
|
||||
var tmp2 = ropef("Tmp$1", [toRope(p.unique)])
|
||||
@@ -804,24 +805,36 @@ proc genSwap(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
if b.com != nil: appf(r.com, "$1;$n", [b.com])
|
||||
appf(r.com, "var $1 = $2; $2 = $3; $3 = $1", [tmp, a.res, b.res])
|
||||
|
||||
proc getFieldPosition(f: PNode): int =
|
||||
case f.kind
|
||||
of nkIntLit..nkUInt64Lit: result = int(f.intVal)
|
||||
of nkSym: result = f.sym.position
|
||||
else: InternalError(f.info, "genFieldPosition")
|
||||
|
||||
proc genFieldAddr(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
var a: TCompRes
|
||||
r.kind = etyBaseIndex
|
||||
var b = if n.kind == nkHiddenAddr: n.sons[0] else: n
|
||||
gen(p, b.sons[0], a)
|
||||
if b.sons[1].kind != nkSym: InternalError(b.sons[1].info, "genFieldAddr")
|
||||
var f = b.sons[1].sym
|
||||
if f.loc.r == nil: f.loc.r = mangleName(f)
|
||||
r.res = makeCString(ropeToStr(f.loc.r))
|
||||
if skipTypes(b.sons[0].typ, abstractVarRange).kind == tyTuple:
|
||||
r.res = makeCString("Field" & $getFieldPosition(b.sons[1]))
|
||||
else:
|
||||
if b.sons[1].kind != nkSym: InternalError(b.sons[1].info, "genFieldAddr")
|
||||
var f = b.sons[1].sym
|
||||
if f.loc.r == nil: f.loc.r = mangleName(f)
|
||||
r.res = makeCString(ropeToStr(f.loc.r))
|
||||
r.com = mergeExpr(a)
|
||||
|
||||
proc genFieldAccess(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
r.kind = etyNone
|
||||
gen(p, n.sons[0], r)
|
||||
if n.sons[1].kind != nkSym: InternalError(n.sons[1].info, "genFieldAddr")
|
||||
var f = n.sons[1].sym
|
||||
if f.loc.r == nil: f.loc.r = mangleName(f)
|
||||
r.res = ropef("$1.$2", [r.res, f.loc.r])
|
||||
if skipTypes(n.sons[0].typ, abstractVarRange).kind == tyTuple:
|
||||
r.res = ropef("$1.Field$2", [r.res, getFieldPosition(n.sons[1]).toRope])
|
||||
else:
|
||||
if n.sons[1].kind != nkSym: InternalError(n.sons[1].info, "genFieldAddr")
|
||||
var f = n.sons[1].sym
|
||||
if f.loc.r == nil: f.loc.r = mangleName(f)
|
||||
r.res = ropef("$1.$2", [r.res, f.loc.r])
|
||||
|
||||
proc genCheckedFieldAddr(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
genFieldAddr(p, n.sons[0], r) # XXX
|
||||
@@ -884,11 +897,17 @@ proc genAddr(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
genCheckedFieldAddr(p, n, r)
|
||||
of nkDotExpr:
|
||||
genFieldAddr(p, n, r)
|
||||
of nkBracketExpr:
|
||||
genArrayAddr(p, n, r)
|
||||
of nkBracketExpr:
|
||||
var ty = skipTypes(n.sons[0].typ, abstractVarRange)
|
||||
if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.sons[0], abstractVarRange)
|
||||
case ty.kind
|
||||
of tyArray, tyArrayConstr, tyOpenArray, tySequence, tyString, tyCString:
|
||||
genArrayAddr(p, n, r)
|
||||
of tyTuple:
|
||||
genFieldAddr(p, n, r)
|
||||
else: InternalError(n.info, "expr(nkBracketExpr, " & $ty.kind & ')')
|
||||
else: InternalError(n.info, "genAddr")
|
||||
|
||||
|
||||
proc genSym(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
var s = n.sym
|
||||
case s.kind
|
||||
@@ -956,6 +975,7 @@ proc genCall(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
genArgs(p, n, r)
|
||||
|
||||
proc genEcho(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
useMagic(p, "rawEcho")
|
||||
app(r.res, "rawEcho")
|
||||
genArgs(p, n, r)
|
||||
|
||||
@@ -1146,6 +1166,25 @@ proc genRepr(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
# XXX:
|
||||
internalError(n.info, "genRepr: Not implemented")
|
||||
|
||||
proc genOf(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
var x: TCompRes
|
||||
let t = n.sons[2].typ
|
||||
gen(p, n.sons[1], x)
|
||||
if tfFinal in t.flags:
|
||||
r.res = ropef("($1.m_type == $2)", [x.res, genTypeInfo(p, t)])
|
||||
else:
|
||||
useMagic(p, "isObj")
|
||||
r.res = ropef("isObj($1.m_type, $2)", [x.res, genTypeInfo(p, t)])
|
||||
r.com = mergeExpr(r.com, x.com)
|
||||
|
||||
proc genReset(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
var x: TCompRes
|
||||
useMagic(p, "genericReset")
|
||||
gen(p, n.sons[1], x)
|
||||
r.res = ropef("$1 = genericReset($1, $2)", [x.res,
|
||||
genTypeInfo(p, n.sons[1].typ)])
|
||||
r.com = mergeExpr(r.com, x.com)
|
||||
|
||||
proc genMagic(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
var
|
||||
a: TCompRes
|
||||
@@ -1216,6 +1255,8 @@ proc genMagic(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
of mNLen..mNError:
|
||||
localError(n.info, errCannotGenerateCodeForX, n.sons[0].sym.name.s)
|
||||
of mNewSeq: binaryStmt(p, n, r, "", "$1 = new Array($2)")
|
||||
of mOf: genOf(p, n, r)
|
||||
of mReset: genReset(p, n, r)
|
||||
of mEcho: genEcho(p, n, r)
|
||||
of mSlurp, mStaticExec:
|
||||
localError(n.info, errXMustBeCompileTime, n.sons[0].sym.name.s)
|
||||
@@ -1252,19 +1293,17 @@ proc genArrayConstr(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
app(r.res, a.res)
|
||||
app(r.res, "]")
|
||||
|
||||
proc genRecordConstr(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
proc genTupleConstr(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
var a: TCompRes
|
||||
var i = 0
|
||||
var length = sonsLen(n)
|
||||
r.res = toRope("{")
|
||||
while i < length:
|
||||
for i in countup(0, sonsLen(n) - 1):
|
||||
if i > 0: app(r.res, ", ")
|
||||
if (n.sons[i].kind != nkSym):
|
||||
internalError(n.sons[i].info, "genRecordConstr")
|
||||
gen(p, n.sons[i + 1], a)
|
||||
var it = n.sons[i]
|
||||
if it.kind == nkExprColonExpr: it = it.sons[1]
|
||||
gen(p, it, a)
|
||||
r.com = mergeExpr(r.com, a.com)
|
||||
appf(r.res, "$1: $2", [mangleName(n.sons[i].sym), a.res])
|
||||
inc(i, 2)
|
||||
appf(r.res, "Field$1: $2", [i.toRope, a.res])
|
||||
r.res.app("}")
|
||||
|
||||
proc genConv(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
var dest = skipTypes(n.typ, abstractVarRange)
|
||||
@@ -1414,9 +1453,6 @@ proc genStmt(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
genSym(p, n.sons[namePos], r2)
|
||||
else:
|
||||
genLineDir(p, n, r)
|
||||
if n.sons[0].kind == nkSym:
|
||||
if n.sons[0].sym.loc.r == nil:
|
||||
n.sons[0].sym.loc.r = toRope(n.sons[0].sym.name.s)
|
||||
gen(p, n, r)
|
||||
app(r.res, ';' & tnl)
|
||||
|
||||
@@ -1460,7 +1496,7 @@ proc gen(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
genCall(p, n, r)
|
||||
of nkCurly: genSetConstr(p, n, r)
|
||||
of nkBracket: genArrayConstr(p, n, r)
|
||||
of nkPar: genRecordConstr(p, n, r)
|
||||
of nkPar: genTupleConstr(p, n, r)
|
||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv: genConv(p, n, r)
|
||||
of nkAddr, nkHiddenAddr: genAddr(p, n, r)
|
||||
of nkDerefExpr, nkHiddenDeref: genDeref(p, n, r)
|
||||
@@ -1477,8 +1513,14 @@ proc gen(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
of nkStmtListExpr: genStmtListExpr(p, n, r)
|
||||
of nkEmpty: nil
|
||||
of nkLambdaKinds:
|
||||
# XXX not correct, as we need to put it into the proper scope!
|
||||
gen(p, n.sons[namePos], r)
|
||||
let s = n.sons[namePos].sym
|
||||
discard mangleName(s)
|
||||
r.res = s.loc.r
|
||||
if lfNoDecl in s.loc.flags or s.magic != mNone or isGenericRoutine(s): nil
|
||||
elif not p.g.generatedSyms.containsOrIncl(s.id):
|
||||
var r2: TCompRes
|
||||
genProc(p, s, r2)
|
||||
app(r.com, mergeStmt(r2))
|
||||
of nkMetaNode: gen(p, n.sons[0], r)
|
||||
of nkType: r.res = genTypeInfo(p, n.typ)
|
||||
else: InternalError(n.info, "gen: unknown node type: " & $n.kind)
|
||||
|
||||
@@ -131,7 +131,9 @@ when has_LLVM_Backend:
|
||||
proc CommandCompileToEcmaScript =
|
||||
incl(gGlobalOptions, optSafeCode)
|
||||
setTarget(osEcmaScript, cpuEcmaScript)
|
||||
initDefines()
|
||||
#initDefines()
|
||||
DefineSymbol("nimrod") # 'nimrod' is always defined
|
||||
DefineSymbol("ecmascript")
|
||||
semanticPasses()
|
||||
registerPass(ecmasgenPass())
|
||||
compileProject()
|
||||
|
||||
@@ -98,9 +98,14 @@ proc HandleCmdLine() =
|
||||
formatFloat(epochTime() - start, ffDecimal, 3),
|
||||
formatSize(getTotalMem())])
|
||||
if optRun in gGlobalOptions:
|
||||
var ex = quoteIfContainsWhite(
|
||||
if gCmd == cmdCompileToEcmaScript:
|
||||
var ex = quoteIfContainsWhite(
|
||||
completeCFilePath(changeFileExt(gProjectFull, "js").prependCurDir))
|
||||
execExternalProgram("node " & ex & ' ' & arguments)
|
||||
else:
|
||||
var ex = quoteIfContainsWhite(
|
||||
changeFileExt(gProjectFull, exeExt).prependCurDir)
|
||||
execExternalProgram(ex & ' ' & arguments)
|
||||
execExternalProgram(ex & ' ' & arguments)
|
||||
|
||||
#GC_disableMarkAndSweep()
|
||||
|
||||
|
||||
@@ -145,6 +145,7 @@ Define Effect
|
||||
``useRealtimeGC`` Enables support of Nimrod's GC for *soft* realtime
|
||||
systems. See the documentation of the `gc <gc.html>`_
|
||||
for further information.
|
||||
``nodejs`` The EcmaScript target is actually ``node.js``.
|
||||
================== =========================================================
|
||||
|
||||
|
||||
|
||||
@@ -35,7 +35,11 @@ proc `!$`*(h: THash): THash {.inline.} =
|
||||
proc hashData*(Data: Pointer, Size: int): THash =
|
||||
## hashes an array of bytes of size `size`
|
||||
var h: THash = 0
|
||||
var p = cast[cstring](Data)
|
||||
when defined(ecmascript):
|
||||
var p: cstring
|
||||
asm """`p` = `Data`;"""
|
||||
else:
|
||||
var p = cast[cstring](Data)
|
||||
var i = 0
|
||||
var s = size
|
||||
while s > 0:
|
||||
@@ -44,9 +48,24 @@ proc hashData*(Data: Pointer, Size: int): THash =
|
||||
Dec(s)
|
||||
result = !$h
|
||||
|
||||
when defined(ecmascript):
|
||||
var objectID = 0
|
||||
|
||||
proc hash*(x: Pointer): THash {.inline.} =
|
||||
## efficient hashing of pointers
|
||||
result = (cast[THash](x)) shr 3 # skip the alignment
|
||||
when defined(ecmascript):
|
||||
asm """
|
||||
if (typeof `x` == "object") {
|
||||
if ("_NimID" in `x`)
|
||||
`result` = `x`["_NimID"];
|
||||
else {
|
||||
`result` = ++`objectID`;
|
||||
`x`["_NimID"] = `result`;
|
||||
}
|
||||
}
|
||||
"""
|
||||
else:
|
||||
result = (cast[THash](x)) shr 3 # skip the alignment
|
||||
|
||||
proc hash*(x: int): THash {.inline.} =
|
||||
## efficient hashing of integers
|
||||
|
||||
@@ -7,7 +7,11 @@
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
proc alert*(s: cstring) {.importc, nodecl.}
|
||||
when defined(nodejs):
|
||||
proc alert*(s: cstring) {.importc: "console.log", nodecl.}
|
||||
else:
|
||||
proc alert*(s: cstring) {.importc, nodecl.}
|
||||
|
||||
proc log*(s: cstring) {.importc: "console.log", nodecl.}
|
||||
|
||||
type
|
||||
@@ -100,7 +104,7 @@ proc raiseException(e: ref E_Base, ename: cstring) {.
|
||||
alert(buf)
|
||||
asm """throw `e`;"""
|
||||
|
||||
proc reraiseException() =
|
||||
proc reraiseException() {.compilerproc, noStackFrame.} =
|
||||
if excHandler == nil:
|
||||
raise newException(ENoExceptionToReraise, "no exception to reraise")
|
||||
else:
|
||||
@@ -295,27 +299,40 @@ type
|
||||
setAttribute*: proc (name, value: cstring)
|
||||
setAttributeNode*: proc (attr: ref TNode)
|
||||
|
||||
var
|
||||
document {.importc, nodecl.}: ref TDocument
|
||||
when defined(nodejs):
|
||||
proc ewriteln(x: cstring) = log(x)
|
||||
|
||||
proc rawEcho {.compilerproc, nostackframe.} =
|
||||
asm """
|
||||
var buf = "";
|
||||
for (var i = 0; i < arguments.length; ++i) {
|
||||
buf += `toEcmaStr`(arguments[i]);
|
||||
}
|
||||
console.log(buf);
|
||||
"""
|
||||
|
||||
proc ewriteln(x: cstring) =
|
||||
var node = document.getElementsByTagName("body")[0]
|
||||
if node != nil:
|
||||
node.appendChild(document.createTextNode(x))
|
||||
else:
|
||||
var
|
||||
document {.importc, nodecl.}: ref TDocument
|
||||
|
||||
proc ewriteln(x: cstring) =
|
||||
var node = document.getElementsByTagName("body")[0]
|
||||
if node != nil:
|
||||
node.appendChild(document.createTextNode(x))
|
||||
node.appendChild(document.createElement("br"))
|
||||
else:
|
||||
raise newException(EInvalidValue, "<body> element does not exist yet!")
|
||||
|
||||
proc rawEcho {.compilerproc.} =
|
||||
var node = document.getElementsByTagName("body")[0]
|
||||
if node == nil: raise newException(EIO, "<body> element does not exist yet!")
|
||||
asm """
|
||||
for (var i = 0; i < arguments.length; ++i) {
|
||||
var x = `toEcmaStr`(arguments[i]);
|
||||
`node`.appendChild(document.createTextNode(x))
|
||||
}
|
||||
"""
|
||||
node.appendChild(document.createElement("br"))
|
||||
else:
|
||||
raise newException(EInvalidValue, "<body> element does not exist yet!")
|
||||
|
||||
proc rawEcho {.compilerproc.} =
|
||||
var node = document.getElementsByTagName("body")[0]
|
||||
if node == nil: raise newException(EIO, "<body> element does not exist yet!")
|
||||
asm """
|
||||
for (var i = 0; i < arguments.length; ++i) {
|
||||
var x = `toEcmaStr`(arguments[i]);
|
||||
`node`.appendChild(document.createTextNode(x))
|
||||
}
|
||||
"""
|
||||
node.appendChild(document.createElement("br"))
|
||||
|
||||
# Arithmetic:
|
||||
proc addInt(a, b: int): int {.noStackFrame, compilerproc.} =
|
||||
@@ -474,7 +491,7 @@ proc isFatPointer(ti: PNimType): bool =
|
||||
|
||||
proc NimCopy(x: pointer, ti: PNimType): pointer {.compilerproc.}
|
||||
|
||||
proc NimCopyAux(dest, src: Pointer, n: ptr TNimNode) {.exportc.} =
|
||||
proc NimCopyAux(dest, src: Pointer, n: ptr TNimNode) {.compilerproc.} =
|
||||
case n.kind
|
||||
of nkNone: sysAssert(false, "NimCopyAux")
|
||||
of nkSlot:
|
||||
@@ -525,6 +542,37 @@ proc NimCopy(x: pointer, ti: PNimType): pointer =
|
||||
else:
|
||||
result = x
|
||||
|
||||
proc genericReset(x: Pointer, ti: PNimType): pointer {.compilerproc.} =
|
||||
case ti.kind
|
||||
of tyPtr, tyRef, tyVar, tyNil:
|
||||
if not isFatPointer(ti):
|
||||
result = nil
|
||||
else:
|
||||
asm """
|
||||
`result` = [null, 0];
|
||||
"""
|
||||
of tySet:
|
||||
asm """
|
||||
`result` = {};
|
||||
"""
|
||||
of tyTuple, tyObject:
|
||||
if ti.kind == tyObject:
|
||||
asm "`result` = {m_type: `ti`};"
|
||||
else:
|
||||
asm "`result` = {};"
|
||||
of tySequence, tyOpenArray:
|
||||
asm """
|
||||
`result` = [];
|
||||
"""
|
||||
of tyArrayConstr, tyArray:
|
||||
asm """
|
||||
`result` = new Array(`x`.length);
|
||||
for (var i = 0; i < `x`.length; ++i) {
|
||||
`result`[i] = genericReset(`x`[i], `ti`.base);
|
||||
}
|
||||
"""
|
||||
else:
|
||||
result = nil
|
||||
|
||||
proc ArrayConstr(len: int, value: pointer, typ: PNimType): pointer {.
|
||||
noStackFrame, compilerproc.} =
|
||||
@@ -552,4 +600,13 @@ proc chckObj(obj, subclass: PNimType) {.compilerproc.} =
|
||||
raise newException(EInvalidObjectConversion, "invalid object conversion")
|
||||
x = x.base
|
||||
|
||||
proc isObj(obj, subclass: PNimType): bool {.compilerproc.} =
|
||||
# checks if obj is of type subclass:
|
||||
var x = obj
|
||||
if x == subclass: return true # optimized fast path
|
||||
while x != subclass:
|
||||
if x == nil: return false
|
||||
x = x.base
|
||||
return true
|
||||
|
||||
{.pop.}
|
||||
|
||||
@@ -169,6 +169,22 @@ proc compileDebuggerTests(r: var TResults, options: string) =
|
||||
compileSingleTest(r, "tools/nimgrep", options &
|
||||
" --debugger:on")
|
||||
|
||||
# ------------------------- JS tests ------------------------------------------
|
||||
|
||||
proc runJsTests(r: var TResults, options: string) =
|
||||
template test(filename: expr): stmt =
|
||||
runSingleTest(r, filename, options & " -d:nodejs", targetJS)
|
||||
runSingleTest(r, filename, options & " -d:nodejs -d:release", targetJS)
|
||||
|
||||
# tactiontable, texceptions, texcpt1, texcsub, tfinally, tfinally2,
|
||||
# tfinally3
|
||||
for t in os.walkFiles("tests/js/t*.nim"):
|
||||
test(t)
|
||||
test "tests/run/tactiontable"
|
||||
test "tests/run/tmultim1"
|
||||
test "tests/run/tmultim3"
|
||||
test "tests/run/tmultim4"
|
||||
|
||||
# ------------------------- register special tests here -----------------------
|
||||
proc runSpecialTests(r: var TResults, options: string) =
|
||||
runRodFiles(r, options)
|
||||
|
||||
@@ -261,7 +261,10 @@ proc compileSingleTest(r: var TResults, test, options: string) =
|
||||
r.addResult(t, given.msg, if given.err: reFailure else: reSuccess)
|
||||
if not given.err: inc(r.passed)
|
||||
|
||||
proc runSingleTest(r: var TResults, test, options: string) =
|
||||
type
|
||||
TTarget = enum targetC, targetJS
|
||||
|
||||
proc runSingleTest(r: var TResults, test, options: string, target: TTarget) =
|
||||
var test = test.addFileExt(".nim")
|
||||
var t = extractFilename(test)
|
||||
echo t
|
||||
@@ -275,9 +278,16 @@ proc runSingleTest(r: var TResults, test, options: string) =
|
||||
if given.err:
|
||||
r.addResult(t, "", given.msg, reFailure)
|
||||
else:
|
||||
var exeFile = changeFileExt(test, ExeExt)
|
||||
var exeFile: string
|
||||
if target == targetC:
|
||||
exeFile = changeFileExt(test, ExeExt)
|
||||
else:
|
||||
let (dir, file, ext) = splitFile(test)
|
||||
exeFile = dir / "nimcache" / file & ".js"
|
||||
|
||||
if existsFile(exeFile):
|
||||
var (buf, exitCode) = execCmdEx(exeFile)
|
||||
var (buf, exitCode) = execCmdEx(
|
||||
(if target==targetJS: "node " else: "") & exeFile)
|
||||
if exitCode != expected.ExitCode:
|
||||
r.addResult(t, "exitcode: " & $expected.ExitCode,
|
||||
"exitcode: " & $exitCode, reFailure)
|
||||
@@ -291,6 +301,9 @@ proc runSingleTest(r: var TResults, test, options: string) =
|
||||
else:
|
||||
r.addResult(t, expected.outp, "executable not found", reFailure)
|
||||
|
||||
proc runSingleTest(r: var TResults, test, options: string) =
|
||||
runSingleTest(r, test, options, targetC)
|
||||
|
||||
proc run(r: var TResults, dir, options: string) =
|
||||
for test in os.walkFiles(dir / "t*.nim"): runSingleTest(r, test, options)
|
||||
|
||||
@@ -350,6 +363,12 @@ proc main() =
|
||||
run(runRes, "tests/run", p.cmdLineRest.string)
|
||||
runSpecialTests(runRes, p.cmdLineRest.string)
|
||||
writeResults(runJson, runRes)
|
||||
of "js":
|
||||
var runRes = initResults()
|
||||
if existsFile(runJSon):
|
||||
runRes = readResults(runJson)
|
||||
runJsTests(runRes, p.cmdLineRest.string)
|
||||
writeResults(runJson, runRes)
|
||||
of "merge":
|
||||
var rejectRes = readResults(rejectJson)
|
||||
var compileRes = readResults(compileJson)
|
||||
|
||||
5
todo.txt
5
todo.txt
@@ -42,6 +42,10 @@ Bugs
|
||||
version 0.9.XX
|
||||
==============
|
||||
|
||||
- JS gen:
|
||||
- document it
|
||||
- test & fix bugs
|
||||
|
||||
- document nimdoc properly finally
|
||||
- implement a warning message for shadowed 'result' variable
|
||||
- implement the high level optimizer
|
||||
@@ -51,7 +55,6 @@ version 0.9.XX
|
||||
- implicit ref/ptr->var conversion; the compiler may store an object
|
||||
implicitly on the heap for write barrier efficiency; better:
|
||||
proc specialization in the code gen
|
||||
- 'of' operator for JS backend
|
||||
- tlastmod returns wrong results on BSD (Linux, MacOS X: works)
|
||||
- nested tuple unpacking; tuple unpacking in non-var-context
|
||||
- 'nimrod def': does not always work?
|
||||
|
||||
Reference in New Issue
Block a user