JS codegen enhancements; still unusable

This commit is contained in:
Araq
2012-07-01 19:35:19 +02:00
parent ee1bcb6414
commit fe285b354d
9 changed files with 223 additions and 59 deletions

View File

@@ -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.}