fixes #2298
This commit is contained in:
parent
b97207a74c
commit
f88678bed4
1 changed files with 205 additions and 203 deletions
|
|
@ -62,13 +62,13 @@ type
|
||||||
res: PRope # result part; index if this is an
|
res: PRope # result part; index if this is an
|
||||||
# (address, index)-tuple
|
# (address, index)-tuple
|
||||||
address: PRope # address of an (address, index)-tuple
|
address: PRope # address of an (address, index)-tuple
|
||||||
|
|
||||||
TBlock = object
|
TBlock = object
|
||||||
id: int # the ID of the label; positive means that it
|
id: int # the ID of the label; positive means that it
|
||||||
# has been used (i.e. the label should be emitted)
|
# has been used (i.e. the label should be emitted)
|
||||||
isLoop: bool # whether it's a 'block' or 'while'
|
isLoop: bool # whether it's a 'block' or 'while'
|
||||||
|
|
||||||
TGlobals = object
|
TGlobals = object
|
||||||
typeInfo, code: PRope
|
typeInfo, code: PRope
|
||||||
forwarded: seq[PSym]
|
forwarded: seq[PSym]
|
||||||
generatedSyms: IntSet
|
generatedSyms: IntSet
|
||||||
|
|
@ -98,7 +98,7 @@ proc newGlobals(): PGlobals =
|
||||||
result.generatedSyms = initIntSet()
|
result.generatedSyms = initIntSet()
|
||||||
result.typeInfoGenerated = initIntSet()
|
result.typeInfoGenerated = initIntSet()
|
||||||
|
|
||||||
proc initCompRes(r: var TCompRes) =
|
proc initCompRes(r: var TCompRes) =
|
||||||
r.address = nil
|
r.address = nil
|
||||||
r.res = nil
|
r.res = nil
|
||||||
r.typ = etyNone
|
r.typ = etyNone
|
||||||
|
|
@ -112,7 +112,7 @@ proc rdLoc(a: TCompRes): PRope {.inline.} =
|
||||||
else:
|
else:
|
||||||
result = ropef("$1[$2]", a.address, a.res)
|
result = ropef("$1[$2]", a.address, a.res)
|
||||||
|
|
||||||
proc newProc(globals: PGlobals, module: BModule, procDef: PNode,
|
proc newProc(globals: PGlobals, module: BModule, procDef: PNode,
|
||||||
options: TOptions): PProc =
|
options: TOptions): PProc =
|
||||||
result = PProc(
|
result = PProc(
|
||||||
blocks: @[],
|
blocks: @[],
|
||||||
|
|
@ -121,30 +121,30 @@ proc newProc(globals: PGlobals, module: BModule, procDef: PNode,
|
||||||
procDef: procDef,
|
procDef: procDef,
|
||||||
g: globals)
|
g: globals)
|
||||||
if procDef != nil: result.prc = procDef.sons[namePos].sym
|
if procDef != nil: result.prc = procDef.sons[namePos].sym
|
||||||
|
|
||||||
const
|
const
|
||||||
MappedToObject = {tyObject, tyArray, tyArrayConstr, tyTuple, tyOpenArray,
|
MappedToObject = {tyObject, tyArray, tyArrayConstr, tyTuple, tyOpenArray,
|
||||||
tySet, tyVar, tyRef, tyPtr, tyBigNum, tyVarargs}
|
tySet, tyVar, tyRef, tyPtr, tyBigNum, tyVarargs}
|
||||||
|
|
||||||
proc mapType(typ: PType): TJSTypeKind =
|
proc mapType(typ: PType): TJSTypeKind =
|
||||||
let t = skipTypes(typ, abstractInst)
|
let t = skipTypes(typ, abstractInst)
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyVar, tyRef, tyPtr:
|
of tyVar, tyRef, tyPtr:
|
||||||
if skipTypes(t.lastSon, abstractInst).kind in MappedToObject:
|
if skipTypes(t.lastSon, abstractInst).kind in MappedToObject:
|
||||||
result = etyObject
|
result = etyObject
|
||||||
else:
|
else:
|
||||||
result = etyBaseIndex
|
result = etyBaseIndex
|
||||||
of tyPointer:
|
of tyPointer:
|
||||||
# treat a tyPointer like a typed pointer to an array of bytes
|
# treat a tyPointer like a typed pointer to an array of bytes
|
||||||
result = etyInt
|
result = etyInt
|
||||||
of tyRange, tyDistinct, tyOrdinal, tyConst, tyMutable, tyIter, tyProxy:
|
of tyRange, tyDistinct, tyOrdinal, tyConst, tyMutable, tyIter, tyProxy:
|
||||||
result = mapType(t.sons[0])
|
result = mapType(t.sons[0])
|
||||||
of tyInt..tyInt64, tyUInt..tyUInt64, tyEnum, tyChar: result = etyInt
|
of tyInt..tyInt64, tyUInt..tyUInt64, tyEnum, tyChar: result = etyInt
|
||||||
of tyBool: result = etyBool
|
of tyBool: result = etyBool
|
||||||
of tyFloat..tyFloat128: result = etyFloat
|
of tyFloat..tyFloat128: result = etyFloat
|
||||||
of tySet: result = etyObject # map a set to a table
|
of tySet: result = etyObject # map a set to a table
|
||||||
of tyString, tySequence: result = etyInt # little hack to get right semantics
|
of tyString, tySequence: result = etyInt # little hack to get right semantics
|
||||||
of tyObject, tyArray, tyArrayConstr, tyTuple, tyOpenArray, tyBigNum,
|
of tyObject, tyArray, tyArrayConstr, tyTuple, tyOpenArray, tyBigNum,
|
||||||
tyVarargs:
|
tyVarargs:
|
||||||
result = etyObject
|
result = etyObject
|
||||||
of tyNil: result = etyNull
|
of tyNil: result = etyNull
|
||||||
|
|
@ -154,10 +154,10 @@ proc mapType(typ: PType): TJSTypeKind =
|
||||||
result = etyNone
|
result = etyNone
|
||||||
of tyProc: result = etyProc
|
of tyProc: result = etyProc
|
||||||
of tyCString: result = etyString
|
of tyCString: result = etyString
|
||||||
|
|
||||||
proc mangleName(s: PSym): PRope =
|
proc mangleName(s: PSym): PRope =
|
||||||
result = s.loc.r
|
result = s.loc.r
|
||||||
if result == nil:
|
if result == nil:
|
||||||
result = toRope(mangle(s.name.s))
|
result = toRope(mangle(s.name.s))
|
||||||
app(result, "_")
|
app(result, "_")
|
||||||
app(result, toRope(s.id))
|
app(result, toRope(s.id))
|
||||||
|
|
@ -166,7 +166,7 @@ proc mangleName(s: PSym): PRope =
|
||||||
proc makeJSString(s: string): PRope = strutils.escape(s).toRope
|
proc makeJSString(s: string): PRope = strutils.escape(s).toRope
|
||||||
|
|
||||||
include jstypes
|
include jstypes
|
||||||
|
|
||||||
proc gen(p: PProc, n: PNode, r: var TCompRes)
|
proc gen(p: PProc, n: PNode, r: var TCompRes)
|
||||||
proc genStmt(p: PProc, n: PNode)
|
proc genStmt(p: PProc, n: PNode)
|
||||||
proc genProc(oldProc: PProc, prc: PSym): PRope
|
proc genProc(oldProc: PProc, prc: PSym): PRope
|
||||||
|
|
@ -341,14 +341,14 @@ const # magic checked op; magic unchecked op; checked op; unchecked op
|
||||||
["", "", "$1", "$1"], # ToBiggestFloat
|
["", "", "$1", "$1"], # ToBiggestFloat
|
||||||
["", "", "Math.floor($1)", "Math.floor($1)"], # ToInt
|
["", "", "Math.floor($1)", "Math.floor($1)"], # ToInt
|
||||||
["", "", "Math.floor($1)", "Math.floor($1)"], # ToBiggestInt
|
["", "", "Math.floor($1)", "Math.floor($1)"], # ToBiggestInt
|
||||||
["nimCharToStr", "nimCharToStr", "nimCharToStr($1)", "nimCharToStr($1)"],
|
["nimCharToStr", "nimCharToStr", "nimCharToStr($1)", "nimCharToStr($1)"],
|
||||||
["nimBoolToStr", "nimBoolToStr", "nimBoolToStr($1)", "nimBoolToStr($1)"], [
|
["nimBoolToStr", "nimBoolToStr", "nimBoolToStr($1)", "nimBoolToStr($1)"], [
|
||||||
"cstrToNimstr", "cstrToNimstr", "cstrToNimstr(($1)+\"\")",
|
"cstrToNimstr", "cstrToNimstr", "cstrToNimstr(($1)+\"\")",
|
||||||
"cstrToNimstr(($1)+\"\")"], ["cstrToNimstr", "cstrToNimstr",
|
"cstrToNimstr(($1)+\"\")"], ["cstrToNimstr", "cstrToNimstr",
|
||||||
"cstrToNimstr(($1)+\"\")",
|
"cstrToNimstr(($1)+\"\")",
|
||||||
"cstrToNimstr(($1)+\"\")"], ["cstrToNimstr",
|
"cstrToNimstr(($1)+\"\")"], ["cstrToNimstr",
|
||||||
"cstrToNimstr", "cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")"],
|
"cstrToNimstr", "cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")"],
|
||||||
["cstrToNimstr", "cstrToNimstr", "cstrToNimstr($1)", "cstrToNimstr($1)"],
|
["cstrToNimstr", "cstrToNimstr", "cstrToNimstr($1)", "cstrToNimstr($1)"],
|
||||||
["", "", "$1", "$1"]]
|
["", "", "$1", "$1"]]
|
||||||
|
|
||||||
luaOps: TMagicOps = [
|
luaOps: TMagicOps = [
|
||||||
|
|
@ -441,14 +441,14 @@ const # magic checked op; magic unchecked op; checked op; unchecked op
|
||||||
["", "", "$1", "$1"], # ToBiggestFloat
|
["", "", "$1", "$1"], # ToBiggestFloat
|
||||||
["", "", "Math.floor($1)", "Math.floor($1)"], # ToInt
|
["", "", "Math.floor($1)", "Math.floor($1)"], # ToInt
|
||||||
["", "", "Math.floor($1)", "Math.floor($1)"], # ToBiggestInt
|
["", "", "Math.floor($1)", "Math.floor($1)"], # ToBiggestInt
|
||||||
["nimCharToStr", "nimCharToStr", "nimCharToStr($1)", "nimCharToStr($1)"],
|
["nimCharToStr", "nimCharToStr", "nimCharToStr($1)", "nimCharToStr($1)"],
|
||||||
["nimBoolToStr", "nimBoolToStr", "nimBoolToStr($1)", "nimBoolToStr($1)"], [
|
["nimBoolToStr", "nimBoolToStr", "nimBoolToStr($1)", "nimBoolToStr($1)"], [
|
||||||
"cstrToNimstr", "cstrToNimstr", "cstrToNimstr(($1)+\"\")",
|
"cstrToNimstr", "cstrToNimstr", "cstrToNimstr(($1)+\"\")",
|
||||||
"cstrToNimstr(($1)+\"\")"], ["cstrToNimstr", "cstrToNimstr",
|
"cstrToNimstr(($1)+\"\")"], ["cstrToNimstr", "cstrToNimstr",
|
||||||
"cstrToNimstr(($1)+\"\")",
|
"cstrToNimstr(($1)+\"\")",
|
||||||
"cstrToNimstr(($1)+\"\")"], ["cstrToNimstr",
|
"cstrToNimstr(($1)+\"\")"], ["cstrToNimstr",
|
||||||
"cstrToNimstr", "cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")"],
|
"cstrToNimstr", "cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")"],
|
||||||
["cstrToNimstr", "cstrToNimstr", "cstrToNimstr($1)", "cstrToNimstr($1)"],
|
["cstrToNimstr", "cstrToNimstr", "cstrToNimstr($1)", "cstrToNimstr($1)"],
|
||||||
["", "", "$1", "$1"]]
|
["", "", "$1", "$1"]]
|
||||||
|
|
||||||
proc binaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) =
|
proc binaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) =
|
||||||
|
|
@ -502,9 +502,9 @@ proc genLineDir(p: PProc, n: PNode) =
|
||||||
appf(p.body, "endb($1);$n", [toRope(line)])
|
appf(p.body, "endb($1);$n", [toRope(line)])
|
||||||
elif ({optLineTrace, optStackTrace} * p.options ==
|
elif ({optLineTrace, optStackTrace} * p.options ==
|
||||||
{optLineTrace, optStackTrace}) and
|
{optLineTrace, optStackTrace}) and
|
||||||
((p.prc == nil) or not (sfPure in p.prc.flags)):
|
((p.prc == nil) or not (sfPure in p.prc.flags)):
|
||||||
appf(p.body, "F.line = $1;$n", [toRope(line)])
|
appf(p.body, "F.line = $1;$n", [toRope(line)])
|
||||||
|
|
||||||
proc genWhileStmt(p: PProc, n: PNode) =
|
proc genWhileStmt(p: PProc, n: PNode) =
|
||||||
var
|
var
|
||||||
cond: TCompRes
|
cond: TCompRes
|
||||||
|
|
@ -533,7 +533,7 @@ proc moveInto(p: PProc, src: var TCompRes, dest: TCompRes) =
|
||||||
src.kind = resNone
|
src.kind = resNone
|
||||||
src.res = nil
|
src.res = nil
|
||||||
|
|
||||||
proc genTry(p: PProc, n: PNode, r: var TCompRes) =
|
proc genTry(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
# code to generate:
|
# code to generate:
|
||||||
#
|
#
|
||||||
# var sp = {prev: excHandler, exc: null};
|
# var sp = {prev: excHandler, exc: null};
|
||||||
|
|
@ -560,8 +560,8 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
inc(p.unique)
|
inc(p.unique)
|
||||||
var safePoint = ropef("Tmp$1", [toRope(p.unique)])
|
var safePoint = ropef("Tmp$1", [toRope(p.unique)])
|
||||||
appf(p.body,
|
appf(p.body,
|
||||||
"var $1 = {prev: excHandler, exc: null};$nexcHandler = $1;$n" |
|
"var $1 = {prev: excHandler, exc: null};$nexcHandler = $1;$n" |
|
||||||
"local $1 = pcall(",
|
"local $1 = pcall(",
|
||||||
[safePoint])
|
[safePoint])
|
||||||
if optStackTrace in p.options: app(p.body, "framePtr = F;" & tnl)
|
if optStackTrace in p.options: app(p.body, "framePtr = F;" & tnl)
|
||||||
appf(p.body, "try {$n" | "function()$n")
|
appf(p.body, "try {$n" | "function()$n")
|
||||||
|
|
@ -574,9 +574,9 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
appf(p.body, "} catch (EXC) {$n lastJSError = EXC;$n")
|
appf(p.body, "} catch (EXC) {$n lastJSError = EXC;$n")
|
||||||
elif p.target == targetLua:
|
elif p.target == targetLua:
|
||||||
appf(p.body, "end)$n")
|
appf(p.body, "end)$n")
|
||||||
while i < length and n.sons[i].kind == nkExceptBranch:
|
while i < length and n.sons[i].kind == nkExceptBranch:
|
||||||
let blen = sonsLen(n.sons[i])
|
let blen = sonsLen(n.sons[i])
|
||||||
if blen == 1:
|
if blen == 1:
|
||||||
# general except section:
|
# general except section:
|
||||||
if i > 1: appf(p.body, "else {$n" | "else$n")
|
if i > 1: appf(p.body, "else {$n" | "else$n")
|
||||||
gen(p, n.sons[i].sons[0], a)
|
gen(p, n.sons[i].sons[0], a)
|
||||||
|
|
@ -585,11 +585,11 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
else:
|
else:
|
||||||
var orExpr: PRope = nil
|
var orExpr: PRope = nil
|
||||||
useMagic(p, "isObj")
|
useMagic(p, "isObj")
|
||||||
for j in countup(0, blen - 2):
|
for j in countup(0, blen - 2):
|
||||||
if n.sons[i].sons[j].kind != nkType:
|
if n.sons[i].sons[j].kind != nkType:
|
||||||
internalError(n.info, "genTryStmt")
|
internalError(n.info, "genTryStmt")
|
||||||
if orExpr != nil: app(orExpr, "||" | " or ")
|
if orExpr != nil: app(orExpr, "||" | " or ")
|
||||||
appf(orExpr, "isObj($1.exc.m_type, $2)",
|
appf(orExpr, "isObj($1.exc.m_type, $2)",
|
||||||
[safePoint, genTypeInfo(p, n.sons[i].sons[j].typ)])
|
[safePoint, genTypeInfo(p, n.sons[i].sons[j].typ)])
|
||||||
if i > 1: app(p.body, "else ")
|
if i > 1: app(p.body, "else ")
|
||||||
appf(p.body, "if ($1.exc && ($2)) {$n" | "if $1.exc and ($2) then$n",
|
appf(p.body, "if ($1.exc && ($2)) {$n" | "if $1.exc and ($2) then$n",
|
||||||
|
|
@ -622,13 +622,13 @@ proc genRaiseStmt(p: PProc, n: PNode) =
|
||||||
useMagic(p, "reraiseException")
|
useMagic(p, "reraiseException")
|
||||||
app(p.body, "reraiseException();" & tnl)
|
app(p.body, "reraiseException();" & tnl)
|
||||||
|
|
||||||
proc genCaseJS(p: PProc, n: PNode, r: var TCompRes) =
|
proc genCaseJS(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
var
|
var
|
||||||
cond, stmt: TCompRes
|
cond, stmt: TCompRes
|
||||||
genLineDir(p, n)
|
genLineDir(p, n)
|
||||||
gen(p, n.sons[0], cond)
|
gen(p, n.sons[0], cond)
|
||||||
let stringSwitch = skipTypes(n.sons[0].typ, abstractVar).kind == tyString
|
let stringSwitch = skipTypes(n.sons[0].typ, abstractVar).kind == tyString
|
||||||
if stringSwitch:
|
if stringSwitch:
|
||||||
useMagic(p, "toJSStr")
|
useMagic(p, "toJSStr")
|
||||||
appf(p.body, "switch (toJSStr($1)) {$n", [cond.rdLoc])
|
appf(p.body, "switch (toJSStr($1)) {$n", [cond.rdLoc])
|
||||||
else:
|
else:
|
||||||
|
|
@ -636,25 +636,25 @@ proc genCaseJS(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
if not isEmptyType(n.typ):
|
if not isEmptyType(n.typ):
|
||||||
r.kind = resVal
|
r.kind = resVal
|
||||||
r.res = getTemp(p)
|
r.res = getTemp(p)
|
||||||
for i in countup(1, sonsLen(n) - 1):
|
for i in countup(1, sonsLen(n) - 1):
|
||||||
let it = n.sons[i]
|
let it = n.sons[i]
|
||||||
case it.kind
|
case it.kind
|
||||||
of nkOfBranch:
|
of nkOfBranch:
|
||||||
for j in countup(0, sonsLen(it) - 2):
|
for j in countup(0, sonsLen(it) - 2):
|
||||||
let e = it.sons[j]
|
let e = it.sons[j]
|
||||||
if e.kind == nkRange:
|
if e.kind == nkRange:
|
||||||
var v = copyNode(e.sons[0])
|
var v = copyNode(e.sons[0])
|
||||||
while v.intVal <= e.sons[1].intVal:
|
while v.intVal <= e.sons[1].intVal:
|
||||||
gen(p, v, cond)
|
gen(p, v, cond)
|
||||||
appf(p.body, "case $1: ", [cond.rdLoc])
|
appf(p.body, "case $1: ", [cond.rdLoc])
|
||||||
inc(v.intVal)
|
inc(v.intVal)
|
||||||
else:
|
else:
|
||||||
if stringSwitch:
|
if stringSwitch:
|
||||||
case e.kind
|
case e.kind
|
||||||
of nkStrLit..nkTripleStrLit: appf(p.body, "case $1: ",
|
of nkStrLit..nkTripleStrLit: appf(p.body, "case $1: ",
|
||||||
[makeJSString(e.strVal)])
|
[makeJSString(e.strVal)])
|
||||||
else: internalError(e.info, "jsgen.genCaseStmt: 2")
|
else: internalError(e.info, "jsgen.genCaseStmt: 2")
|
||||||
else:
|
else:
|
||||||
gen(p, e, cond)
|
gen(p, e, cond)
|
||||||
appf(p.body, "case $1: ", [cond.rdLoc])
|
appf(p.body, "case $1: ", [cond.rdLoc])
|
||||||
gen(p, lastSon(it), stmt)
|
gen(p, lastSon(it), stmt)
|
||||||
|
|
@ -668,7 +668,7 @@ proc genCaseJS(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
else: internalError(it.info, "jsgen.genCaseStmt")
|
else: internalError(it.info, "jsgen.genCaseStmt")
|
||||||
appf(p.body, "}$n")
|
appf(p.body, "}$n")
|
||||||
|
|
||||||
proc genCaseLua(p: PProc, n: PNode, r: var TCompRes) =
|
proc genCaseLua(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
var
|
var
|
||||||
cond, stmt: TCompRes
|
cond, stmt: TCompRes
|
||||||
genLineDir(p, n)
|
genLineDir(p, n)
|
||||||
|
|
@ -681,13 +681,13 @@ proc genCaseLua(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
if not isEmptyType(n.typ):
|
if not isEmptyType(n.typ):
|
||||||
r.kind = resVal
|
r.kind = resVal
|
||||||
r.res = getTemp(p)
|
r.res = getTemp(p)
|
||||||
for i in countup(1, sonsLen(n) - 1):
|
for i in countup(1, sonsLen(n) - 1):
|
||||||
let it = n.sons[i]
|
let it = n.sons[i]
|
||||||
case it.kind
|
case it.kind
|
||||||
of nkOfBranch:
|
of nkOfBranch:
|
||||||
if i != 1: appf(p.body, "$nelsif ")
|
if i != 1: appf(p.body, "$nelsif ")
|
||||||
else: appf(p.body, "if ")
|
else: appf(p.body, "if ")
|
||||||
for j in countup(0, sonsLen(it) - 2):
|
for j in countup(0, sonsLen(it) - 2):
|
||||||
if j != 0: app(p.body, " or ")
|
if j != 0: app(p.body, " or ")
|
||||||
let e = it.sons[j]
|
let e = it.sons[j]
|
||||||
if e.kind == nkRange:
|
if e.kind == nkRange:
|
||||||
|
|
@ -696,7 +696,7 @@ proc genCaseLua(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
gen(p, e.sons[1], ib)
|
gen(p, e.sons[1], ib)
|
||||||
appf(p.body, "$1 >= $2 and $1 <= $3", [tmp, ia.rdLoc, ib.rdLoc])
|
appf(p.body, "$1 >= $2 and $1 <= $3", [tmp, ia.rdLoc, ib.rdLoc])
|
||||||
else:
|
else:
|
||||||
if stringSwitch:
|
if stringSwitch:
|
||||||
case e.kind
|
case e.kind
|
||||||
of nkStrLit..nkTripleStrLit: appf(p.body, "eqStr($1, $2)",
|
of nkStrLit..nkTripleStrLit: appf(p.body, "eqStr($1, $2)",
|
||||||
[tmp, makeJSString(e.strVal)])
|
[tmp, makeJSString(e.strVal)])
|
||||||
|
|
@ -713,11 +713,11 @@ proc genCaseLua(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
moveInto(p, stmt, r)
|
moveInto(p, stmt, r)
|
||||||
else: internalError(it.info, "jsgen.genCaseStmt")
|
else: internalError(it.info, "jsgen.genCaseStmt")
|
||||||
appf(p.body, "$nend$n")
|
appf(p.body, "$nend$n")
|
||||||
|
|
||||||
proc genBlock(p: PProc, n: PNode, r: var TCompRes) =
|
proc genBlock(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
inc(p.unique)
|
inc(p.unique)
|
||||||
let idx = len(p.blocks)
|
let idx = len(p.blocks)
|
||||||
if n.sons[0].kind != nkEmpty:
|
if n.sons[0].kind != nkEmpty:
|
||||||
# named block?
|
# named block?
|
||||||
if (n.sons[0].kind != nkSym): internalError(n.info, "genBlock")
|
if (n.sons[0].kind != nkSym): internalError(n.info, "genBlock")
|
||||||
var sym = n.sons[0].sym
|
var sym = n.sons[0].sym
|
||||||
|
|
@ -731,10 +731,10 @@ proc genBlock(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
appf(p.body, "} while(false);$n" | "$n::L$#::$n", labl.toRope)
|
appf(p.body, "} while(false);$n" | "$n::L$#::$n", labl.toRope)
|
||||||
setLen(p.blocks, idx)
|
setLen(p.blocks, idx)
|
||||||
|
|
||||||
proc genBreakStmt(p: PProc, n: PNode) =
|
proc genBreakStmt(p: PProc, n: PNode) =
|
||||||
var idx: int
|
var idx: int
|
||||||
genLineDir(p, n)
|
genLineDir(p, n)
|
||||||
if n.sons[0].kind != nkEmpty:
|
if n.sons[0].kind != nkEmpty:
|
||||||
# named break?
|
# named break?
|
||||||
assert(n.sons[0].kind == nkSym)
|
assert(n.sons[0].kind == nkSym)
|
||||||
let sym = n.sons[0].sym
|
let sym = n.sons[0].sym
|
||||||
|
|
@ -749,24 +749,24 @@ proc genBreakStmt(p: PProc, n: PNode) =
|
||||||
p.blocks[idx].id = abs(p.blocks[idx].id) # label is used
|
p.blocks[idx].id = abs(p.blocks[idx].id) # label is used
|
||||||
appf(p.body, "break L$1;$n" | "goto ::L$1::;$n", [toRope(p.blocks[idx].id)])
|
appf(p.body, "break L$1;$n" | "goto ::L$1::;$n", [toRope(p.blocks[idx].id)])
|
||||||
|
|
||||||
proc genAsmStmt(p: PProc, n: PNode) =
|
proc genAsmStmt(p: PProc, n: PNode) =
|
||||||
genLineDir(p, n)
|
genLineDir(p, n)
|
||||||
assert(n.kind == nkAsmStmt)
|
assert(n.kind == nkAsmStmt)
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
case n.sons[i].kind
|
case n.sons[i].kind
|
||||||
of nkStrLit..nkTripleStrLit: app(p.body, n.sons[i].strVal)
|
of nkStrLit..nkTripleStrLit: app(p.body, n.sons[i].strVal)
|
||||||
of nkSym: app(p.body, mangleName(n.sons[i].sym))
|
of nkSym: app(p.body, mangleName(n.sons[i].sym))
|
||||||
else: internalError(n.sons[i].info, "jsgen: genAsmStmt()")
|
else: internalError(n.sons[i].info, "jsgen: genAsmStmt()")
|
||||||
|
|
||||||
proc genIf(p: PProc, n: PNode, r: var TCompRes) =
|
proc genIf(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
var cond, stmt: TCompRes
|
var cond, stmt: TCompRes
|
||||||
var toClose = 0
|
var toClose = 0
|
||||||
if not isEmptyType(n.typ):
|
if not isEmptyType(n.typ):
|
||||||
r.kind = resVal
|
r.kind = resVal
|
||||||
r.res = getTemp(p)
|
r.res = getTemp(p)
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
let it = n.sons[i]
|
let it = n.sons[i]
|
||||||
if sonsLen(it) != 1:
|
if sonsLen(it) != 1:
|
||||||
if i > 0:
|
if i > 0:
|
||||||
appf(p.body, "else {$n" | "else$n", [])
|
appf(p.body, "else {$n" | "else$n", [])
|
||||||
inc(toClose)
|
inc(toClose)
|
||||||
|
|
@ -793,18 +793,18 @@ proc generateHeader(p: PProc, typ: PType): PRope =
|
||||||
if isCompileTimeOnly(param.typ): continue
|
if isCompileTimeOnly(param.typ): continue
|
||||||
var name = mangleName(param)
|
var name = mangleName(param)
|
||||||
app(result, name)
|
app(result, name)
|
||||||
if mapType(param.typ) == etyBaseIndex:
|
if mapType(param.typ) == etyBaseIndex:
|
||||||
app(result, ", ")
|
app(result, ", ")
|
||||||
app(result, name)
|
app(result, name)
|
||||||
app(result, "_Idx")
|
app(result, "_Idx")
|
||||||
|
|
||||||
const
|
const
|
||||||
nodeKindsNeedNoCopy = {nkCharLit..nkInt64Lit, nkStrLit..nkTripleStrLit,
|
nodeKindsNeedNoCopy = {nkCharLit..nkInt64Lit, nkStrLit..nkTripleStrLit,
|
||||||
nkFloatLit..nkFloat64Lit, nkCurly, nkPar, nkObjConstr, nkStringToCString,
|
nkFloatLit..nkFloat64Lit, nkCurly, nkPar, nkObjConstr, nkStringToCString,
|
||||||
nkCStringToString, nkCall, nkPrefix, nkPostfix, nkInfix,
|
nkCStringToString, nkCall, nkPrefix, nkPostfix, nkInfix,
|
||||||
nkCommand, nkHiddenCallConv, nkCallStrLit}
|
nkCommand, nkHiddenCallConv, nkCallStrLit}
|
||||||
|
|
||||||
proc needsNoCopy(y: PNode): bool =
|
proc needsNoCopy(y: PNode): bool =
|
||||||
result = (y.kind in nodeKindsNeedNoCopy) or
|
result = (y.kind in nodeKindsNeedNoCopy) or
|
||||||
(skipTypes(y.typ, abstractInst).kind in {tyRef, tyPtr, tyVar})
|
(skipTypes(y.typ, abstractInst).kind in {tyRef, tyPtr, tyVar})
|
||||||
|
|
||||||
|
|
@ -820,22 +820,22 @@ proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
|
||||||
useMagic(p, "nimCopy")
|
useMagic(p, "nimCopy")
|
||||||
appf(p.body, "$1 = nimCopy($2, $3);$n",
|
appf(p.body, "$1 = nimCopy($2, $3);$n",
|
||||||
[a.res, b.res, genTypeInfo(p, y.typ)])
|
[a.res, b.res, genTypeInfo(p, y.typ)])
|
||||||
of etyBaseIndex:
|
of etyBaseIndex:
|
||||||
if a.typ != etyBaseIndex or b.typ != etyBaseIndex:
|
if a.typ != etyBaseIndex or b.typ != etyBaseIndex:
|
||||||
internalError(x.info, "genAsgn")
|
internalError(x.info, "genAsgn")
|
||||||
appf(p.body, "$1 = $2; $3 = $4;$n", [a.address, b.address, a.res, b.res])
|
appf(p.body, "$1 = $2; $3 = $4;$n", [a.address, b.address, a.res, b.res])
|
||||||
else:
|
else:
|
||||||
appf(p.body, "$1 = $2;$n", [a.res, b.res])
|
appf(p.body, "$1 = $2;$n", [a.res, b.res])
|
||||||
|
|
||||||
proc genAsgn(p: PProc, n: PNode) =
|
proc genAsgn(p: PProc, n: PNode) =
|
||||||
genLineDir(p, n)
|
genLineDir(p, n)
|
||||||
genAsgnAux(p, n.sons[0], n.sons[1], noCopyNeeded=false)
|
genAsgnAux(p, n.sons[0], n.sons[1], noCopyNeeded=false)
|
||||||
|
|
||||||
proc genFastAsgn(p: PProc, n: PNode) =
|
proc genFastAsgn(p: PProc, n: PNode) =
|
||||||
genLineDir(p, n)
|
genLineDir(p, n)
|
||||||
genAsgnAux(p, n.sons[0], n.sons[1], noCopyNeeded=true)
|
genAsgnAux(p, n.sons[0], n.sons[1], noCopyNeeded=true)
|
||||||
|
|
||||||
proc genSwap(p: PProc, n: PNode) =
|
proc genSwap(p: PProc, n: PNode) =
|
||||||
var a, b: TCompRes
|
var a, b: TCompRes
|
||||||
gen(p, n.sons[1], a)
|
gen(p, n.sons[1], a)
|
||||||
gen(p, n.sons[2], b)
|
gen(p, n.sons[2], b)
|
||||||
|
|
@ -844,7 +844,7 @@ proc genSwap(p: PProc, n: PNode) =
|
||||||
if mapType(skipTypes(n.sons[1].typ, abstractVar)) == etyBaseIndex:
|
if mapType(skipTypes(n.sons[1].typ, abstractVar)) == etyBaseIndex:
|
||||||
inc(p.unique)
|
inc(p.unique)
|
||||||
let tmp2 = ropef("Tmp$1", [toRope(p.unique)])
|
let tmp2 = ropef("Tmp$1", [toRope(p.unique)])
|
||||||
if a.typ != etyBaseIndex or b.typ != etyBaseIndex:
|
if a.typ != etyBaseIndex or b.typ != etyBaseIndex:
|
||||||
internalError(n.info, "genSwap")
|
internalError(n.info, "genSwap")
|
||||||
appf(p.body, "var $1 = $2; $2 = $3; $3 = $1;$n" |
|
appf(p.body, "var $1 = $2; $2 = $3; $3 = $1;$n" |
|
||||||
"local $1 = $2; $2 = $3; $3 = $1;$n", [
|
"local $1 = $2; $2 = $3; $3 = $1;$n", [
|
||||||
|
|
@ -859,7 +859,7 @@ proc getFieldPosition(f: PNode): int =
|
||||||
of nkSym: result = f.sym.position
|
of nkSym: result = f.sym.position
|
||||||
else: internalError(f.info, "genFieldPosition")
|
else: internalError(f.info, "genFieldPosition")
|
||||||
|
|
||||||
proc genFieldAddr(p: PProc, n: PNode, r: var TCompRes) =
|
proc genFieldAddr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
var a: TCompRes
|
var a: TCompRes
|
||||||
r.typ = etyBaseIndex
|
r.typ = etyBaseIndex
|
||||||
let b = if n.kind == nkHiddenAddr: n.sons[0] else: n
|
let b = if n.kind == nkHiddenAddr: n.sons[0] else: n
|
||||||
|
|
@ -875,7 +875,7 @@ proc genFieldAddr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
r.address = a.res
|
r.address = a.res
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
|
|
||||||
proc genFieldAccess(p: PProc, n: PNode, r: var TCompRes) =
|
proc genFieldAccess(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
r.typ = etyNone
|
r.typ = etyNone
|
||||||
gen(p, n.sons[0], r)
|
gen(p, n.sons[0], r)
|
||||||
if skipTypes(n.sons[0].typ, abstractVarRange).kind == tyTuple:
|
if skipTypes(n.sons[0].typ, abstractVarRange).kind == tyTuple:
|
||||||
|
|
@ -887,14 +887,16 @@ proc genFieldAccess(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
r.res = ropef("$1.$2", [r.res, f.loc.r])
|
r.res = ropef("$1.$2", [r.res, f.loc.r])
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
|
|
||||||
proc genCheckedFieldAddr(p: PProc, n: PNode, r: var TCompRes) =
|
proc genCheckedFieldAddr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
genFieldAddr(p, n.sons[0], r) # XXX
|
let m = if n.kind == nkHiddenAddr: n.sons[0] else: n
|
||||||
|
internalAssert m.kind == nkCheckedFieldExpr
|
||||||
proc genCheckedFieldAccess(p: PProc, n: PNode, r: var TCompRes) =
|
genFieldAddr(p, m.sons[0], r) # XXX
|
||||||
|
|
||||||
|
proc genCheckedFieldAccess(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
genFieldAccess(p, n.sons[0], r) # XXX
|
genFieldAccess(p, n.sons[0], r) # XXX
|
||||||
|
|
||||||
proc genArrayAddr(p: PProc, n: PNode, r: var TCompRes) =
|
proc genArrayAddr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
var
|
var
|
||||||
a, b: TCompRes
|
a, b: TCompRes
|
||||||
first: BiggestInt
|
first: BiggestInt
|
||||||
r.typ = etyBaseIndex
|
r.typ = etyBaseIndex
|
||||||
|
|
@ -908,7 +910,7 @@ proc genArrayAddr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
else: first = 0
|
else: first = 0
|
||||||
if optBoundsCheck in p.options and not isConstExpr(m.sons[1]):
|
if optBoundsCheck in p.options and not isConstExpr(m.sons[1]):
|
||||||
useMagic(p, "chckIndx")
|
useMagic(p, "chckIndx")
|
||||||
r.res = ropef("chckIndx($1, $2, $3.length)-$2",
|
r.res = ropef("chckIndx($1, $2, $3.length)-$2",
|
||||||
[b.res, toRope(first), a.res])
|
[b.res, toRope(first), a.res])
|
||||||
elif first != 0:
|
elif first != 0:
|
||||||
r.res = ropef("($1)-$2", [b.res, toRope(first)])
|
r.res = ropef("($1)-$2", [b.res, toRope(first)])
|
||||||
|
|
@ -916,14 +918,14 @@ proc genArrayAddr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
r.res = b.res
|
r.res = b.res
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
|
|
||||||
proc genArrayAccess(p: PProc, n: PNode, r: var TCompRes) =
|
proc genArrayAccess(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
var ty = skipTypes(n.sons[0].typ, abstractVarRange)
|
var ty = skipTypes(n.sons[0].typ, abstractVarRange)
|
||||||
if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.lastSon, abstractVarRange)
|
if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.lastSon, abstractVarRange)
|
||||||
case ty.kind
|
case ty.kind
|
||||||
of tyArray, tyArrayConstr, tyOpenArray, tySequence, tyString, tyCString,
|
of tyArray, tyArrayConstr, tyOpenArray, tySequence, tyString, tyCString,
|
||||||
tyVarargs:
|
tyVarargs:
|
||||||
genArrayAddr(p, n, r)
|
genArrayAddr(p, n, r)
|
||||||
of tyTuple:
|
of tyTuple:
|
||||||
genFieldAddr(p, n, r)
|
genFieldAddr(p, n, r)
|
||||||
else: internalError(n.info, "expr(nkBracketExpr, " & $ty.kind & ')')
|
else: internalError(n.info, "expr(nkBracketExpr, " & $ty.kind & ')')
|
||||||
r.typ = etyNone
|
r.typ = etyNone
|
||||||
|
|
@ -967,12 +969,12 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
of tyArray, tyArrayConstr, tyOpenArray, tySequence, tyString, tyCString,
|
of tyArray, tyArrayConstr, tyOpenArray, tySequence, tyString, tyCString,
|
||||||
tyVarargs:
|
tyVarargs:
|
||||||
genArrayAddr(p, n, r)
|
genArrayAddr(p, n, r)
|
||||||
of tyTuple:
|
of tyTuple:
|
||||||
genFieldAddr(p, n, r)
|
genFieldAddr(p, n, r)
|
||||||
else: internalError(n.info, "expr(nkBracketExpr, " & $ty.kind & ')')
|
else: internalError(n.info, "expr(nkBracketExpr, " & $ty.kind & ')')
|
||||||
else: internalError(n.info, "genAddr")
|
else: internalError(n.info, "genAddr")
|
||||||
|
|
||||||
proc genSym(p: PProc, n: PNode, r: var TCompRes) =
|
proc genSym(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
var s = n.sym
|
var s = n.sym
|
||||||
case s.kind
|
case s.kind
|
||||||
of skVar, skLet, skParam, skTemp, skResult:
|
of skVar, skLet, skParam, skTemp, skResult:
|
||||||
|
|
@ -1019,9 +1021,9 @@ proc genSym(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
internalError(n.info, "symbol has no generated name: " & s.name.s)
|
internalError(n.info, "symbol has no generated name: " & s.name.s)
|
||||||
r.res = s.loc.r
|
r.res = s.loc.r
|
||||||
r.kind = resVal
|
r.kind = resVal
|
||||||
|
|
||||||
proc genDeref(p: PProc, n: PNode, r: var TCompRes) =
|
proc genDeref(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
if mapType(n.sons[0].typ) == etyObject:
|
if mapType(n.sons[0].typ) == etyObject:
|
||||||
gen(p, n.sons[0], r)
|
gen(p, n.sons[0], r)
|
||||||
else:
|
else:
|
||||||
var a: TCompRes
|
var a: TCompRes
|
||||||
|
|
@ -1041,15 +1043,15 @@ proc genArg(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
|
|
||||||
proc genArgs(p: PProc, n: PNode, r: var TCompRes) =
|
proc genArgs(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
app(r.res, "(")
|
app(r.res, "(")
|
||||||
for i in countup(1, sonsLen(n) - 1):
|
for i in countup(1, sonsLen(n) - 1):
|
||||||
let it = n.sons[i]
|
let it = n.sons[i]
|
||||||
if it.typ.isCompileTimeOnly: continue
|
if it.typ.isCompileTimeOnly: continue
|
||||||
if i > 1: app(r.res, ", ")
|
if i > 1: app(r.res, ", ")
|
||||||
genArg(p, it, r)
|
genArg(p, it, r)
|
||||||
app(r.res, ")")
|
app(r.res, ")")
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
|
|
||||||
proc genCall(p: PProc, n: PNode, r: var TCompRes) =
|
proc genCall(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
gen(p, n.sons[0], r)
|
gen(p, n.sons[0], r)
|
||||||
genArgs(p, n, r)
|
genArgs(p, n, r)
|
||||||
|
|
||||||
|
|
@ -1065,7 +1067,7 @@ proc genInfixCall(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
var op: TCompRes
|
var op: TCompRes
|
||||||
gen(p, n.sons[0], op)
|
gen(p, n.sons[0], op)
|
||||||
app(r.res, op.res)
|
app(r.res, op.res)
|
||||||
|
|
||||||
app(r.res, "(")
|
app(r.res, "(")
|
||||||
for i in countup(2, sonsLen(n) - 1):
|
for i in countup(2, sonsLen(n) - 1):
|
||||||
if i > 2: app(r.res, ", ")
|
if i > 2: app(r.res, ", ")
|
||||||
|
|
@ -1080,88 +1082,88 @@ proc genEcho(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
internalAssert n.kind == nkBracket
|
internalAssert n.kind == nkBracket
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
let it = n.sons[i]
|
let it = n.sons[i]
|
||||||
if it.typ.isCompileTimeOnly: continue
|
if it.typ.isCompileTimeOnly: continue
|
||||||
if i > 0: app(r.res, ", ")
|
if i > 0: app(r.res, ", ")
|
||||||
genArg(p, it, r)
|
genArg(p, it, r)
|
||||||
app(r.res, ")")
|
app(r.res, ")")
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
|
|
||||||
proc putToSeq(s: string, indirect: bool): PRope =
|
proc putToSeq(s: string, indirect: bool): PRope =
|
||||||
result = toRope(s)
|
result = toRope(s)
|
||||||
if indirect: result = ropef("[$1]", [result])
|
if indirect: result = ropef("[$1]", [result])
|
||||||
|
|
||||||
proc createVar(p: PProc, typ: PType, indirect: bool): PRope
|
proc createVar(p: PProc, typ: PType, indirect: bool): PRope
|
||||||
proc createRecordVarAux(p: PProc, rec: PNode, c: var int): PRope =
|
proc createRecordVarAux(p: PProc, rec: PNode, c: var int): PRope =
|
||||||
result = nil
|
result = nil
|
||||||
case rec.kind
|
case rec.kind
|
||||||
of nkRecList:
|
of nkRecList:
|
||||||
for i in countup(0, sonsLen(rec) - 1):
|
for i in countup(0, sonsLen(rec) - 1):
|
||||||
app(result, createRecordVarAux(p, rec.sons[i], c))
|
app(result, createRecordVarAux(p, rec.sons[i], c))
|
||||||
of nkRecCase:
|
of nkRecCase:
|
||||||
app(result, createRecordVarAux(p, rec.sons[0], c))
|
app(result, createRecordVarAux(p, rec.sons[0], c))
|
||||||
for i in countup(1, sonsLen(rec) - 1):
|
for i in countup(1, sonsLen(rec) - 1):
|
||||||
app(result, createRecordVarAux(p, lastSon(rec.sons[i]), c))
|
app(result, createRecordVarAux(p, lastSon(rec.sons[i]), c))
|
||||||
of nkSym:
|
of nkSym:
|
||||||
if c > 0: app(result, ", ")
|
if c > 0: app(result, ", ")
|
||||||
app(result, mangleName(rec.sym))
|
app(result, mangleName(rec.sym))
|
||||||
app(result, ": ")
|
app(result, ": ")
|
||||||
app(result, createVar(p, rec.sym.typ, false))
|
app(result, createVar(p, rec.sym.typ, false))
|
||||||
inc(c)
|
inc(c)
|
||||||
else: internalError(rec.info, "createRecordVarAux")
|
else: internalError(rec.info, "createRecordVarAux")
|
||||||
|
|
||||||
proc createVar(p: PProc, typ: PType, indirect: bool): PRope =
|
proc createVar(p: PProc, typ: PType, indirect: bool): PRope =
|
||||||
var t = skipTypes(typ, abstractInst)
|
var t = skipTypes(typ, abstractInst)
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyInt..tyInt64, tyEnum, tyChar:
|
of tyInt..tyInt64, tyEnum, tyChar:
|
||||||
result = putToSeq("0", indirect)
|
result = putToSeq("0", indirect)
|
||||||
of tyFloat..tyFloat128:
|
of tyFloat..tyFloat128:
|
||||||
result = putToSeq("0.0", indirect)
|
result = putToSeq("0.0", indirect)
|
||||||
of tyRange, tyGenericInst:
|
of tyRange, tyGenericInst:
|
||||||
result = createVar(p, lastSon(typ), indirect)
|
result = createVar(p, lastSon(typ), indirect)
|
||||||
of tySet:
|
of tySet:
|
||||||
result = toRope("{}")
|
result = toRope("{}")
|
||||||
of tyBool:
|
of tyBool:
|
||||||
result = putToSeq("false", indirect)
|
result = putToSeq("false", indirect)
|
||||||
of tyArray, tyArrayConstr:
|
of tyArray, tyArrayConstr:
|
||||||
var length = int(lengthOrd(t))
|
var length = int(lengthOrd(t))
|
||||||
var e = elemType(t)
|
var e = elemType(t)
|
||||||
if length > 32:
|
if length > 32:
|
||||||
useMagic(p, "arrayConstr")
|
useMagic(p, "arrayConstr")
|
||||||
# XXX: arrayConstr depends on nimCopy. This line shouldn't be necessary.
|
# XXX: arrayConstr depends on nimCopy. This line shouldn't be necessary.
|
||||||
useMagic(p, "nimCopy")
|
useMagic(p, "nimCopy")
|
||||||
result = ropef("arrayConstr($1, $2, $3)", [toRope(length),
|
result = ropef("arrayConstr($1, $2, $3)", [toRope(length),
|
||||||
createVar(p, e, false), genTypeInfo(p, e)])
|
createVar(p, e, false), genTypeInfo(p, e)])
|
||||||
else:
|
else:
|
||||||
result = toRope("[")
|
result = toRope("[")
|
||||||
var i = 0
|
var i = 0
|
||||||
while i < length:
|
while i < length:
|
||||||
if i > 0: app(result, ", ")
|
if i > 0: app(result, ", ")
|
||||||
app(result, createVar(p, e, false))
|
app(result, createVar(p, e, false))
|
||||||
inc(i)
|
inc(i)
|
||||||
app(result, "]")
|
app(result, "]")
|
||||||
of tyTuple:
|
of tyTuple:
|
||||||
result = toRope("{")
|
result = toRope("{")
|
||||||
for i in 0.. <t.sonsLen:
|
for i in 0.. <t.sonsLen:
|
||||||
if i > 0: app(result, ", ")
|
if i > 0: app(result, ", ")
|
||||||
appf(result, "Field$1: $2" | "Field$# = $#", i.toRope,
|
appf(result, "Field$1: $2" | "Field$# = $#", i.toRope,
|
||||||
createVar(p, t.sons[i], false))
|
createVar(p, t.sons[i], false))
|
||||||
app(result, "}")
|
app(result, "}")
|
||||||
of tyObject:
|
of tyObject:
|
||||||
result = toRope("{")
|
result = toRope("{")
|
||||||
var c = 0
|
var c = 0
|
||||||
if tfFinal notin t.flags or t.sons[0] != nil:
|
if tfFinal notin t.flags or t.sons[0] != nil:
|
||||||
inc(c)
|
inc(c)
|
||||||
appf(result, "m_type: $1" | "m_type = $#", [genTypeInfo(p, t)])
|
appf(result, "m_type: $1" | "m_type = $#", [genTypeInfo(p, t)])
|
||||||
while t != nil:
|
while t != nil:
|
||||||
app(result, createRecordVarAux(p, t.n, c))
|
app(result, createRecordVarAux(p, t.n, c))
|
||||||
t = t.sons[0]
|
t = t.sons[0]
|
||||||
app(result, "}")
|
app(result, "}")
|
||||||
of tyVar, tyPtr, tyRef:
|
of tyVar, tyPtr, tyRef:
|
||||||
if mapType(t) == etyBaseIndex:
|
if mapType(t) == etyBaseIndex:
|
||||||
result = putToSeq("[null, 0]" | "{nil, 0}", indirect)
|
result = putToSeq("[null, 0]" | "{nil, 0}", indirect)
|
||||||
else:
|
else:
|
||||||
result = putToSeq("null" | "nil", indirect)
|
result = putToSeq("null" | "nil", indirect)
|
||||||
of tySequence, tyString, tyCString, tyPointer, tyProc:
|
of tySequence, tyString, tyCString, tyPointer, tyProc:
|
||||||
result = putToSeq("null" | "nil", indirect)
|
result = putToSeq("null" | "nil", indirect)
|
||||||
else:
|
else:
|
||||||
internalError("createVar: " & $t.kind)
|
internalError("createVar: " & $t.kind)
|
||||||
|
|
@ -1172,42 +1174,42 @@ proc isIndirect(v: PSym): bool =
|
||||||
(mapType(v.typ) != etyObject) and
|
(mapType(v.typ) != etyObject) and
|
||||||
v.kind notin {skProc, skConverter, skMethod, skIterator, skClosureIterator}
|
v.kind notin {skProc, skConverter, skMethod, skIterator, skClosureIterator}
|
||||||
|
|
||||||
proc genVarInit(p: PProc, v: PSym, n: PNode) =
|
proc genVarInit(p: PProc, v: PSym, n: PNode) =
|
||||||
var
|
var
|
||||||
a: TCompRes
|
a: TCompRes
|
||||||
s: PRope
|
s: PRope
|
||||||
if n.kind == nkEmpty:
|
if n.kind == nkEmpty:
|
||||||
appf(p.body, "var $1 = $2;$n" | "local $1 = $2;$n",
|
appf(p.body, "var $1 = $2;$n" | "local $1 = $2;$n",
|
||||||
[mangleName(v), createVar(p, v.typ, isIndirect(v))])
|
[mangleName(v), createVar(p, v.typ, isIndirect(v))])
|
||||||
else:
|
else:
|
||||||
discard mangleName(v)
|
discard mangleName(v)
|
||||||
gen(p, n, a)
|
gen(p, n, a)
|
||||||
case mapType(v.typ)
|
case mapType(v.typ)
|
||||||
of etyObject:
|
of etyObject:
|
||||||
if needsNoCopy(n):
|
if needsNoCopy(n):
|
||||||
s = a.res
|
s = a.res
|
||||||
else:
|
else:
|
||||||
useMagic(p, "nimCopy")
|
useMagic(p, "nimCopy")
|
||||||
s = ropef("nimCopy($1, $2)", [a.res, genTypeInfo(p, n.typ)])
|
s = ropef("nimCopy($1, $2)", [a.res, genTypeInfo(p, n.typ)])
|
||||||
of etyBaseIndex:
|
of etyBaseIndex:
|
||||||
if (a.typ != etyBaseIndex): internalError(n.info, "genVarInit")
|
if (a.typ != etyBaseIndex): internalError(n.info, "genVarInit")
|
||||||
if {sfAddrTaken, sfGlobal} * v.flags != {}:
|
if {sfAddrTaken, sfGlobal} * v.flags != {}:
|
||||||
appf(p.body, "var $1 = [$2, $3];$n" | "local $1 = {$2, $3};$n",
|
appf(p.body, "var $1 = [$2, $3];$n" | "local $1 = {$2, $3};$n",
|
||||||
[v.loc.r, a.address, a.res])
|
[v.loc.r, a.address, a.res])
|
||||||
else:
|
else:
|
||||||
appf(p.body, "var $1 = $2; var $1_Idx = $3;$n" |
|
appf(p.body, "var $1 = $2; var $1_Idx = $3;$n" |
|
||||||
"local $1 = $2; local $1_Idx = $3;$n", [
|
"local $1 = $2; local $1_Idx = $3;$n", [
|
||||||
v.loc.r, a.address, a.res])
|
v.loc.r, a.address, a.res])
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
s = a.res
|
s = a.res
|
||||||
if isIndirect(v):
|
if isIndirect(v):
|
||||||
appf(p.body, "var $1 = [$2];$n" | "local $1 = {$2};$n", [v.loc.r, s])
|
appf(p.body, "var $1 = [$2];$n" | "local $1 = {$2};$n", [v.loc.r, s])
|
||||||
else:
|
else:
|
||||||
appf(p.body, "var $1 = $2;$n" | "local $1 = $2;$n", [v.loc.r, s])
|
appf(p.body, "var $1 = $2;$n" | "local $1 = $2;$n", [v.loc.r, s])
|
||||||
|
|
||||||
proc genVarStmt(p: PProc, n: PNode) =
|
proc genVarStmt(p: PProc, n: PNode) =
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
var a = n.sons[i]
|
var a = n.sons[i]
|
||||||
if a.kind != nkCommentStmt:
|
if a.kind != nkCommentStmt:
|
||||||
if a.kind == nkVarTuple:
|
if a.kind == nkVarTuple:
|
||||||
|
|
@ -1249,7 +1251,7 @@ proc genOrd(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
of tyEnum, tyInt..tyInt64, tyChar: gen(p, n.sons[1], r)
|
of tyEnum, tyInt..tyInt64, tyChar: gen(p, n.sons[1], r)
|
||||||
of tyBool: unaryExpr(p, n, r, "", "($1 ? 1:0)" | "toBool($#)")
|
of tyBool: unaryExpr(p, n, r, "", "($1 ? 1:0)" | "toBool($#)")
|
||||||
else: internalError(n.info, "genOrd")
|
else: internalError(n.info, "genOrd")
|
||||||
|
|
||||||
proc genConStrStr(p: PProc, n: PNode, r: var TCompRes) =
|
proc genConStrStr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
var a: TCompRes
|
var a: TCompRes
|
||||||
|
|
||||||
|
|
@ -1282,7 +1284,7 @@ proc genRepr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
gen(p, n.sons[1], r)
|
gen(p, n.sons[1], r)
|
||||||
useMagic(p, "cstrToNimstr")
|
useMagic(p, "cstrToNimstr")
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
r.res = ropef("cstrToNimstr($1.node.sons[$2].name)",
|
r.res = ropef("cstrToNimstr($1.node.sons[$2].name)",
|
||||||
[genTypeInfo(p, t), r.res])
|
[genTypeInfo(p, t), r.res])
|
||||||
else:
|
else:
|
||||||
# XXX:
|
# XXX:
|
||||||
|
|
@ -1303,11 +1305,11 @@ proc genReset(p: PProc, n: PNode) =
|
||||||
var x: TCompRes
|
var x: TCompRes
|
||||||
useMagic(p, "genericReset")
|
useMagic(p, "genericReset")
|
||||||
gen(p, n.sons[1], x)
|
gen(p, n.sons[1], x)
|
||||||
appf(p.body, "$1 = genericReset($1, $2);$n", [x.res,
|
appf(p.body, "$1 = genericReset($1, $2);$n", [x.res,
|
||||||
genTypeInfo(p, n.sons[1].typ)])
|
genTypeInfo(p, n.sons[1].typ)])
|
||||||
|
|
||||||
proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
|
proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
var
|
var
|
||||||
a: TCompRes
|
a: TCompRes
|
||||||
line, filen: PRope
|
line, filen: PRope
|
||||||
var op = n.sons[0].sym.magic
|
var op = n.sons[0].sym.magic
|
||||||
|
|
@ -1384,34 +1386,34 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
of mCopyStr: binaryExpr(p, n, r, "", "($1.slice($2))")
|
of mCopyStr: binaryExpr(p, n, r, "", "($1.slice($2))")
|
||||||
of mCopyStrLast: ternaryExpr(p, n, r, "", "($1.slice($2, ($3)+1).concat(0))")
|
of mCopyStrLast: ternaryExpr(p, n, r, "", "($1.slice($2, ($3)+1).concat(0))")
|
||||||
of mNewString: unaryExpr(p, n, r, "mnewString", "mnewString($1)")
|
of mNewString: unaryExpr(p, n, r, "mnewString", "mnewString($1)")
|
||||||
of mNewStringOfCap: unaryExpr(p, n, r, "mnewString", "mnewString(0)")
|
of mNewStringOfCap: unaryExpr(p, n, r, "mnewString", "mnewString(0)")
|
||||||
else:
|
else:
|
||||||
genCall(p, n, r)
|
genCall(p, n, r)
|
||||||
#else internalError(e.info, 'genMagic: ' + magicToStr[op]);
|
#else internalError(e.info, 'genMagic: ' + magicToStr[op]);
|
||||||
|
|
||||||
proc genSetConstr(p: PProc, n: PNode, r: var TCompRes) =
|
proc genSetConstr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
var
|
var
|
||||||
a, b: TCompRes
|
a, b: TCompRes
|
||||||
useMagic(p, "SetConstr")
|
useMagic(p, "SetConstr")
|
||||||
r.res = toRope("SetConstr(")
|
r.res = toRope("SetConstr(")
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
if i > 0: app(r.res, ", ")
|
if i > 0: app(r.res, ", ")
|
||||||
var it = n.sons[i]
|
var it = n.sons[i]
|
||||||
if it.kind == nkRange:
|
if it.kind == nkRange:
|
||||||
gen(p, it.sons[0], a)
|
gen(p, it.sons[0], a)
|
||||||
gen(p, it.sons[1], b)
|
gen(p, it.sons[1], b)
|
||||||
appf(r.res, "[$1, $2]", [a.res, b.res])
|
appf(r.res, "[$1, $2]", [a.res, b.res])
|
||||||
else:
|
else:
|
||||||
gen(p, it, a)
|
gen(p, it, a)
|
||||||
app(r.res, a.res)
|
app(r.res, a.res)
|
||||||
app(r.res, ")")
|
app(r.res, ")")
|
||||||
|
|
||||||
proc genArrayConstr(p: PProc, n: PNode, r: var TCompRes) =
|
proc genArrayConstr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
var a: TCompRes
|
var a: TCompRes
|
||||||
r.res = toRope("[")
|
r.res = toRope("[")
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
if i > 0: app(r.res, ", ")
|
if i > 0: app(r.res, ", ")
|
||||||
gen(p, n.sons[i], a)
|
gen(p, n.sons[i], a)
|
||||||
app(r.res, a.res)
|
app(r.res, a.res)
|
||||||
|
|
@ -1444,7 +1446,7 @@ proc genObjConstr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
appf(r.res, "$#: $#" | "$# = $#" , [f.loc.r, a.res])
|
appf(r.res, "$#: $#" | "$# = $#" , [f.loc.r, a.res])
|
||||||
r.res.app("}")
|
r.res.app("}")
|
||||||
|
|
||||||
proc genConv(p: PProc, n: PNode, r: var TCompRes) =
|
proc genConv(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
var dest = skipTypes(n.typ, abstractVarRange)
|
var dest = skipTypes(n.typ, abstractVarRange)
|
||||||
var src = skipTypes(n.sons[1].typ, abstractVarRange)
|
var src = skipTypes(n.sons[1].typ, abstractVarRange)
|
||||||
gen(p, n.sons[1], r)
|
gen(p, n.sons[1], r)
|
||||||
|
|
@ -1460,24 +1462,24 @@ proc genConv(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
else:
|
else:
|
||||||
# TODO: What types must we handle here?
|
# TODO: What types must we handle here?
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc upConv(p: PProc, n: PNode, r: var TCompRes) =
|
proc upConv(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
gen(p, n.sons[0], r) # XXX
|
gen(p, n.sons[0], r) # XXX
|
||||||
|
|
||||||
proc genRangeChck(p: PProc, n: PNode, r: var TCompRes, magic: string) =
|
proc genRangeChck(p: PProc, n: PNode, r: var TCompRes, magic: string) =
|
||||||
var a, b: TCompRes
|
var a, b: TCompRes
|
||||||
gen(p, n.sons[0], r)
|
gen(p, n.sons[0], r)
|
||||||
if optRangeCheck in p.options:
|
if optRangeCheck in p.options:
|
||||||
gen(p, n.sons[1], a)
|
gen(p, n.sons[1], a)
|
||||||
gen(p, n.sons[2], b)
|
gen(p, n.sons[2], b)
|
||||||
useMagic(p, "chckRange")
|
useMagic(p, "chckRange")
|
||||||
r.res = ropef("chckRange($1, $2, $3)", [r.res, a.res, b.res])
|
r.res = ropef("chckRange($1, $2, $3)", [r.res, a.res, b.res])
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
|
|
||||||
proc convStrToCStr(p: PProc, n: PNode, r: var TCompRes) =
|
proc convStrToCStr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
# we do an optimization here as this is likely to slow down
|
# we do an optimization here as this is likely to slow down
|
||||||
# much of the code otherwise:
|
# much of the code otherwise:
|
||||||
if n.sons[0].kind == nkCStringToString:
|
if n.sons[0].kind == nkCStringToString:
|
||||||
gen(p, n.sons[0].sons[0], r)
|
gen(p, n.sons[0].sons[0], r)
|
||||||
else:
|
else:
|
||||||
gen(p, n.sons[0], r)
|
gen(p, n.sons[0], r)
|
||||||
|
|
@ -1486,22 +1488,22 @@ proc convStrToCStr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
r.res = ropef("toJSStr($1)", [r.res])
|
r.res = ropef("toJSStr($1)", [r.res])
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
|
|
||||||
proc convCStrToStr(p: PProc, n: PNode, r: var TCompRes) =
|
proc convCStrToStr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
# we do an optimization here as this is likely to slow down
|
# we do an optimization here as this is likely to slow down
|
||||||
# much of the code otherwise:
|
# much of the code otherwise:
|
||||||
if n.sons[0].kind == nkStringToCString:
|
if n.sons[0].kind == nkStringToCString:
|
||||||
gen(p, n.sons[0].sons[0], r)
|
gen(p, n.sons[0].sons[0], r)
|
||||||
else:
|
else:
|
||||||
gen(p, n.sons[0], r)
|
gen(p, n.sons[0], r)
|
||||||
if r.res == nil: internalError(n.info, "convCStrToStr")
|
if r.res == nil: internalError(n.info, "convCStrToStr")
|
||||||
useMagic(p, "cstrToNimstr")
|
useMagic(p, "cstrToNimstr")
|
||||||
r.res = ropef("cstrToNimstr($1)", [r.res])
|
r.res = ropef("cstrToNimstr($1)", [r.res])
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
|
|
||||||
proc genReturnStmt(p: PProc, n: PNode) =
|
proc genReturnStmt(p: PProc, n: PNode) =
|
||||||
if p.procDef == nil: internalError(n.info, "genReturnStmt")
|
if p.procDef == nil: internalError(n.info, "genReturnStmt")
|
||||||
p.beforeRetNeeded = true
|
p.beforeRetNeeded = true
|
||||||
if (n.sons[0].kind != nkEmpty):
|
if (n.sons[0].kind != nkEmpty):
|
||||||
genStmt(p, n.sons[0])
|
genStmt(p, n.sons[0])
|
||||||
else:
|
else:
|
||||||
genLineDir(p, n)
|
genLineDir(p, n)
|
||||||
|
|
@ -1517,22 +1519,22 @@ proc genProcBody(p: PProc, prc: PSym): PRope =
|
||||||
else:
|
else:
|
||||||
result = nil
|
result = nil
|
||||||
if p.beforeRetNeeded:
|
if p.beforeRetNeeded:
|
||||||
appf(result, "BeforeRet: do {$n$1} while (false); $n" |
|
appf(result, "BeforeRet: do {$n$1} while (false); $n" |
|
||||||
"$#;::BeforeRet::$n", [p.body])
|
"$#;::BeforeRet::$n", [p.body])
|
||||||
else:
|
else:
|
||||||
app(result, p.body)
|
app(result, p.body)
|
||||||
if prc.typ.callConv == ccSysCall and p.target == targetJS:
|
if prc.typ.callConv == ccSysCall and p.target == targetJS:
|
||||||
result = ropef("try {$n$1} catch (e) {$n" &
|
result = ropef("try {$n$1} catch (e) {$n" &
|
||||||
" alert(\"Unhandled exception:\\n\" + e.message + \"\\n\"$n}", [result])
|
" alert(\"Unhandled exception:\\n\" + e.message + \"\\n\"$n}", [result])
|
||||||
if optStackTrace in prc.options:
|
if optStackTrace in prc.options:
|
||||||
app(result, "framePtr = framePtr.prev;" & tnl)
|
app(result, "framePtr = framePtr.prev;" & tnl)
|
||||||
|
|
||||||
proc genProc(oldProc: PProc, prc: PSym): PRope =
|
proc genProc(oldProc: PProc, prc: PSym): PRope =
|
||||||
var
|
var
|
||||||
resultSym: PSym
|
resultSym: PSym
|
||||||
name, returnStmt, resultAsgn, header: PRope
|
name, returnStmt, resultAsgn, header: PRope
|
||||||
a: TCompRes
|
a: TCompRes
|
||||||
#if gVerbosity >= 3:
|
#if gVerbosity >= 3:
|
||||||
# echo "BEGIN generating code for: " & prc.name.s
|
# echo "BEGIN generating code for: " & prc.name.s
|
||||||
var p = newProc(oldProc.g, oldProc.module, prc.ast, prc.options)
|
var p = newProc(oldProc.g, oldProc.module, prc.ast, prc.options)
|
||||||
p.target = oldProc.target
|
p.target = oldProc.target
|
||||||
|
|
@ -1541,17 +1543,17 @@ proc genProc(oldProc: PProc, prc: PSym): PRope =
|
||||||
resultAsgn = nil
|
resultAsgn = nil
|
||||||
name = mangleName(prc)
|
name = mangleName(prc)
|
||||||
header = generateHeader(p, prc.typ)
|
header = generateHeader(p, prc.typ)
|
||||||
if prc.typ.sons[0] != nil and sfPure notin prc.flags:
|
if prc.typ.sons[0] != nil and sfPure notin prc.flags:
|
||||||
resultSym = prc.ast.sons[resultPos].sym
|
resultSym = prc.ast.sons[resultPos].sym
|
||||||
resultAsgn = ropef("var $# = $#;$n" | "local $# = $#;$n", [
|
resultAsgn = ropef("var $# = $#;$n" | "local $# = $#;$n", [
|
||||||
mangleName(resultSym),
|
mangleName(resultSym),
|
||||||
createVar(p, resultSym.typ, isIndirect(resultSym))])
|
createVar(p, resultSym.typ, isIndirect(resultSym))])
|
||||||
gen(p, prc.ast.sons[resultPos], a)
|
gen(p, prc.ast.sons[resultPos], a)
|
||||||
returnStmt = ropef("return $#;$n", [a.res])
|
returnStmt = ropef("return $#;$n", [a.res])
|
||||||
genStmt(p, prc.getBody)
|
genStmt(p, prc.getBody)
|
||||||
result = ropef("function $#($#) {$n$#$#$#$#}$n" |
|
result = ropef("function $#($#) {$n$#$#$#$#}$n" |
|
||||||
"function $#($#) $n$#$#$#$#$nend$n",
|
"function $#($#) $n$#$#$#$#$nend$n",
|
||||||
[name, header, p.locals, resultAsgn,
|
[name, header, p.locals, resultAsgn,
|
||||||
genProcBody(p, prc), returnStmt])
|
genProcBody(p, prc), returnStmt])
|
||||||
#if gVerbosity >= 3:
|
#if gVerbosity >= 3:
|
||||||
# echo "END generated code for: " & prc.name.s
|
# echo "END generated code for: " & prc.name.s
|
||||||
|
|
@ -1584,28 +1586,28 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
r.res = toRope"null" | toRope"nil"
|
r.res = toRope"null" | toRope"nil"
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
if skipTypes(n.typ, abstractVarRange).kind == tyString:
|
if skipTypes(n.typ, abstractVarRange).kind == tyString:
|
||||||
useMagic(p, "cstrToNimstr")
|
useMagic(p, "cstrToNimstr")
|
||||||
r.res = ropef("cstrToNimstr($1)", [makeJSString(n.strVal)])
|
r.res = ropef("cstrToNimstr($1)", [makeJSString(n.strVal)])
|
||||||
else:
|
else:
|
||||||
r.res = makeJSString(n.strVal)
|
r.res = makeJSString(n.strVal)
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
of nkFloatLit..nkFloat64Lit:
|
of nkFloatLit..nkFloat64Lit:
|
||||||
let f = n.floatVal
|
let f = n.floatVal
|
||||||
if f != f: r.res = toRope"NaN"
|
if f != f: r.res = toRope"NaN"
|
||||||
elif f == 0.0: r.res = toRope"0.0"
|
elif f == 0.0: r.res = toRope"0.0"
|
||||||
elif f == 0.5 * f:
|
elif f == 0.5 * f:
|
||||||
if f > 0.0: r.res = toRope"Infinity"
|
if f > 0.0: r.res = toRope"Infinity"
|
||||||
else: r.res = toRope"-Infinity"
|
else: r.res = toRope"-Infinity"
|
||||||
else: r.res = toRope(f.toStrMaxPrecision)
|
else: r.res = toRope(f.toStrMaxPrecision)
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
of nkCallKinds:
|
of nkCallKinds:
|
||||||
if (n.sons[0].kind == nkSym) and (n.sons[0].sym.magic != mNone):
|
if (n.sons[0].kind == nkSym) and (n.sons[0].sym.magic != mNone):
|
||||||
genMagic(p, n, r)
|
genMagic(p, n, r)
|
||||||
elif n.sons[0].kind == nkSym and sfInfixCall in n.sons[0].sym.flags and
|
elif n.sons[0].kind == nkSym and sfInfixCall in n.sons[0].sym.flags and
|
||||||
n.len >= 2:
|
n.len >= 2:
|
||||||
genInfixCall(p, n, r)
|
genInfixCall(p, n, r)
|
||||||
else:
|
else:
|
||||||
genCall(p, n, r)
|
genCall(p, n, r)
|
||||||
of nkCurly: genSetConstr(p, n, r)
|
of nkCurly: genSetConstr(p, n, r)
|
||||||
of nkBracket: genArrayConstr(p, n, r)
|
of nkBracket: genArrayConstr(p, n, r)
|
||||||
|
|
@ -1626,7 +1628,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
of nkStringToCString: convStrToCStr(p, n, r)
|
of nkStringToCString: convStrToCStr(p, n, r)
|
||||||
of nkCStringToString: convCStrToStr(p, n, r)
|
of nkCStringToString: convCStrToStr(p, n, r)
|
||||||
of nkEmpty: discard
|
of nkEmpty: discard
|
||||||
of nkLambdaKinds:
|
of nkLambdaKinds:
|
||||||
let s = n.sons[namePos].sym
|
let s = n.sons[namePos].sym
|
||||||
discard mangleName(s)
|
discard mangleName(s)
|
||||||
r.res = s.loc.r
|
r.res = s.loc.r
|
||||||
|
|
@ -1647,9 +1649,9 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
of nkWhileStmt: genWhileStmt(p, n)
|
of nkWhileStmt: genWhileStmt(p, n)
|
||||||
of nkVarSection, nkLetSection: genVarStmt(p, n)
|
of nkVarSection, nkLetSection: genVarStmt(p, n)
|
||||||
of nkConstSection: discard
|
of nkConstSection: discard
|
||||||
of nkForStmt, nkParForStmt:
|
of nkForStmt, nkParForStmt:
|
||||||
internalError(n.info, "for statement not eliminated")
|
internalError(n.info, "for statement not eliminated")
|
||||||
of nkCaseStmt:
|
of nkCaseStmt:
|
||||||
if p.target == targetJS: genCaseJS(p, n, r)
|
if p.target == targetJS: genCaseJS(p, n, r)
|
||||||
else: genCaseLua(p, n, r)
|
else: genCaseLua(p, n, r)
|
||||||
of nkReturnStmt: genReturnStmt(p, n)
|
of nkReturnStmt: genReturnStmt(p, n)
|
||||||
|
|
@ -1663,8 +1665,8 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
of nkAsmStmt: genAsmStmt(p, n)
|
of nkAsmStmt: genAsmStmt(p, n)
|
||||||
of nkTryStmt: genTry(p, n, r)
|
of nkTryStmt: genTry(p, n, r)
|
||||||
of nkRaiseStmt: genRaiseStmt(p, n)
|
of nkRaiseStmt: genRaiseStmt(p, n)
|
||||||
of nkTypeSection, nkCommentStmt, nkIteratorDef, nkIncludeStmt,
|
of nkTypeSection, nkCommentStmt, nkIteratorDef, nkIncludeStmt,
|
||||||
nkImportStmt, nkImportExceptStmt, nkExportStmt, nkExportExceptStmt,
|
nkImportStmt, nkImportExceptStmt, nkExportStmt, nkExportExceptStmt,
|
||||||
nkFromStmt, nkTemplateDef, nkMacroDef, nkPragma: discard
|
nkFromStmt, nkTemplateDef, nkMacroDef, nkPragma: discard
|
||||||
of nkProcDef, nkMethodDef, nkConverterDef:
|
of nkProcDef, nkMethodDef, nkConverterDef:
|
||||||
var s = n.sons[namePos].sym
|
var s = n.sons[namePos].sym
|
||||||
|
|
@ -1675,33 +1677,33 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
internalError(n.info, "first class iterators not implemented")
|
internalError(n.info, "first class iterators not implemented")
|
||||||
of nkPragmaBlock: gen(p, n.lastSon, r)
|
of nkPragmaBlock: gen(p, n.lastSon, r)
|
||||||
else: internalError(n.info, "gen: unknown node type: " & $n.kind)
|
else: internalError(n.info, "gen: unknown node type: " & $n.kind)
|
||||||
|
|
||||||
var globals: PGlobals
|
var globals: PGlobals
|
||||||
|
|
||||||
proc newModule(module: PSym): BModule =
|
proc newModule(module: PSym): BModule =
|
||||||
new(result)
|
new(result)
|
||||||
result.module = module
|
result.module = module
|
||||||
if globals == nil: globals = newGlobals()
|
if globals == nil: globals = newGlobals()
|
||||||
|
|
||||||
proc genHeader(): PRope =
|
proc genHeader(): PRope =
|
||||||
result = ropef("/* Generated by the Nim Compiler v$1 */$n" &
|
result = ropef("/* Generated by the Nim Compiler v$1 */$n" &
|
||||||
"/* (c) 2015 Andreas Rumpf */$n$n" &
|
"/* (c) 2015 Andreas Rumpf */$n$n" &
|
||||||
"var framePtr = null;$n" &
|
"var framePtr = null;$n" &
|
||||||
"var excHandler = null;$n" &
|
"var excHandler = null;$n" &
|
||||||
"var lastJSError = null;$n",
|
"var lastJSError = null;$n",
|
||||||
[toRope(VersionAsString)])
|
[toRope(VersionAsString)])
|
||||||
|
|
||||||
proc genModule(p: PProc, n: PNode) =
|
proc genModule(p: PProc, n: PNode) =
|
||||||
if optStackTrace in p.options:
|
if optStackTrace in p.options:
|
||||||
appf(p.body, "var F = {procname:$1,prev:framePtr,filename:$2,line:0};$n" &
|
appf(p.body, "var F = {procname:$1,prev:framePtr,filename:$2,line:0};$n" &
|
||||||
"framePtr = F;$n", [
|
"framePtr = F;$n", [
|
||||||
makeJSString("module " & p.module.module.name.s),
|
makeJSString("module " & p.module.module.name.s),
|
||||||
makeJSString(toFilename(p.module.module.info))])
|
makeJSString(toFilename(p.module.module.info))])
|
||||||
genStmt(p, n)
|
genStmt(p, n)
|
||||||
if optStackTrace in p.options:
|
if optStackTrace in p.options:
|
||||||
appf(p.body, "framePtr = framePtr.prev;$n")
|
appf(p.body, "framePtr = framePtr.prev;$n")
|
||||||
|
|
||||||
proc myProcess(b: PPassContext, n: PNode): PNode =
|
proc myProcess(b: PPassContext, n: PNode): PNode =
|
||||||
if passes.skipCodegen(n): return n
|
if passes.skipCodegen(n): return n
|
||||||
result = n
|
result = n
|
||||||
var m = BModule(b)
|
var m = BModule(b)
|
||||||
|
|
@ -1716,17 +1718,17 @@ proc wholeCode*(m: BModule): PRope =
|
||||||
if not globals.generatedSyms.containsOrIncl(prc.id):
|
if not globals.generatedSyms.containsOrIncl(prc.id):
|
||||||
var p = newProc(globals, m, nil, m.module.options)
|
var p = newProc(globals, m, nil, m.module.options)
|
||||||
app(p.g.code, genProc(p, prc))
|
app(p.g.code, genProc(p, prc))
|
||||||
|
|
||||||
var disp = generateMethodDispatchers()
|
var disp = generateMethodDispatchers()
|
||||||
for i in 0..sonsLen(disp)-1:
|
for i in 0..sonsLen(disp)-1:
|
||||||
let prc = disp.sons[i].sym
|
let prc = disp.sons[i].sym
|
||||||
if not globals.generatedSyms.containsOrIncl(prc.id):
|
if not globals.generatedSyms.containsOrIncl(prc.id):
|
||||||
var p = newProc(globals, m, nil, m.module.options)
|
var p = newProc(globals, m, nil, m.module.options)
|
||||||
app(p.g.code, genProc(p, prc))
|
app(p.g.code, genProc(p, prc))
|
||||||
|
|
||||||
result = con(globals.typeInfo, globals.code)
|
result = con(globals.typeInfo, globals.code)
|
||||||
|
|
||||||
proc myClose(b: PPassContext, n: PNode): PNode =
|
proc myClose(b: PPassContext, n: PNode): PNode =
|
||||||
if passes.skipCodegen(n): return n
|
if passes.skipCodegen(n): return n
|
||||||
result = myProcess(b, n)
|
result = myProcess(b, n)
|
||||||
var m = BModule(b)
|
var m = BModule(b)
|
||||||
|
|
@ -1740,11 +1742,11 @@ proc myClose(b: PPassContext, n: PNode): PNode =
|
||||||
changeFileExt(completeCFilePath(m.module.filename), "js")
|
changeFileExt(completeCFilePath(m.module.filename), "js")
|
||||||
discard writeRopeIfNotEqual(con(genHeader(), code), outfile)
|
discard writeRopeIfNotEqual(con(genHeader(), code), outfile)
|
||||||
|
|
||||||
proc myOpenCached(s: PSym, rd: PRodReader): PPassContext =
|
proc myOpenCached(s: PSym, rd: PRodReader): PPassContext =
|
||||||
internalError("symbol files are not possible with the JS code generator")
|
internalError("symbol files are not possible with the JS code generator")
|
||||||
result = nil
|
result = nil
|
||||||
|
|
||||||
proc myOpen(s: PSym): PPassContext =
|
proc myOpen(s: PSym): PPassContext =
|
||||||
result = newModule(s)
|
result = newModule(s)
|
||||||
|
|
||||||
const JSgenPass* = makePass(myOpen, myOpenCached, myProcess, myClose)
|
const JSgenPass* = makePass(myOpen, myOpenCached, myProcess, myClose)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue