diff --git a/contributors.txt b/contributors.txt
index 2f025f4227..97a27f7469 100755
--- a/contributors.txt
+++ b/contributors.txt
@@ -1,3 +1,4 @@
+Comex
Philippe Lhoste
Mario Ray Mahardhika
Dominik Picheta
diff --git a/lib/ecmas/dom.nim b/lib/ecmas/dom.nim
index 6d9224c26d..e9c587928b 100755
--- a/lib/ecmas/dom.nim
+++ b/lib/ecmas/dom.nim
@@ -1,14 +1,13 @@
#
#
# Nimrod's Runtime Library
-# (c) Copyright 2006 Andreas Rumpf
+# (c) Copyright 2010 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## Declaration of the Document Object Model for the ECMAScript backend.
-## (c) 2008 Andreas Rumpf
when not defined(ecmascript):
{.error: "This module only works on the ECMAScript platform".}
diff --git a/lib/system.nim b/lib/system.nim
index 9eabeb2af6..abb3dd6e0c 100755
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -1605,10 +1605,8 @@ when not defined(EcmaScript) and not defined(NimrodVM):
## can be used to mark a condition to be unlikely. This is a hint for the
## optimizer.
-elif defined(ecmaScript):
- include "system/ecmasys"
-elif defined(NimrodVM):
- # Stubs for the GC interface:
+elif defined(ecmaScript) or defined(NimrodVM):
+ # Stubs:
proc GC_disable() = nil
proc GC_enable() = nil
proc GC_fullCollect() = nil
@@ -1620,16 +1618,19 @@ elif defined(NimrodVM):
proc getOccupiedMem(): int = return -1
proc getFreeMem(): int = return -1
proc getTotalMem(): int = return -1
-
- proc cmp(x, y: string): int =
- if x == y: return 0
- if x < y: return -1
- return 1
-
+
proc dealloc(p: pointer) = nil
proc alloc(size: int): pointer = nil
proc alloc0(size: int): pointer = nil
proc realloc(p: Pointer, newsize: int): pointer = nil
+ when defined(ecmaScript):
+ include "system/ecmasys"
+ elif defined(NimrodVM):
+ proc cmp(x, y: string): int =
+ if x == y: return 0
+ if x < y: return -1
+ return 1
+
{.pop.} # checks
{.pop.} # hints
diff --git a/lib/system/ecmasys.nim b/lib/system/ecmasys.nim
index c0d0a5fd67..e2ecb370ad 100755
--- a/lib/system/ecmasys.nim
+++ b/lib/system/ecmasys.nim
@@ -1,26 +1,12 @@
#
#
# Nimrod's Runtime Library
-# (c) Copyright 2008 Andreas Rumpf
+# (c) Copyright 2010 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
-## Stubs for the GC interface:
-
-proc GC_disable() = nil
-proc GC_enable() = nil
-proc GC_fullCollect() = nil
-proc GC_setStrategy(strategy: TGC_Strategy) = nil
-proc GC_enableMarkAndSweep() = nil
-proc GC_disableMarkAndSweep() = nil
-proc GC_getStatistics(): string = return ""
-
-proc getOccupiedMem(): int = return -1
-proc getFreeMem(): int = return -1
-proc getTotalMem(): int = return -1
-
proc alert(s: cstring) {.importc, nodecl.}
type
@@ -130,8 +116,6 @@ proc raiseIndexError() {.compilerproc, noreturn.} =
proc raiseFieldError(f: string) {.compilerproc, noreturn.} =
raise newException(EInvalidField, f & " is not accessible")
-
-
proc SetConstr() {.varargs, pure, compilerproc.} =
asm """
var result = {};
@@ -317,61 +301,58 @@ proc ewriteln(x: cstring) =
else:
raise newException(EInvalidValue, "
element does not exist yet!")
-proc echo*(x: int) = ewriteln($x)
-proc echo*(x: float) = ewriteln($x)
-proc echo*(x: bool) = ewriteln(if x: cstring("true") else: cstring("false"))
-proc echo*(x: string) = ewriteln(x)
-proc echo*(x: cstring) = ewriteln(x)
-
-proc echo[Ty](x: Ty) =
- echo(x)
-
-proc echo[Ty](x: openArray[Ty]) =
- for a in items(x): echo(a)
+proc rawEcho {.compilerproc.} =
+ var node = document.getElementsByTagName("body")[0]
+ if node == nil: raise newException(EIO, " 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 {.pure, compilerproc.} =
asm """
var result = `a` + `b`;
- if (result > 2147483647 || result < -2147483648) raiseOverflow();
+ if (result > 2147483647 || result < -2147483648) `raiseOverflow`();
return result;
"""
proc subInt(a, b: int): int {.pure, compilerproc.} =
asm """
var result = `a` - `b`;
- if (result > 2147483647 || result < -2147483648) raiseOverflow();
+ if (result > 2147483647 || result < -2147483648) `raiseOverflow`();
return result;
"""
proc mulInt(a, b: int): int {.pure, compilerproc.} =
asm """
var result = `a` * `b`;
- if (result > 2147483647 || result < -2147483648) raiseOverflow();
+ if (result > 2147483647 || result < -2147483648) `raiseOverflow`();
return result;
"""
proc divInt(a, b: int): int {.pure, compilerproc.} =
asm """
- if (`b` == 0) raiseDivByZero();
- if (`b` == -1 && `a` == 2147483647) raiseOverflow();
+ if (`b` == 0) `raiseDivByZero`();
+ if (`b` == -1 && `a` == 2147483647) `raiseOverflow`();
return Math.floor(`a` / `b`);
"""
proc modInt(a, b: int): int {.pure, compilerproc.} =
asm """
- if (`b` == 0) raiseDivByZero();
- if (`b` == -1 && `a` == 2147483647) raiseOverflow();
+ if (`b` == 0) `raiseDivByZero`();
+ if (`b` == -1 && `a` == 2147483647) `raiseOverflow`();
return Math.floor(`a` % `b`);
"""
-
-
proc addInt64(a, b: int): int {.pure, compilerproc.} =
asm """
var result = `a` + `b`;
if (result > 9223372036854775807
- || result < -9223372036854775808) raiseOverflow();
+ || result < -9223372036854775808) `raiseOverflow`();
return result;
"""
@@ -379,7 +360,7 @@ proc subInt64(a, b: int): int {.pure, compilerproc.} =
asm """
var result = `a` - `b`;
if (result > 9223372036854775807
- || result < -9223372036854775808) raiseOverflow();
+ || result < -9223372036854775808) `raiseOverflow`();
return result;
"""
@@ -387,21 +368,21 @@ proc mulInt64(a, b: int): int {.pure, compilerproc.} =
asm """
var result = `a` * `b`;
if (result > 9223372036854775807
- || result < -9223372036854775808) raiseOverflow();
+ || result < -9223372036854775808) `raiseOverflow`();
return result;
"""
proc divInt64(a, b: int): int {.pure, compilerproc.} =
asm """
- if (`b` == 0) raiseDivByZero();
- if (`b` == -1 && `a` == 9223372036854775807) raiseOverflow();
+ if (`b` == 0) `raiseDivByZero`();
+ if (`b` == -1 && `a` == 9223372036854775807) `raiseOverflow`();
return Math.floor(`a` / `b`);
"""
proc modInt64(a, b: int): int {.pure, compilerproc.} =
asm """
- if (`b` == 0) raiseDivByZero();
- if (`b` == -1 && `a` == 9223372036854775807) raiseOverflow();
+ if (`b` == 0) `raiseDivByZero`();
+ if (`b` == -1 && `a` == 9223372036854775807) `raiseOverflow`();
return Math.floor(`a` % `b`);
"""
@@ -415,13 +396,13 @@ proc internalAssert(file: cstring, line: int) {.pure, compilerproc.} =
asm """`e`.message = "[Assertion failure] file: "+`file`+", line: "+`line`"""
raise e
-include hti
+include "system/hti"
proc isFatPointer(ti: PNimType): bool =
# This has to be consistent with the code generator!
- return ti.base.kind notin {tyRecord, tyRecordConstr, tyObject,
+ return ti.base.kind notin {tyObject,
tyArray, tyArrayConstr, tyPureObject, tyTuple,
- tyEmptySet, tyOpenArray, tySet, tyVar, tyRef, tyPtr}
+ tyOpenArray, tySet, tyVar, tyRef, tyPtr}
proc NimCopy(x: pointer, ti: PNimType): pointer {.compilerproc.}
@@ -452,7 +433,7 @@ proc NimCopy(x: pointer, ti: PNimType): pointer =
`result`[0] = `x`[0];
`result`[1] = `x`[1];
"""
- of tyEmptySet, tySet:
+ of tySet:
asm """
`result` = {};
for (var key in `x`) { `result`[key] = `x`[key]; }
diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim
index c473c42f0c..65e2334766 100755
--- a/lib/system/excpt.nim
+++ b/lib/system/excpt.nim
@@ -10,6 +10,10 @@
# Exception handling code. This is difficult because it has
# to work if there is no more memory (but it doesn't yet!).
+var
+ stackTraceNewLine* = "\n" ## undocumented feature; it is replaced by ``
``
+ ## for CGI applications
+
when not defined(windows) or not defined(guiapp):
proc writeToStdErr(msg: CString) = write(stdout, msg)
@@ -32,7 +36,7 @@ type
TSafePoint {.compilerproc, final.} = object
prev: PSafePoint # points to next safe point ON THE STACK
status: int
- exc: ref E_Base # XXX only needed for bootstrapping
+ exc: ref E_Base # XXX only needed for bootstrapping; unused
context: C_JmpBuf
var
@@ -55,6 +59,58 @@ proc pushCurrentException(e: ref E_Base) {.compilerRtl, inl.} =
proc popCurrentException {.compilerRtl, inl.} =
currException = currException.parent
+# some platforms have native support for stack traces:
+const
+ nimrodStackTrace = compileOption("stacktrace")
+ nativeStackTrace = (defined(macosx) or defined(linux)) and
+ not nimrodStackTrace and false
+
+# `nativeStackTrace` does not work for me --> deactivated for now. Maybe for
+# the next release version.
+
+when nativeStacktrace:
+ type
+ TDl_info {.importc: "Dl_info", header: "",
+ final, pure.} = object
+ dli_fname: CString
+ dli_fbase: pointer
+ dli_sname: CString
+ dli_saddr: pointer
+
+ proc backtrace(symbols: ptr pointer, size: int): int {.
+ importc: "backtrace", header: "".}
+ proc dladdr(addr1: pointer, info: ptr TDl_info): int {.
+ importc: "dladdr", header: "".}
+
+ var
+ tempAddresses: array [0..127, pointer] # cannot be allocated on the stack!
+ tempDlInfo: TDl_info
+
+ proc auxWriteStackTraceWithBacktrace(s: var string) =
+ # This is allowed to be expensive since it only happens during crashes
+ # (but this way you don't need manual stack tracing)
+ var size = backtrace(cast[ptr pointer](addr(tempAddresses)),
+ len(tempAddresses))
+ var enabled = false
+ for i in 0..size-1:
+ var dlresult = dladdr(tempAddresses[i], addr(tempDlInfo))
+ if enabled:
+ if dlresult != 0:
+ var oldLen = s.len
+ add(s, tempDlInfo.dli_fname)
+ if tempDlInfo.dli_sname != nil:
+ for k in 1..max(1, 25-(s.len-oldLen)): add(s, ' ')
+ add(s, tempDlInfo.dli_sname)
+ else:
+ add(s, '?')
+ add(s, stackTraceNewLine)
+ else:
+ if dlresult != 0 and tempDlInfo.dli_sname != nil and
+ c_strcmp(tempDlInfo.dli_sname, "signalHandler") == 0'i32:
+ # Once we're past signalHandler, we're at what the user is
+ # interested in
+ enabled = true
+
type
PFrame = ptr TFrame
TFrame {.importc, nodecl, final.} = object
@@ -74,9 +130,6 @@ var
tempFrames: array [0..127, PFrame] # cannot be allocated on the stack!
- stackTraceNewLine* = "\n" ## undocumented feature; it is replaced by ``
``
- ## for CGI applications
-
proc auxWriteStackTrace(f: PFrame, s: var string) =
const
firstCalls = 32
@@ -120,7 +173,7 @@ proc auxWriteStackTrace(f: PFrame, s: var string) =
add(s, stackTraceNewLine)
proc rawWriteStackTrace(s: var string) =
- when compileOption("stacktrace") or compileOption("linetrace"):
+ when nimrodStackTrace:
if framePtr == nil:
add(s, "No stack traceback available")
add(s, stackTraceNewLine)
@@ -128,6 +181,10 @@ proc rawWriteStackTrace(s: var string) =
add(s, "Traceback (most recent call last)")
add(s, stackTraceNewLine)
auxWriteStackTrace(framePtr, s)
+ elif nativeStackTrace:
+ add(s, "Traceback from system (most recent call last)")
+ add(s, stackTraceNewLine)
+ auxWriteStackTraceWithBacktrace(s)
else:
add(s, "No stack traceback available")
add(s, stackTraceNewLine)
@@ -197,11 +254,6 @@ proc WriteStackTrace() =
rawWriteStackTrace(s)
writeToStdErr(s)
-#proc stackTraceWrapper {.noconv.} =
-# writeStackTrace()
-
-#addQuitProc(stackTraceWrapper)
-
var
dbgAborting: bool # whether the debugger wants to abort
diff --git a/lib/system/gc.nim b/lib/system/gc.nim
index 0c403b4bc5..c0461d89d7 100755
--- a/lib/system/gc.nim
+++ b/lib/system/gc.nim
@@ -77,14 +77,16 @@ var
# collection, not a lock for threads!
proc lock(gch: var TGcHeap) {.inline.} =
- if isMultiThreaded:
- Lock(gch.zctLock)
- lock(gch.cycleRootsLock)
+ when hasThreadSupport:
+ if isMultiThreaded:
+ Lock(gch.zctLock)
+ lock(gch.cycleRootsLock)
proc unlock(gch: var TGcHeap) {.inline.} =
- if isMultiThreaded:
- unlock(gch.zctLock)
- unlock(gch.cycleRootsLock)
+ when hasThreadSupport:
+ if isMultiThreaded:
+ unlock(gch.zctLock)
+ unlock(gch.cycleRootsLock)
proc addZCT(s: var TCellSeq, c: PCell) {.noinline.} =
if (c.refcount and rcZct) == 0:
@@ -202,15 +204,19 @@ proc prepareDealloc(cell: PCell) =
proc rtlAddCycleRoot(c: PCell) {.rtl, inl.} =
# we MUST access gch as a global here, because this crosses DLL boundaries!
- if isMultiThreaded: Lock(gch.cycleRootsLock)
+ when hasThreadSupport:
+ if isMultiThreaded: Lock(gch.cycleRootsLock)
incl(gch.cycleRoots, c)
- if isMultiThreaded: Unlock(gch.cycleRootsLock)
+ when hasThreadSupport:
+ if isMultiThreaded: Unlock(gch.cycleRootsLock)
proc rtlAddZCT(c: PCell) {.rtl, inl.} =
# we MUST access gch as a global here, because this crosses DLL boundaries!
- if isMultiThreaded: Lock(gch.zctLock)
+ when hasThreadSupport:
+ if isMultiThreaded: Lock(gch.zctLock)
addZCT(gch.zct, c)
- if isMultiThreaded: Unlock(gch.zctLock)
+ when hasThreadSupport:
+ if isMultiThreaded: Unlock(gch.zctLock)
proc decRef(c: PCell) {.inline.} =
when stressGC:
@@ -480,7 +486,7 @@ proc gcMark(p: pointer) {.inline.} =
add(gch.decStack, cell)
proc markThreadStacks(gch: var TGcHeap) =
- when isMultiThreaded:
+ when hasThreadSupport:
nil
# ----------------- stack management --------------------------------------
diff --git a/lib/system/systhread.nim b/lib/system/systhread.nim
index 583cd2a435..af001985e7 100755
--- a/lib/system/systhread.nim
+++ b/lib/system/systhread.nim
@@ -7,12 +7,17 @@
# distribution, for details about the copyright.
#
-when defined(gcc) or defined(llvm_gcc):
+const
+ hasThreadSupport = false # deactivate for now: thread stack walking
+ # is missing!
+ maxThreads = 256
+
+when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport:
proc sync_add_and_fetch(p: var int, val: int): int {.
importc: "__sync_add_and_fetch", nodecl.}
proc sync_sub_and_fetch(p: var int, val: int): int {.
importc: "__sync_sub_and_fetch", nodecl.}
-elif defined(vcc):
+elif defined(vcc) and hasThreadSupport:
proc sync_add_and_fetch(p: var int, val: int): int {.
importc: "NimXadd", nodecl.}
else:
@@ -20,19 +25,18 @@ else:
inc(p, val)
result = p
-const
- isMultiThreaded* = true
- maxThreads = 256
+var
+ isMultiThreaded: bool # true when prog created at least 1 thread
proc atomicInc(memLoc: var int, x: int): int =
- when isMultiThreaded:
+ when hasThreadSupport:
result = sync_add_and_fetch(memLoc, x)
else:
inc(memLoc, x)
result = memLoc
proc atomicDec(memLoc: var int, x: int): int =
- when isMultiThreaded:
+ when hasThreadSupport:
when defined(sync_sub_and_fetch):
result = sync_sub_and_fetch(memLoc, x)
else:
@@ -85,11 +89,8 @@ type
TThreadFunc* = proc (closure: pointer) {.cdecl.}
proc createThread*(t: var TThread, fn: TThreadFunc) =
-
nil
proc destroyThread*(t: var TThread) =
nil
-
-
diff --git a/rod/ecmasgen.nim b/rod/ecmasgen.nim
index 91acb98b2c..c57ee38797 100755
--- a/rod/ecmasgen.nim
+++ b/rod/ecmasgen.nim
@@ -12,9 +12,9 @@
# code!**
import
- ast, astalgo, strutils, nhashes, trees, platform, magicsys, extccomp, options,
- nversion, nimsets, msgs, crc, bitsets, idents, lists, types, os, times, ropes,
- math, passes, ccgutils, wordrecg, rnimsyn, rodread
+ ast, astalgo, strutils, nhashes, trees, platform, magicsys, extccomp,
+ options, nversion, nimsets, msgs, crc, bitsets, idents, lists, types, os,
+ times, ropes, math, passes, ccgutils, wordrecg, rnimsyn, rodread
proc ecmasgenPass*(): TPass
# implementation
@@ -39,7 +39,8 @@ type
kind*: TEcmasTypeKind
com*: PRope # computation part
# address if this is a (address, index)-tuple
- res*: PRope # result part; index if this is a (address, index)-tuple
+ res*: PRope # result part; index if this is an
+ # (address, index)-tuple
TBlock{.final.} = object
id*: int # the ID of the label; positive means that it
@@ -886,12 +887,11 @@ proc genDeref(p: var TProc, n: PNode, r: var TCompRes) =
if a.kind != etyBaseIndex: InternalError(n.info, "genDeref")
r.res = ropef("$1[$2]", [a.com, a.res])
-proc genCall(p: var TProc, n: PNode, r: var TCompRes) =
- var a: TCompRes
- gen(p, n.sons[0], r)
+proc genArgs(p: var TProc, n: PNode, r: var TCompRes) =
app(r.res, "(")
for i in countup(1, sonsLen(n) - 1):
if i > 1: app(r.res, ", ")
+ var a: TCompRes
gen(p, n.sons[i], a)
if a.kind == etyBaseIndex:
app(r.res, a.com)
@@ -901,6 +901,14 @@ proc genCall(p: var TProc, n: PNode, r: var TCompRes) =
app(r.res, mergeExpr(a))
app(r.res, ")")
+proc genCall(p: var TProc, n: PNode, r: var TCompRes) =
+ gen(p, n.sons[0], r)
+ genArgs(p, n, r)
+
+proc genEcho(p: var TProc, n: PNode, r: var TCompRes) =
+ app(r.res, "rawEcho")
+ genArgs(p, n, r)
+
proc putToSeq(s: string, indirect: bool): PRope =
result = toRope(s)
if indirect: result = ropef("[$1]", [result])
@@ -1124,6 +1132,8 @@ proc genMagic(p: var TProc, n: PNode, r: var TCompRes) =
of mInSet: binaryExpr(p, n, r, "", "($1[$2] != undefined)")
of mNLen..mNError:
liMessage(n.info, errCannotGenerateCodeForX, n.sons[0].sym.name.s)
+ of mNewSeq: binaryStmt(p, n, r, "", "$1 = new Array($2)")
+ of mEcho: genEcho(p, n, r)
else:
genCall(p, n, r)
#else internalError(e.info, 'genMagic: ' + magicToStr[op]);
@@ -1389,7 +1399,7 @@ proc newModule(module: PSym, filename: string): BModule =
proc genHeader(): PRope =
result = ropef("/* Generated by the Nimrod Compiler v$1 */$n" &
- "/* (c) 2008 Andreas Rumpf */$n$n" & "$nvar Globals = this;$n" &
+ "/* (c) 2010 Andreas Rumpf */$n$n" & "$nvar Globals = this;$n" &
"var framePtr = null;$n" & "var excHandler = null;$n",
[toRope(versionAsString)])
diff --git a/rod/main.nim b/rod/main.nim
index 2a261bfe5e..46f01ddf5c 100755
--- a/rod/main.nim
+++ b/rod/main.nim
@@ -203,7 +203,7 @@ proc MainCommand(cmd, filename: string) =
gCmd = cmdCompileToCpp
wantFile(filename)
CommandCompileToC(filename)
- of wCompileToEcmaScript:
+ of wCompileToEcmaScript, wJs:
gCmd = cmdCompileToEcmaScript
wantFile(filename)
CommandCompileToEcmaScript(filename)
diff --git a/rod/wordrecg.nim b/rod/wordrecg.nim
index bf2aa84f78..c64985846e 100755
--- a/rod/wordrecg.nim
+++ b/rod/wordrecg.nim
@@ -55,7 +55,7 @@ type
wCc, wGenscript, wCheckPoint, wCheckPoints, wNoMain, wSubsChar,
wAcyclic, wIndex,
wCompileToC, wCompileToCpp, wCompileToEcmaScript, wCompileToLLVM, wPretty,
- wDoc, wGenDepend, wListDef, wCheck, wParse, wScan, wLazy,
+ wDoc, wGenDepend, wListDef, wCheck, wParse, wScan, wJs,
wRst2html, wRst2tex, wI,
wWrite, wPutEnv, wPrependEnv, wAppendEnv, wThreadVar
@@ -103,7 +103,7 @@ const
"nomain", "subschar", "acyclic", "index",
"compiletoc", "compiletocpp", "compiletoecmascript", "compiletollvm",
"pretty", "doc", "gendepend", "listdef", "check", "parse", "scan",
- "lazy", "rst2html", "rst2tex", "i",
+ "js", "rst2html", "rst2tex", "i",
"write", "putenv", "prependenv", "appendenv", "threadvar"]
proc whichKeyword*(id: PIdent): TSpecialWord
diff --git a/tests/ecmas.html b/tests/ecmas.html
index 1cb56e72ac..2004387a1d 100755
--- a/tests/ecmas.html
+++ b/tests/ecmas.html
@@ -2,18 +2,18 @@
-
+
Nimrod ECMAScript Generator Test
-
+
diff --git a/tests/ecmas.nim b/tests/ecmas.nim
index 59e7ae1e84..c25d063c14 100755
--- a/tests/ecmas.nim
+++ b/tests/ecmas.nim
@@ -6,11 +6,14 @@ import
# We need to declare the used elements here. This is annoying but
# prevents any kind of typo:
var
- inputElement {.importc: "document.form1.input", nodecl.}: ref TElement
+ inputElement {.importc: "document.form1.input1", nodecl.}: ref TElement
proc OnButtonClick() {.exportc.} =
- var x: int = parseInt($inputElement.value)
- echo($(x * x))
+ #var x = parseInt($inputElement.value)
+ #echo($(x * x))
+ var input = $inputElement.value
+ echo "Test"
+ echo "Hi, ", input
proc OnLoad() {.exportc.} =
- echo("Welcome! Please take your time to fill in this formular!")
+ echo "Welcome! Please take your time to fill in this formular!"
diff --git a/tinyc/libtcc.c b/tinyc/libtcc.c
index ade77c0dc8..0d8702b5f7 100755
--- a/tinyc/libtcc.c
+++ b/tinyc/libtcc.c
@@ -808,11 +808,11 @@ void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
if (!s1->error_func) {
/* default case: stderr */
fprintf(stderr, "%s\n", buf);
- } else {
+ }
+ if (!is_warning || s1->warn_error) {
s1->error_func(s1->error_opaque, buf);
- }
- if (!is_warning || s1->warn_error)
s1->nb_errors++;
+ }
}
void tcc_set_error_func(TCCState *s, void *error_opaque,
diff --git a/todo.txt b/todo.txt
index 14f1c1f025..bd02a31ee2 100755
--- a/todo.txt
+++ b/todo.txt
@@ -3,6 +3,8 @@ For version 0.8.10
- fix implicit generic routines
- bugfix: ccgexprs
+- bugfix: make ``finally`` more robust
+- bugfix: tiny C broken again!
High priority (version 0.9.0)
diff --git a/tools/nimrepl.nim b/tools/nimrepl.nim
index 247bf0d10c..989689add3 100755
--- a/tools/nimrepl.nim
+++ b/tools/nimrepl.nim
@@ -7,17 +7,38 @@
# distribution, for details about the copyright.
#
-import glib2, gtk2, gdk2, osproc, dialogs, strutils
+import glib2, gtk2, gdk2, os, osproc, dialogs, strutils
+
+when defined(tinyc):
+ const runCmd = "run"
+else:
+ const runCmd = "c -r"
+
+when not defined(findExe):
+ # candidate for the stdlib:
+ proc findExe(exe: string): string =
+ ## returns exe if the exe cannot be found
+ result = addFileExt(exe, os.exeExt)
+ if ExistsFile(result): return
+ var path = os.getEnv("PATH")
+ for candidate in split(path, pathSep):
+ var x = candidate / result
+ if ExistsFile(x): return x
+ result = ""
+
+var nimExe = findExe("nimrod")
+if nimExe.len == 0: nimExe = "../bin" / addFileExt("nimrod", os.exeExt)
proc execCode(code: string): string =
var f: TFile
if open(f, "temp.nim", fmWrite):
f.write(code)
f.close()
+ result = osproc.execProcess(
+ "$# $# --verbosity:0 --hint[Conf]:off temp.nim" % [nimExe, runCmd],
+ {poStdErrToStdOut})
else:
- raise newException(EIO, "Unable to open file")
- result = osproc.execProcess(
- "nimrod c -r --verbosity:0 --hint[Conf]:off temp.nim")
+ result = "cannot open file 'temp.nim'"
var shiftPressed = False
var w: gtk2.PWindow
@@ -29,33 +50,29 @@ proc destroy(widget: PWidget, data: pgpointer){.cdecl.} =
proc FileOpenClicked(menuitem: PMenuItem, userdata: pgpointer) {.cdecl.} =
var path = ChooseFileToOpen(w)
-
if path != "":
-
var file: string = readFile(path)
if file != nil:
set_text(InputTextBuffer, file, len(file))
-
else:
error(w, "Unable to read from file")
proc FileSaveClicked(menuitem: PMenuItem, userdata: pgpointer) {.cdecl.} =
var path = ChooseFileToSave(w)
- if path != "":
- var startIter: TTextIter
- var endIter: TTextIter
- get_start_iter(InputTextBuffer, addr(startIter))
- get_end_iter(InputTextBuffer, addr(endIter))
- var InputText = get_text(InputTextBuffer, addr(startIter),
- addr(endIter), False)
- var f: TFile
- if open(f, path, fmWrite):
- f.write(InputText)
- f.close()
- else:
- error(w, "Unable to write to file")
-
+ if path == "": return
+ var startIter: TTextIter
+ var endIter: TTextIter
+ get_start_iter(InputTextBuffer, addr(startIter))
+ get_end_iter(InputTextBuffer, addr(endIter))
+ var InputText = get_text(InputTextBuffer, addr(startIter),
+ addr(endIter), False)
+ var f: TFile
+ if open(f, path, fmWrite):
+ f.write(InputText)
+ f.close()
+ else:
+ error(w, "Unable to write to file")
proc inputKeyPressed(widget: PWidget, event: PEventKey,
userdata: pgpointer): bool =
@@ -68,13 +85,13 @@ proc setError(msg: string) =
proc inputKeyReleased(widget: PWidget, event: PEventKey,
userdata: pgpointer): bool =
- echo(keyval_name(event.keyval))
+ #echo(keyval_name(event.keyval))
if ($keyval_name(event.keyval)).tolower() == "shift_l":
# SHIFT is released
shiftPressed = False
if ($keyval_name(event.keyval)).tolower() == "return":
- echo($keyval_name(event.keyval), "Shift_L")
+ #echo($keyval_name(event.keyval), "Shift_L")
# Enter pressed
if shiftPressed == False:
var startIter: TTextIter