diff options
author | dom96 <dominikpicheta@googlemail.com> | 2011-09-23 21:43:24 +0100 |
---|---|---|
committer | dom96 <dominikpicheta@googlemail.com> | 2011-09-23 21:43:24 +0100 |
commit | 6deda5a973312e86fe58e319e97afd93bc07c82d (patch) | |
tree | 0769b2871024febab389c8bc72d01cd770b52cfb | |
parent | 2359b8b1073cfd027ac14a147aba06cc18d61010 (diff) | |
download | Nim-6deda5a973312e86fe58e319e97afd93bc07c82d.tar.gz |
Fixed string concatenation and other bugs in the JS backend. Fixed a small bug in the IRC module.
-rwxr-xr-x | compiler/ecmasgen.nim | 108 | ||||
-rwxr-xr-x | doc/lib.txt | 6 | ||||
-rwxr-xr-x | lib/ecmas/dom.nim | 1 | ||||
-rw-r--r-- | lib/pure/irc.nim | 8 | ||||
-rwxr-xr-x | lib/pure/times.nim | 8 | ||||
-rwxr-xr-x | lib/system.nim | 3 | ||||
-rwxr-xr-x | lib/system/ecmasys.nim | 2 | ||||
-rw-r--r-- | lib/system/reprjs.nim | 23 | ||||
-rwxr-xr-x | web/nimrod.ini | 2 |
9 files changed, 117 insertions, 44 deletions
diff --git a/compiler/ecmasgen.nim b/compiler/ecmasgen.nim index 4347bd283..d597da193 100755 --- a/compiler/ecmasgen.nim +++ b/compiler/ecmasgen.nim @@ -778,9 +778,10 @@ proc genSwap(p: var TProc, n: PNode, r: var TCompRes) = proc genFieldAddr(p: var TProc, n: PNode, r: var TCompRes) = var a: TCompRes r.kind = etyBaseIndex - gen(p, n.sons[0], a) - if n.sons[1].kind != nkSym: InternalError(n.sons[1].info, "genFieldAddr") - var f = n.sons[1].sym + 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)) r.com = mergeExpr(a) @@ -1030,42 +1031,68 @@ proc genVarStmt(p: var TProc, n: PNode, r: var TCompRes) = genLineDir(p, a, r) genVarInit(p, v, a.sons[2], r) -proc genConstStmt(p: var TProc, n: PNode, r: var TCompRes) = +proc genConstStmt(p: var TProc, n: PNode, r: var TCompRes) = genLineDir(p, n, r) - for i in countup(0, sonsLen(n) - 1): + for i in countup(0, sonsLen(n) - 1): if n.sons[i].kind == nkCommentStmt: continue assert(n.sons[i].kind == nkConstDef) var c = n.sons[i].sons[0].sym if (c.ast != nil) and (c.typ.kind in ConstantDataTypes) and - not (lfNoDecl in c.loc.flags): + not (lfNoDecl in c.loc.flags): genLineDir(p, n.sons[i], r) genVarInit(p, c, c.ast, r) -proc genNew(p: var TProc, n: PNode, r: var TCompRes) = +proc genNew(p: var TProc, n: PNode, r: var TCompRes) = var a: TCompRes gen(p, n.sons[1], a) var t = skipTypes(n.sons[1].typ, abstractVar).sons[0] if a.com != nil: appf(r.com, "$1;$n", [a.com]) appf(r.com, "$1 = $2;$n", [a.res, createVar(p, t, true)]) -proc genOrd(p: var TProc, n: PNode, r: var TCompRes) = +proc genOrd(p: var TProc, n: PNode, r: var TCompRes) = case skipTypes(n.sons[1].typ, abstractVar).kind of tyEnum, tyInt..tyInt64, tyChar: gen(p, n.sons[1], r) of tyBool: unaryExpr(p, n, r, "", "($1 ? 1:0)") else: InternalError(n.info, "genOrd") -proc genConStrStr(p: var TProc, n: PNode, r: var TCompRes) = - var a, b: TCompRes +proc genConStrStr(p: var TProc, n: PNode, r: var TCompRes) = + var a: TCompRes + gen(p, n.sons[1], a) - gen(p, n.sons[2], b) - r.com = mergeExpr(a.com, b.com) - if skipTypes(n.sons[1].typ, abstractVarRange).kind == tyChar: - a.res = ropef("[$1, 0]", [a.res]) - if skipTypes(n.sons[2].typ, abstractVarRange).kind == tyChar: - b.res = ropef("[$1, 0]", [b.res]) - r.res = ropef("($1.slice(0,-1)).concat($2)", [a.res, b.res]) - -proc genMagic(p: var TProc, n: PNode, r: var TCompRes) = + r.com = mergeExpr(r.com, a.com) + if skipTypes(n.sons[1].typ, abstractVarRange).kind == tyChar: + r.res.app(ropef("[$1].concat(", [a.res])) + else: + r.res.app(ropef("($1.slice(0,-1)).concat(", [a.res])) + + for i in countup(2, sonsLen(n) - 2): + gen(p, n.sons[i], a) + r.com = mergeExpr(r.com, a.com) + + if skipTypes(n.sons[i].typ, abstractVarRange).kind == tyChar: + r.res.app(ropef("[$1],", [a.res])) + else: + r.res.app(ropef("$1.slice(0,-1),", [a.res])) + + gen(p, n.sons[sonsLen(n) - 1], a) + r.com = mergeExpr(r.com, a.com) + if skipTypes(n.sons[sonsLen(n) - 1].typ, abstractVarRange).kind == tyChar: + r.res.app(ropef("[$1, 0])", [a.res])) + else: + r.res.app(ropef("$1)", [a.res])) + +proc genRepr(p: var TProc, n: PNode, r: var TCompRes) = + var t = skipTypes(n.sons[1].typ, abstractVarRange) + case t.kind + of tyInt..tyInt64: + unaryExpr(p, n, r, "", "reprInt($1)") + of tyEnum, tyOrdinal: + binaryExpr(p, n, r, "", "reprEnum($1, $2)") + else: + # XXX: + internalError(n.info, "genRepr: Not implemented") + +proc genMagic(p: var TProc, n: PNode, r: var TCompRes) = var a: TCompRes line, filen: PRope @@ -1073,54 +1100,59 @@ proc genMagic(p: var TProc, n: PNode, r: var TCompRes) = case op of mOr: genOr(p, n.sons[1], n.sons[2], r) of mAnd: genAnd(p, n.sons[1], n.sons[2], r) - of mAddi..mStrToStr: arith(p, n, r, op) #mRepr: genRepr(p, n, r); + of mAddi..mStrToStr: arith(p, n, r, op) + of mRepr: genRepr(p, n, r) of mSwap: genSwap(p, n, r) - of mUnaryLt: + of mUnaryLt: # XXX: range checking? if not (optOverflowCheck in p.Options): unaryExpr(p, n, r, "", "$1 - 1") else: unaryExpr(p, n, r, "subInt", "subInt($1, 1)") - of mPred: + of mPred: # XXX: range checking? if not (optOverflowCheck in p.Options): binaryExpr(p, n, r, "", "$1 - $2") else: binaryExpr(p, n, r, "subInt", "subInt($1, $2)") - of mSucc: + of mSucc: # XXX: range checking? if not (optOverflowCheck in p.Options): binaryExpr(p, n, r, "", "$1 - $2") else: binaryExpr(p, n, r, "addInt", "addInt($1, $2)") of mAppendStrCh: binaryStmt(p, n, r, "addChar", "$1 = addChar($1, $2)") - of mAppendStrStr: - binaryStmt(p, n, r, "", "$1 = ($1.slice(0,-1)).concat($2)") - # XXX: make a copy of $2, because of EMCAScript's sucking semantics + of mAppendStrStr: + if skipTypes(n.sons[1].typ, abstractVarRange).kind == tyCString: + binaryStmt(p, n, r, "", "$1 += $2") + else: + binaryStmt(p, n, r, "", "$1 = ($1.slice(0,-1)).concat($2)") + # XXX: make a copy of $2, because of ECMAScript's sucking semantics of mAppendSeqElem: binaryStmt(p, n, r, "", "$1.push($2)") of mConStrStr: genConStrStr(p, n, r) of mEqStr: binaryExpr(p, n, r, "eqStrings", "eqStrings($1, $2)") of mLeStr: binaryExpr(p, n, r, "cmpStrings", "(cmpStrings($1, $2) <= 0)") of mLtStr: binaryExpr(p, n, r, "cmpStrings", "(cmpStrings($1, $2) < 0)") of mIsNil: unaryExpr(p, n, r, "", "$1 == null") - of mAssert: - if (optAssert in p.Options): + of mEnumToStr: genRepr(p, n, r) + of mAssert: + if (optAssert in p.Options): useMagic(p, "internalAssert") gen(p, n.sons[1], a) line = toRope(toLinenumber(n.info)) filen = makeCString(ToFilename(n.info)) - appf(r.com, "if (!($3)) internalAssert($1, $2)", + appf(r.com, "if (!($3)) internalAssert($1, $2)", [filen, line, mergeExpr(a)]) of mNew, mNewFinalize: genNew(p, n, r) of mSizeOf: r.res = toRope(getSize(n.sons[1].typ)) of mChr: gen(p, n.sons[1], r) # nothing to do of mOrd: genOrd(p, n, r) of mLengthStr: unaryExpr(p, n, r, "", "($1.length-1)") - of mLengthSeq, mLengthOpenArray, mLengthArray: + of mLengthSeq, mLengthOpenArray, mLengthArray: unaryExpr(p, n, r, "", "$1.length") - of mHigh: - if skipTypes(n.sons[0].typ, abstractVar).kind == tyString: + of mHigh: + if skipTypes(n.sons[0].typ, abstractVar).kind == tyString: unaryExpr(p, n, r, "", "($1.length-2)") - else: + else: unaryExpr(p, n, r, "", "($1.length-1)") - of mInc: + of mInc: if not (optOverflowCheck in p.Options): binaryStmt(p, n, r, "", "$1 += $2") else: binaryStmt(p, n, r, "addInt", "$1 = addInt($1, $2)") - of ast.mDec: + of ast.mDec: if not (optOverflowCheck in p.Options): binaryStmt(p, n, r, "", "$1 -= $2") else: binaryStmt(p, n, r, "subInt", "$1 = subInt($1, $2)") of mSetLengthStr: binaryStmt(p, n, r, "", "$1.length = ($2)-1") @@ -1135,12 +1167,12 @@ proc genMagic(p: var TProc, n: PNode, r: var TCompRes) = of mIncl: binaryStmt(p, n, r, "", "$1[$2] = true") of mExcl: binaryStmt(p, n, r, "", "delete $1[$2]") of mInSet: binaryExpr(p, n, r, "", "($1[$2] != undefined)") - of mNLen..mNError: + of mNLen..mNError: localError(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: + genCall(p, n, r) #else internalError(e.info, 'genMagic: ' + magicToStr[op]); proc genSetConstr(p: var TProc, n: PNode, r: var TCompRes) = diff --git a/doc/lib.txt b/doc/lib.txt index 0b30056ee..179861d01 100755 --- a/doc/lib.txt +++ b/doc/lib.txt @@ -274,6 +274,12 @@ Database support redis-server instance, send commands and receive replies. +Modules for JS backend +--------------------------- + +* `dom <dom.html>`_ + Declaration of the Document Object Model for the ECMAScript backend. + Impure libraries ================ diff --git a/lib/ecmas/dom.nim b/lib/ecmas/dom.nim index e9c587928..3a1caecbe 100755 --- a/lib/ecmas/dom.nim +++ b/lib/ecmas/dom.nim @@ -227,6 +227,7 @@ type getAttributeNode*: proc (attr: cstring): ref TNode getElementsByTagName*: proc (): seq[ref TNode] hasChildNodes*: proc (): bool + innerHTML*: cstring insertBefore*: proc (newNode, before: ref TNode) insertData*: proc (position: int, data: cstring) removeAttribute*: proc (attr: cstring) diff --git a/lib/pure/irc.nim b/lib/pure/irc.nim index 5a4c815f6..0397502cd 100644 --- a/lib/pure/irc.nim +++ b/lib/pure/irc.nim @@ -70,7 +70,12 @@ type proc send*(irc: var TIRC, message: string) = ## Sends ``message`` as a raw command. It adds ``\c\L`` for you. - irc.sock.send(message & "\c\L") + try: + irc.sock.send(message & "\c\L") + except EOS: + # Assuming disconnection of every EOS could be bad, + # but I can't exactly check for EBrokenPipe. + irc.connected = false proc privmsg*(irc: var TIRC, target, message: string) = ## Sends ``message`` to ``target``. ``Target`` can be a channel, or a user. @@ -199,6 +204,7 @@ proc poll*(irc: var TIRC, ev: var TIRCEvent, ## ## This function should be called often as it also handles pinging ## the server. + if not irc.connected: ev.typ = EvDisconnected var line = "" var socks = @[irc.sock] var ret = socks.select(timeout) diff --git a/lib/pure/times.nim b/lib/pure/times.nim index da23d4615..378d6ae80 100755 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -52,7 +52,7 @@ elif defined(windows): elif defined(ECMAScript): type - TTime* {.final.} = object + TTime* {.final, importc.} = object getDay: proc (): int getFullYear: proc (): int getHours: proc (): int @@ -62,6 +62,7 @@ elif defined(ECMAScript): getSeconds: proc (): int getTime: proc (): int getTimezoneOffset: proc (): int + getDate: proc (): int getUTCDate: proc (): int getUTCFullYear: proc (): int getUTCHours: proc (): int @@ -310,7 +311,8 @@ when not defined(ECMAScript): result = toFloat(int(clock())) / toFloat(clocksPerSec) else: - proc getTime(): TTime {.importc: "new Date", nodecl.} + proc newDate(): TTime {.importc: "new Date", nodecl.} + proc getTime(): TTime = return newDate() const weekDays: array [0..6, TWeekDay] = [ @@ -346,7 +348,7 @@ else: result.setDate(timeInfo.monthday) proc `$`(timeInfo: TTimeInfo): string = return $(TimeInfoToTIme(timeInfo)) - proc `$`(time: TTime): string = $time.toLocaleString() + proc `$`(time: TTime): string = return $time.toLocaleString() proc `-` (a, b: TTime): int64 = return a.getTime() - b.getTime() diff --git a/lib/system.nim b/lib/system.nim index ea004b925..644202d8c 100755 --- a/lib/system.nim +++ b/lib/system.nim @@ -1495,6 +1495,8 @@ else: `x`[0][len] = 0 """ + proc add*(x: var cstring, y: cstring) {.magic: "AppendStrStr".} + proc echo*[Ty](x: openarray[Ty]) {.magic: "Echo", noSideEffect.} ## special built-in that takes a variable number of arguments. Each argument ## is converted to a string via ``$``, so it works for user-defined @@ -1886,6 +1888,7 @@ elif defined(ecmaScript) or defined(NimrodVM): when defined(ecmaScript): include "system/ecmasys" + include "system/reprjs" elif defined(NimrodVM): proc cmp(x, y: string): int = if x == y: return 0 diff --git a/lib/system/ecmasys.nim b/lib/system/ecmasys.nim index ece33d9dc..5dc01f46e 100755 --- a/lib/system/ecmasys.nim +++ b/lib/system/ecmasys.nim @@ -228,7 +228,7 @@ proc cmp(x, y: string): int = return cmpStrings(x, y) proc eqStrings(a, b: string): bool {.noStackFrame, compilerProc.} = asm """ - if (`a == `b`) return true; + if (`a` == `b`) return true; if ((!`a`) || (!`b`)) return false; var alen = `a`.length; if (alen != `b`.length) return false; diff --git a/lib/system/reprjs.nim b/lib/system/reprjs.nim new file mode 100644 index 000000000..b6b6ffe9c --- /dev/null +++ b/lib/system/reprjs.nim @@ -0,0 +1,23 @@ +# +# +# Nimrod's Runtime Library +# (c) Copyright 2011 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +proc reprInt(x: int64): string {.compilerproc.} = return $x + +proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} = + if ntfEnumHole notin typ.flags: + if e <% typ.node.len: + return $typ.node.sons[e].name + else: + # ugh we need a slow linear search: + var n = typ.node + var s = n.sons + for i in 0 .. n.len-1: + if s[i].offset == e: return $s[i].name + result = $e & " (invalid data!)" + diff --git a/web/nimrod.ini b/web/nimrod.ini index 93fa0bfc2..f2719ae4f 100755 --- a/web/nimrod.ini +++ b/web/nimrod.ini @@ -41,7 +41,7 @@ srcdoc: "pure/json;pure/base64;pure/scgi;pure/redis;impure/graphics" srcdoc: "impure/rdstdin;wrappers/zmq;wrappers/sphinx" srcdoc: "pure/collections/tables;pure/collections/sets;pure/collections/lists" srcdoc: "pure/collections/intsets;pure/collections/queues;pure/encodings" -srcdoc: "pure/events;pure/collections/sequtils;pure/irc" +srcdoc: "pure/events;pure/collections/sequtils;pure/irc;ecmas/dom" webdoc: "wrappers/libcurl;pure/md5;wrappers/mysql;wrappers/iup" webdoc: "wrappers/sqlite3;wrappers/postgres;wrappers/tinyc" |