dead code elimination for JS backend; JS improvements (but doesn't work yet)
This commit is contained in:
parent
2900ceae35
commit
ee1bcb6414
7 changed files with 213 additions and 104 deletions
|
|
@ -26,7 +26,7 @@ type
|
||||||
module*: PSym
|
module*: PSym
|
||||||
|
|
||||||
BModule = ref TEcmasGen
|
BModule = ref TEcmasGen
|
||||||
TEcmasTypeKind = enum
|
TEcmasTypeKind = enum # necessary JS "types"
|
||||||
etyNone, # no type
|
etyNone, # no type
|
||||||
etyNull, # null type
|
etyNull, # null type
|
||||||
etyProc, # proc type
|
etyProc, # proc type
|
||||||
|
|
@ -50,25 +50,29 @@ type
|
||||||
isLoop: bool # whether it's a 'block' or 'while'
|
isLoop: bool # whether it's a 'block' or 'while'
|
||||||
|
|
||||||
TGlobals{.final.} = object
|
TGlobals{.final.} = object
|
||||||
typeInfo*, code*: PRope
|
typeInfo, code: PRope
|
||||||
typeInfoGenerated*: TIntSet
|
forwarded: seq[PSym]
|
||||||
|
generatedSyms: TIntSet
|
||||||
|
typeInfoGenerated: TIntSet
|
||||||
|
|
||||||
PGlobals = ref TGlobals
|
PGlobals = ref TGlobals
|
||||||
TProc{.final.} = object
|
TProc{.final.} = object
|
||||||
procDef*: PNode
|
procDef: PNode
|
||||||
prc*: PSym
|
prc: PSym
|
||||||
data*: PRope
|
data: PRope
|
||||||
options*: TOptions
|
options: TOptions
|
||||||
module*: BModule
|
module: BModule
|
||||||
globals*: PGlobals
|
g: PGlobals
|
||||||
BeforeRetNeeded*: bool
|
BeforeRetNeeded: bool
|
||||||
nestedTryStmts*: int
|
nestedTryStmts: int
|
||||||
unique*: int
|
unique: int
|
||||||
blocks*: seq[TBlock]
|
blocks: seq[TBlock]
|
||||||
|
|
||||||
|
|
||||||
proc newGlobals(): PGlobals =
|
proc newGlobals(): PGlobals =
|
||||||
new(result)
|
new(result)
|
||||||
|
result.forwarded = @[]
|
||||||
|
result.generatedSyms = initIntSet()
|
||||||
result.typeInfoGenerated = initIntSet()
|
result.typeInfoGenerated = initIntSet()
|
||||||
|
|
||||||
proc initCompRes(r: var TCompRes) =
|
proc initCompRes(r: var TCompRes) =
|
||||||
|
|
@ -82,7 +86,7 @@ proc initProc(p: var TProc, globals: PGlobals, module: BModule, procDef: PNode,
|
||||||
p.options = options
|
p.options = options
|
||||||
p.module = module
|
p.module = module
|
||||||
p.procDef = procDef
|
p.procDef = procDef
|
||||||
p.globals = globals
|
p.g = globals
|
||||||
if procDef != nil: p.prc = procDef.sons[namePos].sym
|
if procDef != nil: p.prc = procDef.sons[namePos].sym
|
||||||
|
|
||||||
const
|
const
|
||||||
|
|
@ -196,12 +200,12 @@ proc genObjectFields(p: var TProc, typ: PType, n: PNode): PRope =
|
||||||
proc genObjectInfo(p: var TProc, typ: PType, name: PRope) =
|
proc genObjectInfo(p: var TProc, typ: PType, name: PRope) =
|
||||||
var s = ropef("var $1 = {size: 0, kind: $2, base: null, node: null, " &
|
var s = ropef("var $1 = {size: 0, kind: $2, base: null, node: null, " &
|
||||||
"finalizer: null};$n", [name, toRope(ord(typ.kind))])
|
"finalizer: null};$n", [name, toRope(ord(typ.kind))])
|
||||||
prepend(p.globals.typeInfo, s)
|
prepend(p.g.typeInfo, s)
|
||||||
appf(p.globals.typeInfo, "var NNI$1 = $2;$n",
|
appf(p.g.typeInfo, "var NNI$1 = $2;$n",
|
||||||
[toRope(typ.id), genObjectFields(p, typ, typ.n)])
|
[toRope(typ.id), genObjectFields(p, typ, typ.n)])
|
||||||
appf(p.globals.typeInfo, "$1.node = NNI$2;$n", [name, toRope(typ.id)])
|
appf(p.g.typeInfo, "$1.node = NNI$2;$n", [name, toRope(typ.id)])
|
||||||
if (typ.kind == tyObject) and (typ.sons[0] != nil):
|
if (typ.kind == tyObject) and (typ.sons[0] != nil):
|
||||||
appf(p.globals.typeInfo, "$1.base = $2;$n",
|
appf(p.g.typeInfo, "$1.base = $2;$n",
|
||||||
[name, genTypeInfo(p, typ.sons[0])])
|
[name, genTypeInfo(p, typ.sons[0])])
|
||||||
|
|
||||||
proc genEnumInfo(p: var TProc, typ: PType, name: PRope) =
|
proc genEnumInfo(p: var TProc, typ: PType, name: PRope) =
|
||||||
|
|
@ -221,18 +225,18 @@ proc genEnumInfo(p: var TProc, typ: PType, name: PRope) =
|
||||||
"name: null, len: $2, sons: [$3]};$n", [toRope(typ.id), toRope(length), s])
|
"name: null, len: $2, sons: [$3]};$n", [toRope(typ.id), toRope(length), s])
|
||||||
s = ropef("var $1 = {size: 0, kind: $2, base: null, node: null, " &
|
s = ropef("var $1 = {size: 0, kind: $2, base: null, node: null, " &
|
||||||
"finalizer: null};$n", [name, toRope(ord(typ.kind))])
|
"finalizer: null};$n", [name, toRope(ord(typ.kind))])
|
||||||
prepend(p.globals.typeInfo, s)
|
prepend(p.g.typeInfo, s)
|
||||||
app(p.globals.typeInfo, n)
|
app(p.g.typeInfo, n)
|
||||||
appf(p.globals.typeInfo, "$1.node = NNI$2;$n", [name, toRope(typ.id)])
|
appf(p.g.typeInfo, "$1.node = NNI$2;$n", [name, toRope(typ.id)])
|
||||||
if typ.sons[0] != nil:
|
if typ.sons[0] != nil:
|
||||||
appf(p.globals.typeInfo, "$1.base = $2;$n",
|
appf(p.g.typeInfo, "$1.base = $2;$n",
|
||||||
[name, genTypeInfo(p, typ.sons[0])])
|
[name, genTypeInfo(p, typ.sons[0])])
|
||||||
|
|
||||||
proc genTypeInfo(p: var TProc, typ: PType): PRope =
|
proc genTypeInfo(p: var TProc, typ: PType): PRope =
|
||||||
var t = typ
|
var t = typ
|
||||||
if t.kind == tyGenericInst: t = lastSon(t)
|
if t.kind == tyGenericInst: t = lastSon(t)
|
||||||
result = ropef("NTI$1", [toRope(t.id)])
|
result = ropef("NTI$1", [toRope(t.id)])
|
||||||
if ContainsOrIncl(p.globals.TypeInfoGenerated, t.id): return
|
if ContainsOrIncl(p.g.TypeInfoGenerated, t.id): return
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyDistinct:
|
of tyDistinct:
|
||||||
result = genTypeInfo(p, typ.sons[0])
|
result = genTypeInfo(p, typ.sons[0])
|
||||||
|
|
@ -240,20 +244,20 @@ proc genTypeInfo(p: var TProc, typ: PType): PRope =
|
||||||
var s = ropef(
|
var s = ropef(
|
||||||
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n",
|
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n",
|
||||||
[result, toRope(ord(t.kind))])
|
[result, toRope(ord(t.kind))])
|
||||||
prepend(p.globals.typeInfo, s)
|
prepend(p.g.typeInfo, s)
|
||||||
of tyVar, tyRef, tyPtr, tySequence, tyRange, tySet:
|
of tyVar, tyRef, tyPtr, tySequence, tyRange, tySet:
|
||||||
var s = ropef(
|
var s = ropef(
|
||||||
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n",
|
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n",
|
||||||
[result, toRope(ord(t.kind))])
|
[result, toRope(ord(t.kind))])
|
||||||
prepend(p.globals.typeInfo, s)
|
prepend(p.g.typeInfo, s)
|
||||||
appf(p.globals.typeInfo, "$1.base = $2;$n",
|
appf(p.g.typeInfo, "$1.base = $2;$n",
|
||||||
[result, genTypeInfo(p, typ.sons[0])])
|
[result, genTypeInfo(p, typ.sons[0])])
|
||||||
of tyArrayConstr, tyArray:
|
of tyArrayConstr, tyArray:
|
||||||
var s = ropef(
|
var s = ropef(
|
||||||
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n",
|
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n",
|
||||||
[result, toRope(ord(t.kind))])
|
[result, toRope(ord(t.kind))])
|
||||||
prepend(p.globals.typeInfo, s)
|
prepend(p.g.typeInfo, s)
|
||||||
appf(p.globals.typeInfo, "$1.base = $2;$n",
|
appf(p.g.typeInfo, "$1.base = $2;$n",
|
||||||
[result, genTypeInfo(p, typ.sons[1])])
|
[result, genTypeInfo(p, typ.sons[1])])
|
||||||
of tyEnum: genEnumInfo(p, t, result)
|
of tyEnum: genEnumInfo(p, t, result)
|
||||||
of tyObject, tyTuple: genObjectInfo(p, t, result)
|
of tyObject, tyTuple: genObjectInfo(p, t, result)
|
||||||
|
|
@ -261,10 +265,9 @@ proc genTypeInfo(p: var TProc, typ: PType): PRope =
|
||||||
|
|
||||||
proc gen(p: var TProc, n: PNode, r: var TCompRes)
|
proc gen(p: var TProc, n: PNode, r: var TCompRes)
|
||||||
proc genStmt(p: var TProc, n: PNode, r: var TCompRes)
|
proc genStmt(p: var TProc, n: PNode, r: var TCompRes)
|
||||||
proc useMagic(p: var TProc, ident: string) =
|
proc genProc(oldProc: var TProc, prc: PSym, r: var TCompRes)
|
||||||
nil
|
proc genConstant(p: var TProc, c: PSym, r: var TCompRes)
|
||||||
# to implement
|
|
||||||
|
|
||||||
proc mergeExpr(a, b: PRope): PRope =
|
proc mergeExpr(a, b: PRope): PRope =
|
||||||
if (a != nil):
|
if (a != nil):
|
||||||
if b != nil: result = ropef("($1, $2)", [a, b])
|
if b != nil: result = ropef("($1, $2)", [a, b])
|
||||||
|
|
@ -280,6 +283,22 @@ proc mergeStmt(r: TCompRes): PRope =
|
||||||
elif r.com == nil: result = r.res
|
elif r.com == nil: result = r.res
|
||||||
else: result = ropef("$1$2", [r.com, r.res])
|
else: result = ropef("$1$2", [r.com, r.res])
|
||||||
|
|
||||||
|
proc useMagic(p: var TProc, name: string) =
|
||||||
|
if name.len == 0: return
|
||||||
|
var s = magicsys.getCompilerProc(name)
|
||||||
|
if s != nil:
|
||||||
|
internalAssert s.kind in {skProc, skMethod, skConverter}
|
||||||
|
if not p.g.generatedSyms.containsOrIncl(s.id):
|
||||||
|
var r: TCompRes
|
||||||
|
genProc(p, s, r)
|
||||||
|
app(p.g.code, mergeStmt(r))
|
||||||
|
else:
|
||||||
|
# we used to exclude the system module from this check, but for DLL
|
||||||
|
# generation support this sloppyness leads to hard to detect bugs, so
|
||||||
|
# we're picky here for the system module too:
|
||||||
|
if p.prc != nil: GlobalError(p.prc.info, errSystemNeeds, name)
|
||||||
|
else: rawMessage(errSystemNeeds, name)
|
||||||
|
|
||||||
proc genAnd(p: var TProc, a, b: PNode, r: var TCompRes) =
|
proc genAnd(p: var TProc, a, b: PNode, r: var TCompRes) =
|
||||||
var x, y: TCompRes
|
var x, y: TCompRes
|
||||||
gen(p, a, x)
|
gen(p, a, x)
|
||||||
|
|
@ -403,7 +422,7 @@ const # magic checked op; magic unchecked op; checked op; unchecked op
|
||||||
|
|
||||||
proc binaryExpr(p: var TProc, n: PNode, r: var TCompRes, magic, frmt: string) =
|
proc binaryExpr(p: var TProc, n: PNode, r: var TCompRes, magic, frmt: string) =
|
||||||
var x, y: TCompRes
|
var x, y: TCompRes
|
||||||
if magic != "": useMagic(p, magic)
|
useMagic(p, magic)
|
||||||
gen(p, n.sons[1], x)
|
gen(p, n.sons[1], x)
|
||||||
gen(p, n.sons[2], y)
|
gen(p, n.sons[2], y)
|
||||||
r.res = ropef(frmt, [x.res, y.res])
|
r.res = ropef(frmt, [x.res, y.res])
|
||||||
|
|
@ -411,7 +430,7 @@ proc binaryExpr(p: var TProc, n: PNode, r: var TCompRes, magic, frmt: string) =
|
||||||
|
|
||||||
proc binaryStmt(p: var TProc, n: PNode, r: var TCompRes, magic, frmt: string) =
|
proc binaryStmt(p: var TProc, n: PNode, r: var TCompRes, magic, frmt: string) =
|
||||||
var x, y: TCompRes
|
var x, y: TCompRes
|
||||||
if magic != "": useMagic(p, magic)
|
useMagic(p, magic)
|
||||||
gen(p, n.sons[1], x)
|
gen(p, n.sons[1], x)
|
||||||
gen(p, n.sons[2], y)
|
gen(p, n.sons[2], y)
|
||||||
if x.com != nil: appf(r.com, "$1;$n", [x.com])
|
if x.com != nil: appf(r.com, "$1;$n", [x.com])
|
||||||
|
|
@ -419,7 +438,7 @@ proc binaryStmt(p: var TProc, n: PNode, r: var TCompRes, magic, frmt: string) =
|
||||||
appf(r.com, frmt, [x.res, y.res])
|
appf(r.com, frmt, [x.res, y.res])
|
||||||
|
|
||||||
proc unaryExpr(p: var TProc, n: PNode, r: var TCompRes, magic, frmt: string) =
|
proc unaryExpr(p: var TProc, n: PNode, r: var TCompRes, magic, frmt: string) =
|
||||||
if magic != "": useMagic(p, magic)
|
useMagic(p, magic)
|
||||||
gen(p, n.sons[1], r)
|
gen(p, n.sons[1], r)
|
||||||
r.res = ropef(frmt, [r.res])
|
r.res = ropef(frmt, [r.res])
|
||||||
|
|
||||||
|
|
@ -821,7 +840,7 @@ proc genArrayAddr(p: var TProc, n: PNode, r: var TCompRes) =
|
||||||
var typ = skipTypes(n.sons[0].typ, abstractPtrs)
|
var typ = skipTypes(n.sons[0].typ, abstractPtrs)
|
||||||
if typ.kind in {tyArray, tyArrayConstr}: first = FirstOrd(typ.sons[0])
|
if typ.kind in {tyArray, tyArrayConstr}: first = FirstOrd(typ.sons[0])
|
||||||
else: first = 0
|
else: first = 0
|
||||||
if (optBoundsCheck in p.options) and not isConstExpr(n.sons[1]):
|
if optBoundsCheck in p.options and not isConstExpr(n.sons[1]):
|
||||||
useMagic(p, "chckIndx")
|
useMagic(p, "chckIndx")
|
||||||
b.res = ropef("chckIndx($1, $2, $3.length)-$2",
|
b.res = ropef("chckIndx($1, $2, $3.length)-$2",
|
||||||
[b.res, toRope(first), a.res])
|
[b.res, toRope(first), a.res])
|
||||||
|
|
@ -869,12 +888,13 @@ proc genAddr(p: var TProc, n: PNode, r: var TCompRes) =
|
||||||
genArrayAddr(p, n, r)
|
genArrayAddr(p, n, r)
|
||||||
else: InternalError(n.info, "genAddr")
|
else: InternalError(n.info, "genAddr")
|
||||||
|
|
||||||
|
|
||||||
proc genSym(p: var TProc, n: PNode, r: var TCompRes) =
|
proc genSym(p: var TProc, n: PNode, r: var TCompRes) =
|
||||||
var s = n.sym
|
var s = n.sym
|
||||||
if s.loc.r == nil:
|
|
||||||
InternalError(n.info, "symbol has no generated name: " & s.name.s)
|
|
||||||
case s.kind
|
case s.kind
|
||||||
of skVar, skLet, skParam, skTemp, skResult:
|
of skVar, skLet, skParam, skTemp, skResult:
|
||||||
|
if s.loc.r == nil:
|
||||||
|
InternalError(n.info, "symbol has no generated name: " & s.name.s)
|
||||||
var k = mapType(s.typ)
|
var k = mapType(s.typ)
|
||||||
if k == etyBaseIndex:
|
if k == etyBaseIndex:
|
||||||
r.kind = etyBaseIndex
|
r.kind = etyBaseIndex
|
||||||
|
|
@ -888,7 +908,25 @@ proc genSym(p: var TProc, n: PNode, r: var TCompRes) =
|
||||||
r.res = ropef("$1[0]", [s.loc.r])
|
r.res = ropef("$1[0]", [s.loc.r])
|
||||||
else:
|
else:
|
||||||
r.res = s.loc.r
|
r.res = s.loc.r
|
||||||
else: r.res = s.loc.r
|
of skConst:
|
||||||
|
genConstant(p, s, r)
|
||||||
|
if s.loc.r == nil:
|
||||||
|
InternalError(n.info, "symbol has no generated name: " & s.name.s)
|
||||||
|
r.res = s.loc.r
|
||||||
|
of skProc, skConverter, skMethod:
|
||||||
|
discard mangleName(s)
|
||||||
|
r.res = s.loc.r
|
||||||
|
if lfNoDecl in s.loc.flags or s.magic != mNone or isGenericRoutine(s): nil
|
||||||
|
elif sfForward in s.flags:
|
||||||
|
p.g.forwarded.add(s)
|
||||||
|
elif not p.g.generatedSyms.containsOrIncl(s.id):
|
||||||
|
var r2: TCompRes
|
||||||
|
genProc(p, s, r2)
|
||||||
|
app(p.g.code, mergeStmt(r2))
|
||||||
|
else:
|
||||||
|
if s.loc.r == nil:
|
||||||
|
InternalError(n.info, "symbol has no generated name: " & s.name.s)
|
||||||
|
r.res = s.loc.r
|
||||||
|
|
||||||
proc genDeref(p: var TProc, n: PNode, r: var TCompRes) =
|
proc genDeref(p: var TProc, n: PNode, r: var TCompRes) =
|
||||||
var a: TCompRes
|
var a: TCompRes
|
||||||
|
|
@ -1041,16 +1079,22 @@ proc genVarStmt(p: var TProc, n: PNode, r: var TCompRes) =
|
||||||
genLineDir(p, a, r)
|
genLineDir(p, a, r)
|
||||||
genVarInit(p, v, a.sons[2], r)
|
genVarInit(p, v, a.sons[2], r)
|
||||||
|
|
||||||
proc genConstStmt(p: var TProc, n: PNode, r: var TCompRes) =
|
proc genConstant(p: var TProc, c: PSym, r: var TCompRes) =
|
||||||
genLineDir(p, n, r)
|
if lfNoDecl notin c.loc.flags and not p.g.generatedSyms.containsOrIncl(c.id):
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
genLineDir(p, c.ast, r)
|
||||||
if n.sons[i].kind == nkCommentStmt: continue
|
genVarInit(p, c, c.ast, r)
|
||||||
assert(n.sons[i].kind == nkConstDef)
|
|
||||||
var c = n.sons[i].sons[0].sym
|
when false:
|
||||||
if (c.ast != nil) and (c.typ.kind in ConstantDataTypes) and
|
proc genConstStmt(p: var TProc, n: PNode, r: var TCompRes) =
|
||||||
not (lfNoDecl in c.loc.flags):
|
genLineDir(p, n, r)
|
||||||
genLineDir(p, n.sons[i], r)
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
genVarInit(p, c, c.ast, r)
|
if n.sons[i].kind == nkCommentStmt: continue
|
||||||
|
assert(n.sons[i].kind == nkConstDef)
|
||||||
|
var c = n.sons[i].sons[0].sym
|
||||||
|
if c.ast != nil and c.typ.kind in ConstantDataTypes and
|
||||||
|
lfNoDecl notin c.loc.flags:
|
||||||
|
genLineDir(p, n.sons[i], r)
|
||||||
|
genVarInit(p, c, c.ast, r)
|
||||||
|
|
||||||
proc genNew(p: var TProc, n: PNode, r: var TCompRes) =
|
proc genNew(p: var TProc, n: PNode, r: var TCompRes) =
|
||||||
var a: TCompRes
|
var a: TCompRes
|
||||||
|
|
@ -1299,12 +1343,14 @@ proc genProc(oldProc: var TProc, prc: PSym, r: var TCompRes) =
|
||||||
resultSym: PSym
|
resultSym: PSym
|
||||||
name, returnStmt, resultAsgn, header: PRope
|
name, returnStmt, resultAsgn, header: PRope
|
||||||
a: TCompRes
|
a: TCompRes
|
||||||
initProc(p, oldProc.globals, oldProc.module, prc.ast, prc.options)
|
#if gVerbosity >= 3:
|
||||||
|
# echo "BEGIN generating code for: " & prc.name.s
|
||||||
|
initProc(p, oldProc.g, oldProc.module, prc.ast, prc.options)
|
||||||
returnStmt = nil
|
returnStmt = nil
|
||||||
resultAsgn = nil
|
resultAsgn = nil
|
||||||
name = mangleName(prc)
|
name = mangleName(prc)
|
||||||
header = generateHeader(p, prc.typ)
|
header = generateHeader(p, prc.typ)
|
||||||
if (prc.typ.sons[0] != nil) and not (sfPure in prc.flags):
|
if (prc.typ.sons[0] != nil) and sfPure notin prc.flags:
|
||||||
resultSym = prc.ast.sons[resultPos].sym
|
resultSym = prc.ast.sons[resultPos].sym
|
||||||
resultAsgn = ropef("var $1 = $2;$n", [mangleName(resultSym),
|
resultAsgn = ropef("var $1 = $2;$n", [mangleName(resultSym),
|
||||||
createVar(p, resultSym.typ, isIndirect(resultSym))])
|
createVar(p, resultSym.typ, isIndirect(resultSym))])
|
||||||
|
|
@ -1315,6 +1361,8 @@ proc genProc(oldProc: var TProc, prc: PSym, r: var TCompRes) =
|
||||||
r.com = ropef("function $1($2) {$n$3$4$5}$n",
|
r.com = ropef("function $1($2) {$n$3$4$5}$n",
|
||||||
[name, header, resultAsgn, genProcBody(p, prc, r), returnStmt])
|
[name, header, resultAsgn, genProcBody(p, prc, r), returnStmt])
|
||||||
r.res = nil
|
r.res = nil
|
||||||
|
#if gVerbosity >= 3:
|
||||||
|
# echo "END generated code for: " & prc.name.s
|
||||||
|
|
||||||
proc genStmtListExpr(p: var TProc, n: PNode, r: var TCompRes) =
|
proc genStmtListExpr(p: var TProc, n: PNode, r: var TCompRes) =
|
||||||
var a: TCompRes
|
var a: TCompRes
|
||||||
|
|
@ -1342,7 +1390,7 @@ proc genStmt(p: var TProc, n: PNode, r: var TCompRes) =
|
||||||
of nkIfStmt: genIfStmt(p, n, r)
|
of nkIfStmt: genIfStmt(p, n, r)
|
||||||
of nkWhileStmt: genWhileStmt(p, n, r)
|
of nkWhileStmt: genWhileStmt(p, n, r)
|
||||||
of nkVarSection, nkLetSection: genVarStmt(p, n, r)
|
of nkVarSection, nkLetSection: genVarStmt(p, n, r)
|
||||||
of nkConstSection: genConstStmt(p, n, r)
|
of nkConstSection: nil
|
||||||
of nkForStmt, nkParForStmt:
|
of nkForStmt, nkParForStmt:
|
||||||
internalError(n.info, "for statement not eliminated")
|
internalError(n.info, "for statement not eliminated")
|
||||||
of nkCaseStmt: genCaseStmt(p, n, r)
|
of nkCaseStmt: genCaseStmt(p, n, r)
|
||||||
|
|
@ -1358,16 +1406,13 @@ proc genStmt(p: var TProc, n: PNode, r: var TCompRes) =
|
||||||
of nkTryStmt: genTryStmt(p, n, r)
|
of nkTryStmt: genTryStmt(p, n, r)
|
||||||
of nkRaiseStmt: genRaiseStmt(p, n, r)
|
of nkRaiseStmt: genRaiseStmt(p, n, r)
|
||||||
of nkTypeSection, nkCommentStmt, nkIteratorDef, nkIncludeStmt, nkImportStmt,
|
of nkTypeSection, nkCommentStmt, nkIteratorDef, nkIncludeStmt, nkImportStmt,
|
||||||
nkFromStmt, nkTemplateDef, nkMacroDef, nkPragma:
|
nkFromStmt, nkTemplateDef, nkMacroDef, nkPragma: nil
|
||||||
nil
|
of nkProcDef, nkMethodDef, nkConverterDef:
|
||||||
of nkProcDef, nkMethodDef, nkConverterDef:
|
var s = n.sons[namePos].sym
|
||||||
if (n.sons[genericParamsPos].kind == nkEmpty):
|
if {sfExportc, sfCompilerProc} * s.flags == {sfExportc}:
|
||||||
var prc = n.sons[namePos].sym
|
var r2: TCompRes
|
||||||
if lfNoDecl notin prc.loc.flags and prc.getBody.kind != nkEmpty:
|
genSym(p, n.sons[namePos], r2)
|
||||||
genProc(p, prc, r)
|
else:
|
||||||
else:
|
|
||||||
discard mangleName(prc)
|
|
||||||
else:
|
|
||||||
genLineDir(p, n, r)
|
genLineDir(p, n, r)
|
||||||
if n.sons[0].kind == nkSym:
|
if n.sons[0].kind == nkSym:
|
||||||
if n.sons[0].sym.loc.r == nil:
|
if n.sons[0].sym.loc.r == nil:
|
||||||
|
|
@ -1431,6 +1476,9 @@ proc gen(p: var TProc, n: PNode, r: var TCompRes) =
|
||||||
of nkCStringToString: convCStrToStr(p, n, r)
|
of nkCStringToString: convCStrToStr(p, n, r)
|
||||||
of nkStmtListExpr: genStmtListExpr(p, n, r)
|
of nkStmtListExpr: genStmtListExpr(p, n, r)
|
||||||
of nkEmpty: nil
|
of nkEmpty: nil
|
||||||
|
of nkLambdaKinds:
|
||||||
|
# XXX not correct, as we need to put it into the proper scope!
|
||||||
|
gen(p, n.sons[namePos], r)
|
||||||
of nkMetaNode: gen(p, n.sons[0], r)
|
of nkMetaNode: gen(p, n.sons[0], r)
|
||||||
of nkType: r.res = genTypeInfo(p, n.typ)
|
of nkType: r.res = genTypeInfo(p, n.typ)
|
||||||
else: InternalError(n.info, "gen: unknown node type: " & $n.kind)
|
else: InternalError(n.info, "gen: unknown node type: " & $n.kind)
|
||||||
|
|
@ -1467,14 +1515,23 @@ proc myProcess(b: PPassContext, n: PNode): PNode =
|
||||||
if m.module == nil: InternalError(n.info, "myProcess")
|
if m.module == nil: InternalError(n.info, "myProcess")
|
||||||
initProc(p, globals, m, nil, m.module.options)
|
initProc(p, globals, m, nil, m.module.options)
|
||||||
genModule(p, n, r)
|
genModule(p, n, r)
|
||||||
app(p.globals.code, p.data)
|
app(p.g.code, p.data)
|
||||||
app(p.globals.code, mergeStmt(r))
|
app(p.g.code, mergeStmt(r))
|
||||||
|
|
||||||
proc myClose(b: PPassContext, n: PNode): PNode =
|
proc myClose(b: PPassContext, n: PNode): PNode =
|
||||||
if passes.skipCodegen(n): return n
|
if passes.skipCodegen(n): return n
|
||||||
result = myProcess(b, n)
|
result = myProcess(b, n)
|
||||||
var m = BModule(b)
|
var m = BModule(b)
|
||||||
if sfMainModule in m.module.flags:
|
if sfMainModule in m.module.flags:
|
||||||
|
for prc in globals.forwarded:
|
||||||
|
if not globals.generatedSyms.containsOrIncl(prc.id):
|
||||||
|
var
|
||||||
|
p: TProc
|
||||||
|
r: TCompRes
|
||||||
|
initProc(p, globals, m, nil, m.module.options)
|
||||||
|
genProc(p, prc, r)
|
||||||
|
app(p.g.code, mergeStmt(r))
|
||||||
|
|
||||||
var disp = generateMethodDispatchers()
|
var disp = generateMethodDispatchers()
|
||||||
for i in 0..sonsLen(disp)-1:
|
for i in 0..sonsLen(disp)-1:
|
||||||
var
|
var
|
||||||
|
|
@ -1482,7 +1539,7 @@ proc myClose(b: PPassContext, n: PNode): PNode =
|
||||||
r: TCompRes
|
r: TCompRes
|
||||||
initProc(p, globals, m, nil, m.module.options)
|
initProc(p, globals, m, nil, m.module.options)
|
||||||
genProc(p, disp.sons[i].sym, r)
|
genProc(p, disp.sons[i].sym, r)
|
||||||
app(p.globals.code, mergeStmt(r))
|
app(p.g.code, mergeStmt(r))
|
||||||
|
|
||||||
# write the file:
|
# write the file:
|
||||||
var code = con(globals.typeInfo, globals.code)
|
var code = con(globals.typeInfo, globals.code)
|
||||||
|
|
|
||||||
|
|
@ -510,6 +510,6 @@ proc liftLambdas(fn: PSym, body: PNode): PNode =
|
||||||
|
|
||||||
proc liftLambdas*(n: PNode): PNode =
|
proc liftLambdas*(n: PNode): PNode =
|
||||||
assert n.kind in procDefs
|
assert n.kind in procDefs
|
||||||
if gCmd == cmdCompileToEcmaScript: return n
|
|
||||||
var s = n.sons[namePos].sym
|
var s = n.sons[namePos].sym
|
||||||
|
if gCmd == cmdCompileToEcmaScript: return s.getBody
|
||||||
result = liftLambdas(s, s.getBody)
|
result = liftLambdas(s, s.getBody)
|
||||||
|
|
|
||||||
|
|
@ -246,7 +246,7 @@ const
|
||||||
errWrongNumberOfArguments: "wrong number of arguments",
|
errWrongNumberOfArguments: "wrong number of arguments",
|
||||||
errXCannotBePassedToProcVar: "\'$1\' cannot be passed to a procvar",
|
errXCannotBePassedToProcVar: "\'$1\' cannot be passed to a procvar",
|
||||||
errXCannotBeInParamDecl: "$1 cannot be declared in parameter declaration",
|
errXCannotBeInParamDecl: "$1 cannot be declared in parameter declaration",
|
||||||
errPragmaOnlyInHeaderOfProc: "pragmas are only in the header of a proc allowed",
|
errPragmaOnlyInHeaderOfProc: "pragmas are only allowed in the header of a proc",
|
||||||
errImplOfXNotAllowed: "implementation of \'$1\' is not allowed",
|
errImplOfXNotAllowed: "implementation of \'$1\' is not allowed",
|
||||||
errImplOfXexpected: "implementation of \'$1\' expected",
|
errImplOfXexpected: "implementation of \'$1\' expected",
|
||||||
errNoSymbolToBorrowFromFound: "no symbol to borrow from found",
|
errNoSymbolToBorrowFromFound: "no symbol to borrow from found",
|
||||||
|
|
@ -270,7 +270,7 @@ const
|
||||||
errInvalidParamKindX: "invalid param kind: \'$1\'",
|
errInvalidParamKindX: "invalid param kind: \'$1\'",
|
||||||
errDefaultArgumentInvalid: "default argument invalid",
|
errDefaultArgumentInvalid: "default argument invalid",
|
||||||
errNamedParamHasToBeIdent: "named parameter has to be an identifier",
|
errNamedParamHasToBeIdent: "named parameter has to be an identifier",
|
||||||
errNoReturnTypeForX: "no return type for $1 allowed",
|
errNoReturnTypeForX: "no return type allowed for $1",
|
||||||
errConvNeedsOneArg: "a type conversion needs exactly one argument",
|
errConvNeedsOneArg: "a type conversion needs exactly one argument",
|
||||||
errInvalidPragmaX: "invalid pragma: $1",
|
errInvalidPragmaX: "invalid pragma: $1",
|
||||||
errXNotAllowedHere: "$1 not allowed here",
|
errXNotAllowedHere: "$1 not allowed here",
|
||||||
|
|
|
||||||
|
|
@ -444,7 +444,7 @@ proc unescape*(uri: cstring): cstring {.importc, nodecl.}
|
||||||
|
|
||||||
proc decodeURIComponent*(uri: cstring): cstring {.importc, nodecl.}
|
proc decodeURIComponent*(uri: cstring): cstring {.importc, nodecl.}
|
||||||
proc encodeURIComponent*(uri: cstring): cstring {.importc, nodecl.}
|
proc encodeURIComponent*(uri: cstring): cstring {.importc, nodecl.}
|
||||||
proc isFinite(x: biggestFloat): bool {.importc, nodecl.}
|
proc isFinite*(x: biggestFloat): bool {.importc, nodecl.}
|
||||||
proc isNaN(x: biggestFloat): bool {.importc, nodecl.}
|
proc isNaN*(x: biggestFloat): bool {.importc, nodecl.}
|
||||||
proc parseFloat(s: cstring): biggestFloat {.importc, nodecl.}
|
proc parseFloat*(s: cstring): biggestFloat {.importc, nodecl.}
|
||||||
proc parseInt(s: cstring): int {.importc, nodecl.}
|
proc parseInt*(s: cstring): int {.importc, nodecl.}
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,10 @@ proc raiseException(e: ref E_Base, ename: cstring) {.
|
||||||
if excHandler != nil:
|
if excHandler != nil:
|
||||||
excHandler.exc = e
|
excHandler.exc = e
|
||||||
else:
|
else:
|
||||||
var buf = rawWriteStackTrace()
|
when nimrodStackTrace:
|
||||||
|
var buf = rawWriteStackTrace()
|
||||||
|
else:
|
||||||
|
var buf = ""
|
||||||
if e.msg != nil and e.msg[0] != '\0':
|
if e.msg != nil and e.msg[0] != '\0':
|
||||||
add(buf, "Error: unhandled exception: ")
|
add(buf, "Error: unhandled exception: ")
|
||||||
add(buf, e.msg)
|
add(buf, e.msg)
|
||||||
|
|
@ -388,6 +391,76 @@ proc modInt64(a, b: int): int {.noStackFrame, compilerproc.} =
|
||||||
return Math.floor(`a` % `b`);
|
return Math.floor(`a` % `b`);
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
proc NegInt(a: int): int {.compilerproc.} =
|
||||||
|
result = a*(-1)
|
||||||
|
|
||||||
|
proc NegInt64(a: int64): int64 {.compilerproc.} =
|
||||||
|
result = a*(-1)
|
||||||
|
|
||||||
|
proc AbsInt(a: int): int {.compilerproc.} =
|
||||||
|
result = if a < 0: a*(-1) else: a
|
||||||
|
|
||||||
|
proc AbsInt64(a: int64): int64 {.compilerproc.} =
|
||||||
|
result = if a < 0: a*(-1) else: a
|
||||||
|
|
||||||
|
proc LeU(a, b: int): bool {.compilerproc.} =
|
||||||
|
result = abs(a) <= abs(b)
|
||||||
|
|
||||||
|
proc LtU(a, b: int): bool {.compilerproc.} =
|
||||||
|
result = abs(a) < abs(b)
|
||||||
|
|
||||||
|
proc LeU64(a, b: int64): bool {.compilerproc.} =
|
||||||
|
result = abs(a) <= abs(b)
|
||||||
|
|
||||||
|
proc LtU64(a, b: int64): bool {.compilerproc.} =
|
||||||
|
result = abs(a) < abs(b)
|
||||||
|
|
||||||
|
proc AddU(a, b: int): int {.compilerproc.} =
|
||||||
|
result = abs(a) + abs(b)
|
||||||
|
proc AddU64(a, b: int64): int64 {.compilerproc.} =
|
||||||
|
result = abs(a) + abs(b)
|
||||||
|
|
||||||
|
proc SubU(a, b: int): int {.compilerproc.} =
|
||||||
|
result = abs(a) - abs(b)
|
||||||
|
proc SubU64(a, b: int64): int64 {.compilerproc.} =
|
||||||
|
result = abs(a) - abs(b)
|
||||||
|
|
||||||
|
proc MulU(a, b: int): int {.compilerproc.} =
|
||||||
|
result = abs(a) * abs(b)
|
||||||
|
proc MulU64(a, b: int64): int64 {.compilerproc.} =
|
||||||
|
result = abs(a) * abs(b)
|
||||||
|
|
||||||
|
proc DivU(a, b: int): int {.compilerproc.} =
|
||||||
|
result = abs(a) div abs(b)
|
||||||
|
proc DivU64(a, b: int64): int64 {.compilerproc.} =
|
||||||
|
result = abs(a) div abs(b)
|
||||||
|
|
||||||
|
proc ModU(a, b: int): int {.compilerproc.} =
|
||||||
|
result = abs(a) mod abs(b)
|
||||||
|
proc ModU64(a, b: int64): int64 {.compilerproc.} =
|
||||||
|
result = abs(a) mod abs(b)
|
||||||
|
|
||||||
|
proc Ze(a: int): int {.compilerproc.} =
|
||||||
|
result = a
|
||||||
|
proc Ze64(a: int64): int64 {.compilerproc.} =
|
||||||
|
result = a
|
||||||
|
|
||||||
|
proc toU8(a: int): int8 {.noStackFrame, compilerproc.} =
|
||||||
|
asm """
|
||||||
|
return `a`;
|
||||||
|
"""
|
||||||
|
|
||||||
|
proc toU16(a: int): int16 {.noStackFrame, compilerproc.} =
|
||||||
|
asm """
|
||||||
|
return `a`;
|
||||||
|
"""
|
||||||
|
|
||||||
|
proc toU32(a: int): int32 {.noStackFrame, compilerproc.} =
|
||||||
|
asm """
|
||||||
|
return `a`;
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
proc nimMin(a, b: int): int {.compilerproc.} = return if a <= b: a else: b
|
proc nimMin(a, b: int): int {.compilerproc.} = return if a <= b: a else: b
|
||||||
proc nimMax(a, b: int): int {.compilerproc.} = return if a >= b: a else: b
|
proc nimMax(a, b: int): int {.compilerproc.} = return if a >= b: a else: b
|
||||||
|
|
||||||
|
|
@ -480,28 +553,3 @@ proc chckObj(obj, subclass: PNimType) {.compilerproc.} =
|
||||||
x = x.base
|
x = x.base
|
||||||
|
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
#proc AddU($1, $2)
|
|
||||||
#SubU($1, $2)
|
|
||||||
#MulU($1, $2)
|
|
||||||
#DivU($1, $2)
|
|
||||||
#ModU($1, $2)
|
|
||||||
#AddU64($1, $2)
|
|
||||||
#SubU64($1, $2)
|
|
||||||
#MulU64($1, $2)
|
|
||||||
#DivU64($1, $2)
|
|
||||||
#ModU64($1, $2)
|
|
||||||
#LeU($1, $2)
|
|
||||||
#LtU($1, $2)
|
|
||||||
#LeU64($1, $2)
|
|
||||||
#LtU64($1, $2)
|
|
||||||
#Ze($1)
|
|
||||||
#Ze64($1)
|
|
||||||
#ToU8($1)
|
|
||||||
#ToU16($1)
|
|
||||||
#ToU32($1)
|
|
||||||
|
|
||||||
#NegInt($1)
|
|
||||||
#NegInt64($1)
|
|
||||||
#AbsInt($1)
|
|
||||||
#AbsInt64($1)
|
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,12 @@ var
|
||||||
inputElement {.importc: "document.form1.input1", nodecl.}: ref TElement
|
inputElement {.importc: "document.form1.input1", nodecl.}: ref TElement
|
||||||
|
|
||||||
proc OnButtonClick() {.exportc.} =
|
proc OnButtonClick() {.exportc.} =
|
||||||
var x = parseInt($inputElement.value)
|
let v = $inputElement.value
|
||||||
echo x*x
|
if v.allCharsInSet(whiteSpace):
|
||||||
|
echo "only whitespace, hu?"
|
||||||
|
else:
|
||||||
|
var x = parseInt(v)
|
||||||
|
echo x*x
|
||||||
|
|
||||||
proc OnLoad() {.exportc.} =
|
proc OnLoad() {.exportc.} =
|
||||||
echo "Welcome! Please take your time to fill in this formular!"
|
echo "Welcome! Please take your time to fill in this formular!"
|
||||||
|
|
|
||||||
6
todo.txt
6
todo.txt
|
|
@ -7,6 +7,7 @@ Debug GC session:
|
||||||
New pragmas:
|
New pragmas:
|
||||||
- ``hoist`` pragma for loop hoisting
|
- ``hoist`` pragma for loop hoisting
|
||||||
- test & document ``byCopy`` pragma
|
- test & document ``byCopy`` pragma
|
||||||
|
- document destructors
|
||||||
|
|
||||||
- ``borrow`` needs to take type classes into account
|
- ``borrow`` needs to take type classes into account
|
||||||
- make templates hygienic by default: try to gensym() everything in the 'block'
|
- make templates hygienic by default: try to gensym() everything in the 'block'
|
||||||
|
|
@ -50,8 +51,7 @@ version 0.9.XX
|
||||||
- implicit ref/ptr->var conversion; the compiler may store an object
|
- implicit ref/ptr->var conversion; the compiler may store an object
|
||||||
implicitly on the heap for write barrier efficiency; better:
|
implicitly on the heap for write barrier efficiency; better:
|
||||||
proc specialization in the code gen
|
proc specialization in the code gen
|
||||||
- EcmaScript needs a new and better code gen: simply adapt the C code gen to it
|
- 'of' operator for JS backend
|
||||||
- dead code elim for JS backend; 'of' operator for JS backend
|
|
||||||
- tlastmod returns wrong results on BSD (Linux, MacOS X: works)
|
- tlastmod returns wrong results on BSD (Linux, MacOS X: works)
|
||||||
- nested tuple unpacking; tuple unpacking in non-var-context
|
- nested tuple unpacking; tuple unpacking in non-var-context
|
||||||
- 'nimrod def': does not always work?
|
- 'nimrod def': does not always work?
|
||||||
|
|
@ -104,7 +104,7 @@ Low priority
|
||||||
- change how comments are part of the AST
|
- change how comments are part of the AST
|
||||||
- ``with proc `+`(x, y: T): T`` for generic code
|
- ``with proc `+`(x, y: T): T`` for generic code
|
||||||
- new feature: ``distinct T with operations``
|
- new feature: ``distinct T with operations``
|
||||||
- implement the "easy" constructors idea; document destructors
|
- implement the "easy" constructors idea
|
||||||
- code generated for type information is wasteful
|
- code generated for type information is wasteful
|
||||||
- resizing of strings/sequences could take into account the memory that
|
- resizing of strings/sequences could take into account the memory that
|
||||||
is allocated
|
is allocated
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue