Remove PHP backend. (#7606)
* remove php * fix * keep nimphpext * remove targetJS enum
This commit is contained in:
parent
a708fda733
commit
35b0cc67e8
9 changed files with 330 additions and 778 deletions
|
|
@ -8,7 +8,6 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
# This is the JavaScript code generator.
|
# This is the JavaScript code generator.
|
||||||
# Also a PHP code generator. ;-)
|
|
||||||
|
|
||||||
discard """
|
discard """
|
||||||
The JS code generator contains only 2 tricks:
|
The JS code generator contains only 2 tricks:
|
||||||
|
|
@ -38,11 +37,8 @@ import
|
||||||
from modulegraphs import ModuleGraph
|
from modulegraphs import ModuleGraph
|
||||||
|
|
||||||
type
|
type
|
||||||
TTarget = enum
|
|
||||||
targetJS, targetPHP
|
|
||||||
TJSGen = object of TPassContext
|
TJSGen = object of TPassContext
|
||||||
module: PSym
|
module: PSym
|
||||||
target: TTarget
|
|
||||||
sigConflicts: CountTable[SigHash]
|
sigConflicts: CountTable[SigHash]
|
||||||
|
|
||||||
BModule = ref TJSGen
|
BModule = ref TJSGen
|
||||||
|
|
@ -92,16 +88,12 @@ type
|
||||||
module: BModule
|
module: BModule
|
||||||
g: PGlobals
|
g: PGlobals
|
||||||
beforeRetNeeded: bool
|
beforeRetNeeded: bool
|
||||||
target: TTarget # duplicated here for faster dispatching
|
|
||||||
unique: int # for temp identifier generation
|
unique: int # for temp identifier generation
|
||||||
blocks: seq[TBlock]
|
blocks: seq[TBlock]
|
||||||
extraIndent: int
|
extraIndent: int
|
||||||
up: PProc # up the call chain; required for closure support
|
up: PProc # up the call chain; required for closure support
|
||||||
declaredGlobals: IntSet
|
declaredGlobals: IntSet
|
||||||
|
|
||||||
template `|`(a, b: untyped): untyped {.dirty.} =
|
|
||||||
(if p.target == targetJS: a else: b)
|
|
||||||
|
|
||||||
var indent = "\t".rope
|
var indent = "\t".rope
|
||||||
|
|
||||||
proc indentLine(p: PProc, r: Rope): Rope =
|
proc indentLine(p: PProc, r: Rope): Rope =
|
||||||
|
|
@ -157,11 +149,8 @@ proc newProc(globals: PGlobals, module: BModule, procDef: PNode,
|
||||||
module: module,
|
module: module,
|
||||||
procDef: procDef,
|
procDef: procDef,
|
||||||
g: globals,
|
g: globals,
|
||||||
target: module.target,
|
|
||||||
extraIndent: int(procDef != nil))
|
extraIndent: int(procDef != nil))
|
||||||
if procDef != nil: result.prc = procDef.sons[namePos].sym
|
if procDef != nil: result.prc = procDef.sons[namePos].sym
|
||||||
if result.target == targetPHP:
|
|
||||||
result.declaredGlobals = initIntSet()
|
|
||||||
|
|
||||||
proc declareGlobal(p: PProc; id: int; r: Rope) =
|
proc declareGlobal(p: PProc; id: int; r: Rope) =
|
||||||
if p.prc != nil and not p.declaredGlobals.containsOrIncl(id):
|
if p.prc != nil and not p.declaredGlobals.containsOrIncl(id):
|
||||||
|
|
@ -208,8 +197,7 @@ proc mapType(typ: PType): TJSTypeKind =
|
||||||
of tyUnused, tyOptAsRef: internalError("mapType")
|
of tyUnused, tyOptAsRef: internalError("mapType")
|
||||||
|
|
||||||
proc mapType(p: PProc; typ: PType): TJSTypeKind =
|
proc mapType(p: PProc; typ: PType): TJSTypeKind =
|
||||||
if p.target == targetPHP: result = etyObject
|
result = mapType(typ)
|
||||||
else: result = mapType(typ)
|
|
||||||
|
|
||||||
proc mangleName(m: BModule, s: PSym): Rope =
|
proc mangleName(m: BModule, s: PSym): Rope =
|
||||||
proc validJsName(name: string): bool =
|
proc validJsName(name: string): bool =
|
||||||
|
|
@ -236,7 +224,7 @@ proc mangleName(m: BModule, s: PSym): Rope =
|
||||||
if result == nil:
|
if result == nil:
|
||||||
if s.kind == skField and s.name.s.validJsName:
|
if s.kind == skField and s.name.s.validJsName:
|
||||||
result = rope(s.name.s)
|
result = rope(s.name.s)
|
||||||
elif m.target == targetJS or s.kind == skTemp:
|
elif s.kind == skTemp:
|
||||||
result = rope(mangle(s.name.s))
|
result = rope(mangle(s.name.s))
|
||||||
else:
|
else:
|
||||||
var x = newStringOfCap(s.name.s.len)
|
var x = newStringOfCap(s.name.s.len)
|
||||||
|
|
@ -314,7 +302,7 @@ proc useMagic(p: PProc, name: string) =
|
||||||
proc isSimpleExpr(p: PProc; n: PNode): bool =
|
proc isSimpleExpr(p: PProc; n: PNode): bool =
|
||||||
# calls all the way down --> can stay expression based
|
# calls all the way down --> can stay expression based
|
||||||
if n.kind in nkCallKinds+{nkBracketExpr, nkDotExpr, nkPar, nkTupleConstr} or
|
if n.kind in nkCallKinds+{nkBracketExpr, nkDotExpr, nkPar, nkTupleConstr} or
|
||||||
(p.target == targetJS and n.kind in {nkObjConstr, nkBracket, nkCurly}):
|
(n.kind in {nkObjConstr, nkBracket, nkCurly}):
|
||||||
for c in n:
|
for c in n:
|
||||||
if not p.isSimpleExpr(c): return false
|
if not p.isSimpleExpr(c): return false
|
||||||
result = true
|
result = true
|
||||||
|
|
@ -323,12 +311,9 @@ proc isSimpleExpr(p: PProc; n: PNode): bool =
|
||||||
|
|
||||||
proc getTemp(p: PProc, defineInLocals: bool = true): Rope =
|
proc getTemp(p: PProc, defineInLocals: bool = true): Rope =
|
||||||
inc(p.unique)
|
inc(p.unique)
|
||||||
if p.target == targetJS:
|
|
||||||
result = "Tmp$1" % [rope(p.unique)]
|
result = "Tmp$1" % [rope(p.unique)]
|
||||||
if defineInLocals:
|
if defineInLocals:
|
||||||
add(p.locals, p.indentLine("var $1;$n" % [result]))
|
add(p.locals, p.indentLine("var $1;$n" % [result]))
|
||||||
else:
|
|
||||||
result = "$$Tmp$1" % [rope(p.unique)]
|
|
||||||
|
|
||||||
proc genAnd(p: PProc, a, b: PNode, r: var TCompRes) =
|
proc genAnd(p: PProc, a, b: PNode, r: var TCompRes) =
|
||||||
assert r.kind == resNone
|
assert r.kind == resNone
|
||||||
|
|
@ -477,15 +462,9 @@ proc unsignedTrimmerJS(size: BiggestInt): Rope =
|
||||||
of 4: rope">>> 0"
|
of 4: rope">>> 0"
|
||||||
else: rope""
|
else: rope""
|
||||||
|
|
||||||
proc unsignedTrimmerPHP(size: BiggestInt): Rope =
|
|
||||||
case size
|
|
||||||
of 1: rope"& 0xff"
|
|
||||||
of 2: rope"& 0xffff"
|
|
||||||
of 4: rope"& 0xffffffff"
|
|
||||||
else: rope""
|
|
||||||
|
|
||||||
template unsignedTrimmer(size: BiggestInt): Rope =
|
template unsignedTrimmer(size: BiggestInt): Rope =
|
||||||
size.unsignedTrimmerJS | size.unsignedTrimmerPHP
|
size.unsignedTrimmerJS
|
||||||
|
|
||||||
proc binaryUintExpr(p: PProc, n: PNode, r: var TCompRes, op: string,
|
proc binaryUintExpr(p: PProc, n: PNode, r: var TCompRes, op: string,
|
||||||
reassign = false) =
|
reassign = false) =
|
||||||
|
|
@ -533,45 +512,17 @@ proc arith(p: PProc, n: PNode, r: var TCompRes, op: TMagic) =
|
||||||
of mMulU: binaryUintExpr(p, n, r, "*")
|
of mMulU: binaryUintExpr(p, n, r, "*")
|
||||||
of mDivU: binaryUintExpr(p, n, r, "/")
|
of mDivU: binaryUintExpr(p, n, r, "/")
|
||||||
of mDivI:
|
of mDivI:
|
||||||
if p.target == targetPHP:
|
|
||||||
var x, y: TCompRes
|
|
||||||
gen(p, n.sons[1], x)
|
|
||||||
gen(p, n.sons[2], y)
|
|
||||||
r.res = "intval($1 / $2)" % [x.rdLoc, y.rdLoc]
|
|
||||||
else:
|
|
||||||
arithAux(p, n, r, op)
|
arithAux(p, n, r, op)
|
||||||
of mModI:
|
of mModI:
|
||||||
if p.target == targetPHP:
|
|
||||||
var x, y: TCompRes
|
|
||||||
gen(p, n.sons[1], x)
|
|
||||||
gen(p, n.sons[2], y)
|
|
||||||
r.res = "($1 % $2)" % [x.rdLoc, y.rdLoc]
|
|
||||||
else:
|
|
||||||
arithAux(p, n, r, op)
|
arithAux(p, n, r, op)
|
||||||
of mShrI:
|
of mShrI:
|
||||||
var x, y: TCompRes
|
var x, y: TCompRes
|
||||||
gen(p, n.sons[1], x)
|
gen(p, n.sons[1], x)
|
||||||
gen(p, n.sons[2], y)
|
gen(p, n.sons[2], y)
|
||||||
let trimmer = unsignedTrimmer(n[1].typ.skipTypes(abstractRange).size)
|
let trimmer = unsignedTrimmer(n[1].typ.skipTypes(abstractRange).size)
|
||||||
if p.target == targetPHP:
|
|
||||||
# XXX prevent multi evaluations
|
|
||||||
r.res = "(($1 $2) >= 0) ? (($1 $2) >> $3) : ((($1 $2) & 0x7fffffff) >> $3) | (0x40000000 >> ($3 - 1))" % [x.rdLoc, trimmer, y.rdLoc]
|
|
||||||
else:
|
|
||||||
r.res = "(($1 $2) >>> $3)" % [x.rdLoc, trimmer, y.rdLoc]
|
r.res = "(($1 $2) >>> $3)" % [x.rdLoc, trimmer, y.rdLoc]
|
||||||
of mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr,
|
of mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr,
|
||||||
mCStrToStr, mStrToStr, mEnumToStr:
|
mCStrToStr, mStrToStr, mEnumToStr:
|
||||||
if p.target == targetPHP:
|
|
||||||
if op == mEnumToStr:
|
|
||||||
var x: TCompRes
|
|
||||||
gen(p, n.sons[1], x)
|
|
||||||
r.res = "$#[$#]" % [genEnumInfoPHP(p, n.sons[1].typ), x.rdLoc]
|
|
||||||
elif op == mCharToStr:
|
|
||||||
var x: TCompRes
|
|
||||||
gen(p, n.sons[1], x)
|
|
||||||
r.res = "chr($#)" % [x.rdLoc]
|
|
||||||
else:
|
|
||||||
gen(p, n.sons[1], r)
|
|
||||||
else:
|
|
||||||
arithAux(p, n, r, op)
|
arithAux(p, n, r, op)
|
||||||
else:
|
else:
|
||||||
arithAux(p, n, r, op)
|
arithAux(p, n, r, op)
|
||||||
|
|
@ -591,7 +542,7 @@ proc genLineDir(p: PProc, n: PNode) =
|
||||||
useMagic(p, "endb")
|
useMagic(p, "endb")
|
||||||
lineF(p, "endb($1);$n", [rope(line)])
|
lineF(p, "endb($1);$n", [rope(line)])
|
||||||
elif hasFrameInfo(p):
|
elif hasFrameInfo(p):
|
||||||
lineF(p, "F.line = $1;$n" | "$$F['line'] = $1;$n", [rope(line)])
|
lineF(p, "F.line = $1;$n", [rope(line)])
|
||||||
|
|
||||||
proc genWhileStmt(p: PProc, n: PNode) =
|
proc genWhileStmt(p: PProc, n: PNode) =
|
||||||
var
|
var
|
||||||
|
|
@ -604,12 +555,12 @@ proc genWhileStmt(p: PProc, n: PNode) =
|
||||||
p.blocks[length].id = -p.unique
|
p.blocks[length].id = -p.unique
|
||||||
p.blocks[length].isLoop = true
|
p.blocks[length].isLoop = true
|
||||||
let labl = p.unique.rope
|
let labl = p.unique.rope
|
||||||
lineF(p, "L$1: while (true) {$n" | "while (true) {$n", [labl])
|
lineF(p, "L$1: while (true) {$n", [labl])
|
||||||
p.nested: gen(p, n.sons[0], cond)
|
p.nested: gen(p, n.sons[0], cond)
|
||||||
lineF(p, "if (!$1) break L$2;$n" | "if (!$1) goto L$2;$n",
|
lineF(p, "if (!$1) break L$2;$n",
|
||||||
[cond.res, labl])
|
[cond.res, labl])
|
||||||
p.nested: genStmt(p, n.sons[1])
|
p.nested: genStmt(p, n.sons[1])
|
||||||
lineF(p, "}$n" | "}L$#:;$n", [labl])
|
lineF(p, "}$n", [labl])
|
||||||
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) =
|
||||||
|
|
@ -653,26 +604,22 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
var i = 1
|
var i = 1
|
||||||
var length = sonsLen(n)
|
var length = sonsLen(n)
|
||||||
var catchBranchesExist = length > 1 and n.sons[i].kind == nkExceptBranch
|
var catchBranchesExist = length > 1 and n.sons[i].kind == nkExceptBranch
|
||||||
if catchBranchesExist and p.target == targetJS:
|
if catchBranchesExist:
|
||||||
add(p.body, "++excHandler;" & tnl)
|
add(p.body, "++excHandler;" & tnl)
|
||||||
var tmpFramePtr = rope"F"
|
var tmpFramePtr = rope"F"
|
||||||
if optStackTrace notin p.options:
|
if optStackTrace notin p.options:
|
||||||
tmpFramePtr = p.getTemp(true)
|
tmpFramePtr = p.getTemp(true)
|
||||||
line(p, tmpFramePtr & " = framePtr;" & tnl)
|
line(p, tmpFramePtr & " = framePtr;" & tnl)
|
||||||
lineF(p, "try {$n", [])
|
lineF(p, "try {$n", [])
|
||||||
if p.target == targetPHP and p.globals == nil:
|
|
||||||
p.globals = "global $lastJSError; global $prevJSError;".rope
|
|
||||||
var a: TCompRes
|
var a: TCompRes
|
||||||
gen(p, n.sons[0], a)
|
gen(p, n.sons[0], a)
|
||||||
moveInto(p, a, r)
|
moveInto(p, a, r)
|
||||||
var generalCatchBranchExists = false
|
var generalCatchBranchExists = false
|
||||||
let dollar = rope(if p.target == targetJS: "" else: "$")
|
let dollar = rope("")
|
||||||
if p.target == targetJS and catchBranchesExist:
|
if catchBranchesExist:
|
||||||
addf(p.body, "--excHandler;$n} catch (EXC) {$n var prevJSError = lastJSError;$n" &
|
addf(p.body, "--excHandler;$n} catch (EXC) {$n var prevJSError = lastJSError;$n" &
|
||||||
" lastJSError = EXC;$n --excHandler;$n", [])
|
" lastJSError = EXC;$n --excHandler;$n", [])
|
||||||
line(p, "framePtr = $1;$n" % [tmpFramePtr])
|
line(p, "framePtr = $1;$n" % [tmpFramePtr])
|
||||||
elif p.target == targetPHP:
|
|
||||||
lineF(p, "} catch (Exception $$EXC) {$n $$prevJSError = $$lastJSError;$n $$lastJSError = $$EXC;$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:
|
||||||
|
|
@ -704,18 +651,10 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
line(p, indent & "reraiseException();" & tnl)
|
line(p, indent & "reraiseException();" & tnl)
|
||||||
line(p, "}" & tnl)
|
line(p, "}" & tnl)
|
||||||
addf(p.body, "$1lastJSError = $1prevJSError;$n", [dollar])
|
addf(p.body, "$1lastJSError = $1prevJSError;$n", [dollar])
|
||||||
if p.target == targetJS:
|
|
||||||
line(p, "} finally {" & tnl)
|
line(p, "} finally {" & tnl)
|
||||||
line(p, "framePtr = $1;$n" % [tmpFramePtr])
|
line(p, "framePtr = $1;$n" % [tmpFramePtr])
|
||||||
if p.target == targetPHP:
|
|
||||||
# XXX ugly hack for PHP codegen
|
|
||||||
line(p, "}" & 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])
|
genStmt(p, n.sons[i].sons[0])
|
||||||
if p.target == targetPHP:
|
|
||||||
# XXX ugly hack for PHP codegen
|
|
||||||
line(p, "if($lastJSError) throw($lastJSError);" & tnl)
|
|
||||||
if p.target == targetJS:
|
|
||||||
line(p, "}" & tnl)
|
line(p, "}" & tnl)
|
||||||
|
|
||||||
proc genRaiseStmt(p: PProc, n: PNode) =
|
proc genRaiseStmt(p: PProc, n: PNode) =
|
||||||
|
|
@ -737,7 +676,7 @@ proc genCaseJS(p: PProc, n: PNode, r: var 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 and p.target == targetJS:
|
if stringSwitch:
|
||||||
useMagic(p, "toJSStr")
|
useMagic(p, "toJSStr")
|
||||||
lineF(p, "switch (toJSStr($1)) {$n", [cond.rdLoc])
|
lineF(p, "switch (toJSStr($1)) {$n", [cond.rdLoc])
|
||||||
else:
|
else:
|
||||||
|
|
@ -789,12 +728,12 @@ proc genBlock(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
sym.loc.k = locOther
|
sym.loc.k = locOther
|
||||||
sym.position = idx+1
|
sym.position = idx+1
|
||||||
let labl = p.unique
|
let labl = p.unique
|
||||||
lineF(p, "L$1: do {$n" | "", [labl.rope])
|
lineF(p, "L$1: do {$n", [labl.rope])
|
||||||
setLen(p.blocks, idx + 1)
|
setLen(p.blocks, idx + 1)
|
||||||
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
|
||||||
gen(p, n.sons[1], r)
|
gen(p, n.sons[1], r)
|
||||||
setLen(p.blocks, idx)
|
setLen(p.blocks, idx)
|
||||||
lineF(p, "} while(false);$n" | "$nL$#:;$n", [labl.rope])
|
lineF(p, "} while(false);$n", [labl.rope])
|
||||||
|
|
||||||
proc genBreakStmt(p: PProc, n: PNode) =
|
proc genBreakStmt(p: PProc, n: PNode) =
|
||||||
var idx: int
|
var idx: int
|
||||||
|
|
@ -812,7 +751,7 @@ proc genBreakStmt(p: PProc, n: PNode) =
|
||||||
if idx < 0 or not p.blocks[idx].isLoop:
|
if idx < 0 or not p.blocks[idx].isLoop:
|
||||||
internalError(n.info, "no loop to break")
|
internalError(n.info, "no loop to break")
|
||||||
p.blocks[idx].id = abs(p.blocks[idx].id) # label is used
|
p.blocks[idx].id = abs(p.blocks[idx].id) # label is used
|
||||||
lineF(p, "break L$1;$n" | "goto L$1;$n", [rope(p.blocks[idx].id)])
|
lineF(p, "break L$1;$n", [rope(p.blocks[idx].id)])
|
||||||
|
|
||||||
proc genAsmOrEmitStmt(p: PProc, n: PNode) =
|
proc genAsmOrEmitStmt(p: PProc, n: PNode) =
|
||||||
genLineDir(p, n)
|
genLineDir(p, n)
|
||||||
|
|
@ -826,7 +765,6 @@ proc genAsmOrEmitStmt(p: PProc, n: PNode) =
|
||||||
let v = it.sym
|
let v = it.sym
|
||||||
# for backwards compatibility we don't deref syms here :-(
|
# for backwards compatibility we don't deref syms here :-(
|
||||||
if v.kind in {skVar, skLet, skTemp, skConst, skResult, skParam, skForVar}:
|
if v.kind in {skVar, skLet, skTemp, skConst, skResult, skParam, skForVar}:
|
||||||
if p.target == targetPHP: p.body.add "$"
|
|
||||||
p.body.add mangleName(p.module, v)
|
p.body.add mangleName(p.module, v)
|
||||||
else:
|
else:
|
||||||
var r: TCompRes
|
var r: TCompRes
|
||||||
|
|
@ -869,24 +807,11 @@ proc generateHeader(p: PProc, typ: PType): Rope =
|
||||||
if isCompileTimeOnly(param.typ): continue
|
if isCompileTimeOnly(param.typ): continue
|
||||||
if result != nil: add(result, ", ")
|
if result != nil: add(result, ", ")
|
||||||
var name = mangleName(p.module, param)
|
var name = mangleName(p.module, param)
|
||||||
if p.target == targetJS:
|
|
||||||
add(result, name)
|
add(result, name)
|
||||||
if mapType(param.typ) == etyBaseIndex:
|
if mapType(param.typ) == etyBaseIndex:
|
||||||
add(result, ", ")
|
add(result, ", ")
|
||||||
add(result, name)
|
add(result, name)
|
||||||
add(result, "_Idx")
|
add(result, "_Idx")
|
||||||
elif not (i == 1 and param.name.s == "this"):
|
|
||||||
let k = param.typ.skipTypes({tyGenericInst, tyAlias, tySink}).kind
|
|
||||||
if k in {tyVar, tyRef, tyPtr, tyLent, tyPointer}:
|
|
||||||
add(result, "&")
|
|
||||||
add(result, "$")
|
|
||||||
add(result, name)
|
|
||||||
# XXX I think something like this is needed for PHP to really support
|
|
||||||
# ptr "inside" strings and seq
|
|
||||||
#if mapType(param.typ) == etyBaseIndex:
|
|
||||||
# add(result, ", $")
|
|
||||||
# add(result, name)
|
|
||||||
# add(result, "_Idx")
|
|
||||||
|
|
||||||
proc countJsParams(typ: PType): int =
|
proc countJsParams(typ: PType): int =
|
||||||
for i in countup(1, sonsLen(typ.n) - 1):
|
for i in countup(1, sonsLen(typ.n) - 1):
|
||||||
|
|
@ -906,21 +831,10 @@ const
|
||||||
|
|
||||||
proc needsNoCopy(p: PProc; y: PNode): bool =
|
proc needsNoCopy(p: PProc; y: PNode): bool =
|
||||||
result = (y.kind in nodeKindsNeedNoCopy) or
|
result = (y.kind in nodeKindsNeedNoCopy) or
|
||||||
(skipTypes(y.typ, abstractInst).kind in {tyRef, tyPtr, tyLent, tyVar}) or
|
(skipTypes(y.typ, abstractInst).kind in {tyRef, tyPtr, tyLent, tyVar})
|
||||||
p.target == targetPHP
|
|
||||||
|
|
||||||
proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
|
proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
|
||||||
var a, b: TCompRes
|
var a, b: TCompRes
|
||||||
|
|
||||||
if p.target == targetPHP and x.kind == nkBracketExpr and
|
|
||||||
x[0].typ.skipTypes(abstractVar).kind in {tyString, tyCString}:
|
|
||||||
var c: TCompRes
|
|
||||||
gen(p, x[0], a)
|
|
||||||
gen(p, x[1], b)
|
|
||||||
gen(p, y, c)
|
|
||||||
lineF(p, "$#[$#] = chr($#);$n", [a.rdLoc, b.rdLoc, c.rdLoc])
|
|
||||||
return
|
|
||||||
|
|
||||||
var xtyp = mapType(p, x.typ)
|
var xtyp = mapType(p, x.typ)
|
||||||
|
|
||||||
if x.kind == nkHiddenDeref and x.sons[0].kind == nkCall and xtyp != etyObject:
|
if x.kind == nkHiddenDeref and x.sons[0].kind == nkCall and xtyp != etyObject:
|
||||||
|
|
@ -968,7 +882,7 @@ proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
|
||||||
|
|
||||||
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=p.target == targetPHP)
|
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)
|
||||||
|
|
@ -991,12 +905,10 @@ proc genSwap(p: PProc, n: PNode) =
|
||||||
let tmp2 = p.getTemp(false)
|
let tmp2 = p.getTemp(false)
|
||||||
if a.typ != etyBaseIndex or b.typ != etyBaseIndex:
|
if a.typ != etyBaseIndex or b.typ != etyBaseIndex:
|
||||||
internalError(n.info, "genSwap")
|
internalError(n.info, "genSwap")
|
||||||
lineF(p, "var $1 = $2; $2 = $3; $3 = $1;$n" |
|
lineF(p, "var $1 = $2; $2 = $3; $3 = $1;$n",
|
||||||
"$1 = $2; $2 = $3; $3 = $1;$n",
|
|
||||||
[tmp, a.address, b.address])
|
[tmp, a.address, b.address])
|
||||||
tmp = tmp2
|
tmp = tmp2
|
||||||
lineF(p, "var $1 = $2; $2 = $3; $3 = $1;" |
|
lineF(p, "var $1 = $2; $2 = $3; $3 = $1;",
|
||||||
"$1 = $2; $2 = $3; $3 = $1;",
|
|
||||||
[tmp, a.res, b.res])
|
[tmp, a.res, b.res])
|
||||||
|
|
||||||
proc getFieldPosition(f: PNode): int =
|
proc getFieldPosition(f: PNode): int =
|
||||||
|
|
@ -1011,10 +923,7 @@ proc genFieldAddr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
let b = if n.kind == nkHiddenAddr: n.sons[0] else: n
|
let b = if n.kind == nkHiddenAddr: n.sons[0] else: n
|
||||||
gen(p, b.sons[0], a)
|
gen(p, b.sons[0], a)
|
||||||
if skipTypes(b.sons[0].typ, abstractVarRange).kind == tyTuple:
|
if skipTypes(b.sons[0].typ, abstractVarRange).kind == tyTuple:
|
||||||
if p.target == targetJS:
|
r.res = makeJSString("Field" & $getFieldPosition(b.sons[1]))
|
||||||
r.res = makeJSString( "Field" & $getFieldPosition(b.sons[1]) )
|
|
||||||
else:
|
|
||||||
r.res = getFieldPosition(b.sons[1]).rope
|
|
||||||
else:
|
else:
|
||||||
if b.sons[1].kind != nkSym: internalError(b.sons[1].info, "genFieldAddr")
|
if b.sons[1].kind != nkSym: internalError(b.sons[1].info, "genFieldAddr")
|
||||||
var f = b.sons[1].sym
|
var f = b.sons[1].sym
|
||||||
|
|
@ -1029,19 +938,13 @@ proc genFieldAccess(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
gen(p, n.sons[0], r)
|
gen(p, n.sons[0], r)
|
||||||
let otyp = skipTypes(n.sons[0].typ, abstractVarRange)
|
let otyp = skipTypes(n.sons[0].typ, abstractVarRange)
|
||||||
if otyp.kind == tyTuple:
|
if otyp.kind == tyTuple:
|
||||||
r.res = ("$1.Field$2" | "$1[$2]") %
|
r.res = ("$1.Field$2") %
|
||||||
[r.res, getFieldPosition(n.sons[1]).rope]
|
[r.res, getFieldPosition(n.sons[1]).rope]
|
||||||
else:
|
else:
|
||||||
if n.sons[1].kind != nkSym: internalError(n.sons[1].info, "genFieldAccess")
|
if n.sons[1].kind != nkSym: internalError(n.sons[1].info, "genFieldAccess")
|
||||||
var f = n.sons[1].sym
|
var f = n.sons[1].sym
|
||||||
if f.loc.r == nil: f.loc.r = mangleName(p.module, f)
|
if f.loc.r == nil: f.loc.r = mangleName(p.module, f)
|
||||||
if p.target == targetJS:
|
|
||||||
r.res = "$1.$2" % [r.res, f.loc.r]
|
r.res = "$1.$2" % [r.res, f.loc.r]
|
||||||
else:
|
|
||||||
if {sfImportc, sfExportc} * f.flags != {}:
|
|
||||||
r.res = "$1->$2" % [r.res, f.loc.r]
|
|
||||||
else:
|
|
||||||
r.res = "$1['$2']" % [r.res, f.loc.r]
|
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
|
|
||||||
proc genAddr(p: PProc, n: PNode, r: var TCompRes)
|
proc genAddr(p: PProc, n: PNode, r: var TCompRes)
|
||||||
|
|
@ -1069,12 +972,6 @@ proc genArrayAddr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
else: first = 0
|
else: first = 0
|
||||||
if optBoundsCheck in p.options:
|
if optBoundsCheck in p.options:
|
||||||
useMagic(p, "chckIndx")
|
useMagic(p, "chckIndx")
|
||||||
if p.target == targetPHP:
|
|
||||||
if typ.kind != tyString:
|
|
||||||
r.res = "chckIndx($1, $2, count($3)-1)-$2" % [b.res, rope(first), a.res]
|
|
||||||
else:
|
|
||||||
r.res = "chckIndx($1, $2, strlen($3))-$2" % [b.res, rope(first), a.res]
|
|
||||||
else:
|
|
||||||
r.res = "chckIndx($1, $2, $3.length+$2-1)-$2" % [b.res, rope(first), a.res]
|
r.res = "chckIndx($1, $2, $3.length+$2-1)-$2" % [b.res, rope(first), a.res]
|
||||||
elif first != 0:
|
elif first != 0:
|
||||||
r.res = "($1)-$2" % [b.res, rope(first)]
|
r.res = "($1)-$2" % [b.res, rope(first)]
|
||||||
|
|
@ -1089,27 +986,11 @@ proc genArrayAccess(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
of tyArray, tyOpenArray, tySequence, tyString, tyCString, tyVarargs:
|
of tyArray, tyOpenArray, tySequence, tyString, tyCString, tyVarargs:
|
||||||
genArrayAddr(p, n, r)
|
genArrayAddr(p, n, r)
|
||||||
of tyTuple:
|
of tyTuple:
|
||||||
if p.target == targetPHP:
|
|
||||||
genFieldAccess(p, n, r)
|
|
||||||
return
|
|
||||||
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
|
||||||
if r.res == nil: internalError(n.info, "genArrayAccess")
|
if r.res == nil: internalError(n.info, "genArrayAccess")
|
||||||
if p.target == targetPHP:
|
if ty.kind == tyCString:
|
||||||
if n.sons[0].kind in nkCallKinds+{nkStrLit..nkTripleStrLit}:
|
|
||||||
useMagic(p, "nimAt")
|
|
||||||
if ty.kind in {tyString, tyCString}:
|
|
||||||
# XXX this needs to be more like substr($1,$2)
|
|
||||||
r.res = "ord(nimAt($1, $2))" % [r.address, r.res]
|
|
||||||
else:
|
|
||||||
r.res = "nimAt($1, $2)" % [r.address, r.res]
|
|
||||||
elif ty.kind in {tyString, tyCString}:
|
|
||||||
# XXX this needs to be more like substr($1,$2)
|
|
||||||
r.res = "ord(@$1[$2])" % [r.address, r.res]
|
|
||||||
else:
|
|
||||||
r.res = "$1[$2]" % [r.address, r.res]
|
|
||||||
elif ty.kind == tyCString:
|
|
||||||
r.res = "$1.charCodeAt($2)" % [r.address, r.res]
|
r.res = "$1.charCodeAt($2)" % [r.address, r.res]
|
||||||
else:
|
else:
|
||||||
r.res = "$1[$2]" % [r.address, r.res]
|
r.res = "$1[$2]" % [r.address, r.res]
|
||||||
|
|
@ -1122,7 +1003,7 @@ template isIndirect(x: PSym): bool =
|
||||||
#(mapType(v.typ) != etyObject) and
|
#(mapType(v.typ) != etyObject) and
|
||||||
{sfImportc, sfVolatile, sfExportc} * v.flags == {} and
|
{sfImportc, sfVolatile, sfExportc} * v.flags == {} and
|
||||||
v.kind notin {skProc, skFunc, skConverter, skMethod, skIterator,
|
v.kind notin {skProc, skFunc, skConverter, skMethod, skIterator,
|
||||||
skConst, skTemp, skLet} and p.target == targetJS)
|
skConst, skTemp, skLet})
|
||||||
|
|
||||||
proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
|
proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
case n.sons[0].kind
|
case n.sons[0].kind
|
||||||
|
|
@ -1138,8 +1019,6 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
r.typ = etyNone
|
r.typ = etyNone
|
||||||
if isIndirect(s):
|
if isIndirect(s):
|
||||||
r.res = s.loc.r & "[0]"
|
r.res = s.loc.r & "[0]"
|
||||||
elif p.target == targetPHP:
|
|
||||||
r.res = "&" & s.loc.r
|
|
||||||
else:
|
else:
|
||||||
r.res = s.loc.r
|
r.res = s.loc.r
|
||||||
r.address = nil
|
r.address = nil
|
||||||
|
|
@ -1180,15 +1059,7 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
else: internalError(n.sons[0].info, "genAddr: " & $n.sons[0].kind)
|
else: internalError(n.sons[0].info, "genAddr: " & $n.sons[0].kind)
|
||||||
|
|
||||||
proc thisParam(p: PProc; typ: PType): PType =
|
proc thisParam(p: PProc; typ: PType): PType =
|
||||||
if p.target == targetPHP:
|
discard
|
||||||
# XXX Might be very useful for the JS backend too?
|
|
||||||
let typ = skipTypes(typ, abstractInst)
|
|
||||||
assert(typ.kind == tyProc)
|
|
||||||
if 1 < sonsLen(typ.n):
|
|
||||||
assert(typ.n.sons[1].kind == nkSym)
|
|
||||||
let param = typ.n.sons[1].sym
|
|
||||||
if param.name.s == "this":
|
|
||||||
result = param.typ.skipTypes(abstractVar)
|
|
||||||
|
|
||||||
proc attachProc(p: PProc; content: Rope; s: PSym) =
|
proc attachProc(p: PProc; content: Rope; s: PSym) =
|
||||||
let otyp = thisParam(p, s.typ)
|
let otyp = thisParam(p, s.typ)
|
||||||
|
|
@ -1220,7 +1091,6 @@ proc genSym(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
of skVar, skLet, skParam, skTemp, skResult, skForVar:
|
of skVar, skLet, skParam, skTemp, skResult, skForVar:
|
||||||
if s.loc.r == nil:
|
if s.loc.r == nil:
|
||||||
internalError(n.info, "symbol has no generated name: " & s.name.s)
|
internalError(n.info, "symbol has no generated name: " & s.name.s)
|
||||||
if p.target == targetJS:
|
|
||||||
let k = mapType(p, s.typ)
|
let k = mapType(p, s.typ)
|
||||||
if k == etyBaseIndex:
|
if k == etyBaseIndex:
|
||||||
r.typ = etyBaseIndex
|
r.typ = etyBaseIndex
|
||||||
|
|
@ -1234,24 +1104,13 @@ proc genSym(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
r.res = "$1[0]" % [s.loc.r]
|
r.res = "$1[0]" % [s.loc.r]
|
||||||
else:
|
else:
|
||||||
r.res = s.loc.r
|
r.res = s.loc.r
|
||||||
else:
|
|
||||||
r.res = "$" & s.loc.r
|
|
||||||
if sfGlobal in s.flags:
|
|
||||||
p.declareGlobal(s.id, r.res)
|
|
||||||
of skConst:
|
of skConst:
|
||||||
genConstant(p, s)
|
genConstant(p, s)
|
||||||
if s.loc.r == nil:
|
if s.loc.r == nil:
|
||||||
internalError(n.info, "symbol has no generated name: " & s.name.s)
|
internalError(n.info, "symbol has no generated name: " & s.name.s)
|
||||||
if p.target == targetJS:
|
|
||||||
r.res = s.loc.r
|
r.res = s.loc.r
|
||||||
else:
|
|
||||||
r.res = "$" & s.loc.r
|
|
||||||
p.declareGlobal(s.id, r.res)
|
|
||||||
of skProc, skFunc, skConverter, skMethod:
|
of skProc, skFunc, skConverter, skMethod:
|
||||||
discard mangleName(p.module, s)
|
discard mangleName(p.module, s)
|
||||||
if p.target == targetPHP and r.kind != resCallee:
|
|
||||||
r.res = makeJsString($s.loc.r)
|
|
||||||
else:
|
|
||||||
r.res = s.loc.r
|
r.res = s.loc.r
|
||||||
if lfNoDecl in s.loc.flags or s.magic != mNone or
|
if lfNoDecl in s.loc.flags or s.magic != mNone or
|
||||||
{sfImportc, sfInfixCall} * s.flags != {}:
|
{sfImportc, sfInfixCall} * s.flags != {}:
|
||||||
|
|
@ -1421,10 +1280,8 @@ proc genInfixCall(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
r.res = "$1[$2]" % [r.address, r.res]
|
r.res = "$1[$2]" % [r.address, r.res]
|
||||||
r.address = nil
|
r.address = nil
|
||||||
r.typ = etyNone
|
r.typ = etyNone
|
||||||
add(r.res, "." | "->")
|
add(r.res, ".")
|
||||||
var op: TCompRes
|
var op: TCompRes
|
||||||
if p.target == targetPHP:
|
|
||||||
op.kind = resCallee
|
|
||||||
gen(p, n.sons[0], op)
|
gen(p, n.sons[0], op)
|
||||||
add(r.res, op.res)
|
add(r.res, op.res)
|
||||||
genArgs(p, n, r, 2)
|
genArgs(p, n, r, 2)
|
||||||
|
|
@ -1433,28 +1290,21 @@ proc genCall(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
if n.sons[0].kind == nkSym and thisParam(p, n.sons[0].typ) != nil:
|
if n.sons[0].kind == nkSym and thisParam(p, n.sons[0].typ) != nil:
|
||||||
genInfixCall(p, n, r)
|
genInfixCall(p, n, r)
|
||||||
return
|
return
|
||||||
if p.target == targetPHP:
|
|
||||||
r.kind = resCallee
|
|
||||||
gen(p, n.sons[0], r)
|
gen(p, n.sons[0], r)
|
||||||
genArgs(p, n, r)
|
genArgs(p, n, r)
|
||||||
|
|
||||||
proc genEcho(p: PProc, n: PNode, r: var TCompRes) =
|
proc genEcho(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
let n = n[1].skipConv
|
let n = n[1].skipConv
|
||||||
internalAssert n.kind == nkBracket
|
internalAssert n.kind == nkBracket
|
||||||
if p.target == targetJS:
|
|
||||||
useMagic(p, "toJSStr") # Used in rawEcho
|
useMagic(p, "toJSStr") # Used in rawEcho
|
||||||
useMagic(p, "rawEcho")
|
useMagic(p, "rawEcho")
|
||||||
elif n.len == 0:
|
add(r.res, "rawEcho(")
|
||||||
r.kind = resExpr
|
|
||||||
add(r.res, """print("\n")""")
|
|
||||||
return
|
|
||||||
add(r.res, "rawEcho(" | "print(")
|
|
||||||
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: add(r.res, ", " | ".")
|
if i > 0: add(r.res, ", ")
|
||||||
genArgNoParam(p, it, r)
|
genArgNoParam(p, it, r)
|
||||||
add(r.res, ")" | """."\n")""")
|
add(r.res, ")")
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
|
|
||||||
proc putToSeq(s: string, indirect: bool): Rope =
|
proc putToSeq(s: string, indirect: bool): Rope =
|
||||||
|
|
@ -1474,10 +1324,7 @@ proc createRecordVarAux(p: PProc, rec: PNode, excludedFieldIDs: IntSet, output:
|
||||||
of nkSym:
|
of nkSym:
|
||||||
if rec.sym.id notin excludedFieldIDs:
|
if rec.sym.id notin excludedFieldIDs:
|
||||||
if output.len > 0: output.add(", ")
|
if output.len > 0: output.add(", ")
|
||||||
if p.target == targetJS:
|
|
||||||
output.addf("$#: ", [mangleName(p.module, rec.sym)])
|
output.addf("$#: ", [mangleName(p.module, rec.sym)])
|
||||||
else:
|
|
||||||
output.addf("'$#' => ", [mangleName(p.module, rec.sym)])
|
|
||||||
output.add(createVar(p, rec.sym.typ, false))
|
output.add(createVar(p, rec.sym.typ, false))
|
||||||
else: internalError(rec.info, "createRecordVarAux")
|
else: internalError(rec.info, "createRecordVarAux")
|
||||||
|
|
||||||
|
|
@ -1485,7 +1332,7 @@ proc createObjInitList(p: PProc, typ: PType, excludedFieldIDs: IntSet, output: v
|
||||||
var t = typ
|
var t = typ
|
||||||
if objHasTypeField(t):
|
if objHasTypeField(t):
|
||||||
if output.len > 0: output.add(", ")
|
if output.len > 0: output.add(", ")
|
||||||
addf(output, "m_type: $1" | "'m_type' => $#", [genTypeInfo(p, t)])
|
addf(output, "m_type: $1", [genTypeInfo(p, t)])
|
||||||
while t != nil:
|
while t != nil:
|
||||||
t = t.skipTypes(skipPtrs)
|
t = t.skipTypes(skipPtrs)
|
||||||
createRecordVarAux(p, t.n, excludedFieldIDs, output)
|
createRecordVarAux(p, t.n, excludedFieldIDs, output)
|
||||||
|
|
@ -1514,32 +1361,31 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
|
||||||
of tyRange, tyGenericInst, tyAlias, tySink:
|
of tyRange, tyGenericInst, tyAlias, tySink:
|
||||||
result = createVar(p, lastSon(typ), indirect)
|
result = createVar(p, lastSon(typ), indirect)
|
||||||
of tySet:
|
of tySet:
|
||||||
result = putToSeq("{}" | "array()", indirect)
|
result = putToSeq("{}", indirect)
|
||||||
of tyBool:
|
of tyBool:
|
||||||
result = putToSeq("false", indirect)
|
result = putToSeq("false", indirect)
|
||||||
of tyArray:
|
of tyArray:
|
||||||
let length = int(lengthOrd(t))
|
let length = int(lengthOrd(t))
|
||||||
let e = elemType(t)
|
let e = elemType(t)
|
||||||
let jsTyp = arrayTypeForElemType(e)
|
let jsTyp = arrayTypeForElemType(e)
|
||||||
if not jsTyp.isNil and p.target == targetJS:
|
if not jsTyp.isNil:
|
||||||
result = "new $1($2)" % [rope(jsTyp), rope(length)]
|
result = "new $1($2)" % [rope(jsTyp), rope(length)]
|
||||||
elif length > 32:
|
elif 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.
|
||||||
if p.target == targetJS: useMagic(p, "nimCopy")
|
useMagic(p, "nimCopy")
|
||||||
result = "arrayConstr($1, $2, $3)" % [rope(length),
|
result = "arrayConstr($1, $2, $3)" % [rope(length),
|
||||||
createVar(p, e, false), genTypeInfo(p, e)]
|
createVar(p, e, false), genTypeInfo(p, e)]
|
||||||
else:
|
else:
|
||||||
result = rope("[" | "array(")
|
result = rope("[")
|
||||||
var i = 0
|
var i = 0
|
||||||
while i < length:
|
while i < length:
|
||||||
if i > 0: add(result, ", ")
|
if i > 0: add(result, ", ")
|
||||||
add(result, createVar(p, e, false))
|
add(result, createVar(p, e, false))
|
||||||
inc(i)
|
inc(i)
|
||||||
add(result, "]" | ")")
|
add(result, "]")
|
||||||
if indirect: result = "[$1]" % [result]
|
if indirect: result = "[$1]" % [result]
|
||||||
of tyTuple:
|
of tyTuple:
|
||||||
if p.target == targetJS:
|
|
||||||
result = rope("{")
|
result = rope("{")
|
||||||
for i in 0..<t.sonsLen:
|
for i in 0..<t.sonsLen:
|
||||||
if i > 0: add(result, ", ")
|
if i > 0: add(result, ", ")
|
||||||
|
|
@ -1547,16 +1393,10 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
|
||||||
createVar(p, t.sons[i], false)])
|
createVar(p, t.sons[i], false)])
|
||||||
add(result, "}")
|
add(result, "}")
|
||||||
if indirect: result = "[$1]" % [result]
|
if indirect: result = "[$1]" % [result]
|
||||||
else:
|
|
||||||
result = rope("array(")
|
|
||||||
for i in 0..<t.sonsLen:
|
|
||||||
if i > 0: add(result, ", ")
|
|
||||||
add(result, createVar(p, t.sons[i], false))
|
|
||||||
add(result, ")")
|
|
||||||
of tyObject:
|
of tyObject:
|
||||||
var initList: Rope
|
var initList: Rope
|
||||||
createObjInitList(p, t, initIntSet(), initList)
|
createObjInitList(p, t, initIntSet(), initList)
|
||||||
result = ("{$1}" | "array($#)") % [initList]
|
result = ("{$1}") % [initList]
|
||||||
if indirect: result = "[$1]" % [result]
|
if indirect: result = "[$1]" % [result]
|
||||||
of tyVar, tyPtr, tyLent, tyRef:
|
of tyVar, tyPtr, tyLent, tyRef:
|
||||||
if mapType(p, t) == etyBaseIndex:
|
if mapType(p, t) == etyBaseIndex:
|
||||||
|
|
@ -1597,7 +1437,7 @@ proc genVarInit(p: PProc, v: PSym, n: PNode) =
|
||||||
varCode = v.constraint.strVal
|
varCode = v.constraint.strVal
|
||||||
|
|
||||||
if n.kind == nkEmpty:
|
if n.kind == nkEmpty:
|
||||||
lineF(p, varCode & " = $3;$n" | "$$$2 = $3;$n",
|
lineF(p, varCode & " = $3;$n",
|
||||||
[returnType, varName, createVar(p, v.typ, isIndirect(v))])
|
[returnType, varName, createVar(p, v.typ, isIndirect(v))])
|
||||||
if v.typ.kind in {tyVar, tyPtr, tyLent, tyRef} and mapType(p, v.typ) == etyBaseIndex:
|
if v.typ.kind in {tyVar, tyPtr, tyLent, tyRef} and mapType(p, v.typ) == etyBaseIndex:
|
||||||
lineF(p, "var $1_Idx = 0;$n", [varName])
|
lineF(p, "var $1_Idx = 0;$n", [varName])
|
||||||
|
|
@ -1632,7 +1472,7 @@ proc genVarInit(p: PProc, v: PSym, n: PNode) =
|
||||||
if isIndirect(v):
|
if isIndirect(v):
|
||||||
lineF(p, varCode & " = [$3];$n", [returnType, v.loc.r, s])
|
lineF(p, varCode & " = [$3];$n", [returnType, v.loc.r, s])
|
||||||
else:
|
else:
|
||||||
lineF(p, varCode & " = $3;$n" | "$$$2 = $3;$n", [returnType, v.loc.r, s])
|
lineF(p, varCode & " = $3;$n", [returnType, v.loc.r, s])
|
||||||
|
|
||||||
if useReloadingGuard:
|
if useReloadingGuard:
|
||||||
lineF(p, "}$n")
|
lineF(p, "}$n")
|
||||||
|
|
@ -1665,18 +1505,14 @@ proc genNew(p: PProc, n: PNode) =
|
||||||
var a: TCompRes
|
var a: TCompRes
|
||||||
gen(p, n.sons[1], a)
|
gen(p, n.sons[1], a)
|
||||||
var t = skipTypes(n.sons[1].typ, abstractVar).sons[0]
|
var t = skipTypes(n.sons[1].typ, abstractVar).sons[0]
|
||||||
if p.target == targetJS:
|
|
||||||
lineF(p, "$1 = $2;$n", [a.res, createVar(p, t, false)])
|
lineF(p, "$1 = $2;$n", [a.res, createVar(p, t, false)])
|
||||||
else:
|
|
||||||
lineF(p, "$3 = $2; $1 = &$3;$n", [a.res, createVar(p, t, false), getTemp(p)])
|
|
||||||
|
|
||||||
proc genNewSeq(p: PProc, n: PNode) =
|
proc genNewSeq(p: PProc, n: PNode) =
|
||||||
var x, y: TCompRes
|
var x, y: TCompRes
|
||||||
gen(p, n.sons[1], x)
|
gen(p, n.sons[1], x)
|
||||||
gen(p, n.sons[2], y)
|
gen(p, n.sons[2], y)
|
||||||
let t = skipTypes(n.sons[1].typ, abstractVar).sons[0]
|
let t = skipTypes(n.sons[1].typ, abstractVar).sons[0]
|
||||||
lineF(p, "$1 = new Array($2); for (var i=0;i<$2;++i) {$1[i]=$3;}" |
|
lineF(p, "$1 = new Array($2); for (var i=0;i<$2;++i) {$1[i]=$3;}", [
|
||||||
"$1 = array(); for ($$i=0;$$i<$2;++$$i) {$1[]=$3;}", [
|
|
||||||
x.rdLoc, y.rdLoc, createVar(p, t, false)])
|
x.rdLoc, y.rdLoc, createVar(p, t, false)])
|
||||||
|
|
||||||
proc genOrd(p: PProc, n: PNode, r: var TCompRes) =
|
proc genOrd(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
|
|
@ -1708,21 +1544,6 @@ proc genConStrStr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
else:
|
else:
|
||||||
r.res.add("$1)" % [a.res])
|
r.res.add("$1)" % [a.res])
|
||||||
|
|
||||||
proc genConStrStrPHP(p: PProc, n: PNode, r: var TCompRes) =
|
|
||||||
var a: TCompRes
|
|
||||||
gen(p, n.sons[1], a)
|
|
||||||
r.kind = resExpr
|
|
||||||
if skipTypes(n.sons[1].typ, abstractVarRange).kind == tyChar:
|
|
||||||
r.res.add("chr($1)" % [a.res])
|
|
||||||
else:
|
|
||||||
r.res.add(a.res)
|
|
||||||
for i in countup(2, sonsLen(n) - 1):
|
|
||||||
gen(p, n.sons[i], a)
|
|
||||||
if skipTypes(n.sons[i].typ, abstractVarRange).kind == tyChar:
|
|
||||||
r.res.add(".chr($1)" % [a.res])
|
|
||||||
else:
|
|
||||||
r.res.add(".$1" % [a.res])
|
|
||||||
|
|
||||||
proc genToArray(p: PProc; n: PNode; r: var TCompRes) =
|
proc genToArray(p: PProc; n: PNode; r: var TCompRes) =
|
||||||
# we map mArray to PHP's array constructor, a mild hack:
|
# we map mArray to PHP's array constructor, a mild hack:
|
||||||
var a, b: TCompRes
|
var a, b: TCompRes
|
||||||
|
|
@ -1766,9 +1587,6 @@ proc genReprAux(p: PProc, n: PNode, r: var TCompRes, magic: string, typ: Rope =
|
||||||
add(r.res, ")")
|
add(r.res, ")")
|
||||||
|
|
||||||
proc genRepr(p: PProc, n: PNode, r: var TCompRes) =
|
proc genRepr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
if p.target == targetPHP:
|
|
||||||
localError(n.info, "'repr' not available for PHP backend")
|
|
||||||
return
|
|
||||||
let t = skipTypes(n.sons[1].typ, abstractVarRange)
|
let t = skipTypes(n.sons[1].typ, abstractVarRange)
|
||||||
case t.kind:
|
case t.kind:
|
||||||
of tyInt..tyInt64, tyUInt..tyUInt64:
|
of tyInt..tyInt64, tyUInt..tyUInt64:
|
||||||
|
|
@ -1828,23 +1646,16 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
if not (optOverflowCheck in p.options): unaryExpr(p, n, r, "", "$1 - 1")
|
if not (optOverflowCheck in p.options): unaryExpr(p, n, r, "", "$1 - 1")
|
||||||
else: unaryExpr(p, n, r, "subInt", "subInt($1, 1)")
|
else: unaryExpr(p, n, r, "subInt", "subInt($1, 1)")
|
||||||
of mAppendStrCh:
|
of mAppendStrCh:
|
||||||
if p.target == targetJS:
|
|
||||||
binaryExpr(p, n, r, "addChar",
|
binaryExpr(p, n, r, "addChar",
|
||||||
"if ($1 != null) { addChar($1, $2); } else { $1 = [$2, 0]; }")
|
"if ($1 != null) { addChar($1, $2); } else { $1 = [$2, 0]; }")
|
||||||
else:
|
|
||||||
binaryExpr(p, n, r, "", "$1 .= chr($2)")
|
|
||||||
of mAppendStrStr:
|
of mAppendStrStr:
|
||||||
if p.target == targetJS:
|
|
||||||
if skipTypes(n.sons[1].typ, abstractVarRange).kind == tyCString:
|
if skipTypes(n.sons[1].typ, abstractVarRange).kind == tyCString:
|
||||||
binaryExpr(p, n, r, "", "if ($1 != null) { $1 += $2; } else { $1 = $2; }")
|
binaryExpr(p, n, r, "", "if ($1 != null) { $1 += $2; } else { $1 = $2; }")
|
||||||
else:
|
else:
|
||||||
binaryExpr(p, n, r, "",
|
binaryExpr(p, n, r, "",
|
||||||
"if ($1 != null) { $1 = ($1.slice(0, -1)).concat($2); } else { $1 = $2;}")
|
"if ($1 != null) { $1 = ($1.slice(0, -1)).concat($2); } else { $1 = $2;}")
|
||||||
# XXX: make a copy of $2, because of Javascript's sucking semantics
|
# XXX: make a copy of $2, because of Javascript's sucking semantics
|
||||||
else:
|
|
||||||
binaryExpr(p, n, r, "", "$1 .= $2;")
|
|
||||||
of mAppendSeqElem:
|
of mAppendSeqElem:
|
||||||
if p.target == targetJS:
|
|
||||||
var x, y: TCompRes
|
var x, y: TCompRes
|
||||||
gen(p, n.sons[1], x)
|
gen(p, n.sons[1], x)
|
||||||
gen(p, n.sons[2], y)
|
gen(p, n.sons[2], y)
|
||||||
|
|
@ -1857,28 +1668,14 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
[c, y.rdLoc, genTypeInfo(p, n[2].typ)])
|
[c, y.rdLoc, genTypeInfo(p, n[2].typ)])
|
||||||
r.res = "if ($1 != null) { $1.push($2); } else { $1 = [$2]; }" % [x.rdLoc, c]
|
r.res = "if ($1 != null) { $1.push($2); } else { $1 = [$2]; }" % [x.rdLoc, c]
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
else:
|
|
||||||
binaryExpr(p, n, r, "", "$1[] = $2")
|
|
||||||
of mConStrStr:
|
of mConStrStr:
|
||||||
if p.target == targetJS:
|
|
||||||
genConStrStr(p, n, r)
|
genConStrStr(p, n, r)
|
||||||
else:
|
|
||||||
genConStrStrPHP(p, n, r)
|
|
||||||
of mEqStr:
|
of mEqStr:
|
||||||
if p.target == targetJS:
|
|
||||||
binaryExpr(p, n, r, "eqStrings", "eqStrings($1, $2)")
|
binaryExpr(p, n, r, "eqStrings", "eqStrings($1, $2)")
|
||||||
else:
|
|
||||||
binaryExpr(p, n, r, "", "($1 == $2)")
|
|
||||||
of mLeStr:
|
of mLeStr:
|
||||||
if p.target == targetJS:
|
|
||||||
binaryExpr(p, n, r, "cmpStrings", "(cmpStrings($1, $2) <= 0)")
|
binaryExpr(p, n, r, "cmpStrings", "(cmpStrings($1, $2) <= 0)")
|
||||||
else:
|
|
||||||
binaryExpr(p, n, r, "", "($1 <= $2)")
|
|
||||||
of mLtStr:
|
of mLtStr:
|
||||||
if p.target == targetJS:
|
|
||||||
binaryExpr(p, n, r, "cmpStrings", "(cmpStrings($1, $2) < 0)")
|
binaryExpr(p, n, r, "cmpStrings", "(cmpStrings($1, $2) < 0)")
|
||||||
else:
|
|
||||||
binaryExpr(p, n, r, "", "($1 < $2)")
|
|
||||||
of mIsNil: unaryExpr(p, n, r, "", "($1 === null)")
|
of mIsNil: unaryExpr(p, n, r, "", "($1 === null)")
|
||||||
of mEnumToStr: genRepr(p, n, r)
|
of mEnumToStr: genRepr(p, n, r)
|
||||||
of mNew, mNewFinalize: genNew(p, n)
|
of mNew, mNewFinalize: genNew(p, n)
|
||||||
|
|
@ -1886,24 +1683,20 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
of mChr, mArrToSeq: gen(p, n.sons[1], r) # nothing to do
|
of mChr, mArrToSeq: gen(p, n.sons[1], r) # nothing to do
|
||||||
of mOrd: genOrd(p, n, r)
|
of mOrd: genOrd(p, n, r)
|
||||||
of mLengthStr:
|
of mLengthStr:
|
||||||
if p.target == targetJS and n.sons[1].typ.skipTypes(abstractInst).kind == tyCString:
|
if n.sons[1].typ.skipTypes(abstractInst).kind == tyCString:
|
||||||
unaryExpr(p, n, r, "", "($1 != null ? $1.length : 0)")
|
unaryExpr(p, n, r, "", "($1 != null ? $1.length : 0)")
|
||||||
else:
|
else:
|
||||||
unaryExpr(p, n, r, "", "($1 != null ? $1.length-1 : 0)" |
|
unaryExpr(p, n, r, "", "($1 != null ? $1.length-1 : 0)")
|
||||||
"strlen($1)")
|
of mXLenStr: unaryExpr(p, n, r, "", "$1.length-1")
|
||||||
of mXLenStr: unaryExpr(p, n, r, "", "$1.length-1" | "strlen($1)")
|
|
||||||
of mLengthSeq, mLengthOpenArray, mLengthArray:
|
of mLengthSeq, mLengthOpenArray, mLengthArray:
|
||||||
unaryExpr(p, n, r, "", "($1 != null ? $1.length : 0)" |
|
unaryExpr(p, n, r, "", "($1 != null ? $1.length : 0)")
|
||||||
"count($1)")
|
|
||||||
of mXLenSeq:
|
of mXLenSeq:
|
||||||
unaryExpr(p, n, r, "", "$1.length" | "count($1)")
|
unaryExpr(p, n, r, "", "$1.length")
|
||||||
of mHigh:
|
of mHigh:
|
||||||
if skipTypes(n.sons[1].typ, abstractVar).kind == tyString:
|
if skipTypes(n.sons[1].typ, abstractVar).kind == tyString:
|
||||||
unaryExpr(p, n, r, "", "($1 != null ? ($1.length-2) : -1)" |
|
unaryExpr(p, n, r, "", "($1 != null ? ($1.length-2) : -1)")
|
||||||
"(strlen($1)-1)")
|
|
||||||
else:
|
else:
|
||||||
unaryExpr(p, n, r, "", "($1 != null ? ($1.length-1) : -1)" |
|
unaryExpr(p, n, r, "", "($1 != null ? ($1.length-1) : -1)")
|
||||||
"(count($1)-1)")
|
|
||||||
of mInc:
|
of mInc:
|
||||||
if n[1].typ.skipTypes(abstractRange).kind in tyUInt .. tyUInt64:
|
if n[1].typ.skipTypes(abstractRange).kind in tyUInt .. tyUInt64:
|
||||||
binaryUintExpr(p, n, r, "+", true)
|
binaryUintExpr(p, n, r, "+", true)
|
||||||
|
|
@ -1917,7 +1710,7 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
if optOverflowCheck notin p.options: binaryExpr(p, n, r, "", "$1 -= $2")
|
if optOverflowCheck notin p.options: binaryExpr(p, n, r, "", "$1 -= $2")
|
||||||
else: binaryExpr(p, n, r, "subInt", "$1 = subInt($1, $2)")
|
else: binaryExpr(p, n, r, "subInt", "$1 = subInt($1, $2)")
|
||||||
of mSetLengthStr:
|
of mSetLengthStr:
|
||||||
binaryExpr(p, n, r, "", "$1.length = $2+1; $1[$1.length-1] = 0" | "$1 = substr($1, 0, $2)")
|
binaryExpr(p, n, r, "", "$1.length = $2+1; $1[$1.length-1] = 0")
|
||||||
of mSetLengthSeq:
|
of mSetLengthSeq:
|
||||||
var x, y: TCompRes
|
var x, y: TCompRes
|
||||||
gen(p, n.sons[1], x)
|
gen(p, n.sons[1], x)
|
||||||
|
|
@ -1934,50 +1727,23 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
of mPlusSet: binaryExpr(p, n, r, "SetPlus", "SetPlus($1, $2)")
|
of mPlusSet: binaryExpr(p, n, r, "SetPlus", "SetPlus($1, $2)")
|
||||||
of mMinusSet: binaryExpr(p, n, r, "SetMinus", "SetMinus($1, $2)")
|
of mMinusSet: binaryExpr(p, n, r, "SetMinus", "SetMinus($1, $2)")
|
||||||
of mIncl: binaryExpr(p, n, r, "", "$1[$2] = true")
|
of mIncl: binaryExpr(p, n, r, "", "$1[$2] = true")
|
||||||
of mExcl: binaryExpr(p, n, r, "", "delete $1[$2]" | "unset $1[$2]")
|
of mExcl: binaryExpr(p, n, r, "", "delete $1[$2]")
|
||||||
of mInSet:
|
of mInSet:
|
||||||
if p.target == targetJS:
|
|
||||||
binaryExpr(p, n, r, "", "($1[$2] != undefined)")
|
binaryExpr(p, n, r, "", "($1[$2] != undefined)")
|
||||||
else:
|
|
||||||
let s = n.sons[1]
|
|
||||||
if s.kind == nkCurly:
|
|
||||||
var a, b, x: TCompRes
|
|
||||||
gen(p, n.sons[2], x)
|
|
||||||
r.res = rope("(")
|
|
||||||
r.kind = resExpr
|
|
||||||
for i in countup(0, sonsLen(s) - 1):
|
|
||||||
if i > 0: add(r.res, " || ")
|
|
||||||
var it = s.sons[i]
|
|
||||||
if it.kind == nkRange:
|
|
||||||
gen(p, it.sons[0], a)
|
|
||||||
gen(p, it.sons[1], b)
|
|
||||||
addf(r.res, "($1 >= $2 && $1 <= $3)", [x.res, a.res, b.res,])
|
|
||||||
else:
|
|
||||||
gen(p, it, a)
|
|
||||||
addf(r.res, "($1 == $2)", [x.res, a.res])
|
|
||||||
add(r.res, ")")
|
|
||||||
else:
|
|
||||||
binaryExpr(p, n, r, "", "isset($1[$2])")
|
|
||||||
of mNewSeq: genNewSeq(p, n)
|
of mNewSeq: genNewSeq(p, n)
|
||||||
of mNewSeqOfCap: unaryExpr(p, n, r, "", "[]" | "array()")
|
of mNewSeqOfCap: unaryExpr(p, n, r, "", "[]")
|
||||||
of mOf: genOf(p, n, r)
|
of mOf: genOf(p, n, r)
|
||||||
of mReset: genReset(p, n)
|
of mReset: genReset(p, n)
|
||||||
of mEcho: genEcho(p, n, r)
|
of mEcho: genEcho(p, n, r)
|
||||||
of mNLen..mNError, mSlurp, mStaticExec:
|
of mNLen..mNError, mSlurp, mStaticExec:
|
||||||
localError(n.info, errXMustBeCompileTime, n.sons[0].sym.name.s)
|
localError(n.info, errXMustBeCompileTime, n.sons[0].sym.name.s)
|
||||||
of mCopyStr:
|
of mCopyStr:
|
||||||
binaryExpr(p, n, r, "", "($1.slice($2))" | "substr($1, $2)")
|
binaryExpr(p, n, r, "", "($1.slice($2))")
|
||||||
of mCopyStrLast:
|
of mCopyStrLast:
|
||||||
if p.target == targetJS:
|
|
||||||
ternaryExpr(p, n, r, "", "($1.slice($2, ($3)+1).concat(0))")
|
ternaryExpr(p, n, r, "", "($1.slice($2, ($3)+1).concat(0))")
|
||||||
else:
|
|
||||||
ternaryExpr(p, n, r, "nimSubstr", "nimSubstr($#, $#, $#)")
|
|
||||||
of mNewString: unaryExpr(p, n, r, "mnewString", "mnewString($1)")
|
of mNewString: unaryExpr(p, n, r, "mnewString", "mnewString($1)")
|
||||||
of mNewStringOfCap:
|
of mNewStringOfCap:
|
||||||
if p.target == targetJS:
|
|
||||||
unaryExpr(p, n, r, "mnewString", "mnewString(0)")
|
unaryExpr(p, n, r, "mnewString", "mnewString(0)")
|
||||||
else:
|
|
||||||
unaryExpr(p, n, r, "", "''")
|
|
||||||
of mDotDot:
|
of mDotDot:
|
||||||
genProcForSymIfNeeded(p, n.sons[0].sym)
|
genProcForSymIfNeeded(p, n.sons[0].sym)
|
||||||
genCall(p, n, r)
|
genCall(p, n, r)
|
||||||
|
|
@ -1985,8 +1751,7 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
useMagic(p, "nimParseBiggestFloat")
|
useMagic(p, "nimParseBiggestFloat")
|
||||||
genCall(p, n, r)
|
genCall(p, n, r)
|
||||||
of mArray:
|
of mArray:
|
||||||
if p.target == targetPHP: genToArray(p, n, r)
|
genCall(p, n, r)
|
||||||
else: genCall(p, n, r)
|
|
||||||
else:
|
else:
|
||||||
genCall(p, n, r)
|
genCall(p, n, r)
|
||||||
#else internalError(e.info, 'genMagic: ' + magicToStr[op]);
|
#else internalError(e.info, 'genMagic: ' + magicToStr[op]);
|
||||||
|
|
@ -2003,13 +1768,13 @@ proc genSetConstr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
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)
|
||||||
addf(r.res, "[$1, $2]" | "array($#,$#)", [a.res, b.res])
|
addf(r.res, "[$1, $2]", [a.res, b.res])
|
||||||
else:
|
else:
|
||||||
gen(p, it, a)
|
gen(p, it, a)
|
||||||
add(r.res, a.res)
|
add(r.res, a.res)
|
||||||
add(r.res, ")")
|
add(r.res, ")")
|
||||||
# emit better code for constant sets:
|
# emit better code for constant sets:
|
||||||
if p.target == targetJS and isDeepConstExpr(n):
|
if isDeepConstExpr(n):
|
||||||
inc(p.g.unique)
|
inc(p.g.unique)
|
||||||
let tmp = rope("ConstSet") & rope(p.g.unique)
|
let tmp = rope("ConstSet") & rope(p.g.unique)
|
||||||
addf(p.g.constants, "var $1 = $2;$n", [tmp, r.res])
|
addf(p.g.constants, "var $1 = $2;$n", [tmp, r.res])
|
||||||
|
|
@ -2017,25 +1782,25 @@ proc genSetConstr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
|
|
||||||
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 = rope("[" | "array(")
|
r.res = rope("[")
|
||||||
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: add(r.res, ", ")
|
if i > 0: add(r.res, ", ")
|
||||||
gen(p, n.sons[i], a)
|
gen(p, n.sons[i], a)
|
||||||
add(r.res, a.res)
|
add(r.res, a.res)
|
||||||
add(r.res, "]" | ")")
|
add(r.res, "]")
|
||||||
|
|
||||||
proc genTupleConstr(p: PProc, n: PNode, r: var TCompRes) =
|
proc genTupleConstr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
var a: TCompRes
|
var a: TCompRes
|
||||||
r.res = rope("{" | "array(")
|
r.res = rope("{")
|
||||||
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: add(r.res, ", ")
|
if i > 0: add(r.res, ", ")
|
||||||
var it = n.sons[i]
|
var it = n.sons[i]
|
||||||
if it.kind == nkExprColonExpr: it = it.sons[1]
|
if it.kind == nkExprColonExpr: it = it.sons[1]
|
||||||
gen(p, it, a)
|
gen(p, it, a)
|
||||||
addf(r.res, "Field$#: $#" | "$2", [i.rope, a.res])
|
addf(r.res, "Field$#: $#", [i.rope, a.res])
|
||||||
r.res.add("}" | ")")
|
r.res.add("}")
|
||||||
|
|
||||||
proc genObjConstr(p: PProc, n: PNode, r: var TCompRes) =
|
proc genObjConstr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
var a: TCompRes
|
var a: TCompRes
|
||||||
|
|
@ -2059,10 +1824,10 @@ proc genObjConstr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
else:
|
else:
|
||||||
useMagic(p, "nimCopy")
|
useMagic(p, "nimCopy")
|
||||||
a.res = "nimCopy(null, $1, $2)" % [a.rdLoc, genTypeInfo(p, typ)]
|
a.res = "nimCopy(null, $1, $2)" % [a.rdLoc, genTypeInfo(p, typ)]
|
||||||
addf(initList, "$#: $#" | "'$#' => $#" , [f.loc.r, a.res])
|
addf(initList, "$#: $#", [f.loc.r, a.res])
|
||||||
let t = skipTypes(n.typ, abstractInst + skipPtrs)
|
let t = skipTypes(n.typ, abstractInst + skipPtrs)
|
||||||
createObjInitList(p, t, fieldIDs, initList)
|
createObjInitList(p, t, fieldIDs, initList)
|
||||||
r.res = ("{$1}" | "array($#)") % [initList]
|
r.res = ("{$1}") % [initList]
|
||||||
|
|
||||||
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)
|
||||||
|
|
@ -2125,18 +1890,17 @@ proc genReturnStmt(p: PProc, n: PNode) =
|
||||||
genStmt(p, n.sons[0])
|
genStmt(p, n.sons[0])
|
||||||
else:
|
else:
|
||||||
genLineDir(p, n)
|
genLineDir(p, n)
|
||||||
lineF(p, "break BeforeRet;$n" | "goto BeforeRet;$n", [])
|
lineF(p, "break BeforeRet;$n", [])
|
||||||
|
|
||||||
proc frameCreate(p: PProc; procname, filename: Rope): Rope =
|
proc frameCreate(p: PProc; procname, filename: Rope): Rope =
|
||||||
let frameFmt =
|
let frameFmt =
|
||||||
"var F={procname:$1,prev:framePtr,filename:$2,line:0};$n" |
|
"var F={procname:$1,prev:framePtr,filename:$2,line:0};$n"
|
||||||
"global $$framePtr; $$F=array('procname'=>$#,'prev'=>$$framePtr,'filename'=>$#,'line'=>0);$n"
|
|
||||||
|
|
||||||
result = p.indentLine(frameFmt % [procname, filename])
|
result = p.indentLine(frameFmt % [procname, filename])
|
||||||
result.add p.indentLine(ropes.`%`("framePtr = F;$n" | "$$framePtr = &$$F;$n", []))
|
result.add p.indentLine(ropes.`%`("framePtr = F;$n", []))
|
||||||
|
|
||||||
proc frameDestroy(p: PProc): Rope =
|
proc frameDestroy(p: PProc): Rope =
|
||||||
result = p.indentLine rope(("framePtr = F.prev;" | "$framePtr = $F['prev'];") & tnl)
|
result = p.indentLine rope(("framePtr = F.prev;") & tnl)
|
||||||
|
|
||||||
proc genProcBody(p: PProc, prc: PSym): Rope =
|
proc genProcBody(p: PProc, prc: PSym): Rope =
|
||||||
if hasFrameInfo(p):
|
if hasFrameInfo(p):
|
||||||
|
|
@ -2146,15 +1910,12 @@ proc genProcBody(p: PProc, prc: PSym): Rope =
|
||||||
else:
|
else:
|
||||||
result = nil
|
result = nil
|
||||||
if p.beforeRetNeeded:
|
if p.beforeRetNeeded:
|
||||||
if p.target == targetJS:
|
|
||||||
result.add p.indentLine(~"BeforeRet: do {$n")
|
result.add p.indentLine(~"BeforeRet: do {$n")
|
||||||
result.add p.body
|
result.add p.body
|
||||||
result.add p.indentLine(~"} while (false);$n")
|
result.add p.indentLine(~"} while (false);$n")
|
||||||
else:
|
|
||||||
addF(result, "$# BeforeRet:;$n", [p.body])
|
|
||||||
else:
|
else:
|
||||||
add(result, p.body)
|
add(result, p.body)
|
||||||
if prc.typ.callConv == ccSysCall and p.target == targetJS:
|
if prc.typ.callConv == ccSysCall:
|
||||||
result = ("try {$n$1} catch (e) {$n" &
|
result = ("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 hasFrameInfo(p):
|
if hasFrameInfo(p):
|
||||||
|
|
@ -2182,7 +1943,7 @@ proc genProc(oldProc: PProc, prc: PSym): Rope =
|
||||||
resultSym = prc.ast.sons[resultPos].sym
|
resultSym = prc.ast.sons[resultPos].sym
|
||||||
let mname = mangleName(p.module, resultSym)
|
let mname = mangleName(p.module, resultSym)
|
||||||
let resVar = createVar(p, resultSym.typ, isIndirect(resultSym))
|
let resVar = createVar(p, resultSym.typ, isIndirect(resultSym))
|
||||||
resultAsgn = p.indentLine(("var $# = $#;$n" | "$$$# = $#;$n") % [mname, resVar])
|
resultAsgn = p.indentLine(("var $# = $#;$n") % [mname, resVar])
|
||||||
if resultSym.typ.kind in {tyVar, tyPtr, tyLent, tyRef} and
|
if resultSym.typ.kind in {tyVar, tyPtr, tyLent, tyRef} and
|
||||||
mapType(p, resultSym.typ) == etyBaseIndex:
|
mapType(p, resultSym.typ) == etyBaseIndex:
|
||||||
resultAsgn.add p.indentLine("var $#_Idx = 0;$n" % [mname])
|
resultAsgn.add p.indentLine("var $#_Idx = 0;$n" % [mname])
|
||||||
|
|
@ -2267,8 +2028,7 @@ proc genCast(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
elif fromUint:
|
elif fromUint:
|
||||||
if src.size == 4 and dest.size == 4:
|
if src.size == 4 and dest.size == 4:
|
||||||
# XXX prevent multi evaluations
|
# XXX prevent multi evaluations
|
||||||
r.res = "($1|0)" % [r.res] |
|
r.res = "($1|0)" % [r.res]
|
||||||
"($1>(float)2147483647?(int)$1-4294967296:$1)" % [r.res]
|
|
||||||
else:
|
else:
|
||||||
let trimmer = unsignedTrimmer(dest.size)
|
let trimmer = unsignedTrimmer(dest.size)
|
||||||
let minuend = case dest.size
|
let minuend = case dest.size
|
||||||
|
|
@ -2304,8 +2064,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
r.res = rope"null"
|
r.res = rope"null"
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
if skipTypes(n.typ, abstractVarRange).kind == tyString and
|
if skipTypes(n.typ, abstractVarRange).kind == tyString:
|
||||||
p.target == targetJS:
|
|
||||||
useMagic(p, "makeNimstrLit")
|
useMagic(p, "makeNimstrLit")
|
||||||
r.res = "makeNimstrLit($1)" % [makeJSString(n.strVal)]
|
r.res = "makeNimstrLit($1)" % [makeJSString(n.strVal)]
|
||||||
else:
|
else:
|
||||||
|
|
@ -2342,10 +2101,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
of nkObjConstr: genObjConstr(p, n, r)
|
of nkObjConstr: genObjConstr(p, n, r)
|
||||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv: genConv(p, n, r)
|
of nkHiddenStdConv, nkHiddenSubConv, nkConv: genConv(p, n, r)
|
||||||
of nkAddr, nkHiddenAddr:
|
of nkAddr, nkHiddenAddr:
|
||||||
if p.target == targetJS:
|
|
||||||
genAddr(p, n, r)
|
genAddr(p, n, r)
|
||||||
else:
|
|
||||||
gen(p, n.sons[0], r)
|
|
||||||
of nkDerefExpr, nkHiddenDeref: genDeref(p, n, r)
|
of nkDerefExpr, nkHiddenDeref: genDeref(p, n, r)
|
||||||
of nkBracketExpr: genArrayAccess(p, n, r)
|
of nkBracketExpr: genArrayAccess(p, n, r)
|
||||||
of nkDotExpr: genFieldAccess(p, n, r)
|
of nkDotExpr: genFieldAccess(p, n, r)
|
||||||
|
|
@ -2422,8 +2178,7 @@ proc newModule(module: PSym): BModule =
|
||||||
if globals == nil:
|
if globals == nil:
|
||||||
globals = newGlobals()
|
globals = newGlobals()
|
||||||
|
|
||||||
proc genHeader(target: TTarget): Rope =
|
proc genHeader(): Rope =
|
||||||
if target == targetJS:
|
|
||||||
result = (
|
result = (
|
||||||
"/* Generated by the Nim Compiler v$1 */$n" &
|
"/* Generated by the Nim Compiler v$1 */$n" &
|
||||||
"/* (c) " & copyrightYear & " Andreas Rumpf */$n$n" &
|
"/* (c) " & copyrightYear & " Andreas Rumpf */$n$n" &
|
||||||
|
|
@ -2439,14 +2194,6 @@ proc genHeader(target: TTarget): Rope =
|
||||||
"if (typeof Float32Array === 'undefined') Float32Array = Array;$n" &
|
"if (typeof Float32Array === 'undefined') Float32Array = Array;$n" &
|
||||||
"if (typeof Float64Array === 'undefined') Float64Array = Array;$n") %
|
"if (typeof Float64Array === 'undefined') Float64Array = Array;$n") %
|
||||||
[rope(VersionAsString)]
|
[rope(VersionAsString)]
|
||||||
else:
|
|
||||||
result = ("<?php$n" &
|
|
||||||
"/* Generated by the Nim Compiler v$1 */$n" &
|
|
||||||
"/* (c) " & copyrightYear & " Andreas Rumpf */$n$n" &
|
|
||||||
"$$framePtr = null;$n" &
|
|
||||||
"$$excHandler = 0;$n" &
|
|
||||||
"$$lastJSError = null;$n") %
|
|
||||||
[rope(VersionAsString)]
|
|
||||||
|
|
||||||
proc genModule(p: PProc, n: PNode) =
|
proc genModule(p: PProc, n: PNode) =
|
||||||
if optStackTrace in p.options:
|
if optStackTrace in p.options:
|
||||||
|
|
@ -2513,7 +2260,7 @@ proc myClose(graph: ModuleGraph; b: PPassContext, n: PNode): PNode =
|
||||||
result = myProcess(b, n)
|
result = myProcess(b, n)
|
||||||
var m = BModule(b)
|
var m = BModule(b)
|
||||||
if sfMainModule in m.module.flags:
|
if sfMainModule in m.module.flags:
|
||||||
let ext = if m.target == targetJS: "js" else: "php"
|
let ext = "js"
|
||||||
let f = if globals.classes.len == 0: m.module.filename
|
let f = if globals.classes.len == 0: m.module.filename
|
||||||
else: "nimsystem"
|
else: "nimsystem"
|
||||||
let code = wholeCode(graph, m)
|
let code = wholeCode(graph, m)
|
||||||
|
|
@ -2523,7 +2270,7 @@ proc myClose(graph: ModuleGraph; b: PPassContext, n: PNode): PNode =
|
||||||
else: getCurrentDir() / options.outFile
|
else: getCurrentDir() / options.outFile
|
||||||
else:
|
else:
|
||||||
changeFileExt(completeCFilePath(f), ext)
|
changeFileExt(completeCFilePath(f), ext)
|
||||||
discard writeRopeIfNotEqual(genHeader(m.target) & code, outfile)
|
discard writeRopeIfNotEqual(genHeader() & code, outfile)
|
||||||
for obj, content in items(globals.classes):
|
for obj, content in items(globals.classes):
|
||||||
genClass(obj, content, ext)
|
genClass(obj, content, ext)
|
||||||
|
|
||||||
|
|
@ -2533,7 +2280,6 @@ proc myOpenCached(graph: ModuleGraph; s: PSym, rd: PRodReader): PPassContext =
|
||||||
|
|
||||||
proc myOpen(graph: ModuleGraph; s: PSym; cache: IdentCache): PPassContext =
|
proc myOpen(graph: ModuleGraph; s: PSym; cache: IdentCache): PPassContext =
|
||||||
var r = newModule(s)
|
var r = newModule(s)
|
||||||
r.target = if gCmd == cmdCompileToPHP: targetPHP else: targetJS
|
|
||||||
result = r
|
result = r
|
||||||
|
|
||||||
const JSgenPass* = makePass(myOpen, myOpenCached, myProcess, myClose)
|
const JSgenPass* = makePass(myOpen, myOpenCached, myProcess, myClose)
|
||||||
|
|
|
||||||
|
|
@ -121,26 +121,7 @@ proc genEnumInfo(p: PProc, typ: PType, name: Rope) =
|
||||||
addf(p.g.typeInfo, "$1.base = $2;$n",
|
addf(p.g.typeInfo, "$1.base = $2;$n",
|
||||||
[name, genTypeInfo(p, typ.sons[0])])
|
[name, genTypeInfo(p, typ.sons[0])])
|
||||||
|
|
||||||
proc genEnumInfoPHP(p: PProc; t: PType): Rope =
|
|
||||||
let t = t.skipTypes({tyGenericInst, tyDistinct, tyAlias, tySink})
|
|
||||||
result = "$$NTI$1" % [rope(t.id)]
|
|
||||||
p.declareGlobal(t.id, result)
|
|
||||||
if containsOrIncl(p.g.typeInfoGenerated, t.id): return
|
|
||||||
|
|
||||||
let length = sonsLen(t.n)
|
|
||||||
var s: Rope = nil
|
|
||||||
for i in countup(0, length - 1):
|
|
||||||
if (t.n.sons[i].kind != nkSym): internalError(t.n.info, "genEnumInfo")
|
|
||||||
let field = t.n.sons[i].sym
|
|
||||||
if i > 0: add(s, ", " & tnl)
|
|
||||||
let extName = if field.ast == nil: field.name.s else: field.ast.strVal
|
|
||||||
addf(s, "$# => $#$n",
|
|
||||||
[rope(field.position), makeJSString(extName)])
|
|
||||||
prepend(p.g.typeInfo, "$$$# = $#;$n" % [result, s])
|
|
||||||
|
|
||||||
proc genTypeInfo(p: PProc, typ: PType): Rope =
|
proc genTypeInfo(p: PProc, typ: PType): Rope =
|
||||||
if p.target == targetPHP:
|
|
||||||
return makeJSString(typeToString(typ, preferModuleInfo))
|
|
||||||
let t = typ.skipTypes({tyGenericInst, tyDistinct, tyAlias, tySink})
|
let t = typ.skipTypes({tyGenericInst, tyDistinct, tyAlias, tySink})
|
||||||
result = "NTI$1" % [rope(t.id)]
|
result = "NTI$1" % [rope(t.id)]
|
||||||
if containsOrIncl(p.g.typeInfoGenerated, t.id): return
|
if containsOrIncl(p.g.typeInfoGenerated, t.id): return
|
||||||
|
|
|
||||||
|
|
@ -230,7 +230,7 @@ template isIterator*(owner: PSym): bool =
|
||||||
proc liftingHarmful(owner: PSym): bool {.inline.} =
|
proc liftingHarmful(owner: PSym): bool {.inline.} =
|
||||||
## lambda lifting can be harmful for JS-like code generators.
|
## lambda lifting can be harmful for JS-like code generators.
|
||||||
let isCompileTime = sfCompileTime in owner.flags or owner.kind == skMacro
|
let isCompileTime = sfCompileTime in owner.flags or owner.kind == skMacro
|
||||||
result = gCmd in {cmdCompileToPHP, cmdCompileToJS} and not isCompileTime
|
result = gCmd == cmdCompileToJS and not isCompileTime
|
||||||
|
|
||||||
proc liftIterSym*(n: PNode; owner: PSym): PNode =
|
proc liftIterSym*(n: PNode; owner: PSym): PNode =
|
||||||
# transforms (iter) to (let env = newClosure[iter](); (iter, env))
|
# transforms (iter) to (let env = newClosure[iter](); (iter, env))
|
||||||
|
|
@ -813,7 +813,7 @@ proc liftLambdas*(fn: PSym, body: PNode; tooEarly: var bool): PNode =
|
||||||
let isCompileTime = sfCompileTime in fn.flags or fn.kind == skMacro
|
let isCompileTime = sfCompileTime in fn.flags or fn.kind == skMacro
|
||||||
|
|
||||||
if body.kind == nkEmpty or (
|
if body.kind == nkEmpty or (
|
||||||
gCmd in {cmdCompileToPHP, cmdCompileToJS} and not isCompileTime) or
|
gCmd == cmdCompileToJS and not isCompileTime) or
|
||||||
fn.skipGenericOwner.kind != skModule:
|
fn.skipGenericOwner.kind != skModule:
|
||||||
# ignore forward declaration:
|
# ignore forward declaration:
|
||||||
result = body
|
result = body
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,6 @@ proc commandCompileToJS(graph: ModuleGraph; cache: IdentCache) =
|
||||||
defineSymbol("nimrod") # 'nimrod' is always defined
|
defineSymbol("nimrod") # 'nimrod' is always defined
|
||||||
defineSymbol("ecmascript") # For backward compatibility
|
defineSymbol("ecmascript") # For backward compatibility
|
||||||
defineSymbol("js")
|
defineSymbol("js")
|
||||||
if gCmd == cmdCompileToPHP: defineSymbol("nimphp")
|
|
||||||
semanticPasses()
|
semanticPasses()
|
||||||
registerPass(JSgenPass)
|
registerPass(JSgenPass)
|
||||||
compileProject(graph, cache)
|
compileProject(graph, cache)
|
||||||
|
|
@ -189,9 +188,6 @@ proc mainCommand*(graph: ModuleGraph; cache: IdentCache) =
|
||||||
of "js", "compiletojs":
|
of "js", "compiletojs":
|
||||||
gCmd = cmdCompileToJS
|
gCmd = cmdCompileToJS
|
||||||
commandCompileToJS(graph, cache)
|
commandCompileToJS(graph, cache)
|
||||||
of "php":
|
|
||||||
gCmd = cmdCompileToPHP
|
|
||||||
commandCompileToJS(graph, cache)
|
|
||||||
of "doc0":
|
of "doc0":
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
gCmd = cmdDoc
|
gCmd = cmdDoc
|
||||||
|
|
|
||||||
|
|
@ -90,14 +90,6 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
|
||||||
ex = quoteShell(
|
ex = quoteShell(
|
||||||
completeCFilePath(changeFileExt(gProjectFull, "js").prependCurDir))
|
completeCFilePath(changeFileExt(gProjectFull, "js").prependCurDir))
|
||||||
execExternalProgram(findNodeJs() & " " & ex & ' ' & commands.arguments)
|
execExternalProgram(findNodeJs() & " " & ex & ' ' & commands.arguments)
|
||||||
elif gCmd == cmdCompileToPHP:
|
|
||||||
var ex: string
|
|
||||||
if options.outFile.len > 0:
|
|
||||||
ex = options.outFile.prependCurDir.quoteShell
|
|
||||||
else:
|
|
||||||
ex = quoteShell(
|
|
||||||
completeCFilePath(changeFileExt(gProjectFull, "php").prependCurDir))
|
|
||||||
execExternalProgram("php " & ex & ' ' & commands.arguments)
|
|
||||||
else:
|
else:
|
||||||
var binPath: string
|
var binPath: string
|
||||||
if options.outFile.len > 0:
|
if options.outFile.len > 0:
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,6 @@ type
|
||||||
# **keep binary compatible**
|
# **keep binary compatible**
|
||||||
cmdNone, cmdCompileToC, cmdCompileToCpp, cmdCompileToOC,
|
cmdNone, cmdCompileToC, cmdCompileToCpp, cmdCompileToOC,
|
||||||
cmdCompileToJS,
|
cmdCompileToJS,
|
||||||
cmdCompileToPHP,
|
|
||||||
cmdCompileToLLVM, cmdInterpret, cmdPretty, cmdDoc,
|
cmdCompileToLLVM, cmdInterpret, cmdPretty, cmdDoc,
|
||||||
cmdGenDepend, cmdDump,
|
cmdGenDepend, cmdDump,
|
||||||
cmdCheck, # semantic checking for whole project
|
cmdCheck, # semantic checking for whole project
|
||||||
|
|
|
||||||
|
|
@ -586,7 +586,7 @@ proc cmdChangeTriggersRecompilation(old, new: TCommands): bool =
|
||||||
# new command forces us to consider it here :-)
|
# new command forces us to consider it here :-)
|
||||||
case old
|
case old
|
||||||
of cmdCompileToC, cmdCompileToCpp, cmdCompileToOC,
|
of cmdCompileToC, cmdCompileToCpp, cmdCompileToOC,
|
||||||
cmdCompileToJS, cmdCompileToPHP, cmdCompileToLLVM:
|
cmdCompileToJS, cmdCompileToLLVM:
|
||||||
if new in {cmdDoc, cmdCheck, cmdIdeTools, cmdPretty, cmdDef,
|
if new in {cmdDoc, cmdCheck, cmdIdeTools, cmdPretty, cmdDef,
|
||||||
cmdInteractive}:
|
cmdInteractive}:
|
||||||
return false
|
return false
|
||||||
|
|
|
||||||
|
|
@ -2404,7 +2404,7 @@ proc `==` *[T](x, y: seq[T]): bool {.noSideEffect.} =
|
||||||
if x.isNil and y.isNil:
|
if x.isNil and y.isNil:
|
||||||
return true
|
return true
|
||||||
else:
|
else:
|
||||||
when not defined(JS) or defined(nimphp):
|
when not defined(JS):
|
||||||
proc seqToPtr[T](x: seq[T]): pointer {.inline, nosideeffect.} =
|
proc seqToPtr[T](x: seq[T]): pointer {.inline, nosideeffect.} =
|
||||||
result = cast[pointer](x)
|
result = cast[pointer](x)
|
||||||
else:
|
else:
|
||||||
|
|
@ -2766,9 +2766,6 @@ type
|
||||||
|
|
||||||
when defined(JS):
|
when defined(JS):
|
||||||
proc add*(x: var string, y: cstring) {.asmNoStackFrame.} =
|
proc add*(x: var string, y: cstring) {.asmNoStackFrame.} =
|
||||||
when defined(nimphp):
|
|
||||||
asm """`x` .= `y`;"""
|
|
||||||
else:
|
|
||||||
asm """
|
asm """
|
||||||
var len = `x`[0].length-1;
|
var len = `x`[0].length-1;
|
||||||
for (var i = 0; i < `y`.length; ++i) {
|
for (var i = 0; i < `y`.length; ++i) {
|
||||||
|
|
|
||||||
|
|
@ -48,9 +48,6 @@ proc nimCharToStr(x: char): string {.compilerproc.} =
|
||||||
result[0] = x
|
result[0] = x
|
||||||
|
|
||||||
proc isNimException(): bool {.asmNoStackFrame.} =
|
proc isNimException(): bool {.asmNoStackFrame.} =
|
||||||
when defined(nimphp):
|
|
||||||
asm "return isset(`lastJSError`['m_type']);"
|
|
||||||
else:
|
|
||||||
asm "return `lastJSError`.m_type;"
|
asm "return `lastJSError`.m_type;"
|
||||||
|
|
||||||
proc getCurrentException*(): ref Exception {.compilerRtl, benign.} =
|
proc getCurrentException*(): ref Exception {.compilerRtl, benign.} =
|
||||||
|
|
@ -61,7 +58,6 @@ proc getCurrentExceptionMsg*(): string =
|
||||||
if isNimException():
|
if isNimException():
|
||||||
return cast[Exception](lastJSError).msg
|
return cast[Exception](lastJSError).msg
|
||||||
else:
|
else:
|
||||||
when not defined(nimphp):
|
|
||||||
var msg: cstring
|
var msg: cstring
|
||||||
{.emit: """
|
{.emit: """
|
||||||
if (`lastJSError`.message !== undefined) {
|
if (`lastJSError`.message !== undefined) {
|
||||||
|
|
@ -140,9 +136,6 @@ proc raiseException(e: ref Exception, ename: cstring) {.
|
||||||
e.name = ename
|
e.name = ename
|
||||||
if excHandler == 0:
|
if excHandler == 0:
|
||||||
unhandledException(e)
|
unhandledException(e)
|
||||||
when defined(nimphp):
|
|
||||||
asm """throw new Exception($`e`["message"]);"""
|
|
||||||
else:
|
|
||||||
when NimStackTrace:
|
when NimStackTrace:
|
||||||
e.trace = rawWriteStackTrace()
|
e.trace = rawWriteStackTrace()
|
||||||
asm "throw `e`;"
|
asm "throw `e`;"
|
||||||
|
|
@ -173,22 +166,6 @@ proc raiseFieldError(f: string) {.compilerproc, noreturn.} =
|
||||||
raise newException(FieldError, f & " is not accessible")
|
raise newException(FieldError, f & " is not accessible")
|
||||||
|
|
||||||
proc setConstr() {.varargs, asmNoStackFrame, compilerproc.} =
|
proc setConstr() {.varargs, asmNoStackFrame, compilerproc.} =
|
||||||
when defined(nimphp):
|
|
||||||
asm """
|
|
||||||
$args = func_get_args();
|
|
||||||
$result = array();
|
|
||||||
foreach ($args as $x) {
|
|
||||||
if (is_array($x)) {
|
|
||||||
for ($j = $x[0]; $j <= $x[1]; $j++) {
|
|
||||||
$result[$j] = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$result[$x] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
asm """
|
asm """
|
||||||
var result = {};
|
var result = {};
|
||||||
for (var i = 0; i < arguments.length; ++i) {
|
for (var i = 0; i < arguments.length; ++i) {
|
||||||
|
|
@ -205,9 +182,6 @@ proc setConstr() {.varargs, asmNoStackFrame, compilerproc.} =
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc makeNimstrLit(c: cstring): string {.asmNoStackFrame, compilerproc.} =
|
proc makeNimstrLit(c: cstring): string {.asmNoStackFrame, compilerproc.} =
|
||||||
when defined(nimphp):
|
|
||||||
{.emit: """return `c`;""".}
|
|
||||||
else:
|
|
||||||
{.emit: """
|
{.emit: """
|
||||||
var ln = `c`.length;
|
var ln = `c`.length;
|
||||||
var result = new Array(ln + 1);
|
var result = new Array(ln + 1);
|
||||||
|
|
@ -220,9 +194,6 @@ proc makeNimstrLit(c: cstring): string {.asmNoStackFrame, compilerproc.} =
|
||||||
""".}
|
""".}
|
||||||
|
|
||||||
proc cstrToNimstr(c: cstring): string {.asmNoStackFrame, compilerproc.} =
|
proc cstrToNimstr(c: cstring): string {.asmNoStackFrame, compilerproc.} =
|
||||||
when defined(nimphp):
|
|
||||||
{.emit: """return `c`;""".}
|
|
||||||
else:
|
|
||||||
{.emit: """
|
{.emit: """
|
||||||
var ln = `c`.length;
|
var ln = `c`.length;
|
||||||
var result = new Array(ln);
|
var result = new Array(ln);
|
||||||
|
|
@ -261,9 +232,6 @@ proc cstrToNimstr(c: cstring): string {.asmNoStackFrame, compilerproc.} =
|
||||||
""".}
|
""".}
|
||||||
|
|
||||||
proc toJSStr(s: string): cstring {.asmNoStackFrame, compilerproc.} =
|
proc toJSStr(s: string): cstring {.asmNoStackFrame, compilerproc.} =
|
||||||
when defined(nimphp):
|
|
||||||
{.emit: """return `s`;""".}
|
|
||||||
else:
|
|
||||||
asm """
|
asm """
|
||||||
var len = `s`.length-1;
|
var len = `s`.length-1;
|
||||||
var asciiPart = new Array(len);
|
var asciiPart = new Array(len);
|
||||||
|
|
@ -295,11 +263,6 @@ proc toJSStr(s: string): cstring {.asmNoStackFrame, compilerproc.} =
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc mnewString(len: int): string {.asmNoStackFrame, compilerproc.} =
|
proc mnewString(len: int): string {.asmNoStackFrame, compilerproc.} =
|
||||||
when defined(nimphp):
|
|
||||||
asm """
|
|
||||||
return str_repeat(chr(0),`len`);
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
asm """
|
asm """
|
||||||
var result = new Array(`len`+1);
|
var result = new Array(`len`+1);
|
||||||
result[0] = 0;
|
result[0] = 0;
|
||||||
|
|
@ -307,24 +270,8 @@ proc mnewString(len: int): string {.asmNoStackFrame, compilerproc.} =
|
||||||
return result;
|
return result;
|
||||||
"""
|
"""
|
||||||
|
|
||||||
when defined(nimphp):
|
|
||||||
proc nimAt(x: string; i: int): string {.asmNoStackFrame, compilerproc.} =
|
|
||||||
asm """
|
|
||||||
return `x`[`i`];
|
|
||||||
"""
|
|
||||||
|
|
||||||
when defined(nimphp):
|
|
||||||
proc nimSubstr(s: string; a, b: int): string {.
|
|
||||||
asmNoStackFrame, compilerproc.} =
|
|
||||||
asm """return substr(`s`,`a`,`b`-`a`+1);"""
|
|
||||||
|
|
||||||
proc SetCard(a: int): int {.compilerproc, asmNoStackFrame.} =
|
proc SetCard(a: int): int {.compilerproc, asmNoStackFrame.} =
|
||||||
# argument type is a fake
|
# argument type is a fake
|
||||||
when defined(nimphp):
|
|
||||||
asm """
|
|
||||||
return count(`a`);
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
asm """
|
asm """
|
||||||
var result = 0;
|
var result = 0;
|
||||||
for (var elem in `a`) { ++result; }
|
for (var elem in `a`) { ++result; }
|
||||||
|
|
@ -332,13 +279,6 @@ proc SetCard(a: int): int {.compilerproc, asmNoStackFrame.} =
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc SetEq(a, b: int): bool {.compilerproc, asmNoStackFrame.} =
|
proc SetEq(a, b: int): bool {.compilerproc, asmNoStackFrame.} =
|
||||||
when defined(nimphp):
|
|
||||||
asm """
|
|
||||||
foreach (`a` as $elem=>$_) { if (!isset(`b`[$elem])) return false; }
|
|
||||||
foreach (`b` as $elem=>$_) { if (!isset(`a`[$elem])) return false; }
|
|
||||||
return true;
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
asm """
|
asm """
|
||||||
for (var elem in `a`) { if (!`b`[elem]) return false; }
|
for (var elem in `a`) { if (!`b`[elem]) return false; }
|
||||||
for (var elem in `b`) { if (!`a`[elem]) return false; }
|
for (var elem in `b`) { if (!`a`[elem]) return false; }
|
||||||
|
|
@ -346,12 +286,6 @@ proc SetEq(a, b: int): bool {.compilerproc, asmNoStackFrame.} =
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc SetLe(a, b: int): bool {.compilerproc, asmNoStackFrame.} =
|
proc SetLe(a, b: int): bool {.compilerproc, asmNoStackFrame.} =
|
||||||
when defined(nimphp):
|
|
||||||
asm """
|
|
||||||
foreach (`a` as $elem=>$_) { if (!isset(`b`[$elem])) return false; }
|
|
||||||
return true;
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
asm """
|
asm """
|
||||||
for (var elem in `a`) { if (!`b`[elem]) return false; }
|
for (var elem in `a`) { if (!`b`[elem]) return false; }
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -361,15 +295,6 @@ proc SetLt(a, b: int): bool {.compilerproc.} =
|
||||||
result = SetLe(a, b) and not SetEq(a, b)
|
result = SetLe(a, b) and not SetEq(a, b)
|
||||||
|
|
||||||
proc SetMul(a, b: int): int {.compilerproc, asmNoStackFrame.} =
|
proc SetMul(a, b: int): int {.compilerproc, asmNoStackFrame.} =
|
||||||
when defined(nimphp):
|
|
||||||
asm """
|
|
||||||
var $result = array();
|
|
||||||
foreach (`a` as $elem=>$_) {
|
|
||||||
if (isset(`b`[$elem])) { $result[$elem] = true; }
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
asm """
|
asm """
|
||||||
var result = {};
|
var result = {};
|
||||||
for (var elem in `a`) {
|
for (var elem in `a`) {
|
||||||
|
|
@ -379,14 +304,6 @@ proc SetMul(a, b: int): int {.compilerproc, asmNoStackFrame.} =
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc SetPlus(a, b: int): int {.compilerproc, asmNoStackFrame.} =
|
proc SetPlus(a, b: int): int {.compilerproc, asmNoStackFrame.} =
|
||||||
when defined(nimphp):
|
|
||||||
asm """
|
|
||||||
var $result = array();
|
|
||||||
foreach (`a` as $elem=>$_) { $result[$elem] = true; }
|
|
||||||
foreach (`b` as $elem=>$_) { $result[$elem] = true; }
|
|
||||||
return $result;
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
asm """
|
asm """
|
||||||
var result = {};
|
var result = {};
|
||||||
for (var elem in `a`) { result[elem] = true; }
|
for (var elem in `a`) { result[elem] = true; }
|
||||||
|
|
@ -395,15 +312,6 @@ proc SetPlus(a, b: int): int {.compilerproc, asmNoStackFrame.} =
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc SetMinus(a, b: int): int {.compilerproc, asmNoStackFrame.} =
|
proc SetMinus(a, b: int): int {.compilerproc, asmNoStackFrame.} =
|
||||||
when defined(nimphp):
|
|
||||||
asm """
|
|
||||||
$result = array();
|
|
||||||
foreach (`a` as $elem=>$_) {
|
|
||||||
if (!isset(`b`[$elem])) { $result[$elem] = true; }
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
asm """
|
asm """
|
||||||
var result = {};
|
var result = {};
|
||||||
for (var elem in `a`) {
|
for (var elem in `a`) {
|
||||||
|
|
@ -425,13 +333,6 @@ proc cmpStrings(a, b: string): int {.asmNoStackFrame, compilerProc.} =
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc cmp(x, y: string): int =
|
proc cmp(x, y: string): int =
|
||||||
when defined(nimphp):
|
|
||||||
asm """
|
|
||||||
if(`x` < `y`) `result` = -1;
|
|
||||||
elseif (`x` > `y`) `result` = 1;
|
|
||||||
else `result` = 0;
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
return cmpStrings(x, y)
|
return cmpStrings(x, y)
|
||||||
|
|
||||||
proc eqStrings(a, b: string): bool {.asmNoStackFrame, compilerProc.} =
|
proc eqStrings(a, b: string): bool {.asmNoStackFrame, compilerProc.} =
|
||||||
|
|
@ -467,7 +368,7 @@ elif not defined(nimOldEcho):
|
||||||
console.log(buf);
|
console.log(buf);
|
||||||
"""
|
"""
|
||||||
|
|
||||||
elif not defined(nimphp):
|
else:
|
||||||
proc ewriteln(x: cstring) =
|
proc ewriteln(x: cstring) =
|
||||||
var node : JSRef
|
var node : JSRef
|
||||||
{.emit: "`node` = document.getElementsByTagName('body')[0];".}
|
{.emit: "`node` = document.getElementsByTagName('body')[0];".}
|
||||||
|
|
@ -493,11 +394,6 @@ elif not defined(nimphp):
|
||||||
|
|
||||||
# Arithmetic:
|
# Arithmetic:
|
||||||
proc addInt(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
proc addInt(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
||||||
when defined(nimphp):
|
|
||||||
asm """
|
|
||||||
return `a` + `b`;
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
asm """
|
asm """
|
||||||
var result = `a` + `b`;
|
var result = `a` + `b`;
|
||||||
if (result > 2147483647 || result < -2147483648) `raiseOverflow`();
|
if (result > 2147483647 || result < -2147483648) `raiseOverflow`();
|
||||||
|
|
@ -505,11 +401,6 @@ proc addInt(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc subInt(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
proc subInt(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
||||||
when defined(nimphp):
|
|
||||||
asm """
|
|
||||||
return `a` - `b`;
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
asm """
|
asm """
|
||||||
var result = `a` - `b`;
|
var result = `a` - `b`;
|
||||||
if (result > 2147483647 || result < -2147483648) `raiseOverflow`();
|
if (result > 2147483647 || result < -2147483648) `raiseOverflow`();
|
||||||
|
|
@ -517,11 +408,6 @@ proc subInt(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc mulInt(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
proc mulInt(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
||||||
when defined(nimphp):
|
|
||||||
asm """
|
|
||||||
return `a` * `b`;
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
asm """
|
asm """
|
||||||
var result = `a` * `b`;
|
var result = `a` * `b`;
|
||||||
if (result > 2147483647 || result < -2147483648) `raiseOverflow`();
|
if (result > 2147483647 || result < -2147483648) `raiseOverflow`();
|
||||||
|
|
@ -529,11 +415,6 @@ proc mulInt(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc divInt(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
proc divInt(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
||||||
when defined(nimphp):
|
|
||||||
asm """
|
|
||||||
return trunc(`a` / `b`);
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
asm """
|
asm """
|
||||||
if (`b` == 0) `raiseDivByZero`();
|
if (`b` == 0) `raiseDivByZero`();
|
||||||
if (`b` == -1 && `a` == 2147483647) `raiseOverflow`();
|
if (`b` == -1 && `a` == 2147483647) `raiseOverflow`();
|
||||||
|
|
@ -541,11 +422,6 @@ proc divInt(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc modInt(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
proc modInt(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
||||||
when defined(nimphp):
|
|
||||||
asm """
|
|
||||||
return `a` % `b`;
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
asm """
|
asm """
|
||||||
if (`b` == 0) `raiseDivByZero`();
|
if (`b` == 0) `raiseDivByZero`();
|
||||||
if (`b` == -1 && `a` == 2147483647) `raiseOverflow`();
|
if (`b` == -1 && `a` == 2147483647) `raiseOverflow`();
|
||||||
|
|
@ -553,11 +429,6 @@ proc modInt(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc addInt64(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
proc addInt64(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
||||||
when defined(nimphp):
|
|
||||||
asm """
|
|
||||||
return `a` + `b`;
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
asm """
|
asm """
|
||||||
var result = `a` + `b`;
|
var result = `a` + `b`;
|
||||||
if (result > 9223372036854775807
|
if (result > 9223372036854775807
|
||||||
|
|
@ -566,11 +437,6 @@ proc addInt64(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc subInt64(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
proc subInt64(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
||||||
when defined(nimphp):
|
|
||||||
asm """
|
|
||||||
return `a` - `b`;
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
asm """
|
asm """
|
||||||
var result = `a` - `b`;
|
var result = `a` - `b`;
|
||||||
if (result > 9223372036854775807
|
if (result > 9223372036854775807
|
||||||
|
|
@ -579,11 +445,6 @@ proc subInt64(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc mulInt64(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
proc mulInt64(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
||||||
when defined(nimphp):
|
|
||||||
asm """
|
|
||||||
return `a` * `b`;
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
asm """
|
asm """
|
||||||
var result = `a` * `b`;
|
var result = `a` * `b`;
|
||||||
if (result > 9223372036854775807
|
if (result > 9223372036854775807
|
||||||
|
|
@ -592,11 +453,6 @@ proc mulInt64(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc divInt64(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
proc divInt64(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
||||||
when defined(nimphp):
|
|
||||||
asm """
|
|
||||||
return trunc(`a` / `b`);
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
asm """
|
asm """
|
||||||
if (`b` == 0) `raiseDivByZero`();
|
if (`b` == 0) `raiseDivByZero`();
|
||||||
if (`b` == -1 && `a` == 9223372036854775807) `raiseOverflow`();
|
if (`b` == -1 && `a` == 9223372036854775807) `raiseOverflow`();
|
||||||
|
|
@ -604,11 +460,6 @@ proc divInt64(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc modInt64(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
proc modInt64(a, b: int): int {.asmNoStackFrame, compilerproc.} =
|
||||||
when defined(nimphp):
|
|
||||||
asm """
|
|
||||||
return `a` % `b`;
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
asm """
|
asm """
|
||||||
if (`b` == 0) `raiseDivByZero`();
|
if (`b` == 0) `raiseDivByZero`();
|
||||||
if (`b` == -1 && `a` == 9223372036854775807) `raiseOverflow`();
|
if (`b` == -1 && `a` == 9223372036854775807) `raiseOverflow`();
|
||||||
|
|
@ -767,17 +618,7 @@ proc genericReset(x: JSRef, ti: PNimType): JSRef {.compilerproc.} =
|
||||||
else:
|
else:
|
||||||
discard
|
discard
|
||||||
|
|
||||||
when defined(nimphp):
|
proc arrayConstr(len: int, value: JSRef, typ: PNimType): JSRef {.
|
||||||
proc arrayConstr(len: int, value: string, typ: string): JSRef {.
|
|
||||||
asmNoStackFrame, compilerproc.} =
|
|
||||||
# types are fake
|
|
||||||
asm """
|
|
||||||
$result = array();
|
|
||||||
for ($i = 0; $i < `len`; $i++) $result[] = `value`;
|
|
||||||
return $result;
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
proc arrayConstr(len: int, value: JSRef, typ: PNimType): JSRef {.
|
|
||||||
asmNoStackFrame, compilerproc.} =
|
asmNoStackFrame, compilerproc.} =
|
||||||
# types are fake
|
# types are fake
|
||||||
asm """
|
asm """
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue