new js codegen: bugfixes
This commit is contained in:
parent
2afadc5c9c
commit
d64d6a70d4
1 changed files with 28 additions and 35 deletions
|
|
@ -161,7 +161,7 @@ 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, r: var TCompRes)
|
proc genStmt(p: PProc, n: PNode)
|
||||||
proc genProc(oldProc: PProc, prc: PSym): PRope
|
proc genProc(oldProc: PProc, prc: PSym): PRope
|
||||||
proc genConstant(p: PProc, c: PSym)
|
proc genConstant(p: PProc, c: PSym)
|
||||||
|
|
||||||
|
|
@ -387,7 +387,7 @@ proc genLineDir(p: PProc, n: PNode) =
|
||||||
|
|
||||||
proc genWhileStmt(p: PProc, n: PNode) =
|
proc genWhileStmt(p: PProc, n: PNode) =
|
||||||
var
|
var
|
||||||
cond, stmt: TCompRes
|
cond: TCompRes
|
||||||
internalAssert isEmptyType(n.typ)
|
internalAssert isEmptyType(n.typ)
|
||||||
genLineDir(p, n)
|
genLineDir(p, n)
|
||||||
inc(p.unique)
|
inc(p.unique)
|
||||||
|
|
@ -400,15 +400,16 @@ proc genWhileStmt(p: PProc, n: PNode) =
|
||||||
gen(p, n.sons[0], cond)
|
gen(p, n.sons[0], cond)
|
||||||
appf(p.body, "if (!$1) break L$2;$n" | "if not $1 then goto ::L$2:: end;$n",
|
appf(p.body, "if (!$1) break L$2;$n" | "if not $1 then goto ::L$2:: end;$n",
|
||||||
[cond.res, labl])
|
[cond.res, labl])
|
||||||
genStmt(p, n.sons[1], stmt)
|
genStmt(p, n.sons[1])
|
||||||
internalAssert stmt.res.isNil
|
|
||||||
appf(p.body, "}$n" | "end$n", [])
|
appf(p.body, "}$n" | "end$n", [])
|
||||||
setlen(p.blocks, length)
|
setlen(p.blocks, length)
|
||||||
|
|
||||||
proc moveInto(p: PProc, src: var TCompRes, dest: TCompRes) =
|
proc moveInto(p: PProc, src: var TCompRes, dest: TCompRes) =
|
||||||
if src.kind != resNone:
|
if src.kind != resNone:
|
||||||
assert dest.kind != resNone
|
if dest.kind != resNone:
|
||||||
p.body.appf("$1 = $2;$n", dest.rdLoc, src.rdLoc)
|
p.body.appf("$1 = $2;$n", dest.rdLoc, src.rdLoc)
|
||||||
|
else:
|
||||||
|
p.body.appf("$1;$n", src.rdLoc)
|
||||||
src.kind = resNone
|
src.kind = resNone
|
||||||
src.res = nil
|
src.res = nil
|
||||||
|
|
||||||
|
|
@ -442,11 +443,11 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
app(p.body, "try {" & tnl)
|
app(p.body, "try {" & tnl)
|
||||||
var length = sonsLen(n)
|
var length = sonsLen(n)
|
||||||
var a: TCompRes
|
var a: TCompRes
|
||||||
genStmt(p, n.sons[0], a)
|
gen(p, n.sons[0], a)
|
||||||
if not isEmptyType(n.typ):
|
if not isEmptyType(n.typ):
|
||||||
r.kind = resVal
|
r.kind = resVal
|
||||||
r.res = getTemp(p)
|
r.res = getTemp(p)
|
||||||
moveInto(p, a, r)
|
moveInto(p, a, r)
|
||||||
var i = 1
|
var i = 1
|
||||||
if length > 1 and n.sons[i].kind == nkExceptBranch:
|
if length > 1 and n.sons[i].kind == nkExceptBranch:
|
||||||
appf(p.body, "} catch (EXC) {$n")
|
appf(p.body, "} catch (EXC) {$n")
|
||||||
|
|
@ -455,7 +456,7 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
if blen == 1:
|
if blen == 1:
|
||||||
# general except section:
|
# general except section:
|
||||||
if i > 1: app(p.body, "else {" & tnl)
|
if i > 1: app(p.body, "else {" & tnl)
|
||||||
genStmt(p, n.sons[i].sons[0], a)
|
gen(p, n.sons[i].sons[0], a)
|
||||||
moveInto(p, a, r)
|
moveInto(p, a, r)
|
||||||
if i > 1: app(p.body, '}' & tnl)
|
if i > 1: app(p.body, '}' & tnl)
|
||||||
else:
|
else:
|
||||||
|
|
@ -469,13 +470,13 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
[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", [safePoint, orExpr])
|
appf(p.body, "if ($1.exc && ($2)) {$n", [safePoint, orExpr])
|
||||||
genStmt(p, n.sons[i].sons[blen - 1], a)
|
gen(p, n.sons[i].sons[blen - 1], a)
|
||||||
moveInto(p, a, r)
|
moveInto(p, a, r)
|
||||||
appf(p.body, "}$n")
|
appf(p.body, "}$n")
|
||||||
inc(i)
|
inc(i)
|
||||||
app(p.body, "} finally {" & tnl & "excHandler = excHandler.prev;" & tnl)
|
app(p.body, "} finally {" & tnl & "excHandler = excHandler.prev;" & tnl)
|
||||||
if i < length and n.sons[i].kind == nkFinally:
|
if i < length and n.sons[i].kind == nkFinally:
|
||||||
genStmt(p, n.sons[i].sons[0], a)
|
gen(p, n.sons[i].sons[0], a)
|
||||||
moveInto(p, a, r)
|
moveInto(p, a, r)
|
||||||
app(p.body, '}' & tnl)
|
app(p.body, '}' & tnl)
|
||||||
|
|
||||||
|
|
@ -527,12 +528,12 @@ proc genCase(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
else:
|
else:
|
||||||
gen(p, e, cond)
|
gen(p, e, cond)
|
||||||
appf(p.body, "case $1: ", [cond.rdLoc])
|
appf(p.body, "case $1: ", [cond.rdLoc])
|
||||||
genStmt(p, lastSon(it), stmt)
|
gen(p, lastSon(it), stmt)
|
||||||
moveInto(p, stmt, r)
|
moveInto(p, stmt, r)
|
||||||
appf(p.body, "$nbreak;$n")
|
appf(p.body, "$nbreak;$n")
|
||||||
of nkElse:
|
of nkElse:
|
||||||
appf(p.body, "default: $n")
|
appf(p.body, "default: $n")
|
||||||
genStmt(p, it.sons[0], stmt)
|
gen(p, it.sons[0], stmt)
|
||||||
moveInto(p, stmt, r)
|
moveInto(p, stmt, r)
|
||||||
appf(p.body, "break;$n")
|
appf(p.body, "break;$n")
|
||||||
else: internalError(it.info, "jsgen.genCaseStmt")
|
else: internalError(it.info, "jsgen.genCaseStmt")
|
||||||
|
|
@ -554,7 +555,7 @@ proc genBlock(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
p.blocks[idx].id = - p.unique # negative because it isn't used yet
|
p.blocks[idx].id = - p.unique # negative because it isn't used yet
|
||||||
labl = p.unique
|
labl = p.unique
|
||||||
appf(p.body, "L$1: do {$n", toRope(labl))
|
appf(p.body, "L$1: do {$n", toRope(labl))
|
||||||
genStmt(p, n.sons[1], r)
|
gen(p, n.sons[1], r)
|
||||||
appf(p.body, "} while(false);$n")
|
appf(p.body, "} while(false);$n")
|
||||||
setlen(p.blocks, idx)
|
setlen(p.blocks, idx)
|
||||||
|
|
||||||
|
|
@ -599,11 +600,11 @@ proc genIf(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
inc(toClose)
|
inc(toClose)
|
||||||
gen(p, it.sons[0], cond)
|
gen(p, it.sons[0], cond)
|
||||||
appf(p.body, "if ($1) {$n", cond.rdLoc)
|
appf(p.body, "if ($1) {$n", cond.rdLoc)
|
||||||
genStmt(p, it.sons[1], stmt)
|
gen(p, it.sons[1], stmt)
|
||||||
else:
|
else:
|
||||||
# else part:
|
# else part:
|
||||||
appf(p.body, "else {$n")
|
appf(p.body, "else {$n")
|
||||||
genStmt(p, it.sons[0], stmt)
|
gen(p, it.sons[0], stmt)
|
||||||
moveInto(p, stmt, r)
|
moveInto(p, stmt, r)
|
||||||
appf(p.body, "}$n")
|
appf(p.body, "}$n")
|
||||||
app(p.body, repeatChar(toClose, '}') & tnl)
|
app(p.body, repeatChar(toClose, '}') & tnl)
|
||||||
|
|
@ -1284,11 +1285,10 @@ proc convCStrToStr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
|
|
||||||
proc genReturnStmt(p: PProc, n: PNode) =
|
proc genReturnStmt(p: PProc, n: PNode) =
|
||||||
var a: TCompRes
|
|
||||||
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], a)
|
genStmt(p, n.sons[0])
|
||||||
else:
|
else:
|
||||||
genLineDir(p, n)
|
genLineDir(p, n)
|
||||||
app(p.body, "break BeforeRet;" & tnl)
|
app(p.body, "break BeforeRet;" & tnl)
|
||||||
|
|
@ -1314,7 +1314,7 @@ proc genProc(oldProc: PProc, prc: PSym): PRope =
|
||||||
var
|
var
|
||||||
resultSym: PSym
|
resultSym: PSym
|
||||||
name, returnStmt, resultAsgn, header: PRope
|
name, returnStmt, resultAsgn, header: PRope
|
||||||
a, r: 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)
|
||||||
|
|
@ -1330,16 +1330,17 @@ proc genProc(oldProc: PProc, prc: PSym): PRope =
|
||||||
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, r)
|
genStmt(p, prc.getBody)
|
||||||
if r.res != nil: app(p.body, r.res)
|
|
||||||
result = ropef("function $#($#) {$n$#$#$#$#}$n",
|
result = ropef("function $#($#) {$n$#$#$#$#}$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
|
||||||
|
|
||||||
proc genStmt(p: PProc, n: PNode, r: var TCompRes) =
|
proc genStmt(p: PProc, n: PNode) =
|
||||||
|
var r: TCompRes
|
||||||
gen(p, n, r)
|
gen(p, n, r)
|
||||||
|
if r.res != nil: appf(p.body, "$#;$n", r.res)
|
||||||
|
|
||||||
proc gen(p: PProc, n: PNode, r: var TCompRes) =
|
proc gen(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
r.typ = etyNone
|
r.typ = etyNone
|
||||||
|
|
@ -1415,15 +1416,10 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
# this shows the distinction is nice for backends and should be kept
|
# this shows the distinction is nice for backends and should be kept
|
||||||
# in the frontend
|
# in the frontend
|
||||||
let isExpr = not isEmptyType(n.typ)
|
let isExpr = not isEmptyType(n.typ)
|
||||||
var a: TCompRes
|
|
||||||
for i in countup(0, sonsLen(n) - 1 - isExpr.ord):
|
for i in countup(0, sonsLen(n) - 1 - isExpr.ord):
|
||||||
a.res = nil
|
genStmt(p, n.sons[i])
|
||||||
genStmt(p, n.sons[i], a)
|
|
||||||
if a.res != nil:
|
|
||||||
app(p.body, a.res)
|
|
||||||
app(p.body, ";" & tnl)
|
|
||||||
if isExpr:
|
if isExpr:
|
||||||
genStmt(p, lastSon(n), r)
|
gen(p, lastSon(n), r)
|
||||||
of nkBlockStmt, nkBlockExpr: genBlock(p, n, r)
|
of nkBlockStmt, nkBlockExpr: genBlock(p, n, r)
|
||||||
of nkIfStmt, nkIfExpr: genIf(p, n, r)
|
of nkIfStmt, nkIfExpr: genIf(p, n, r)
|
||||||
of nkWhileStmt: genWhileStmt(p, n)
|
of nkWhileStmt: genWhileStmt(p, n)
|
||||||
|
|
@ -1474,10 +1470,7 @@ proc genModule(p: PProc, n: PNode) =
|
||||||
"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))])
|
||||||
var r: TCompRes
|
genStmt(p, n)
|
||||||
genStmt(p, n, r)
|
|
||||||
if r.res != nil:
|
|
||||||
appf(p.body, "$#;$n", r.res)
|
|
||||||
if optStackTrace in p.options:
|
if optStackTrace in p.options:
|
||||||
appf(p.body, "framePtr = framePtr.prev;$n")
|
appf(p.body, "framePtr = framePtr.prev;$n")
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue