From 1785c6877ba0d5329c700e82b6ccf0e7a2e684b8 Mon Sep 17 00:00:00 2001 From: Simon Hafner Date: Thu, 14 Feb 2013 13:59:12 -0600 Subject: EcmaScript => JS. Fixes #330 No one calls it EcmaScript anymore. --- lib/system/ecmasys.nim | 622 ------------------------------------------------- lib/system/jssys.nim | 622 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 622 insertions(+), 622 deletions(-) delete mode 100755 lib/system/ecmasys.nim create mode 100755 lib/system/jssys.nim (limited to 'lib/system') diff --git a/lib/system/ecmasys.nim b/lib/system/ecmasys.nim deleted file mode 100755 index f78b7f68c..000000000 --- a/lib/system/ecmasys.nim +++ /dev/null @@ -1,622 +0,0 @@ -# -# -# Nimrod's Runtime Library -# (c) Copyright 2012 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -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 - PSafePoint = ptr TSafePoint - TSafePoint {.compilerproc, final.} = object - prev: PSafePoint # points to next safe point - exc: ref E_Base - - PCallFrame = ptr TCallFrame - TCallFrame {.importc, nodecl, final.} = object - prev: PCallFrame - procname: CString - line: int # current line number - filename: CString - -var - framePtr {.importc, nodecl, volatile.}: PCallFrame - excHandler {.importc, nodecl, volatile.}: PSafePoint = nil - # list of exception handlers - # a global variable for the root of all try blocks - -{.push stacktrace: off, profiler:off.} -proc nimBoolToStr(x: bool): string {.compilerproc.} = - if x: result = "true" - else: result = "false" - -proc nimCharToStr(x: char): string {.compilerproc.} = - result = newString(1) - result[0] = x - -proc getCurrentExceptionMsg(): string = - if excHandler != nil: return $excHandler.exc.msg - return "" - -proc auxWriteStackTrace(f: PCallFrame): string = - type - TTempFrame = tuple[procname: CString, line: int] - var - it = f - i = 0 - total = 0 - tempFrames: array [0..63, TTempFrame] - while it != nil and i <= high(tempFrames): - tempFrames[i].procname = it.procname - tempFrames[i].line = it.line - inc(i) - inc(total) - it = it.prev - while it != nil: - inc(total) - it = it.prev - result = "" - # if the buffer overflowed print '...': - if total != i: - add(result, "(") - add(result, $(total-i)) - add(result, " calls omitted) ...\n") - for j in countdown(i-1, 0): - add(result, tempFrames[j].procname) - if tempFrames[j].line > 0: - add(result, ", line: ") - add(result, $tempFrames[j].line) - add(result, "\n") - -proc rawWriteStackTrace(): string = - if framePtr == nil: - result = "No stack traceback available\n" - else: - result = "Traceback (most recent call last)\n"& auxWriteStackTrace(framePtr) - framePtr = nil - -proc raiseException(e: ref E_Base, ename: cstring) {. - compilerproc, noStackFrame.} = - e.name = ename - if excHandler != nil: - excHandler.exc = e - else: - when nimrodStackTrace: - var buf = rawWriteStackTrace() - else: - var buf = "" - if e.msg != nil and e.msg[0] != '\0': - add(buf, "Error: unhandled exception: ") - add(buf, e.msg) - else: - add(buf, "Error: unhandled exception") - add(buf, " [") - add(buf, ename) - add(buf, "]\n") - alert(buf) - asm """throw `e`;""" - -proc reraiseException() {.compilerproc, noStackFrame.} = - if excHandler == nil: - raise newException(ENoExceptionToReraise, "no exception to reraise") - else: - asm """throw excHandler.exc;""" - -proc raiseOverflow {.exportc: "raiseOverflow", noreturn.} = - raise newException(EOverflow, "over- or underflow") - -proc raiseDivByZero {.exportc: "raiseDivByZero", noreturn.} = - raise newException(EDivByZero, "divison by zero") - -proc raiseRangeError() {.compilerproc, noreturn.} = - raise newException(EOutOfRange, "value out of range") - -proc raiseIndexError() {.compilerproc, noreturn.} = - raise newException(EInvalidIndex, "index out of bounds") - -proc raiseFieldError(f: string) {.compilerproc, noreturn.} = - raise newException(EInvalidField, f & " is not accessible") - -proc SetConstr() {.varargs, noStackFrame, compilerproc.} = - asm """ - var result = {}; - for (var i = 0; i < arguments.length; ++i) { - var x = arguments[i]; - if (typeof(x) == "object") { - for (var j = x[0]; j <= x[1]; ++j) { - result[j] = true; - } - } else { - result[x] = true; - } - } - return result; - """ - -proc cstrToNimstr(c: cstring): string {.noStackFrame, compilerproc.} = - asm """ - var result = []; - for (var i = 0; i < `c`.length; ++i) { - result[i] = `c`.charCodeAt(i); - } - result[result.length] = 0; // terminating zero - return result; - """ - -proc toEcmaStr(s: string): cstring {.noStackFrame, compilerproc.} = - asm """ - var len = `s`.length-1; - var result = new Array(len); - var fcc = String.fromCharCode; - for (var i = 0; i < len; ++i) { - result[i] = fcc(`s`[i]); - } - return result.join(""); - """ - -proc mnewString(len: int): string {.noStackFrame, compilerproc.} = - asm """ - var result = new Array(`len`+1); - result[0] = 0; - result[`len`] = 0; - return result; - """ - -proc SetCard(a: int): int {.compilerproc, noStackFrame.} = - # argument type is a fake - asm """ - var result = 0; - for (var elem in `a`) { ++result; } - return result; - """ - -proc SetEq(a, b: int): bool {.compilerproc, noStackFrame.} = - asm """ - for (var elem in `a`) { if (!`b`[elem]) return false; } - for (var elem in `b`) { if (!`a`[elem]) return false; } - return true; - """ - -proc SetLe(a, b: int): bool {.compilerproc, noStackFrame.} = - asm """ - for (var elem in `a`) { if (!`b`[elem]) return false; } - return true; - """ - -proc SetLt(a, b: int): bool {.compilerproc.} = - result = SetLe(a, b) and not SetEq(a, b) - -proc SetMul(a, b: int): int {.compilerproc, noStackFrame.} = - asm """ - var result = {}; - for (var elem in `a`) { - if (`b`[elem]) { result[elem] = true; } - } - return result; - """ - -proc SetPlus(a, b: int): int {.compilerproc, noStackFrame.} = - asm """ - var result = {}; - for (var elem in `a`) { result[elem] = true; } - for (var elem in `b`) { result[elem] = true; } - return result; - """ - -proc SetMinus(a, b: int): int {.compilerproc, noStackFrame.} = - asm """ - var result = {}; - for (var elem in `a`) { - if (!`b`[elem]) { result[elem] = true; } - } - return result; - """ - -proc cmpStrings(a, b: string): int {.noStackFrame, compilerProc.} = - asm """ - if (`a` == `b`) return 0; - if (!`a`) return -1; - if (!`b`) return 1; - for (var i = 0; i < `a`.length-1; ++i) { - var result = `a`[i] - `b`[i]; - if (result != 0) return result; - } - return 0; - """ - -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 false; - var alen = `a`.length; - if (alen != `b`.length) return false; - for (var i = 0; i < alen; ++i) - if (`a`[i] != `b`[i]) return false; - return true; - """ - -type - TDocument {.importc.} = object of TObject - write: proc (text: cstring) {.nimcall.} - writeln: proc (text: cstring) {.nimcall.} - createAttribute: proc (identifier: cstring): ref TNode {.nimcall.} - createElement: proc (identifier: cstring): ref TNode {.nimcall.} - createTextNode: proc (identifier: cstring): ref TNode {.nimcall.} - getElementById: proc (id: cstring): ref TNode {.nimcall.} - getElementsByName: proc (name: cstring): seq[ref TNode] {.nimcall.} - getElementsByTagName: proc (name: cstring): seq[ref TNode] {.nimcall.} - - TNodeType* = enum - ElementNode = 1, - AttributeNode, - TextNode, - CDATANode, - EntityRefNode, - EntityNode, - ProcessingInstructionNode, - CommentNode, - DocumentNode, - DocumentTypeNode, - DocumentFragmentNode, - NotationNode - TNode* {.importc.} = object of TObject - attributes*: seq[ref TNode] - childNodes*: seq[ref TNode] - data*: cstring - firstChild*: ref TNode - lastChild*: ref TNode - nextSibling*: ref TNode - nodeName*: cstring - nodeType*: TNodeType - nodeValue*: cstring - parentNode*: ref TNode - previousSibling*: ref TNode - appendChild*: proc (child: ref TNode) {.nimcall.} - appendData*: proc (data: cstring) {.nimcall.} - cloneNode*: proc (copyContent: bool) {.nimcall.} - deleteData*: proc (start, len: int) {.nimcall.} - getAttribute*: proc (attr: cstring): cstring {.nimcall.} - getAttributeNode*: proc (attr: cstring): ref TNode {.nimcall.} - getElementsByTagName*: proc (): seq[ref TNode] {.nimcall.} - hasChildNodes*: proc (): bool {.nimcall.} - insertBefore*: proc (newNode, before: ref TNode) {.nimcall.} - insertData*: proc (position: int, data: cstring) {.nimcall.} - removeAttribute*: proc (attr: cstring) {.nimcall.} - removeAttributeNode*: proc (attr: ref TNode) {.nimcall.} - removeChild*: proc (child: ref TNode) {.nimcall.} - replaceChild*: proc (newNode, oldNode: ref TNode) {.nimcall.} - replaceData*: proc (start, len: int, text: cstring) {.nimcall.} - setAttribute*: proc (name, value: cstring) {.nimcall.} - setAttributeNode*: proc (attr: ref TNode) {.nimcall.} - -when defined(kwin): - proc rawEcho {.compilerproc, nostackframe.} = - asm """ - var buf = ""; - for (var i = 0; i < arguments.length; ++i) { - buf += `toEcmaStr`(arguments[i]); - } - print(buf); - """ - -elif 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); - """ - -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, " element does not exist yet!") - - 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 {.noStackFrame, compilerproc.} = - asm """ - var result = `a` + `b`; - if (result > 2147483647 || result < -2147483648) `raiseOverflow`(); - return result; - """ - -proc subInt(a, b: int): int {.noStackFrame, compilerproc.} = - asm """ - var result = `a` - `b`; - if (result > 2147483647 || result < -2147483648) `raiseOverflow`(); - return result; - """ - -proc mulInt(a, b: int): int {.noStackFrame, compilerproc.} = - asm """ - var result = `a` * `b`; - if (result > 2147483647 || result < -2147483648) `raiseOverflow`(); - return result; - """ - -proc divInt(a, b: int): int {.noStackFrame, compilerproc.} = - asm """ - if (`b` == 0) `raiseDivByZero`(); - if (`b` == -1 && `a` == 2147483647) `raiseOverflow`(); - return Math.floor(`a` / `b`); - """ - -proc modInt(a, b: int): int {.noStackFrame, compilerproc.} = - asm """ - if (`b` == 0) `raiseDivByZero`(); - if (`b` == -1 && `a` == 2147483647) `raiseOverflow`(); - return Math.floor(`a` % `b`); - """ - -proc addInt64(a, b: int): int {.noStackFrame, compilerproc.} = - asm """ - var result = `a` + `b`; - if (result > 9223372036854775807 - || result < -9223372036854775808) `raiseOverflow`(); - return result; - """ - -proc subInt64(a, b: int): int {.noStackFrame, compilerproc.} = - asm """ - var result = `a` - `b`; - if (result > 9223372036854775807 - || result < -9223372036854775808) `raiseOverflow`(); - return result; - """ - -proc mulInt64(a, b: int): int {.noStackFrame, compilerproc.} = - asm """ - var result = `a` * `b`; - if (result > 9223372036854775807 - || result < -9223372036854775808) `raiseOverflow`(); - return result; - """ - -proc divInt64(a, b: int): int {.noStackFrame, compilerproc.} = - asm """ - if (`b` == 0) `raiseDivByZero`(); - if (`b` == -1 && `a` == 9223372036854775807) `raiseOverflow`(); - return Math.floor(`a` / `b`); - """ - -proc modInt64(a, b: int): int {.noStackFrame, compilerproc.} = - asm """ - if (`b` == 0) `raiseDivByZero`(); - if (`b` == -1 && `a` == 9223372036854775807) `raiseOverflow`(); - return Math.floor(`a` % `b`); - """ - -proc NegInt(a: int): int {.compilerproc.} = - result = a*(-1) - -proc NegInt64(a: int64): int64 {.compilerproc.} = - result = a*(-1) - -proc AbsInt(a: int): int {.compilerproc.} = - result = if a < 0: a*(-1) else: a - -proc AbsInt64(a: int64): int64 {.compilerproc.} = - result = if a < 0: a*(-1) else: a - -proc LeU(a, b: int): bool {.compilerproc.} = - result = abs(a) <= abs(b) - -proc LtU(a, b: int): bool {.compilerproc.} = - result = abs(a) < abs(b) - -proc LeU64(a, b: int64): bool {.compilerproc.} = - result = abs(a) <= abs(b) - -proc LtU64(a, b: int64): bool {.compilerproc.} = - result = abs(a) < abs(b) - -proc AddU(a, b: int): int {.compilerproc.} = - result = abs(a) + abs(b) -proc AddU64(a, b: int64): int64 {.compilerproc.} = - result = abs(a) + abs(b) - -proc SubU(a, b: int): int {.compilerproc.} = - result = abs(a) - abs(b) -proc SubU64(a, b: int64): int64 {.compilerproc.} = - result = abs(a) - abs(b) - -proc MulU(a, b: int): int {.compilerproc.} = - result = abs(a) * abs(b) -proc MulU64(a, b: int64): int64 {.compilerproc.} = - result = abs(a) * abs(b) - -proc DivU(a, b: int): int {.compilerproc.} = - result = abs(a) div abs(b) -proc DivU64(a, b: int64): int64 {.compilerproc.} = - result = abs(a) div abs(b) - -proc ModU(a, b: int): int {.compilerproc.} = - result = abs(a) mod abs(b) -proc ModU64(a, b: int64): int64 {.compilerproc.} = - result = abs(a) mod abs(b) - -proc Ze(a: int): int {.compilerproc.} = - result = a -proc Ze64(a: int64): int64 {.compilerproc.} = - result = a - -proc toU8(a: int): int8 {.noStackFrame, compilerproc.} = - asm """ - return `a`; - """ - -proc toU16(a: int): int16 {.noStackFrame, compilerproc.} = - asm """ - return `a`; - """ - -proc toU32(a: int): int32 {.noStackFrame, compilerproc.} = - asm """ - return `a`; - """ - - -proc nimMin(a, b: int): int {.compilerproc.} = return if a <= b: a else: b -proc nimMax(a, b: int): int {.compilerproc.} = return if a >= b: a else: b - -include "system/hti" - -proc isFatPointer(ti: PNimType): bool = - # This has to be consistent with the code generator! - return ti.base.kind notin {tyObject, - tyArray, tyArrayConstr, tyTuple, - tyOpenArray, tySet, tyVar, tyRef, tyPtr} - -proc NimCopy(x: pointer, ti: PNimType): pointer {.compilerproc.} - -proc NimCopyAux(dest, src: Pointer, n: ptr TNimNode) {.compilerproc.} = - case n.kind - of nkNone: sysAssert(false, "NimCopyAux") - of nkSlot: - asm "`dest`[`n`.offset] = NimCopy(`src`[`n`.offset], `n`.typ);" - of nkList: - for i in 0..n.len-1: - NimCopyAux(dest, src, n.sons[i]) - of nkCase: - asm """ - `dest`[`n`.offset] = NimCopy(`src`[`n`.offset], `n`.typ); - for (var i = 0; i < `n`.sons.length; ++i) { - NimCopyAux(`dest`, `src`, `n`.sons[i][1]); - } - """ - -proc NimCopy(x: pointer, ti: PNimType): pointer = - case ti.kind - of tyPtr, tyRef, tyVar, tyNil: - if not isFatPointer(ti): - result = x - else: - asm """ - `result` = [null, 0]; - `result`[0] = `x`[0]; - `result`[1] = `x`[1]; - """ - of tySet: - asm """ - `result` = {}; - for (var key in `x`) { `result`[key] = `x`[key]; } - """ - of tyTuple, tyObject: - if ti.base != nil: result = NimCopy(x, ti.base) - elif ti.kind == tyObject: - asm "`result` = {m_type: `ti`};" - else: - asm "`result` = {};" - NimCopyAux(result, x, ti.node) - of tySequence, tyArrayConstr, tyOpenArray, tyArray: - asm """ - `result` = new Array(`x`.length); - for (var i = 0; i < `x`.length; ++i) { - `result`[i] = NimCopy(`x`[i], `ti`.base); - } - """ - of tyString: - asm "`result` = `x`.slice(0);" - 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.} = - # types are fake - asm """ - var result = new Array(`len`); - for (var i = 0; i < `len`; ++i) result[i] = NimCopy(`value`, `typ`); - return result; - """ - -proc chckIndx(i, a, b: int): int {.compilerproc.} = - if i >= a and i <= b: return i - else: raiseIndexError() - -proc chckRange(i, a, b: int): int {.compilerproc.} = - if i >= a and i <= b: return i - else: raiseRangeError() - -proc chckObj(obj, subclass: PNimType) {.compilerproc.} = - # checks if obj is of type subclass: - var x = obj - if x == subclass: return # optimized fast path - while x != subclass: - if x == nil: - 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.} diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim new file mode 100755 index 000000000..6040fdf53 --- /dev/null +++ b/lib/system/jssys.nim @@ -0,0 +1,622 @@ +# +# +# Nimrod's Runtime Library +# (c) Copyright 2012 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +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 + PSafePoint = ptr TSafePoint + TSafePoint {.compilerproc, final.} = object + prev: PSafePoint # points to next safe point + exc: ref E_Base + + PCallFrame = ptr TCallFrame + TCallFrame {.importc, nodecl, final.} = object + prev: PCallFrame + procname: CString + line: int # current line number + filename: CString + +var + framePtr {.importc, nodecl, volatile.}: PCallFrame + excHandler {.importc, nodecl, volatile.}: PSafePoint = nil + # list of exception handlers + # a global variable for the root of all try blocks + +{.push stacktrace: off, profiler:off.} +proc nimBoolToStr(x: bool): string {.compilerproc.} = + if x: result = "true" + else: result = "false" + +proc nimCharToStr(x: char): string {.compilerproc.} = + result = newString(1) + result[0] = x + +proc getCurrentExceptionMsg(): string = + if excHandler != nil: return $excHandler.exc.msg + return "" + +proc auxWriteStackTrace(f: PCallFrame): string = + type + TTempFrame = tuple[procname: CString, line: int] + var + it = f + i = 0 + total = 0 + tempFrames: array [0..63, TTempFrame] + while it != nil and i <= high(tempFrames): + tempFrames[i].procname = it.procname + tempFrames[i].line = it.line + inc(i) + inc(total) + it = it.prev + while it != nil: + inc(total) + it = it.prev + result = "" + # if the buffer overflowed print '...': + if total != i: + add(result, "(") + add(result, $(total-i)) + add(result, " calls omitted) ...\n") + for j in countdown(i-1, 0): + add(result, tempFrames[j].procname) + if tempFrames[j].line > 0: + add(result, ", line: ") + add(result, $tempFrames[j].line) + add(result, "\n") + +proc rawWriteStackTrace(): string = + if framePtr == nil: + result = "No stack traceback available\n" + else: + result = "Traceback (most recent call last)\n"& auxWriteStackTrace(framePtr) + framePtr = nil + +proc raiseException(e: ref E_Base, ename: cstring) {. + compilerproc, noStackFrame.} = + e.name = ename + if excHandler != nil: + excHandler.exc = e + else: + when nimrodStackTrace: + var buf = rawWriteStackTrace() + else: + var buf = "" + if e.msg != nil and e.msg[0] != '\0': + add(buf, "Error: unhandled exception: ") + add(buf, e.msg) + else: + add(buf, "Error: unhandled exception") + add(buf, " [") + add(buf, ename) + add(buf, "]\n") + alert(buf) + asm """throw `e`;""" + +proc reraiseException() {.compilerproc, noStackFrame.} = + if excHandler == nil: + raise newException(ENoExceptionToReraise, "no exception to reraise") + else: + asm """throw excHandler.exc;""" + +proc raiseOverflow {.exportc: "raiseOverflow", noreturn.} = + raise newException(EOverflow, "over- or underflow") + +proc raiseDivByZero {.exportc: "raiseDivByZero", noreturn.} = + raise newException(EDivByZero, "divison by zero") + +proc raiseRangeError() {.compilerproc, noreturn.} = + raise newException(EOutOfRange, "value out of range") + +proc raiseIndexError() {.compilerproc, noreturn.} = + raise newException(EInvalidIndex, "index out of bounds") + +proc raiseFieldError(f: string) {.compilerproc, noreturn.} = + raise newException(EInvalidField, f & " is not accessible") + +proc SetConstr() {.varargs, noStackFrame, compilerproc.} = + asm """ + var result = {}; + for (var i = 0; i < arguments.length; ++i) { + var x = arguments[i]; + if (typeof(x) == "object") { + for (var j = x[0]; j <= x[1]; ++j) { + result[j] = true; + } + } else { + result[x] = true; + } + } + return result; + """ + +proc cstrToNimstr(c: cstring): string {.noStackFrame, compilerproc.} = + asm """ + var result = []; + for (var i = 0; i < `c`.length; ++i) { + result[i] = `c`.charCodeAt(i); + } + result[result.length] = 0; // terminating zero + return result; + """ + +proc toJSStr(s: string): cstring {.noStackFrame, compilerproc.} = + asm """ + var len = `s`.length-1; + var result = new Array(len); + var fcc = String.fromCharCode; + for (var i = 0; i < len; ++i) { + result[i] = fcc(`s`[i]); + } + return result.join(""); + """ + +proc mnewString(len: int): string {.noStackFrame, compilerproc.} = + asm """ + var result = new Array(`len`+1); + result[0] = 0; + result[`len`] = 0; + return result; + """ + +proc SetCard(a: int): int {.compilerproc, noStackFrame.} = + # argument type is a fake + asm """ + var result = 0; + for (var elem in `a`) { ++result; } + return result; + """ + +proc SetEq(a, b: int): bool {.compilerproc, noStackFrame.} = + asm """ + for (var elem in `a`) { if (!`b`[elem]) return false; } + for (var elem in `b`) { if (!`a`[elem]) return false; } + return true; + """ + +proc SetLe(a, b: int): bool {.compilerproc, noStackFrame.} = + asm """ + for (var elem in `a`) { if (!`b`[elem]) return false; } + return true; + """ + +proc SetLt(a, b: int): bool {.compilerproc.} = + result = SetLe(a, b) and not SetEq(a, b) + +proc SetMul(a, b: int): int {.compilerproc, noStackFrame.} = + asm """ + var result = {}; + for (var elem in `a`) { + if (`b`[elem]) { result[elem] = true; } + } + return result; + """ + +proc SetPlus(a, b: int): int {.compilerproc, noStackFrame.} = + asm """ + var result = {}; + for (var elem in `a`) { result[elem] = true; } + for (var elem in `b`) { result[elem] = true; } + return result; + """ + +proc SetMinus(a, b: int): int {.compilerproc, noStackFrame.} = + asm """ + var result = {}; + for (var elem in `a`) { + if (!`b`[elem]) { result[elem] = true; } + } + return result; + """ + +proc cmpStrings(a, b: string): int {.noStackFrame, compilerProc.} = + asm """ + if (`a` == `b`) return 0; + if (!`a`) return -1; + if (!`b`) return 1; + for (var i = 0; i < `a`.length-1; ++i) { + var result = `a`[i] - `b`[i]; + if (result != 0) return result; + } + return 0; + """ + +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 false; + var alen = `a`.length; + if (alen != `b`.length) return false; + for (var i = 0; i < alen; ++i) + if (`a`[i] != `b`[i]) return false; + return true; + """ + +type + TDocument {.importc.} = object of TObject + write: proc (text: cstring) {.nimcall.} + writeln: proc (text: cstring) {.nimcall.} + createAttribute: proc (identifier: cstring): ref TNode {.nimcall.} + createElement: proc (identifier: cstring): ref TNode {.nimcall.} + createTextNode: proc (identifier: cstring): ref TNode {.nimcall.} + getElementById: proc (id: cstring): ref TNode {.nimcall.} + getElementsByName: proc (name: cstring): seq[ref TNode] {.nimcall.} + getElementsByTagName: proc (name: cstring): seq[ref TNode] {.nimcall.} + + TNodeType* = enum + ElementNode = 1, + AttributeNode, + TextNode, + CDATANode, + EntityRefNode, + EntityNode, + ProcessingInstructionNode, + CommentNode, + DocumentNode, + DocumentTypeNode, + DocumentFragmentNode, + NotationNode + TNode* {.importc.} = object of TObject + attributes*: seq[ref TNode] + childNodes*: seq[ref TNode] + data*: cstring + firstChild*: ref TNode + lastChild*: ref TNode + nextSibling*: ref TNode + nodeName*: cstring + nodeType*: TNodeType + nodeValue*: cstring + parentNode*: ref TNode + previousSibling*: ref TNode + appendChild*: proc (child: ref TNode) {.nimcall.} + appendData*: proc (data: cstring) {.nimcall.} + cloneNode*: proc (copyContent: bool) {.nimcall.} + deleteData*: proc (start, len: int) {.nimcall.} + getAttribute*: proc (attr: cstring): cstring {.nimcall.} + getAttributeNode*: proc (attr: cstring): ref TNode {.nimcall.} + getElementsByTagName*: proc (): seq[ref TNode] {.nimcall.} + hasChildNodes*: proc (): bool {.nimcall.} + insertBefore*: proc (newNode, before: ref TNode) {.nimcall.} + insertData*: proc (position: int, data: cstring) {.nimcall.} + removeAttribute*: proc (attr: cstring) {.nimcall.} + removeAttributeNode*: proc (attr: ref TNode) {.nimcall.} + removeChild*: proc (child: ref TNode) {.nimcall.} + replaceChild*: proc (newNode, oldNode: ref TNode) {.nimcall.} + replaceData*: proc (start, len: int, text: cstring) {.nimcall.} + setAttribute*: proc (name, value: cstring) {.nimcall.} + setAttributeNode*: proc (attr: ref TNode) {.nimcall.} + +when defined(kwin): + proc rawEcho {.compilerproc, nostackframe.} = + asm """ + var buf = ""; + for (var i = 0; i < arguments.length; ++i) { + buf += `toJSStr`(arguments[i]); + } + print(buf); + """ + +elif defined(nodejs): + proc ewriteln(x: cstring) = log(x) + + proc rawEcho {.compilerproc, nostackframe.} = + asm """ + var buf = ""; + for (var i = 0; i < arguments.length; ++i) { + buf += `toJSStr`(arguments[i]); + } + console.log(buf); + """ + +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, " element does not exist yet!") + + 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 = `toJSStr`(arguments[i]); + `node`.appendChild(document.createTextNode(x)) + } + """ + node.appendChild(document.createElement("br")) + +# Arithmetic: +proc addInt(a, b: int): int {.noStackFrame, compilerproc.} = + asm """ + var result = `a` + `b`; + if (result > 2147483647 || result < -2147483648) `raiseOverflow`(); + return result; + """ + +proc subInt(a, b: int): int {.noStackFrame, compilerproc.} = + asm """ + var result = `a` - `b`; + if (result > 2147483647 || result < -2147483648) `raiseOverflow`(); + return result; + """ + +proc mulInt(a, b: int): int {.noStackFrame, compilerproc.} = + asm """ + var result = `a` * `b`; + if (result > 2147483647 || result < -2147483648) `raiseOverflow`(); + return result; + """ + +proc divInt(a, b: int): int {.noStackFrame, compilerproc.} = + asm """ + if (`b` == 0) `raiseDivByZero`(); + if (`b` == -1 && `a` == 2147483647) `raiseOverflow`(); + return Math.floor(`a` / `b`); + """ + +proc modInt(a, b: int): int {.noStackFrame, compilerproc.} = + asm """ + if (`b` == 0) `raiseDivByZero`(); + if (`b` == -1 && `a` == 2147483647) `raiseOverflow`(); + return Math.floor(`a` % `b`); + """ + +proc addInt64(a, b: int): int {.noStackFrame, compilerproc.} = + asm """ + var result = `a` + `b`; + if (result > 9223372036854775807 + || result < -9223372036854775808) `raiseOverflow`(); + return result; + """ + +proc subInt64(a, b: int): int {.noStackFrame, compilerproc.} = + asm """ + var result = `a` - `b`; + if (result > 9223372036854775807 + || result < -9223372036854775808) `raiseOverflow`(); + return result; + """ + +proc mulInt64(a, b: int): int {.noStackFrame, compilerproc.} = + asm """ + var result = `a` * `b`; + if (result > 9223372036854775807 + || result < -9223372036854775808) `raiseOverflow`(); + return result; + """ + +proc divInt64(a, b: int): int {.noStackFrame, compilerproc.} = + asm """ + if (`b` == 0) `raiseDivByZero`(); + if (`b` == -1 && `a` == 9223372036854775807) `raiseOverflow`(); + return Math.floor(`a` / `b`); + """ + +proc modInt64(a, b: int): int {.noStackFrame, compilerproc.} = + asm """ + if (`b` == 0) `raiseDivByZero`(); + if (`b` == -1 && `a` == 9223372036854775807) `raiseOverflow`(); + return Math.floor(`a` % `b`); + """ + +proc NegInt(a: int): int {.compilerproc.} = + result = a*(-1) + +proc NegInt64(a: int64): int64 {.compilerproc.} = + result = a*(-1) + +proc AbsInt(a: int): int {.compilerproc.} = + result = if a < 0: a*(-1) else: a + +proc AbsInt64(a: int64): int64 {.compilerproc.} = + result = if a < 0: a*(-1) else: a + +proc LeU(a, b: int): bool {.compilerproc.} = + result = abs(a) <= abs(b) + +proc LtU(a, b: int): bool {.compilerproc.} = + result = abs(a) < abs(b) + +proc LeU64(a, b: int64): bool {.compilerproc.} = + result = abs(a) <= abs(b) + +proc LtU64(a, b: int64): bool {.compilerproc.} = + result = abs(a) < abs(b) + +proc AddU(a, b: int): int {.compilerproc.} = + result = abs(a) + abs(b) +proc AddU64(a, b: int64): int64 {.compilerproc.} = + result = abs(a) + abs(b) + +proc SubU(a, b: int): int {.compilerproc.} = + result = abs(a) - abs(b) +proc SubU64(a, b: int64): int64 {.compilerproc.} = + result = abs(a) - abs(b) + +proc MulU(a, b: int): int {.compilerproc.} = + result = abs(a) * abs(b) +proc MulU64(a, b: int64): int64 {.compilerproc.} = + result = abs(a) * abs(b) + +proc DivU(a, b: int): int {.compilerproc.} = + result = abs(a) div abs(b) +proc DivU64(a, b: int64): int64 {.compilerproc.} = + result = abs(a) div abs(b) + +proc ModU(a, b: int): int {.compilerproc.} = + result = abs(a) mod abs(b) +proc ModU64(a, b: int64): int64 {.compilerproc.} = + result = abs(a) mod abs(b) + +proc Ze(a: int): int {.compilerproc.} = + result = a +proc Ze64(a: int64): int64 {.compilerproc.} = + result = a + +proc toU8(a: int): int8 {.noStackFrame, compilerproc.} = + asm """ + return `a`; + """ + +proc toU16(a: int): int16 {.noStackFrame, compilerproc.} = + asm """ + return `a`; + """ + +proc toU32(a: int): int32 {.noStackFrame, compilerproc.} = + asm """ + return `a`; + """ + + +proc nimMin(a, b: int): int {.compilerproc.} = return if a <= b: a else: b +proc nimMax(a, b: int): int {.compilerproc.} = return if a >= b: a else: b + +include "system/hti" + +proc isFatPointer(ti: PNimType): bool = + # This has to be consistent with the code generator! + return ti.base.kind notin {tyObject, + tyArray, tyArrayConstr, tyTuple, + tyOpenArray, tySet, tyVar, tyRef, tyPtr} + +proc NimCopy(x: pointer, ti: PNimType): pointer {.compilerproc.} + +proc NimCopyAux(dest, src: Pointer, n: ptr TNimNode) {.compilerproc.} = + case n.kind + of nkNone: sysAssert(false, "NimCopyAux") + of nkSlot: + asm "`dest`[`n`.offset] = NimCopy(`src`[`n`.offset], `n`.typ);" + of nkList: + for i in 0..n.len-1: + NimCopyAux(dest, src, n.sons[i]) + of nkCase: + asm """ + `dest`[`n`.offset] = NimCopy(`src`[`n`.offset], `n`.typ); + for (var i = 0; i < `n`.sons.length; ++i) { + NimCopyAux(`dest`, `src`, `n`.sons[i][1]); + } + """ + +proc NimCopy(x: pointer, ti: PNimType): pointer = + case ti.kind + of tyPtr, tyRef, tyVar, tyNil: + if not isFatPointer(ti): + result = x + else: + asm """ + `result` = [null, 0]; + `result`[0] = `x`[0]; + `result`[1] = `x`[1]; + """ + of tySet: + asm """ + `result` = {}; + for (var key in `x`) { `result`[key] = `x`[key]; } + """ + of tyTuple, tyObject: + if ti.base != nil: result = NimCopy(x, ti.base) + elif ti.kind == tyObject: + asm "`result` = {m_type: `ti`};" + else: + asm "`result` = {};" + NimCopyAux(result, x, ti.node) + of tySequence, tyArrayConstr, tyOpenArray, tyArray: + asm """ + `result` = new Array(`x`.length); + for (var i = 0; i < `x`.length; ++i) { + `result`[i] = NimCopy(`x`[i], `ti`.base); + } + """ + of tyString: + asm "`result` = `x`.slice(0);" + 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.} = + # types are fake + asm """ + var result = new Array(`len`); + for (var i = 0; i < `len`; ++i) result[i] = NimCopy(`value`, `typ`); + return result; + """ + +proc chckIndx(i, a, b: int): int {.compilerproc.} = + if i >= a and i <= b: return i + else: raiseIndexError() + +proc chckRange(i, a, b: int): int {.compilerproc.} = + if i >= a and i <= b: return i + else: raiseRangeError() + +proc chckObj(obj, subclass: PNimType) {.compilerproc.} = + # checks if obj is of type subclass: + var x = obj + if x == subclass: return # optimized fast path + while x != subclass: + if x == nil: + 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.} -- cgit 1.4.1-2-gfad0 From 260ddd735a684392de7bb41e6c576ad5af7e163f Mon Sep 17 00:00:00 2001 From: Simon Hafner Date: Sat, 9 Feb 2013 15:19:09 -0600 Subject: on the path to get unittest running from JS --- lib/pure/unittest.nim | 39 +++++++++++++++++++++++++++------------ lib/system/jssys.nim | 2 +- 2 files changed, 28 insertions(+), 13 deletions(-) (limited to 'lib/system') diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim index fce84bea4..dac9dedcf 100644 --- a/lib/pure/unittest.nim +++ b/lib/pure/unittest.nim @@ -17,7 +17,13 @@ ## It is loosely based on C++'s boost.test and Haskell's QuickTest import - macros, terminal, os + macros + +when defined(stdout): + import os + +when not defined(ECMAScript): + import terminal type TTestStatus* = enum OK, FAILED @@ -52,12 +58,15 @@ proc testDone(name: string, s: TTestStatus) = program_result += 1 if OutputLevel != PRINT_NONE and (OutputLevel == PRINT_ALL or s == FAILED): - var color = (if s == OK: fgGreen else: fgRed) - - if ColorOutput: - styledEcho styleBright, color, "[", $s, "] ", fgWhite, name, "\n" + proc rawPrint() = echo("[", $s, "] ", name, "\n") + when not defined(ECMAScript): + if ColorOutput and not defined(ECMAScript): + var color = (if s == OK: fgGreen else: fgRed) + styledEcho styleBright, color, "[", $s, "] ", fgWhite, name, "\n" + else: + rawPrint() else: - echo "[", $s, "] ", name, "\n" + rawPrint() template test*(name: expr, body: stmt): stmt {.immediate, dirty.} = bind shouldRun, checkpoints, testDone @@ -87,7 +96,8 @@ template fail* = for msg in items(checkpoints): echo msg - if AbortOnError: quit(1) + when not defined(ECMAScript): + if AbortOnError: quit(1) TestStatusIMPL = FAILED checkpoints = @[] @@ -171,14 +181,19 @@ macro expect*(exceptions: varargs[expr], body: stmt): stmt {.immediate.} = result = getAst(expectBody(errorTypes, exp.lineinfo, body)) -## Reading settings -var envOutLvl = os.getEnv("NIMTEST_OUTPUT_LVL").string +when defined(stdout): + ## Reading settings + var envOutLvl = os.getEnv("NIMTEST_OUTPUT_LVL").string + + AbortOnError = existsEnv("NIMTEST_ABORT_ON_ERROR") + ColorOutput = not existsEnv("NIMTEST_NO_COLOR") + +else: + var envOutLvl = "" # TODO + ColorOutput = false if envOutLvl.len > 0: for opt in countup(low(TOutputLevel), high(TOutputLevel)): if $opt == envOutLvl: OutputLevel = opt break - -AbortOnError = existsEnv("NIMTEST_ABORT_ON_ERROR") -ColorOutput = not existsEnv("NIMTEST_NO_COLOR") diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim index 6040fdf53..789e39d6d 100755 --- a/lib/system/jssys.nim +++ b/lib/system/jssys.nim @@ -42,7 +42,7 @@ proc nimCharToStr(x: char): string {.compilerproc.} = result = newString(1) result[0] = x -proc getCurrentExceptionMsg(): string = +proc getCurrentExceptionMsg*(): string = if excHandler != nil: return $excHandler.exc.msg return "" -- cgit 1.4.1-2-gfad0