variable dynamic lib names
This commit is contained in:
parent
3b7ef2288f
commit
7063670a2c
14 changed files with 504 additions and 766 deletions
|
|
@ -145,12 +145,12 @@ type
|
||||||
E_Base* {.compilerproc.} = object of TObject ## base exception class;
|
E_Base* {.compilerproc.} = object of TObject ## base exception class;
|
||||||
## each exception has to
|
## each exception has to
|
||||||
## inherit from `E_Base`.
|
## inherit from `E_Base`.
|
||||||
name*: cstring ## The exception's name is its Nimrod identifier.
|
name: cstring ## The exception's name is its Nimrod identifier.
|
||||||
## This field is filled automatically in the
|
## This field is filled automatically in the
|
||||||
## ``raise`` statement.
|
## ``raise`` statement.
|
||||||
msg* {.exportc: "message".}: cstring ## the exception's message. Not
|
msg* {.exportc: "message".}: string ## the exception's message. Not
|
||||||
## providing an
|
## providing an exception message
|
||||||
## exception message is bad style.
|
## is bad style.
|
||||||
|
|
||||||
EAsynch* = object of E_Base ## Abstract exception class for
|
EAsynch* = object of E_Base ## Abstract exception class for
|
||||||
## *asynchronous exceptions* (interrupts).
|
## *asynchronous exceptions* (interrupts).
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,8 @@ when defined(MACOSX):
|
||||||
LUA_LIB_NAME* = "liblua(|5.2|5.1|5.0).dylib"
|
LUA_LIB_NAME* = "liblua(|5.2|5.1|5.0).dylib"
|
||||||
elif defined(UNIX):
|
elif defined(UNIX):
|
||||||
const
|
const
|
||||||
LUA_NAME* = "liblua(|5.2|5.1|5.0).so.(|0)"
|
LUA_NAME* = "liblua(|5.2|5.1|5.0).so(|.0)"
|
||||||
LUA_LIB_NAME* = "liblua(|5.2|5.1|5.0).so.(|0)"
|
LUA_LIB_NAME* = "liblua(|5.2|5.1|5.0).so(|.0)"
|
||||||
else:
|
else:
|
||||||
const
|
const
|
||||||
LUA_NAME* = "lua(|5.2|5.1|5.0).dll"
|
LUA_NAME* = "lua(|5.2|5.1|5.0).dll"
|
||||||
|
|
|
||||||
32
rod/ast.nim
32
rod/ast.nim
|
|
@ -409,7 +409,8 @@ type
|
||||||
kind*: TLibKind
|
kind*: TLibKind
|
||||||
generated*: bool # needed for the backends:
|
generated*: bool # needed for the backends:
|
||||||
name*: PRope
|
name*: PRope
|
||||||
path*: string
|
path*: PNode # can be a string literal!
|
||||||
|
|
||||||
|
|
||||||
PLib* = ref TLib
|
PLib* = ref TLib
|
||||||
TSym* = object of TIdObj
|
TSym* = object of TIdObj
|
||||||
|
|
@ -949,6 +950,35 @@ proc sonsNotNil(n: PNode): bool =
|
||||||
proc addSonIfNotNil(father, n: PNode) =
|
proc addSonIfNotNil(father, n: PNode) =
|
||||||
if n != nil: addSon(father, n)
|
if n != nil: addSon(father, n)
|
||||||
|
|
||||||
|
proc getInt*(a: PNode): biggestInt =
|
||||||
|
case a.kind
|
||||||
|
of nkIntLit..nkInt64Lit: result = a.intVal
|
||||||
|
else:
|
||||||
|
internalError(a.info, "getInt")
|
||||||
|
result = 0
|
||||||
|
|
||||||
|
proc getFloat*(a: PNode): biggestFloat =
|
||||||
|
case a.kind
|
||||||
|
of nkFloatLit..nkFloat64Lit: result = a.floatVal
|
||||||
|
else:
|
||||||
|
internalError(a.info, "getFloat")
|
||||||
|
result = 0.0
|
||||||
|
|
||||||
|
proc getStr*(a: PNode): string =
|
||||||
|
case a.kind
|
||||||
|
of nkStrLit..nkTripleStrLit: result = a.strVal
|
||||||
|
else:
|
||||||
|
internalError(a.info, "getStr")
|
||||||
|
result = ""
|
||||||
|
|
||||||
|
proc getStrOrChar*(a: PNode): string =
|
||||||
|
case a.kind
|
||||||
|
of nkStrLit..nkTripleStrLit: result = a.strVal
|
||||||
|
of nkCharLit: result = chr(int(a.intVal)) & ""
|
||||||
|
else:
|
||||||
|
internalError(a.info, "getStrOrChar")
|
||||||
|
result = ""
|
||||||
|
|
||||||
proc mustRehash(length, counter: int): bool =
|
proc mustRehash(length, counter: int): bool =
|
||||||
assert(length > counter)
|
assert(length > counter)
|
||||||
result = (length * 2 < counter * 3) or (length - counter < 4)
|
result = (length * 2 < counter * 3) or (length - counter < 4)
|
||||||
|
|
|
||||||
|
|
@ -219,8 +219,7 @@ proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||||
proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||||
# This function replaces all other methods for generating
|
# This function replaces all other methods for generating
|
||||||
# the assignment operation in C.
|
# the assignment operation in C.
|
||||||
var ty: PType
|
var ty = skipTypes(dest.t, abstractVarRange)
|
||||||
ty = skipTypes(dest.t, abstractVarRange)
|
|
||||||
case ty.kind
|
case ty.kind
|
||||||
of tyRef:
|
of tyRef:
|
||||||
genRefAssign(p, dest, src, flags)
|
genRefAssign(p, dest, src, flags)
|
||||||
|
|
|
||||||
44
rod/cgen.nim
44
rod/cgen.nim
|
|
@ -164,11 +164,11 @@ proc isSimpleConst(typ: PType): bool =
|
||||||
proc useHeader(m: BModule, sym: PSym) =
|
proc useHeader(m: BModule, sym: PSym) =
|
||||||
if lfHeader in sym.loc.Flags:
|
if lfHeader in sym.loc.Flags:
|
||||||
assert(sym.annex != nil)
|
assert(sym.annex != nil)
|
||||||
discard lists.IncludeStr(m.headerFiles, sym.annex.path)
|
discard lists.IncludeStr(m.headerFiles, getStr(sym.annex.path))
|
||||||
|
|
||||||
proc UseMagic(m: BModule, name: string)
|
proc UseMagic(m: BModule, name: string)
|
||||||
include
|
|
||||||
"ccgtypes.nim"
|
include "ccgtypes.nim"
|
||||||
|
|
||||||
# ------------------------------ Manager of temporaries ------------------
|
# ------------------------------ Manager of temporaries ------------------
|
||||||
|
|
||||||
|
|
@ -333,32 +333,36 @@ proc libCandidates(s: string, dest: var TStringSeq) =
|
||||||
add(dest, s)
|
add(dest, s)
|
||||||
|
|
||||||
proc loadDynamicLib(m: BModule, lib: PLib) =
|
proc loadDynamicLib(m: BModule, lib: PLib) =
|
||||||
var
|
|
||||||
tmp, loadlib: PRope
|
|
||||||
s: TStringSeq
|
|
||||||
assert(lib != nil)
|
assert(lib != nil)
|
||||||
if not lib.generated:
|
if not lib.generated:
|
||||||
lib.generated = true
|
lib.generated = true
|
||||||
tmp = getGlobalTempName()
|
var tmp = getGlobalTempName()
|
||||||
assert(lib.name == nil)
|
assert(lib.name == nil)
|
||||||
lib.name = tmp # BUGFIX: useMagic has awful side-effects
|
lib.name = tmp # BUGFIX: useMagic has awful side-effects
|
||||||
appff(m.s[cfsVars], "static void* $1;$n",
|
appf(m.s[cfsVars], "static void* $1;$n", [tmp])
|
||||||
"$1 = linkonce global i8* zeroinitializer$n", [tmp])
|
if lib.path.kind in {nkStrLit..nkTripleStrLit}:
|
||||||
s = @[]
|
var s: TStringSeq = @[]
|
||||||
libCandidates(lib.path, s)
|
libCandidates(lib.path.strVal, s)
|
||||||
loadlib = nil
|
var loadlib: PRope = nil
|
||||||
for i in countup(0, high(s)):
|
for i in countup(0, high(s)):
|
||||||
inc(m.labels)
|
inc(m.labels)
|
||||||
if i > 0: app(loadlib, "||")
|
if i > 0: app(loadlib, "||")
|
||||||
appff(loadlib, "($1 = nimLoadLibrary((NimStringDesc*) &$2))$n",
|
appf(loadlib, "($1 = nimLoadLibrary((NimStringDesc*) &$2))$n",
|
||||||
"%MOC$4 = call i8* @nimLoadLibrary($3 $2)$n" &
|
[tmp, getStrLit(m, s[i])])
|
||||||
"store i8* %MOC$4, i8** $1$n", [tmp, getStrLit(m, s[i]),
|
appf(m.s[cfsDynLibInit],
|
||||||
getTypeDesc(m, getSysType(tyString)), toRope(m.labels)])
|
|
||||||
appff(m.s[cfsDynLibInit],
|
|
||||||
"if (!($1)) nimLoadLibraryError((NimStringDesc*) &$2);$n",
|
"if (!($1)) nimLoadLibraryError((NimStringDesc*) &$2);$n",
|
||||||
"XXX too implement", [loadlib, getStrLit(m, lib.path)])
|
[loadlib, getStrLit(m, lib.path.strVal)])
|
||||||
#appf(m.s[cfsDynLibDeinit], "if ($1 != NIM_NIL) nimUnloadLibrary($1);$n",
|
else:
|
||||||
# [tmp])
|
var p = newProc(nil, m)
|
||||||
|
var dest: TLoc
|
||||||
|
initLocExpr(p, lib.path, dest)
|
||||||
|
app(m.s[cfsVars], p.s[cpsLocals])
|
||||||
|
app(m.s[cfsDynLibInit], p.s[cpsInit])
|
||||||
|
app(m.s[cfsDynLibInit], p.s[cpsStmts])
|
||||||
|
appf(m.s[cfsDynLibInit],
|
||||||
|
"if (!($1 = nimLoadLibrary($2))) nimLoadLibraryError($2);$n",
|
||||||
|
[tmp, rdLoc(dest)])
|
||||||
|
|
||||||
useMagic(m, "nimLoadLibrary")
|
useMagic(m, "nimLoadLibrary")
|
||||||
useMagic(m, "nimUnloadLibrary")
|
useMagic(m, "nimUnloadLibrary")
|
||||||
useMagic(m, "NimStringDesc")
|
useMagic(m, "NimStringDesc")
|
||||||
|
|
|
||||||
233
rod/evals.nim
233
rod/evals.nim
|
|
@ -54,9 +54,10 @@ var emptyNode: PNode
|
||||||
proc newStackFrame(): PStackFrame =
|
proc newStackFrame(): PStackFrame =
|
||||||
new(result)
|
new(result)
|
||||||
initIdNodeTable(result.mapping)
|
initIdNodeTable(result.mapping)
|
||||||
result.params = @ []
|
result.params = @[]
|
||||||
|
|
||||||
proc newEvalContext(module: PSym, filename: string, optEval: bool): PEvalContext =
|
proc newEvalContext(module: PSym, filename: string,
|
||||||
|
optEval: bool): PEvalContext =
|
||||||
new(result)
|
new(result)
|
||||||
result.module = module
|
result.module = module
|
||||||
result.optEval = optEval
|
result.optEval = optEval
|
||||||
|
|
@ -70,6 +71,7 @@ proc popStackFrame(c: PEvalContext) =
|
||||||
c.tos = c.tos.next
|
c.tos = c.tos.next
|
||||||
|
|
||||||
proc evalAux(c: PEvalContext, n: PNode): PNode
|
proc evalAux(c: PEvalContext, n: PNode): PNode
|
||||||
|
|
||||||
proc stackTraceAux(x: PStackFrame) =
|
proc stackTraceAux(x: PStackFrame) =
|
||||||
if x != nil:
|
if x != nil:
|
||||||
stackTraceAux(x.next)
|
stackTraceAux(x.next)
|
||||||
|
|
@ -85,9 +87,8 @@ proc isSpecial(n: PNode): bool =
|
||||||
result = (n.kind == nkExceptBranch) or (n.kind == nkEmpty)
|
result = (n.kind == nkExceptBranch) or (n.kind == nkEmpty)
|
||||||
|
|
||||||
proc evalIf(c: PEvalContext, n: PNode): PNode =
|
proc evalIf(c: PEvalContext, n: PNode): PNode =
|
||||||
var i, length: int
|
var i = 0
|
||||||
i = 0
|
var length = sonsLen(n)
|
||||||
length = sonsLen(n)
|
|
||||||
while (i < length) and (sonsLen(n.sons[i]) >= 2):
|
while (i < length) and (sonsLen(n.sons[i]) >= 2):
|
||||||
result = evalAux(c, n.sons[i].sons[0])
|
result = evalAux(c, n.sons[i].sons[0])
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
|
|
@ -100,10 +101,9 @@ proc evalIf(c: PEvalContext, n: PNode): PNode =
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
|
|
||||||
proc evalCase(c: PEvalContext, n: PNode): PNode =
|
proc evalCase(c: PEvalContext, n: PNode): PNode =
|
||||||
var res: PNode
|
|
||||||
result = evalAux(c, n.sons[0])
|
result = evalAux(c, n.sons[0])
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
res = result
|
var res = result
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
for i in countup(1, sonsLen(n) - 1):
|
for i in countup(1, sonsLen(n) - 1):
|
||||||
if n.sons[i].kind == nkOfBranch:
|
if n.sons[i].kind == nkOfBranch:
|
||||||
|
|
@ -152,8 +152,7 @@ proc evalBlock(c: PEvalContext, n: PNode): PNode =
|
||||||
result = emptyNode # consume ``break`` token
|
result = emptyNode # consume ``break`` token
|
||||||
|
|
||||||
proc evalFinally(c: PEvalContext, n, exc: PNode): PNode =
|
proc evalFinally(c: PEvalContext, n, exc: PNode): PNode =
|
||||||
var finallyNode: PNode
|
var finallyNode = lastSon(n)
|
||||||
finallyNode = lastSon(n)
|
|
||||||
if finallyNode.kind == nkFinally:
|
if finallyNode.kind == nkFinally:
|
||||||
result = evalAux(c, finallyNode)
|
result = evalAux(c, finallyNode)
|
||||||
if result.kind != nkExceptBranch: result = exc
|
if result.kind != nkExceptBranch: result = exc
|
||||||
|
|
@ -161,9 +160,6 @@ proc evalFinally(c: PEvalContext, n, exc: PNode): PNode =
|
||||||
result = exc
|
result = exc
|
||||||
|
|
||||||
proc evalTry(c: PEvalContext, n: PNode): PNode =
|
proc evalTry(c: PEvalContext, n: PNode): PNode =
|
||||||
var
|
|
||||||
exc: PNode
|
|
||||||
i, length, blen: int
|
|
||||||
result = evalAux(c, n.sons[0])
|
result = evalAux(c, n.sons[0])
|
||||||
case result.kind
|
case result.kind
|
||||||
of nkBreakStmt, nkReturnToken:
|
of nkBreakStmt, nkReturnToken:
|
||||||
|
|
@ -172,11 +168,11 @@ proc evalTry(c: PEvalContext, n: PNode): PNode =
|
||||||
if sonsLen(result) >= 1:
|
if sonsLen(result) >= 1:
|
||||||
# creating a nkExceptBranch without sons means that it could not be
|
# creating a nkExceptBranch without sons means that it could not be
|
||||||
# evaluated
|
# evaluated
|
||||||
exc = result
|
var exc = result
|
||||||
i = 1
|
var i = 1
|
||||||
length = sonsLen(n)
|
var length = sonsLen(n)
|
||||||
while (i < length) and (n.sons[i].kind == nkExceptBranch):
|
while (i < length) and (n.sons[i].kind == nkExceptBranch):
|
||||||
blen = sonsLen(n.sons[i])
|
var blen = sonsLen(n.sons[i])
|
||||||
if blen == 1:
|
if blen == 1:
|
||||||
# general except section:
|
# general except section:
|
||||||
result = evalAux(c, n.sons[i].sons[0])
|
result = evalAux(c, n.sons[i].sons[0])
|
||||||
|
|
@ -194,8 +190,7 @@ proc evalTry(c: PEvalContext, n: PNode): PNode =
|
||||||
else: result = evalFinally(c, n, emptyNode)
|
else: result = evalFinally(c, n, emptyNode)
|
||||||
|
|
||||||
proc getNullValue(typ: PType, info: TLineInfo): PNode =
|
proc getNullValue(typ: PType, info: TLineInfo): PNode =
|
||||||
var t: PType
|
var t = skipTypes(typ, abstractRange)
|
||||||
t = skipTypes(typ, abstractRange)
|
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyBool, tyChar, tyInt..tyInt64:
|
of tyBool, tyChar, tyInt..tyInt64:
|
||||||
|
|
@ -219,15 +214,12 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
|
||||||
else: InternalError("getNullValue")
|
else: InternalError("getNullValue")
|
||||||
|
|
||||||
proc evalVar(c: PEvalContext, n: PNode): PNode =
|
proc evalVar(c: PEvalContext, n: PNode): PNode =
|
||||||
var
|
|
||||||
v: PSym
|
|
||||||
a: PNode
|
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
a = n.sons[i]
|
var a = n.sons[i]
|
||||||
if a.kind == nkCommentStmt: continue
|
if a.kind == nkCommentStmt: continue
|
||||||
assert(a.kind == nkIdentDefs)
|
assert(a.kind == nkIdentDefs)
|
||||||
assert(a.sons[0].kind == nkSym)
|
assert(a.sons[0].kind == nkSym)
|
||||||
v = a.sons[0].sym
|
var v = a.sons[0].sym
|
||||||
if a.sons[2] != nil:
|
if a.sons[2] != nil:
|
||||||
result = evalAux(c, a.sons[2])
|
result = evalAux(c, a.sons[2])
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
|
|
@ -237,14 +229,11 @@ proc evalVar(c: PEvalContext, n: PNode): PNode =
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
|
|
||||||
proc evalCall(c: PEvalContext, n: PNode): PNode =
|
proc evalCall(c: PEvalContext, n: PNode): PNode =
|
||||||
var
|
|
||||||
d: PStackFrame
|
|
||||||
prc: PNode
|
|
||||||
result = evalAux(c, n.sons[0])
|
result = evalAux(c, n.sons[0])
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
prc = result # bind the actual params to the local parameter
|
var prc = result
|
||||||
# of a new binding
|
# bind the actual params to the local parameter of a new binding
|
||||||
d = newStackFrame()
|
var d = newStackFrame()
|
||||||
d.call = n
|
d.call = n
|
||||||
if prc.kind == nkSym:
|
if prc.kind == nkSym:
|
||||||
d.prc = prc.sym
|
d.prc = prc.sym
|
||||||
|
|
@ -265,8 +254,7 @@ proc evalCall(c: PEvalContext, n: PNode): PNode =
|
||||||
proc evalVariable(c: PStackFrame, sym: PSym): PNode =
|
proc evalVariable(c: PStackFrame, sym: PSym): PNode =
|
||||||
# We need to return a node to the actual value,
|
# We need to return a node to the actual value,
|
||||||
# which can be modified.
|
# which can be modified.
|
||||||
var x: PStackFrame
|
var x = c
|
||||||
x = c
|
|
||||||
while x != nil:
|
while x != nil:
|
||||||
if sfResult in sym.flags:
|
if sfResult in sym.flags:
|
||||||
return x.params[0]
|
return x.params[0]
|
||||||
|
|
@ -276,15 +264,12 @@ proc evalVariable(c: PStackFrame, sym: PSym): PNode =
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
|
|
||||||
proc evalArrayAccess(c: PEvalContext, n: PNode): PNode =
|
proc evalArrayAccess(c: PEvalContext, n: PNode): PNode =
|
||||||
var
|
|
||||||
x: PNode
|
|
||||||
idx: biggestInt
|
|
||||||
result = evalAux(c, n.sons[0])
|
result = evalAux(c, n.sons[0])
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
x = result
|
var x = result
|
||||||
result = evalAux(c, n.sons[1])
|
result = evalAux(c, n.sons[1])
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
idx = getOrdValue(result)
|
var idx = getOrdValue(result)
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
case x.kind
|
case x.kind
|
||||||
of nkBracket, nkPar, nkMetaNode:
|
of nkBracket, nkPar, nkMetaNode:
|
||||||
|
|
@ -436,15 +421,14 @@ proc evalAnd(c: PEvalContext, n: PNode): PNode =
|
||||||
if result.intVal != 0: result = evalAux(c, n.sons[2])
|
if result.intVal != 0: result = evalAux(c, n.sons[2])
|
||||||
|
|
||||||
proc evalNoOpt(c: PEvalContext, n: PNode): PNode =
|
proc evalNoOpt(c: PEvalContext, n: PNode): PNode =
|
||||||
result = newNodeI(nkExceptBranch, n.info) # creating a nkExceptBranch without sons means that it could not be
|
result = newNodeI(nkExceptBranch, n.info)
|
||||||
# evaluated
|
# creating a nkExceptBranch without sons means that it could not be evaluated
|
||||||
|
|
||||||
proc evalNew(c: PEvalContext, n: PNode): PNode =
|
proc evalNew(c: PEvalContext, n: PNode): PNode =
|
||||||
var t: PType
|
|
||||||
if c.optEval:
|
if c.optEval:
|
||||||
result = evalNoOpt(c, n)
|
result = evalNoOpt(c, n)
|
||||||
else:
|
else:
|
||||||
t = skipTypes(n.sons[1].typ, abstractVar)
|
var t = skipTypes(n.sons[1].typ, abstractVar)
|
||||||
result = newNodeIT(nkRefTy, n.info, t)
|
result = newNodeIT(nkRefTy, n.info, t)
|
||||||
addSon(result, getNullValue(t.sons[0], n.info))
|
addSon(result, getNullValue(t.sons[0], n.info))
|
||||||
|
|
||||||
|
|
@ -457,13 +441,10 @@ proc evalDeref(c: PEvalContext, n: PNode): PNode =
|
||||||
else: InternalError(n.info, "evalDeref " & $result.kind)
|
else: InternalError(n.info, "evalDeref " & $result.kind)
|
||||||
|
|
||||||
proc evalAddr(c: PEvalContext, n: PNode): PNode =
|
proc evalAddr(c: PEvalContext, n: PNode): PNode =
|
||||||
var
|
|
||||||
a: PNode
|
|
||||||
t: PType
|
|
||||||
result = evalAux(c, n.sons[0])
|
result = evalAux(c, n.sons[0])
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
a = result
|
var a = result
|
||||||
t = newType(tyPtr, c.module)
|
var t = newType(tyPtr, c.module)
|
||||||
addSon(t, a.typ)
|
addSon(t, a.typ)
|
||||||
result = newNodeIT(nkRefTy, n.info, t)
|
result = newNodeIT(nkRefTy, n.info, t)
|
||||||
addSon(result, a)
|
addSon(result, a)
|
||||||
|
|
@ -477,11 +458,10 @@ proc evalCheckedFieldAccess(c: PEvalContext, n: PNode): PNode =
|
||||||
result = evalAux(c, n.sons[0])
|
result = evalAux(c, n.sons[0])
|
||||||
|
|
||||||
proc evalUpConv(c: PEvalContext, n: PNode): PNode =
|
proc evalUpConv(c: PEvalContext, n: PNode): PNode =
|
||||||
var dest, src: PType
|
|
||||||
result = evalAux(c, n.sons[0])
|
result = evalAux(c, n.sons[0])
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
dest = skipTypes(n.typ, abstractPtrs)
|
var dest = skipTypes(n.typ, abstractPtrs)
|
||||||
src = skipTypes(result.typ, abstractPtrs)
|
var src = skipTypes(result.typ, abstractPtrs)
|
||||||
if inheritanceDiff(src, dest) > 0:
|
if inheritanceDiff(src, dest) > 0:
|
||||||
stackTrace(c, n, errInvalidConversionFromTypeX, typeToString(src))
|
stackTrace(c, n, errInvalidConversionFromTypeX, typeToString(src))
|
||||||
|
|
||||||
|
|
@ -710,48 +690,27 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
k: biggestInt
|
k: biggestInt
|
||||||
m = getMagic(n)
|
m = getMagic(n)
|
||||||
case m
|
case m
|
||||||
of mNone:
|
of mNone: result = evalCall(c, n)
|
||||||
result = evalCall(c, n)
|
of mIs: result = evalIs(c, n)
|
||||||
of mIs:
|
of mSizeOf: internalError(n.info, "sizeof() should have been evaluated")
|
||||||
result = evalIs(c, n)
|
of mHigh: result = evalHigh(c, n)
|
||||||
of mSizeOf:
|
of mAssert: result = evalAssert(c, n)
|
||||||
internalError(n.info, "sizeof() should have been evaluated")
|
of mExit: result = evalExit(c, n)
|
||||||
of mHigh:
|
of mNew, mNewFinalize: result = evalNew(c, n)
|
||||||
result = evalHigh(c, n)
|
of mNewSeq: result = evalNewSeq(c, n)
|
||||||
of mAssert:
|
of mSwap: result = evalSwap(c, n)
|
||||||
result = evalAssert(c, n)
|
of mInc: result = evalIncDec(c, n, 1)
|
||||||
of mExit:
|
of ast.mDec: result = evalIncDec(c, n, - 1)
|
||||||
result = evalExit(c, n)
|
of mEcho: result = evalEcho(c, n)
|
||||||
of mNew, mNewFinalize:
|
of mSetLengthStr: result = evalSetLengthStr(c, n)
|
||||||
result = evalNew(c, n)
|
of mSetLengthSeq: result = evalSetLengthSeq(c, n)
|
||||||
of mNewSeq:
|
of mIncl: result = evalIncl(c, n)
|
||||||
result = evalNewSeq(c, n)
|
of mExcl: result = evalExcl(c, n)
|
||||||
of mSwap:
|
of mAnd: result = evalAnd(c, n)
|
||||||
result = evalSwap(c, n)
|
of mOr: result = evalOr(c, n)
|
||||||
of mInc:
|
of mAppendStrCh: result = evalAppendStrCh(c, n)
|
||||||
result = evalIncDec(c, n, 1)
|
of mAppendStrStr: result = evalAppendStrStr(c, n)
|
||||||
of ast.mDec:
|
of mAppendSeqElem: result = evalAppendSeqElem(c, n)
|
||||||
result = evalIncDec(c, n, - 1)
|
|
||||||
of mEcho:
|
|
||||||
result = evalEcho(c, n)
|
|
||||||
of mSetLengthStr:
|
|
||||||
result = evalSetLengthStr(c, n)
|
|
||||||
of mSetLengthSeq:
|
|
||||||
result = evalSetLengthSeq(c, n)
|
|
||||||
of mIncl:
|
|
||||||
result = evalIncl(c, n)
|
|
||||||
of mExcl:
|
|
||||||
result = evalExcl(c, n)
|
|
||||||
of mAnd:
|
|
||||||
result = evalAnd(c, n)
|
|
||||||
of mOr:
|
|
||||||
result = evalOr(c, n)
|
|
||||||
of mAppendStrCh:
|
|
||||||
result = evalAppendStrCh(c, n)
|
|
||||||
of mAppendStrStr:
|
|
||||||
result = evalAppendStrStr(c, n)
|
|
||||||
of mAppendSeqElem:
|
|
||||||
result = evalAppendSeqElem(c, n)
|
|
||||||
of mNLen:
|
of mNLen:
|
||||||
result = evalAux(c, n.sons[1])
|
result = evalAux(c, n.sons[1])
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
|
|
@ -848,8 +807,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
result = evalAux(c, n.sons[1])
|
result = evalAux(c, n.sons[1])
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
if result.kind != nkIdent: InternalError(n.info, "no symbol")
|
if result.kind != nkIdent: InternalError(n.info, "no symbol")
|
||||||
of mNGetType:
|
of mNGetType: result = evalAux(c, n.sons[1])
|
||||||
result = evalAux(c, n.sons[1])
|
|
||||||
of mNStrVal:
|
of mNStrVal:
|
||||||
result = evalAux(c, n.sons[1])
|
result = evalAux(c, n.sons[1])
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
|
|
@ -1009,14 +967,10 @@ proc evalAux(c: PEvalContext, n: PNode): PNode =
|
||||||
dec(gNestedEvals)
|
dec(gNestedEvals)
|
||||||
if gNestedEvals <= 0: stackTrace(c, n, errTooManyIterations)
|
if gNestedEvals <= 0: stackTrace(c, n, errTooManyIterations)
|
||||||
case n.kind # atoms:
|
case n.kind # atoms:
|
||||||
of nkEmpty:
|
of nkEmpty: result = n
|
||||||
result = n
|
of nkSym: result = evalSym(c, n)
|
||||||
of nkSym:
|
of nkType..pred(nkNilLit): result = copyNode(n)
|
||||||
result = evalSym(c, n)
|
of nkNilLit: result = n # end of atoms
|
||||||
of nkType..pred(nkNilLit):
|
|
||||||
result = copyNode(n)
|
|
||||||
of nkNilLit:
|
|
||||||
result = n # end of atoms
|
|
||||||
of nkCall, nkHiddenCallConv, nkMacroStmt, nkCommand, nkCallStrLit:
|
of nkCall, nkHiddenCallConv, nkMacroStmt, nkCommand, nkCallStrLit:
|
||||||
result = evalMagicOrCall(c, n)
|
result = evalMagicOrCall(c, n)
|
||||||
of nkCurly, nkBracket, nkRange:
|
of nkCurly, nkBracket, nkRange:
|
||||||
|
|
@ -1033,52 +987,29 @@ proc evalAux(c: PEvalContext, n: PNode): PNode =
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
a.sons[i].sons[1] = result
|
a.sons[i].sons[1] = result
|
||||||
result = a
|
result = a
|
||||||
of nkBracketExpr:
|
of nkBracketExpr: result = evalArrayAccess(c, n)
|
||||||
result = evalArrayAccess(c, n)
|
of nkDotExpr: result = evalFieldAccess(c, n)
|
||||||
of nkDotExpr:
|
of nkDerefExpr, nkHiddenDeref: result = evalDeref(c, n)
|
||||||
result = evalFieldAccess(c, n)
|
of nkAddr, nkHiddenAddr: result = evalAddr(c, n)
|
||||||
of nkDerefExpr, nkHiddenDeref:
|
of nkHiddenStdConv, nkHiddenSubConv, nkConv: result = evalConv(c, n)
|
||||||
result = evalDeref(c, n)
|
of nkAsgn, nkFastAsgn: result = evalAsgn(c, n)
|
||||||
of nkAddr, nkHiddenAddr:
|
of nkWhenStmt, nkIfStmt, nkIfExpr: result = evalIf(c, n)
|
||||||
result = evalAddr(c, n)
|
of nkWhileStmt: result = evalWhile(c, n)
|
||||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
of nkCaseStmt: result = evalCase(c, n)
|
||||||
result = evalConv(c, n)
|
of nkVarSection: result = evalVar(c, n)
|
||||||
of nkAsgn, nkFastAsgn:
|
of nkTryStmt: result = evalTry(c, n)
|
||||||
result = evalAsgn(c, n)
|
of nkRaiseStmt: result = evalRaise(c, n)
|
||||||
of nkWhenStmt, nkIfStmt, nkIfExpr:
|
of nkReturnStmt: result = evalReturn(c, n)
|
||||||
result = evalIf(c, n)
|
of nkBreakStmt, nkReturnToken: result = n
|
||||||
of nkWhileStmt:
|
of nkBlockExpr, nkBlockStmt: result = evalBlock(c, n)
|
||||||
result = evalWhile(c, n)
|
of nkDiscardStmt: result = evalAux(c, n.sons[0])
|
||||||
of nkCaseStmt:
|
of nkCheckedFieldExpr: result = evalCheckedFieldAccess(c, n)
|
||||||
result = evalCase(c, n)
|
of nkObjDownConv: result = evalAux(c, n.sons[0])
|
||||||
of nkVarSection:
|
of nkObjUpConv: result = evalUpConv(c, n)
|
||||||
result = evalVar(c, n)
|
of nkChckRangeF, nkChckRange64, nkChckRange: result = evalRangeChck(c, n)
|
||||||
of nkTryStmt:
|
of nkStringToCString: result = evalConvStrToCStr(c, n)
|
||||||
result = evalTry(c, n)
|
of nkCStringToString: result = evalConvCStrToStr(c, n)
|
||||||
of nkRaiseStmt:
|
of nkPassAsOpenArray: result = evalAux(c, n.sons[0])
|
||||||
result = evalRaise(c, n)
|
|
||||||
of nkReturnStmt:
|
|
||||||
result = evalReturn(c, n)
|
|
||||||
of nkBreakStmt, nkReturnToken:
|
|
||||||
result = n
|
|
||||||
of nkBlockExpr, nkBlockStmt:
|
|
||||||
result = evalBlock(c, n)
|
|
||||||
of nkDiscardStmt:
|
|
||||||
result = evalAux(c, n.sons[0])
|
|
||||||
of nkCheckedFieldExpr:
|
|
||||||
result = evalCheckedFieldAccess(c, n)
|
|
||||||
of nkObjDownConv:
|
|
||||||
result = evalAux(c, n.sons[0])
|
|
||||||
of nkObjUpConv:
|
|
||||||
result = evalUpConv(c, n)
|
|
||||||
of nkChckRangeF, nkChckRange64, nkChckRange:
|
|
||||||
result = evalRangeChck(c, n)
|
|
||||||
of nkStringToCString:
|
|
||||||
result = evalConvStrToCStr(c, n)
|
|
||||||
of nkCStringToString:
|
|
||||||
result = evalConvCStrToStr(c, n)
|
|
||||||
of nkPassAsOpenArray:
|
|
||||||
result = evalAux(c, n.sons[0])
|
|
||||||
of nkStmtListExpr, nkStmtList, nkModule:
|
of nkStmtListExpr, nkStmtList, nkModule:
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
result = evalAux(c, n.sons[i])
|
result = evalAux(c, n.sons[i])
|
||||||
|
|
@ -1106,11 +1037,8 @@ proc eval(c: PEvalContext, n: PNode): PNode =
|
||||||
stackTrace(c, n, errUnhandledExceptionX, typeToString(result.typ))
|
stackTrace(c, n, errUnhandledExceptionX, typeToString(result.typ))
|
||||||
|
|
||||||
proc evalConstExpr(module: PSym, e: PNode): PNode =
|
proc evalConstExpr(module: PSym, e: PNode): PNode =
|
||||||
var
|
var p = newEvalContext(module, "", true)
|
||||||
p: PEvalContext
|
var s = newStackFrame()
|
||||||
s: PStackFrame
|
|
||||||
p = newEvalContext(module, "", true)
|
|
||||||
s = newStackFrame()
|
|
||||||
s.call = e
|
s.call = e
|
||||||
pushStackFrame(p, s)
|
pushStackFrame(p, s)
|
||||||
result = eval(p, e)
|
result = eval(p, e)
|
||||||
|
|
@ -1118,8 +1046,7 @@ proc evalConstExpr(module: PSym, e: PNode): PNode =
|
||||||
popStackFrame(p)
|
popStackFrame(p)
|
||||||
|
|
||||||
proc myOpen(module: PSym, filename: string): PPassContext =
|
proc myOpen(module: PSym, filename: string): PPassContext =
|
||||||
var c: PEvalContext
|
var c = newEvalContext(module, filename, false)
|
||||||
c = newEvalContext(module, filename, false)
|
|
||||||
pushStackFrame(c, newStackFrame())
|
pushStackFrame(c, newStackFrame())
|
||||||
result = c
|
result = c
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
os, platform, condsyms, ast, astalgo, idents, semdata, msgs, rnimsyn,
|
os, platform, condsyms, ast, astalgo, idents, semdata, msgs, rnimsyn,
|
||||||
wordrecg, ropes, options, strutils, lists, extccomp, math, magicsys
|
wordrecg, ropes, options, strutils, lists, extccomp, math, magicsys, trees
|
||||||
|
|
||||||
const
|
const
|
||||||
FirstCallConv* = wNimcall
|
FirstCallConv* = wNimcall
|
||||||
|
|
@ -78,17 +78,17 @@ proc MakeExternExport(s: PSym, extname: string) =
|
||||||
s.loc.r = toRope(extname)
|
s.loc.r = toRope(extname)
|
||||||
incl(s.flags, sfExportc)
|
incl(s.flags, sfExportc)
|
||||||
|
|
||||||
proc expectStrLit(c: PContext, n: PNode): string =
|
proc getStrLitNode(c: PContext, n: PNode): PNode =
|
||||||
if n.kind != nkExprColonExpr:
|
if n.kind != nkExprColonExpr:
|
||||||
liMessage(n.info, errStringLiteralExpected)
|
liMessage(n.info, errStringLiteralExpected)
|
||||||
result = ""
|
|
||||||
else:
|
else:
|
||||||
n.sons[1] = c.semConstExpr(c, n.sons[1])
|
n.sons[1] = c.semConstExpr(c, n.sons[1])
|
||||||
case n.sons[1].kind
|
case n.sons[1].kind
|
||||||
of nkStrLit, nkRStrLit, nkTripleStrLit: result = n.sons[1].strVal
|
of nkStrLit, nkRStrLit, nkTripleStrLit: result = n.sons[1]
|
||||||
else:
|
else: liMessage(n.info, errStringLiteralExpected)
|
||||||
liMessage(n.info, errStringLiteralExpected)
|
|
||||||
result = ""
|
proc expectStrLit(c: PContext, n: PNode): string =
|
||||||
|
result = getStrLitNode(c, n).strVal
|
||||||
|
|
||||||
proc expectIntLit(c: PContext, n: PNode): int =
|
proc expectIntLit(c: PContext, n: PNode): int =
|
||||||
if n.kind != nkExprColonExpr:
|
if n.kind != nkExprColonExpr:
|
||||||
|
|
@ -128,23 +128,22 @@ proc wordToCallConv(sw: TSpecialWord): TCallingConvention =
|
||||||
# the same
|
# the same
|
||||||
result = TCallingConvention(ord(ccDefault) + ord(sw) - ord(wNimcall))
|
result = TCallingConvention(ord(ccDefault) + ord(sw) - ord(wNimcall))
|
||||||
|
|
||||||
proc onOff(c: PContext, n: PNode, op: TOptions) =
|
proc IsTurnedOn(c: PContext, n: PNode): bool =
|
||||||
if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent):
|
if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent):
|
||||||
case whichKeyword(n.sons[1].ident)
|
case whichKeyword(n.sons[1].ident)
|
||||||
of wOn: gOptions = gOptions + op
|
of wOn: result = true
|
||||||
of wOff: gOptions = gOptions - op
|
of wOff: result = false
|
||||||
else: liMessage(n.info, errOnOrOffExpected)
|
else: liMessage(n.info, errOnOrOffExpected)
|
||||||
else:
|
else:
|
||||||
liMessage(n.info, errOnOrOffExpected)
|
liMessage(n.info, errOnOrOffExpected)
|
||||||
|
|
||||||
|
proc onOff(c: PContext, n: PNode, op: TOptions) =
|
||||||
|
if IsTurnedOn(c, n): gOptions = gOptions + op
|
||||||
|
else: gOptions = gOptions - op
|
||||||
|
|
||||||
proc pragmaDeadCodeElim(c: PContext, n: PNode) =
|
proc pragmaDeadCodeElim(c: PContext, n: PNode) =
|
||||||
if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent):
|
if IsTurnedOn(c, n): incl(c.module.flags, sfDeadCodeElim)
|
||||||
case whichKeyword(n.sons[1].ident)
|
else: excl(c.module.flags, sfDeadCodeElim)
|
||||||
of wOn: incl(c.module.flags, sfDeadCodeElim)
|
|
||||||
of wOff: excl(c.module.flags, sfDeadCodeElim)
|
|
||||||
else: liMessage(n.info, errOnOrOffExpected)
|
|
||||||
else:
|
|
||||||
liMessage(n.info, errOnOrOffExpected)
|
|
||||||
|
|
||||||
proc processCallConv(c: PContext, n: PNode) =
|
proc processCallConv(c: PContext, n: PNode) =
|
||||||
if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent):
|
if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent):
|
||||||
|
|
@ -156,27 +155,31 @@ proc processCallConv(c: PContext, n: PNode) =
|
||||||
else:
|
else:
|
||||||
liMessage(n.info, errCallConvExpected)
|
liMessage(n.info, errCallConvExpected)
|
||||||
|
|
||||||
proc getLib(c: PContext, kind: TLibKind, path: string): PLib =
|
proc getLib(c: PContext, kind: TLibKind, path: PNode): PLib =
|
||||||
var it = PLib(c.libs.head)
|
var it = PLib(c.libs.head)
|
||||||
while it != nil:
|
while it != nil:
|
||||||
if it.kind == kind:
|
if it.kind == kind:
|
||||||
if ospCaseInsensitive in platform.OS[targetOS].props:
|
if trees.ExprStructuralEquivalent(it.path, path): return it
|
||||||
if cmpIgnoreCase(it.path, path) == 0:
|
|
||||||
return it
|
|
||||||
else:
|
|
||||||
if it.path == path:
|
|
||||||
return it
|
|
||||||
it = PLib(it.next)
|
it = PLib(it.next)
|
||||||
result = newLib(kind)
|
result = newLib(kind)
|
||||||
result.path = path
|
result.path = path
|
||||||
Append(c.libs, result)
|
Append(c.libs, result)
|
||||||
|
|
||||||
|
proc expectDynlibNode(c: PContext, n: PNode): PNode =
|
||||||
|
if n.kind != nkExprColonExpr: liMessage(n.info, errStringLiteralExpected)
|
||||||
|
else:
|
||||||
|
result = c.semExpr(c, n.sons[1])
|
||||||
|
if result.typ == nil or result.typ.kind != tyString:
|
||||||
|
liMessage(n.info, errStringLiteralExpected)
|
||||||
|
if result.kind == nkSym and result.sym.kind == skConst:
|
||||||
|
result = result.sym.ast # look it up
|
||||||
|
|
||||||
proc processDynLib(c: PContext, n: PNode, sym: PSym) =
|
proc processDynLib(c: PContext, n: PNode, sym: PSym) =
|
||||||
if (sym == nil) or (sym.kind == skModule):
|
if (sym == nil) or (sym.kind == skModule):
|
||||||
POptionEntry(c.optionStack.tail).dynlib = getLib(c, libDynamic,
|
POptionEntry(c.optionStack.tail).dynlib = getLib(c, libDynamic,
|
||||||
expectStrLit(c, n))
|
expectDynlibNode(c, n))
|
||||||
elif n.kind == nkExprColonExpr:
|
elif n.kind == nkExprColonExpr:
|
||||||
var lib = getLib(c, libDynamic, expectStrLit(c, n))
|
var lib = getLib(c, libDynamic, expectDynlibNode(c, n))
|
||||||
addToLib(lib, sym)
|
addToLib(lib, sym)
|
||||||
incl(sym.loc.flags, lfDynamicLib)
|
incl(sym.loc.flags, lfDynamicLib)
|
||||||
else:
|
else:
|
||||||
|
|
@ -366,7 +369,7 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
|
||||||
noval(it)
|
noval(it)
|
||||||
incl(sym.flags, sfMerge)
|
incl(sym.flags, sfMerge)
|
||||||
of wHeader:
|
of wHeader:
|
||||||
var lib = getLib(c, libHeader, expectStrLit(c, it))
|
var lib = getLib(c, libHeader, getStrLitNode(c, it))
|
||||||
addToLib(lib, sym)
|
addToLib(lib, sym)
|
||||||
incl(sym.flags, sfImportc)
|
incl(sym.flags, sfImportc)
|
||||||
incl(sym.loc.flags, lfHeader)
|
incl(sym.loc.flags, lfHeader)
|
||||||
|
|
|
||||||
179
rod/rodread.nim
179
rod/rodread.nim
|
|
@ -146,9 +146,9 @@ proc rrGetType(r: PRodReader, id: int, info: TLineInfo): PType
|
||||||
proc decode(r: PRodReader): string
|
proc decode(r: PRodReader): string
|
||||||
proc decodeInt(r: PRodReader): int
|
proc decodeInt(r: PRodReader): int
|
||||||
proc decodeBInt(r: PRodReader): biggestInt
|
proc decodeBInt(r: PRodReader): biggestInt
|
||||||
|
|
||||||
proc encode(s: string): PRope =
|
proc encode(s: string): PRope =
|
||||||
var res: string
|
var res = ""
|
||||||
res = ""
|
|
||||||
for i in countup(0, len(s) + 0 - 1):
|
for i in countup(0, len(s) + 0 - 1):
|
||||||
case s[i]
|
case s[i]
|
||||||
of 'a'..'z', 'A'..'Z', '0'..'9', '_': add(res, s[i])
|
of 'a'..'z', 'A'..'Z', '0'..'9', '_': add(res, s[i])
|
||||||
|
|
@ -156,29 +156,24 @@ proc encode(s: string): PRope =
|
||||||
result = toRope(res)
|
result = toRope(res)
|
||||||
|
|
||||||
proc encodeIntAux(str: var string, x: BiggestInt) =
|
proc encodeIntAux(str: var string, x: BiggestInt) =
|
||||||
const
|
const chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
chars: string = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
var d: char
|
||||||
var
|
var v = x
|
||||||
v, rem: biggestInt
|
var rem: biggestInt = v mod 190
|
||||||
d: char
|
|
||||||
idx: int
|
|
||||||
v = x
|
|
||||||
rem = v mod 190
|
|
||||||
if (rem < 0):
|
if (rem < 0):
|
||||||
str = str & '-'
|
add(str, '-')
|
||||||
v = - (v div 190)
|
v = - (v div 190)
|
||||||
rem = - rem
|
rem = - rem
|
||||||
else:
|
else:
|
||||||
v = v div 190
|
v = v div 190
|
||||||
idx = int(rem)
|
var idx = int(rem)
|
||||||
if idx < 62: d = chars[idx + 0]
|
if idx < 62: d = chars[idx + 0]
|
||||||
else: d = chr(idx - 62 + 128)
|
else: d = chr(idx - 62 + 128)
|
||||||
if (v != 0): encodeIntAux(str, v)
|
if (v != 0): encodeIntAux(str, v)
|
||||||
add(str, d)
|
add(str, d)
|
||||||
|
|
||||||
proc encodeInt(x: BiggestInt): PRope =
|
proc encodeInt(x: BiggestInt): PRope =
|
||||||
var res: string
|
var res = ""
|
||||||
res = ""
|
|
||||||
encodeIntAux(res, x)
|
encodeIntAux(res, x)
|
||||||
result = toRope(res)
|
result = toRope(res)
|
||||||
|
|
||||||
|
|
@ -303,8 +298,8 @@ proc decodeType(r: PRodReader, info: TLineInfo): PType =
|
||||||
if debugIds: registerID(result)
|
if debugIds: registerID(result)
|
||||||
else:
|
else:
|
||||||
InternalError(info, "decodeType: no id")
|
InternalError(info, "decodeType: no id")
|
||||||
IdTablePut(gTypeTable, result, result) # here this also
|
# here this also avoids endless recursion for recursive type
|
||||||
# avoids endless recursion for recursive type
|
IdTablePut(gTypeTable, result, result)
|
||||||
if r.s[r.pos] == '(': result.n = decodeNode(r, UnknownLineInfo())
|
if r.s[r.pos] == '(': result.n = decodeNode(r, UnknownLineInfo())
|
||||||
if r.s[r.pos] == '$':
|
if r.s[r.pos] == '$':
|
||||||
inc(r.pos)
|
inc(r.pos)
|
||||||
|
|
@ -343,7 +338,7 @@ proc decodeType(r: PRodReader, info: TLineInfo): PType =
|
||||||
d = decodeInt(r)
|
d = decodeInt(r)
|
||||||
addSon(result, rrGetType(r, d, info))
|
addSon(result, rrGetType(r, d, info))
|
||||||
|
|
||||||
proc decodeLib(r: PRodReader): PLib =
|
proc decodeLib(r: PRodReader, info: TLineInfo): PLib =
|
||||||
result = nil
|
result = nil
|
||||||
if r.s[r.pos] == '|':
|
if r.s[r.pos] == '|':
|
||||||
new(result)
|
new(result)
|
||||||
|
|
@ -354,11 +349,10 @@ proc decodeLib(r: PRodReader): PLib =
|
||||||
result.name = toRope(decode(r))
|
result.name = toRope(decode(r))
|
||||||
if r.s[r.pos] != '|': InternalError("decodeLib: 2")
|
if r.s[r.pos] != '|': InternalError("decodeLib: 2")
|
||||||
inc(r.pos)
|
inc(r.pos)
|
||||||
result.path = decode(r)
|
result.path = decodeNode(r, info)
|
||||||
|
|
||||||
proc decodeSym(r: PRodReader, info: TLineInfo): PSym =
|
proc decodeSym(r: PRodReader, info: TLineInfo): PSym =
|
||||||
var
|
var
|
||||||
k: TSymKind
|
|
||||||
id: int
|
id: int
|
||||||
ident: PIdent
|
ident: PIdent
|
||||||
result = nil
|
result = nil
|
||||||
|
|
@ -367,7 +361,7 @@ proc decodeSym(r: PRodReader, info: TLineInfo): PSym =
|
||||||
if r.s[r.pos] == '}':
|
if r.s[r.pos] == '}':
|
||||||
inc(r.pos)
|
inc(r.pos)
|
||||||
return # nil sym
|
return # nil sym
|
||||||
k = TSymKind(decodeInt(r))
|
var k = TSymKind(decodeInt(r))
|
||||||
if r.s[r.pos] == '+':
|
if r.s[r.pos] == '+':
|
||||||
inc(r.pos)
|
inc(r.pos)
|
||||||
id = decodeInt(r)
|
id = decodeInt(r)
|
||||||
|
|
@ -412,22 +406,20 @@ proc decodeSym(r: PRodReader, info: TLineInfo): PSym =
|
||||||
inc(r.pos)
|
inc(r.pos)
|
||||||
result.position = decodeInt(r)
|
result.position = decodeInt(r)
|
||||||
else:
|
else:
|
||||||
result.position = 0 # BUGFIX: this may have been misused as reader index!
|
result.position = 0
|
||||||
|
# BUGFIX: this may have been misused as reader index!
|
||||||
if r.s[r.pos] == '`':
|
if r.s[r.pos] == '`':
|
||||||
inc(r.pos)
|
inc(r.pos)
|
||||||
result.offset = decodeInt(r)
|
result.offset = decodeInt(r)
|
||||||
else:
|
else:
|
||||||
result.offset = - 1
|
result.offset = - 1
|
||||||
decodeLoc(r, result.loc, result.info)
|
decodeLoc(r, result.loc, result.info)
|
||||||
result.annex = decodeLib(r)
|
result.annex = decodeLib(r, info)
|
||||||
|
|
||||||
proc decodeInt(r: PRodReader): int =
|
proc decodeInt(r: PRodReader): int =
|
||||||
# base 190 numbers
|
# base 190 numbers
|
||||||
var
|
var i = r.pos
|
||||||
i: int
|
var sign = - 1
|
||||||
sign: int
|
|
||||||
i = r.pos
|
|
||||||
sign = - 1
|
|
||||||
assert(r.s[i] in {'a'..'z', 'A'..'Z', '0'..'9', '-', '\x80'..'\xFF'})
|
assert(r.s[i] in {'a'..'z', 'A'..'Z', '0'..'9', '-', '\x80'..'\xFF'})
|
||||||
if r.s[i] == '-':
|
if r.s[i] == '-':
|
||||||
inc(i)
|
inc(i)
|
||||||
|
|
@ -445,11 +437,8 @@ proc decodeInt(r: PRodReader): int =
|
||||||
r.pos = i
|
r.pos = i
|
||||||
|
|
||||||
proc decodeBInt(r: PRodReader): biggestInt =
|
proc decodeBInt(r: PRodReader): biggestInt =
|
||||||
var
|
var i = r.pos
|
||||||
i: int
|
var sign: biggestInt = - 1
|
||||||
sign: biggestInt
|
|
||||||
i = r.pos
|
|
||||||
sign = - 1
|
|
||||||
assert(r.s[i] in {'a'..'z', 'A'..'Z', '0'..'9', '-', '\x80'..'\xFF'})
|
assert(r.s[i] in {'a'..'z', 'A'..'Z', '0'..'9', '-', '\x80'..'\xFF'})
|
||||||
if r.s[i] == '-':
|
if r.s[i] == '-':
|
||||||
inc(i)
|
inc(i)
|
||||||
|
|
@ -471,18 +460,16 @@ proc hexChar(c: char, xi: var int) =
|
||||||
of '0'..'9': xi = (xi shl 4) or (ord(c) - ord('0'))
|
of '0'..'9': xi = (xi shl 4) or (ord(c) - ord('0'))
|
||||||
of 'a'..'f': xi = (xi shl 4) or (ord(c) - ord('a') + 10)
|
of 'a'..'f': xi = (xi shl 4) or (ord(c) - ord('a') + 10)
|
||||||
of 'A'..'F': xi = (xi shl 4) or (ord(c) - ord('A') + 10)
|
of 'A'..'F': xi = (xi shl 4) or (ord(c) - ord('A') + 10)
|
||||||
else:
|
else: nil
|
||||||
nil
|
|
||||||
|
|
||||||
proc decode(r: PRodReader): string =
|
proc decode(r: PRodReader): string =
|
||||||
var i, xi: int
|
var i = r.pos
|
||||||
i = r.pos
|
|
||||||
result = ""
|
result = ""
|
||||||
while true:
|
while true:
|
||||||
case r.s[i]
|
case r.s[i]
|
||||||
of '\\':
|
of '\\':
|
||||||
inc(i, 3)
|
inc(i, 3)
|
||||||
xi = 0
|
var xi = 0
|
||||||
hexChar(r.s[i - 2], xi)
|
hexChar(r.s[i - 2], xi)
|
||||||
hexChar(r.s[i - 1], xi)
|
hexChar(r.s[i - 1], xi)
|
||||||
add(result, chr(xi))
|
add(result, chr(xi))
|
||||||
|
|
@ -493,28 +480,23 @@ proc decode(r: PRodReader): string =
|
||||||
r.pos = i
|
r.pos = i
|
||||||
|
|
||||||
proc skipSection(r: PRodReader) =
|
proc skipSection(r: PRodReader) =
|
||||||
var c: int
|
|
||||||
if r.s[r.pos] == ':':
|
if r.s[r.pos] == ':':
|
||||||
while r.s[r.pos] > '\x0A': inc(r.pos)
|
while r.s[r.pos] > '\x0A': inc(r.pos)
|
||||||
elif r.s[r.pos] == '(':
|
elif r.s[r.pos] == '(':
|
||||||
c = 0 # count () pairs
|
var c = 0 # count () pairs
|
||||||
inc(r.pos)
|
inc(r.pos)
|
||||||
while true:
|
while true:
|
||||||
case r.s[r.pos]
|
case r.s[r.pos]
|
||||||
of '\x0A':
|
of '\x0A': inc(r.line)
|
||||||
inc(r.line)
|
of '(': inc(c)
|
||||||
of '(':
|
|
||||||
inc(c)
|
|
||||||
of ')':
|
of ')':
|
||||||
if c == 0:
|
if c == 0:
|
||||||
inc(r.pos)
|
inc(r.pos)
|
||||||
break
|
break
|
||||||
elif c > 0:
|
elif c > 0:
|
||||||
dec(c)
|
dec(c)
|
||||||
of '\0':
|
of '\0': break # end of file
|
||||||
break # end of file
|
else: nil
|
||||||
else:
|
|
||||||
nil
|
|
||||||
inc(r.pos)
|
inc(r.pos)
|
||||||
else:
|
else:
|
||||||
InternalError("skipSection " & $(r.line))
|
InternalError("skipSection " & $(r.line))
|
||||||
|
|
@ -535,18 +517,14 @@ proc newStub(r: PRodReader, name: string, id: int): PSym =
|
||||||
if debugIds: registerID(result)
|
if debugIds: registerID(result)
|
||||||
|
|
||||||
proc processInterf(r: PRodReader, module: PSym) =
|
proc processInterf(r: PRodReader, module: PSym) =
|
||||||
var
|
|
||||||
s: PSym
|
|
||||||
w: string
|
|
||||||
key: int
|
|
||||||
if r.interfIdx == 0: InternalError("processInterf")
|
if r.interfIdx == 0: InternalError("processInterf")
|
||||||
r.pos = r.interfIdx
|
r.pos = r.interfIdx
|
||||||
while (r.s[r.pos] > '\x0A') and (r.s[r.pos] != ')'):
|
while (r.s[r.pos] > '\x0A') and (r.s[r.pos] != ')'):
|
||||||
w = decode(r)
|
var w = decode(r)
|
||||||
inc(r.pos)
|
inc(r.pos)
|
||||||
key = decodeInt(r)
|
var key = decodeInt(r)
|
||||||
inc(r.pos) # #10
|
inc(r.pos) # #10
|
||||||
s = newStub(r, w, key)
|
var s = newStub(r, w, key)
|
||||||
s.owner = module
|
s.owner = module
|
||||||
StrTableAdd(module.tab, s)
|
StrTableAdd(module.tab, s)
|
||||||
IdTablePut(r.syms, s, s)
|
IdTablePut(r.syms, s, s)
|
||||||
|
|
@ -685,14 +663,12 @@ proc processRodFile(r: PRodReader, crc: TCrc32) =
|
||||||
inc(r.pos)
|
inc(r.pos)
|
||||||
inc(r.line)
|
inc(r.line)
|
||||||
|
|
||||||
proc newRodReader(modfilename: string, crc: TCrc32, readerIndex: int): PRodReader =
|
proc newRodReader(modfilename: string, crc: TCrc32,
|
||||||
var
|
readerIndex: int): PRodReader =
|
||||||
version: string
|
|
||||||
r: PRodReader
|
|
||||||
new(result)
|
new(result)
|
||||||
result.files = @ []
|
result.files = @[]
|
||||||
result.modDeps = @ []
|
result.modDeps = @[]
|
||||||
r = result
|
var r = result
|
||||||
r.reason = rrNone
|
r.reason = rrNone
|
||||||
r.pos = 0
|
r.pos = 0
|
||||||
r.line = 1
|
r.line = 1
|
||||||
|
|
@ -704,7 +680,7 @@ proc newRodReader(modfilename: string, crc: TCrc32, readerIndex: int): PRodReade
|
||||||
initIITable(r.index.tab)
|
initIITable(r.index.tab)
|
||||||
initIITable(r.imports.tab) # looks like a ROD file
|
initIITable(r.imports.tab) # looks like a ROD file
|
||||||
inc(r.pos, 4)
|
inc(r.pos, 4)
|
||||||
version = ""
|
var version = ""
|
||||||
while not (r.s[r.pos] in {'\0', '\x0A'}):
|
while not (r.s[r.pos] in {'\0', '\x0A'}):
|
||||||
add(version, r.s[r.pos])
|
add(version, r.s[r.pos])
|
||||||
inc(r.pos)
|
inc(r.pos)
|
||||||
|
|
@ -719,12 +695,11 @@ proc newRodReader(modfilename: string, crc: TCrc32, readerIndex: int): PRodReade
|
||||||
result = nil
|
result = nil
|
||||||
|
|
||||||
proc rrGetType(r: PRodReader, id: int, info: TLineInfo): PType =
|
proc rrGetType(r: PRodReader, id: int, info: TLineInfo): PType =
|
||||||
var oldPos, d: int
|
|
||||||
result = PType(IdTableGet(gTypeTable, id))
|
result = PType(IdTableGet(gTypeTable, id))
|
||||||
if result == nil:
|
if result == nil:
|
||||||
# load the type:
|
# load the type:
|
||||||
oldPos = r.pos
|
var oldPos = r.pos
|
||||||
d = IITableGet(r.index.tab, id)
|
var d = IITableGet(r.index.tab, id)
|
||||||
if d == invalidKey: InternalError(info, "rrGetType")
|
if d == invalidKey: InternalError(info, "rrGetType")
|
||||||
r.pos = d + r.dataIdx
|
r.pos = d + r.dataIdx
|
||||||
result = decodeType(r, info)
|
result = decodeType(r, info)
|
||||||
|
|
@ -739,39 +714,29 @@ type
|
||||||
|
|
||||||
TFileModuleMap = seq[TFileModuleRec]
|
TFileModuleMap = seq[TFileModuleRec]
|
||||||
|
|
||||||
var gMods: TFileModuleMap = @ []
|
var gMods: TFileModuleMap = @[]
|
||||||
|
|
||||||
proc decodeSymSafePos(rd: PRodReader, offset: int, info: TLineInfo): PSym =
|
proc decodeSymSafePos(rd: PRodReader, offset: int, info: TLineInfo): PSym =
|
||||||
# all compiled modules
|
# all compiled modules
|
||||||
var oldPos: int
|
|
||||||
if rd.dataIdx == 0: InternalError(info, "dataIdx == 0")
|
if rd.dataIdx == 0: InternalError(info, "dataIdx == 0")
|
||||||
oldPos = rd.pos
|
var oldPos = rd.pos
|
||||||
rd.pos = offset + rd.dataIdx
|
rd.pos = offset + rd.dataIdx
|
||||||
result = decodeSym(rd, info)
|
result = decodeSym(rd, info)
|
||||||
rd.pos = oldPos
|
rd.pos = oldPos
|
||||||
|
|
||||||
proc rrGetSym(r: PRodReader, id: int, info: TLineInfo): PSym =
|
proc rrGetSym(r: PRodReader, id: int, info: TLineInfo): PSym =
|
||||||
var
|
|
||||||
d, moduleID: int
|
|
||||||
rd: PRodReader
|
|
||||||
result = PSym(IdTableGet(r.syms, id))
|
result = PSym(IdTableGet(r.syms, id))
|
||||||
if result == nil:
|
if result == nil:
|
||||||
# load the symbol:
|
# load the symbol:
|
||||||
d = IITableGet(r.index.tab, id)
|
var d = IITableGet(r.index.tab, id)
|
||||||
if d == invalidKey:
|
if d == invalidKey:
|
||||||
moduleID = IiTableGet(r.imports.tab, id)
|
var moduleID = IiTableGet(r.imports.tab, id)
|
||||||
if moduleID < 0:
|
if moduleID < 0:
|
||||||
InternalError(info,
|
InternalError(info,
|
||||||
"missing from both indexes: +" & ropeToStr(encodeInt(id))) #
|
"missing from both indexes: +" & ropeToStr(encodeInt(id)))
|
||||||
# find
|
# find the reader with the correct moduleID:
|
||||||
# the
|
|
||||||
# reader
|
|
||||||
# with
|
|
||||||
# the
|
|
||||||
# correct
|
|
||||||
# moduleID:
|
|
||||||
for i in countup(0, high(gMods)):
|
for i in countup(0, high(gMods)):
|
||||||
rd = gMods[i].rd
|
var rd = gMods[i].rd
|
||||||
if (rd != nil):
|
if (rd != nil):
|
||||||
if (rd.moduleID == moduleID):
|
if (rd.moduleID == moduleID):
|
||||||
d = IITableGet(rd.index.tab, id)
|
d = IITableGet(rd.index.tab, id)
|
||||||
|
|
@ -792,56 +757,47 @@ proc rrGetSym(r: PRodReader, id: int, info: TLineInfo): PSym =
|
||||||
if (result != nil) and (result.kind == skStub): loadStub(result)
|
if (result != nil) and (result.kind == skStub): loadStub(result)
|
||||||
|
|
||||||
proc loadInitSection(r: PRodReader): PNode =
|
proc loadInitSection(r: PRodReader): PNode =
|
||||||
var d, oldPos, p: int
|
|
||||||
if (r.initIdx == 0) or (r.dataIdx == 0): InternalError("loadInitSection")
|
if (r.initIdx == 0) or (r.dataIdx == 0): InternalError("loadInitSection")
|
||||||
oldPos = r.pos
|
var oldPos = r.pos
|
||||||
r.pos = r.initIdx
|
r.pos = r.initIdx
|
||||||
result = newNode(nkStmtList)
|
result = newNode(nkStmtList)
|
||||||
while (r.s[r.pos] > '\x0A') and (r.s[r.pos] != ')'):
|
while (r.s[r.pos] > '\x0A') and (r.s[r.pos] != ')'):
|
||||||
d = decodeInt(r)
|
var d = decodeInt(r)
|
||||||
inc(r.pos) # #10
|
inc(r.pos) # #10
|
||||||
p = r.pos
|
var p = r.pos
|
||||||
r.pos = d + r.dataIdx
|
r.pos = d + r.dataIdx
|
||||||
addSon(result, decodeNode(r, UnknownLineInfo()))
|
addSon(result, decodeNode(r, UnknownLineInfo()))
|
||||||
r.pos = p
|
r.pos = p
|
||||||
r.pos = oldPos
|
r.pos = oldPos
|
||||||
|
|
||||||
proc loadConverters(r: PRodReader) =
|
proc loadConverters(r: PRodReader) =
|
||||||
var d: int
|
|
||||||
# We have to ensure that no exported converter is a stub anymore.
|
# We have to ensure that no exported converter is a stub anymore.
|
||||||
if (r.convertersIdx == 0) or (r.dataIdx == 0):
|
if (r.convertersIdx == 0) or (r.dataIdx == 0):
|
||||||
InternalError("importConverters")
|
InternalError("importConverters")
|
||||||
r.pos = r.convertersIdx
|
r.pos = r.convertersIdx
|
||||||
while (r.s[r.pos] > '\x0A'):
|
while (r.s[r.pos] > '\x0A'):
|
||||||
d = decodeInt(r)
|
var d = decodeInt(r)
|
||||||
discard rrGetSym(r, d, UnknownLineInfo())
|
discard rrGetSym(r, d, UnknownLineInfo())
|
||||||
if r.s[r.pos] == ' ': inc(r.pos)
|
if r.s[r.pos] == ' ': inc(r.pos)
|
||||||
|
|
||||||
proc getModuleIdx(filename: string): int =
|
proc getModuleIdx(filename: string): int =
|
||||||
for i in countup(0, high(gMods)):
|
for i in countup(0, high(gMods)):
|
||||||
if sameFile(gMods[i].filename, filename):
|
if sameFile(gMods[i].filename, filename): return i
|
||||||
return i
|
|
||||||
result = len(gMods)
|
result = len(gMods)
|
||||||
setlen(gMods, result + 1)
|
setlen(gMods, result + 1)
|
||||||
|
|
||||||
proc checkDep(filename: string): TReasonForRecompile =
|
proc checkDep(filename: string): TReasonForRecompile =
|
||||||
var
|
var idx = getModuleIdx(filename)
|
||||||
crc: TCrc32
|
|
||||||
r: PRodReader
|
|
||||||
rodfile: string
|
|
||||||
idx: int
|
|
||||||
res: TReasonForRecompile
|
|
||||||
idx = getModuleIdx(filename)
|
|
||||||
if gMods[idx].reason != rrEmpty:
|
if gMods[idx].reason != rrEmpty:
|
||||||
# reason has already been computed for this module:
|
# reason has already been computed for this module:
|
||||||
return gMods[idx].reason
|
return gMods[idx].reason
|
||||||
crc = crcFromFile(filename)
|
var crc: TCrc32 = crcFromFile(filename)
|
||||||
gMods[idx].reason = rrNone # we need to set it here to avoid cycles
|
gMods[idx].reason = rrNone # we need to set it here to avoid cycles
|
||||||
gMods[idx].filename = filename
|
gMods[idx].filename = filename
|
||||||
gMods[idx].crc = crc
|
gMods[idx].crc = crc
|
||||||
result = rrNone
|
result = rrNone
|
||||||
r = nil
|
var r: PRodReader = nil
|
||||||
rodfile = toGeneratedFile(filename, RodExt)
|
var rodfile = toGeneratedFile(filename, RodExt)
|
||||||
if ExistsFile(rodfile):
|
if ExistsFile(rodfile):
|
||||||
r = newRodReader(rodfile, crc, idx)
|
r = newRodReader(rodfile, crc, idx)
|
||||||
if r == nil:
|
if r == nil:
|
||||||
|
|
@ -853,7 +809,7 @@ proc checkDep(filename: string): TReasonForRecompile =
|
||||||
# NOTE: we need to process the entire module graph so that no ID will
|
# NOTE: we need to process the entire module graph so that no ID will
|
||||||
# be used twice! However, compilation speed does not suffer much from
|
# be used twice! However, compilation speed does not suffer much from
|
||||||
# this, since results are cached.
|
# this, since results are cached.
|
||||||
res = checkDep(JoinPath(options.libpath, addFileExt("system", nimExt)))
|
var res = checkDep(options.libpath / addFileExt("system", nimExt))
|
||||||
if res != rrNone: result = rrModDeps
|
if res != rrNone: result = rrModDeps
|
||||||
for i in countup(0, high(r.modDeps)):
|
for i in countup(0, high(r.modDeps)):
|
||||||
res = checkDep(r.modDeps[i])
|
res = checkDep(r.modDeps[i])
|
||||||
|
|
@ -870,12 +826,11 @@ proc checkDep(filename: string): TReasonForRecompile =
|
||||||
gMods[idx].reason = result # now we know better
|
gMods[idx].reason = result # now we know better
|
||||||
|
|
||||||
proc handleSymbolFile(module: PSym, filename: string): PRodReader =
|
proc handleSymbolFile(module: PSym, filename: string): PRodReader =
|
||||||
var idx: int
|
|
||||||
if not (optSymbolFiles in gGlobalOptions):
|
if not (optSymbolFiles in gGlobalOptions):
|
||||||
module.id = getID()
|
module.id = getID()
|
||||||
return nil
|
return nil
|
||||||
discard checkDep(filename)
|
discard checkDep(filename)
|
||||||
idx = getModuleIdx(filename)
|
var idx = getModuleIdx(filename)
|
||||||
if gMods[idx].reason == rrEmpty: InternalError("handleSymbolFile")
|
if gMods[idx].reason == rrEmpty: InternalError("handleSymbolFile")
|
||||||
result = gMods[idx].rd
|
result = gMods[idx].rd
|
||||||
if result != nil:
|
if result != nil:
|
||||||
|
|
@ -888,26 +843,22 @@ proc handleSymbolFile(module: PSym, filename: string): PRodReader =
|
||||||
module.id = getID()
|
module.id = getID()
|
||||||
|
|
||||||
proc GetCRC(filename: string): TCrc32 =
|
proc GetCRC(filename: string): TCrc32 =
|
||||||
var idx: int
|
var idx = getModuleIdx(filename)
|
||||||
idx = getModuleIdx(filename)
|
|
||||||
result = gMods[idx].crc
|
result = gMods[idx].crc
|
||||||
|
|
||||||
proc loadStub(s: PSym) =
|
proc loadStub(s: PSym) =
|
||||||
var
|
|
||||||
rd: PRodReader
|
|
||||||
d, theId: int
|
|
||||||
rs: PSym
|
|
||||||
if s.kind != skStub:
|
if s.kind != skStub:
|
||||||
InternalError("loadStub") #MessageOut('loading stub: ' + s.name.s);
|
InternalError("loadStub") #MessageOut('loading stub: ' + s.name.s);
|
||||||
rd = gMods[s.position].rd
|
var rd = gMods[s.position].rd
|
||||||
theId = s.id # used for later check
|
var theId = s.id # used for later check
|
||||||
d = IITableGet(rd.index.tab, s.id)
|
var d = IITableGet(rd.index.tab, s.id)
|
||||||
if d == invalidKey: InternalError("loadStub: invalid key")
|
if d == invalidKey: InternalError("loadStub: invalid key")
|
||||||
rs = decodeSymSafePos(rd, d, UnknownLineInfo())
|
var rs = decodeSymSafePos(rd, d, UnknownLineInfo())
|
||||||
if rs != s:
|
if rs != s:
|
||||||
InternalError(rs.info, "loadStub: wrong symbol")
|
InternalError(rs.info, "loadStub: wrong symbol")
|
||||||
elif rs.id != theId:
|
elif rs.id != theId:
|
||||||
InternalError(rs.info, "loadStub: wrong ID") #MessageOut('loaded stub: ' + s.name.s);
|
InternalError(rs.info, "loadStub: wrong ID")
|
||||||
|
#MessageOut('loaded stub: ' + s.name.s);
|
||||||
|
|
||||||
InitIdTable(gTypeTable)
|
InitIdTable(gTypeTable)
|
||||||
InitStrTable(rodCompilerProcs)
|
InitStrTable(rodCompilerProcs)
|
||||||
|
|
@ -49,11 +49,10 @@ proc encodeStr(w: PRodWriter, s: string): PRope =
|
||||||
result = encode(s)
|
result = encode(s)
|
||||||
|
|
||||||
proc processStacks(w: PRodWriter)
|
proc processStacks(w: PRodWriter)
|
||||||
|
|
||||||
proc getDefines(): PRope =
|
proc getDefines(): PRope =
|
||||||
var
|
var it: TTabIter
|
||||||
it: TTabIter
|
var s = InitTabIter(it, gSymbols)
|
||||||
s: PSym
|
|
||||||
s = InitTabIter(it, gSymbols)
|
|
||||||
result = nil
|
result = nil
|
||||||
while s != nil:
|
while s != nil:
|
||||||
if s.position == 1:
|
if s.position == 1:
|
||||||
|
|
@ -96,28 +95,26 @@ proc addInclDep(w: PRodWriter, dep: string) =
|
||||||
app(w.inclDeps, rodNL)
|
app(w.inclDeps, rodNL)
|
||||||
|
|
||||||
proc pushType(w: PRodWriter, t: PType) =
|
proc pushType(w: PRodWriter, t: PType) =
|
||||||
var L: int
|
|
||||||
# check so that the stack does not grow too large:
|
# check so that the stack does not grow too large:
|
||||||
if IiTableGet(w.index.tab, t.id) == invalidKey:
|
if IiTableGet(w.index.tab, t.id) == invalidKey:
|
||||||
L = len(w.tstack)
|
var L = len(w.tstack)
|
||||||
setlen(w.tstack, L + 1)
|
setlen(w.tstack, L + 1)
|
||||||
w.tstack[L] = t
|
w.tstack[L] = t
|
||||||
|
|
||||||
proc pushSym(w: PRodWriter, s: PSym) =
|
proc pushSym(w: PRodWriter, s: PSym) =
|
||||||
var L: int
|
|
||||||
# check so that the stack does not grow too large:
|
# check so that the stack does not grow too large:
|
||||||
if IiTableGet(w.index.tab, s.id) == invalidKey:
|
if IiTableGet(w.index.tab, s.id) == invalidKey:
|
||||||
L = len(w.sstack)
|
var L = len(w.sstack)
|
||||||
setlen(w.sstack, L + 1)
|
setlen(w.sstack, L + 1)
|
||||||
w.sstack[L] = s
|
w.sstack[L] = s
|
||||||
|
|
||||||
proc encodeNode(w: PRodWriter, fInfo: TLineInfo, n: PNode): PRope =
|
proc encodeNode(w: PRodWriter, fInfo: TLineInfo, n: PNode): PRope =
|
||||||
var f: TNodeFlags
|
|
||||||
if n == nil:
|
if n == nil:
|
||||||
# nil nodes have to be stored too:
|
# nil nodes have to be stored too:
|
||||||
return toRope("()")
|
return toRope("()")
|
||||||
result = toRope("(")
|
result = toRope("(")
|
||||||
app(result, encodeInt(ord(n.kind))) # we do not write comments for now
|
app(result, encodeInt(ord(n.kind)))
|
||||||
|
# we do not write comments for now
|
||||||
# Line information takes easily 20% or more of the filesize! Therefore we
|
# Line information takes easily 20% or more of the filesize! Therefore we
|
||||||
# omit line information if it is the same as the father's line information:
|
# omit line information if it is the same as the father's line information:
|
||||||
if (finfo.fileIndex != n.info.fileIndex):
|
if (finfo.fileIndex != n.info.fileIndex):
|
||||||
|
|
@ -126,9 +123,10 @@ proc encodeNode(w: PRodWriter, fInfo: TLineInfo, n: PNode): PRope =
|
||||||
elif (finfo.line != n.info.line):
|
elif (finfo.line != n.info.line):
|
||||||
appf(result, "?$1,$2", [encodeInt(n.info.col), encodeInt(n.info.line)])
|
appf(result, "?$1,$2", [encodeInt(n.info.col), encodeInt(n.info.line)])
|
||||||
elif (finfo.col != n.info.col):
|
elif (finfo.col != n.info.col):
|
||||||
appf(result, "?$1", [encodeInt(n.info.col)]) # No need to output the file index, as this is the serialization of one
|
appf(result, "?$1", [encodeInt(n.info.col)])
|
||||||
|
# No need to output the file index, as this is the serialization of one
|
||||||
# file.
|
# file.
|
||||||
f = n.flags * PersistentNodeFlags
|
var f = n.flags * PersistentNodeFlags
|
||||||
if f != {}: appf(result, "$$$1", [encodeInt(cast[int32](f))])
|
if f != {}: appf(result, "$$$1", [encodeInt(cast[int32](f))])
|
||||||
if n.typ != nil:
|
if n.typ != nil:
|
||||||
appf(result, "^$1", [encodeInt(n.typ.id)])
|
appf(result, "^$1", [encodeInt(n.typ.id)])
|
||||||
|
|
@ -191,11 +189,11 @@ proc encodeType(w: PRodWriter, t: PType): PRope =
|
||||||
appf(result, "^$1", [encodeInt(t.sons[i].id)])
|
appf(result, "^$1", [encodeInt(t.sons[i].id)])
|
||||||
pushType(w, t.sons[i])
|
pushType(w, t.sons[i])
|
||||||
|
|
||||||
proc encodeLib(w: PRodWriter, lib: PLib): PRope =
|
proc encodeLib(w: PRodWriter, lib: PLib, info: TLineInfo): PRope =
|
||||||
result = nil
|
result = nil
|
||||||
appf(result, "|$1", [encodeInt(ord(lib.kind))])
|
appf(result, "|$1", [encodeInt(ord(lib.kind))])
|
||||||
appf(result, "|$1", [encodeStr(w, ropeToStr(lib.name))])
|
appf(result, "|$1", [encodeStr(w, ropeToStr(lib.name))])
|
||||||
appf(result, "|$1", [encodeStr(w, lib.path)])
|
appf(result, "|$1", [encodeNode(w, info, lib.path)])
|
||||||
|
|
||||||
proc encodeSym(w: PRodWriter, s: PSym): PRope =
|
proc encodeSym(w: PRodWriter, s: PSym): PRope =
|
||||||
var
|
var
|
||||||
|
|
@ -235,7 +233,7 @@ proc encodeSym(w: PRodWriter, s: PSym): PRope =
|
||||||
if s.position != 0: appf(result, "%$1", [encodeInt(s.position)])
|
if s.position != 0: appf(result, "%$1", [encodeInt(s.position)])
|
||||||
if s.offset != - 1: appf(result, "`$1", [encodeInt(s.offset)])
|
if s.offset != - 1: appf(result, "`$1", [encodeInt(s.offset)])
|
||||||
app(result, encodeLoc(w, s.loc))
|
app(result, encodeLoc(w, s.loc))
|
||||||
if s.annex != nil: app(result, encodeLib(w, s.annex))
|
if s.annex != nil: app(result, encodeLib(w, s.annex, s.info))
|
||||||
|
|
||||||
proc addToIndex(w: var TIndex, key, val: int) =
|
proc addToIndex(w: var TIndex, key, val: int) =
|
||||||
if key - w.lastIdxKey == 1:
|
if key - w.lastIdxKey == 1:
|
||||||
|
|
@ -367,7 +365,8 @@ proc writeRod(w: PRodWriter) =
|
||||||
app(content, toRope(')' & rodNL))
|
app(content, toRope(')' & rodNL))
|
||||||
app(content, toRope("DATA(" & rodNL))
|
app(content, toRope("DATA(" & rodNL))
|
||||||
app(content, w.data)
|
app(content, w.data)
|
||||||
app(content, toRope(')' & rodNL)) #MessageOut('interf ' + ToString(ropeLen(w.interf)));
|
app(content, toRope(')' & rodNL))
|
||||||
|
#MessageOut('interf ' + ToString(ropeLen(w.interf)));
|
||||||
#MessageOut('index ' + ToString(ropeLen(w.indexRope)));
|
#MessageOut('index ' + ToString(ropeLen(w.indexRope)));
|
||||||
#MessageOut('init ' + ToString(ropeLen(w.init)));
|
#MessageOut('init ' + ToString(ropeLen(w.init)));
|
||||||
#MessageOut('data ' + ToString(ropeLen(w.data)));
|
#MessageOut('data ' + ToString(ropeLen(w.data)));
|
||||||
|
|
@ -411,7 +410,8 @@ proc process(c: PPassContext, n: PNode): PNode =
|
||||||
if a.kind == nkCommentStmt: continue
|
if a.kind == nkCommentStmt: continue
|
||||||
if a.sons[0].kind != nkSym: InternalError(a.info, "rodwrite.process")
|
if a.sons[0].kind != nkSym: InternalError(a.info, "rodwrite.process")
|
||||||
s = a.sons[0].sym
|
s = a.sons[0].sym
|
||||||
addInterfaceSym(w, s) # this takes care of enum fields too
|
addInterfaceSym(w, s)
|
||||||
|
# this takes care of enum fields too
|
||||||
# Note: The check for ``s.typ.kind = tyEnum`` is wrong for enum
|
# Note: The check for ``s.typ.kind = tyEnum`` is wrong for enum
|
||||||
# type aliasing! Otherwise the same enum symbol would be included
|
# type aliasing! Otherwise the same enum symbol would be included
|
||||||
# several times!
|
# several times!
|
||||||
|
|
@ -435,15 +435,13 @@ proc process(c: PPassContext, n: PNode): PNode =
|
||||||
nil
|
nil
|
||||||
|
|
||||||
proc myOpen(module: PSym, filename: string): PPassContext =
|
proc myOpen(module: PSym, filename: string): PPassContext =
|
||||||
var w: PRodWriter
|
|
||||||
if module.id < 0: InternalError("rodwrite: module ID not set")
|
if module.id < 0: InternalError("rodwrite: module ID not set")
|
||||||
w = newRodWriter(filename, rodread.GetCRC(filename), module)
|
var w = newRodWriter(filename, rodread.GetCRC(filename), module)
|
||||||
rawAddInterfaceSym(w, module)
|
rawAddInterfaceSym(w, module)
|
||||||
result = w
|
result = w
|
||||||
|
|
||||||
proc myClose(c: PPassContext, n: PNode): PNode =
|
proc myClose(c: PPassContext, n: PNode): PNode =
|
||||||
var w: PRodWriter
|
var w = PRodWriter(c)
|
||||||
w = PRodWriter(c)
|
|
||||||
writeRod(w)
|
writeRod(w)
|
||||||
result = n
|
result = n
|
||||||
|
|
||||||
|
|
|
||||||
71
rod/sem.nim
71
rod/sem.nim
|
|
@ -9,8 +9,7 @@
|
||||||
|
|
||||||
# This module implements the semantic checking pass.
|
# This module implements the semantic checking pass.
|
||||||
|
|
||||||
import #var
|
import
|
||||||
# point: array [0..3] of int;
|
|
||||||
strutils, nhashes, lists, options, scanner, ast, astalgo, trees, treetab,
|
strutils, nhashes, lists, options, scanner, ast, astalgo, trees, treetab,
|
||||||
wordrecg, ropes, msgs, os, condsyms, idents, rnimsyn, types, platform, math,
|
wordrecg, ropes, msgs, os, condsyms, idents, rnimsyn, types, platform, math,
|
||||||
magicsys, pnimsyn, nversion, nimsets, semdata, evals, semfold, importer,
|
magicsys, pnimsyn, nversion, nimsets, semdata, evals, semfold, importer,
|
||||||
|
|
@ -20,8 +19,7 @@ proc semPass*(): TPass
|
||||||
# implementation
|
# implementation
|
||||||
|
|
||||||
proc considerAcc(n: PNode): PIdent =
|
proc considerAcc(n: PNode): PIdent =
|
||||||
var x: PNode
|
var x = n
|
||||||
x = n
|
|
||||||
if x.kind == nkAccQuoted: x = x.sons[0]
|
if x.kind == nkAccQuoted: x = x.sons[0]
|
||||||
case x.kind
|
case x.kind
|
||||||
of nkIdent: result = x.ident
|
of nkIdent: result = x.ident
|
||||||
|
|
@ -62,6 +60,7 @@ proc addParams(c: PContext, n: PNode)
|
||||||
proc addResult(c: PContext, t: PType, info: TLineInfo)
|
proc addResult(c: PContext, t: PType, info: TLineInfo)
|
||||||
proc addResultNode(c: PContext, n: PNode)
|
proc addResultNode(c: PContext, n: PNode)
|
||||||
proc instGenericContainer(c: PContext, n: PNode, header: PType): PType
|
proc instGenericContainer(c: PContext, n: PNode, header: PType): PType
|
||||||
|
|
||||||
proc semConstExpr(c: PContext, n: PNode): PNode =
|
proc semConstExpr(c: PContext, n: PNode): PNode =
|
||||||
result = semExprWithType(c, n)
|
result = semExprWithType(c, n)
|
||||||
if result == nil:
|
if result == nil:
|
||||||
|
|
@ -71,8 +70,7 @@ proc semConstExpr(c: PContext, n: PNode): PNode =
|
||||||
if result == nil: liMessage(n.info, errConstExprExpected)
|
if result == nil: liMessage(n.info, errConstExprExpected)
|
||||||
|
|
||||||
proc semAndEvalConstExpr(c: PContext, n: PNode): PNode =
|
proc semAndEvalConstExpr(c: PContext, n: PNode): PNode =
|
||||||
var e: PNode
|
var e = semExprWithType(c, n)
|
||||||
e = semExprWithType(c, n)
|
|
||||||
if e == nil:
|
if e == nil:
|
||||||
liMessage(n.info, errConstExprExpected)
|
liMessage(n.info, errConstExprExpected)
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -91,19 +89,16 @@ proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode =
|
||||||
of tyTypeDesc: result.typ = semTypeNode(c, result, nil)
|
of tyTypeDesc: result.typ = semTypeNode(c, result, nil)
|
||||||
else: liMessage(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0]))
|
else: liMessage(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0]))
|
||||||
|
|
||||||
include
|
include "semtempl.nim"
|
||||||
"semtempl.nim"
|
|
||||||
|
|
||||||
proc semMacroExpr(c: PContext, n: PNode, sym: PSym, semCheck: bool = true): PNode =
|
proc semMacroExpr(c: PContext, n: PNode, sym: PSym,
|
||||||
var
|
semCheck: bool = true): PNode =
|
||||||
p: PEvalContext
|
|
||||||
s: PStackFrame
|
|
||||||
inc(evalTemplateCounter)
|
inc(evalTemplateCounter)
|
||||||
if evalTemplateCounter > 100:
|
if evalTemplateCounter > 100:
|
||||||
liMessage(n.info, errTemplateInstantiationTooNested)
|
liMessage(n.info, errTemplateInstantiationTooNested)
|
||||||
markUsed(n, sym)
|
markUsed(n, sym)
|
||||||
p = newEvalContext(c.module, "", false)
|
var p = newEvalContext(c.module, "", false)
|
||||||
s = newStackFrame()
|
var s = newStackFrame()
|
||||||
s.call = n
|
s.call = n
|
||||||
setlen(s.params, 2)
|
setlen(s.params, 2)
|
||||||
s.params[0] = newNodeIT(nkNilLit, n.info, sym.typ.sons[0])
|
s.params[0] = newNodeIT(nkNilLit, n.info, sym.typ.sons[0])
|
||||||
|
|
@ -116,11 +111,7 @@ proc semMacroExpr(c: PContext, n: PNode, sym: PSym, semCheck: bool = true): PNod
|
||||||
if semCheck: result = semAfterMacroCall(c, result, sym)
|
if semCheck: result = semAfterMacroCall(c, result, sym)
|
||||||
dec(evalTemplateCounter)
|
dec(evalTemplateCounter)
|
||||||
|
|
||||||
include
|
include "seminst.nim", "sigmatch.nim"
|
||||||
"seminst.nim"
|
|
||||||
|
|
||||||
include
|
|
||||||
"sigmatch.nim"
|
|
||||||
|
|
||||||
proc CheckBool(t: PNode) =
|
proc CheckBool(t: PNode) =
|
||||||
if (t.Typ == nil) or
|
if (t.Typ == nil) or
|
||||||
|
|
@ -132,37 +123,27 @@ proc typeMismatch(n: PNode, formal, actual: PType) =
|
||||||
typeToString(actual) & ") " &
|
typeToString(actual) & ") " &
|
||||||
`%`(msgKindToString(errButExpectedX), [typeToString(formal)]))
|
`%`(msgKindToString(errButExpectedX), [typeToString(formal)]))
|
||||||
|
|
||||||
include
|
include "semtypes.nim", "semexprs.nim", "semgnrc.nim", "semstmts.nim"
|
||||||
"semtypes.nim"
|
|
||||||
|
|
||||||
include
|
|
||||||
"semexprs.nim"
|
|
||||||
|
|
||||||
include
|
|
||||||
"semgnrc.nim"
|
|
||||||
|
|
||||||
include
|
|
||||||
"semstmts.nim"
|
|
||||||
|
|
||||||
proc addCodeForGenerics(c: PContext, n: PNode) =
|
proc addCodeForGenerics(c: PContext, n: PNode) =
|
||||||
var
|
|
||||||
prc: PSym
|
|
||||||
it: PNode
|
|
||||||
for i in countup(c.lastGenericIdx, sonsLen(c.generics) - 1):
|
for i in countup(c.lastGenericIdx, sonsLen(c.generics) - 1):
|
||||||
it = c.generics.sons[i].sons[1]
|
var it = c.generics.sons[i].sons[1]
|
||||||
if it.kind != nkSym: InternalError("addCodeForGenerics")
|
if it.kind != nkSym: InternalError("addCodeForGenerics")
|
||||||
prc = it.sym
|
var prc = it.sym
|
||||||
if (prc.kind in {skProc, skMethod, skConverter}) and (prc.magic == mNone):
|
if (prc.kind in {skProc, skMethod, skConverter}) and (prc.magic == mNone):
|
||||||
if (prc.ast == nil) or (prc.ast.sons[codePos] == nil):
|
if (prc.ast == nil) or (prc.ast.sons[codePos] == nil):
|
||||||
InternalError(prc.info, "no code for " & prc.name.s)
|
InternalError(prc.info, "no code for " & prc.name.s)
|
||||||
addSon(n, prc.ast)
|
addSon(n, prc.ast)
|
||||||
c.lastGenericIdx = sonsLen(c.generics)
|
c.lastGenericIdx = sonsLen(c.generics)
|
||||||
|
|
||||||
|
proc semExprNoFlags(c: PContext, n: PNode): PNode =
|
||||||
|
result = semExpr(c, n, {})
|
||||||
|
|
||||||
proc myOpen(module: PSym, filename: string): PPassContext =
|
proc myOpen(module: PSym, filename: string): PPassContext =
|
||||||
var c: PContext
|
var c = newContext(module, filename)
|
||||||
c = newContext(module, filename)
|
|
||||||
if (c.p != nil): InternalError(module.info, "sem.myOpen")
|
if (c.p != nil): InternalError(module.info, "sem.myOpen")
|
||||||
c.semConstExpr = semConstExpr
|
c.semConstExpr = semConstExpr
|
||||||
|
c.semExpr = semExprNoFlags
|
||||||
c.p = newProcCon(module)
|
c.p = newProcCon(module)
|
||||||
pushOwner(c.module)
|
pushOwner(c.module)
|
||||||
openScope(c.tab) # scope for imported symbols
|
openScope(c.tab) # scope for imported symbols
|
||||||
|
|
@ -177,20 +158,17 @@ proc myOpen(module: PSym, filename: string): PPassContext =
|
||||||
result = c
|
result = c
|
||||||
|
|
||||||
proc myOpenCached(module: PSym, filename: string, rd: PRodReader): PPassContext =
|
proc myOpenCached(module: PSym, filename: string, rd: PRodReader): PPassContext =
|
||||||
var c: PContext
|
var c = PContext(myOpen(module, filename))
|
||||||
c = PContext(myOpen(module, filename))
|
|
||||||
c.fromCache = true
|
c.fromCache = true
|
||||||
result = c
|
result = c
|
||||||
|
|
||||||
proc myProcess(context: PPassContext, n: PNode): PNode =
|
proc myProcess(context: PPassContext, n: PNode): PNode =
|
||||||
var
|
|
||||||
c: PContext
|
|
||||||
a: PNode
|
|
||||||
result = nil
|
result = nil
|
||||||
c = PContext(context)
|
var c = PContext(context)
|
||||||
result = semStmt(c, n) # BUGFIX: process newly generated generics here, not at the end!
|
result = semStmt(c, n)
|
||||||
|
# BUGFIX: process newly generated generics here, not at the end!
|
||||||
if sonsLen(c.generics) > 0:
|
if sonsLen(c.generics) > 0:
|
||||||
a = newNodeI(nkStmtList, n.info)
|
var a = newNodeI(nkStmtList, n.info)
|
||||||
addCodeForGenerics(c, a)
|
addCodeForGenerics(c, a)
|
||||||
if sonsLen(a) > 0:
|
if sonsLen(a) > 0:
|
||||||
# a generic has been added to `a`:
|
# a generic has been added to `a`:
|
||||||
|
|
@ -198,8 +176,7 @@ proc myProcess(context: PPassContext, n: PNode): PNode =
|
||||||
result = a
|
result = a
|
||||||
|
|
||||||
proc myClose(context: PPassContext, n: PNode): PNode =
|
proc myClose(context: PPassContext, n: PNode): PNode =
|
||||||
var c: PContext
|
var c = PContext(context)
|
||||||
c = PContext(context)
|
|
||||||
closeScope(c.tab) # close module's scope
|
closeScope(c.tab) # close module's scope
|
||||||
rawCloseScope(c.tab) # imported symbols; don't check for unused ones!
|
rawCloseScope(c.tab) # imported symbols; don't check for unused ones!
|
||||||
if n == nil:
|
if n == nil:
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@ import
|
||||||
magicsys, nversion, nimsets, pnimsyn, times, passes, rodread
|
magicsys, nversion, nimsets, pnimsyn, times, passes, rodread
|
||||||
|
|
||||||
type
|
type
|
||||||
TOptionEntry* = object of lists.TListEntry # entries to put on a stack for pragma parsing
|
TOptionEntry* = object of lists.TListEntry # entries to put on a
|
||||||
|
# stack for pragma parsing
|
||||||
options*: TOptions
|
options*: TOptions
|
||||||
defaultCC*: TCallingConvention
|
defaultCC*: TCallingConvention
|
||||||
dynlib*: PLib
|
dynlib*: PLib
|
||||||
|
|
@ -46,15 +47,16 @@ type
|
||||||
optionStack*: TLinkedList
|
optionStack*: TLinkedList
|
||||||
libs*: TLinkedList # all libs used by this module
|
libs*: TLinkedList # all libs used by this module
|
||||||
fromCache*: bool # is the module read from a cache?
|
fromCache*: bool # is the module read from a cache?
|
||||||
semConstExpr*: proc (c: PContext, n: PNode): PNode # for the pragmas module
|
semConstExpr*: proc (c: PContext, n: PNode): PNode # for the pragmas
|
||||||
|
semExpr*: proc (c: PContext, n: PNode): PNode # for the pragmas
|
||||||
includedFiles*: TIntSet # used to detect recursive include files
|
includedFiles*: TIntSet # used to detect recursive include files
|
||||||
filename*: string # the module's filename
|
filename*: string # the module's filename
|
||||||
|
|
||||||
|
|
||||||
var gInstTypes*: TIdTable
|
var gInstTypes*: TIdTable # map PType to PType
|
||||||
|
|
||||||
proc newContext*(module: PSym, nimfile: string): PContext
|
proc newContext*(module: PSym, nimfile: string): PContext
|
||||||
# map PType to PType
|
|
||||||
proc newProcCon*(owner: PSym): PProcCon
|
proc newProcCon*(owner: PSym): PProcCon
|
||||||
proc lastOptionEntry*(c: PContext): POptionEntry
|
proc lastOptionEntry*(c: PContext): POptionEntry
|
||||||
proc newOptionEntry*(): POptionEntry
|
proc newOptionEntry*(): POptionEntry
|
||||||
|
|
@ -70,15 +72,15 @@ proc illFormedAst*(n: PNode)
|
||||||
proc getSon*(n: PNode, indx: int): PNode
|
proc getSon*(n: PNode, indx: int): PNode
|
||||||
proc checkSonsLen*(n: PNode, length: int)
|
proc checkSonsLen*(n: PNode, length: int)
|
||||||
proc checkMinSonsLen*(n: PNode, length: int)
|
proc checkMinSonsLen*(n: PNode, length: int)
|
||||||
# owner handling:
|
|
||||||
|
# owner handling:
|
||||||
proc getCurrOwner*(): PSym
|
proc getCurrOwner*(): PSym
|
||||||
proc PushOwner*(owner: PSym)
|
proc PushOwner*(owner: PSym)
|
||||||
proc PopOwner*()
|
proc PopOwner*()
|
||||||
# implementation
|
# implementation
|
||||||
|
|
||||||
var gOwners: seq[PSym]
|
var gOwners: seq[PSym] = @[]
|
||||||
|
|
||||||
gOwners = @ []
|
|
||||||
proc getCurrOwner(): PSym =
|
proc getCurrOwner(): PSym =
|
||||||
# owner stack (used for initializing the
|
# owner stack (used for initializing the
|
||||||
# owner field of syms)
|
# owner field of syms)
|
||||||
|
|
@ -88,14 +90,10 @@ proc getCurrOwner(): PSym =
|
||||||
result = gOwners[high(gOwners)]
|
result = gOwners[high(gOwners)]
|
||||||
|
|
||||||
proc PushOwner(owner: PSym) =
|
proc PushOwner(owner: PSym) =
|
||||||
var length: int
|
add(gOwners, owner)
|
||||||
length = len(gOwners)
|
|
||||||
setlen(gOwners, length + 1)
|
|
||||||
gOwners[length] = owner
|
|
||||||
|
|
||||||
proc PopOwner() =
|
proc PopOwner() =
|
||||||
var length: int
|
var length = len(gOwners)
|
||||||
length = len(gOwners)
|
|
||||||
if (length <= 0): InternalError("popOwner")
|
if (length <= 0): InternalError("popOwner")
|
||||||
setlen(gOwners, length - 1)
|
setlen(gOwners, length - 1)
|
||||||
|
|
||||||
|
|
@ -128,8 +126,7 @@ proc newContext(module: PSym, nimfile: string): PContext =
|
||||||
IntSetInit(result.includedFiles)
|
IntSetInit(result.includedFiles)
|
||||||
|
|
||||||
proc addConverter(c: PContext, conv: PSym) =
|
proc addConverter(c: PContext, conv: PSym) =
|
||||||
var L: int
|
var L = len(c.converters)
|
||||||
L = len(c.converters)
|
|
||||||
for i in countup(0, L - 1):
|
for i in countup(0, L - 1):
|
||||||
if c.converters[i].id == conv.id: return
|
if c.converters[i].id == conv.id: return
|
||||||
setlen(c.converters, L + 1)
|
setlen(c.converters, L + 1)
|
||||||
|
|
@ -162,9 +159,9 @@ proc fillTypeS(dest: PType, kind: TTypeKind, c: PContext) =
|
||||||
dest.owner = getCurrOwner()
|
dest.owner = getCurrOwner()
|
||||||
dest.size = - 1
|
dest.size = - 1
|
||||||
|
|
||||||
proc makeRangeType(c: PContext, first, last: biggestInt, info: TLineInfo): PType =
|
proc makeRangeType(c: PContext, first, last: biggestInt,
|
||||||
var n: PNode
|
info: TLineInfo): PType =
|
||||||
n = newNodeI(nkRange, info)
|
var n = newNodeI(nkRange, info)
|
||||||
addSon(n, newIntNode(nkIntLit, first))
|
addSon(n, newIntNode(nkIntLit, first))
|
||||||
addSon(n, newIntNode(nkIntLit, last))
|
addSon(n, newIntNode(nkIntLit, last))
|
||||||
result = newTypeS(tyRange, c)
|
result = newTypeS(tyRange, c)
|
||||||
|
|
|
||||||
275
rod/semfold.nim
275
rod/semfold.nim
|
|
@ -14,7 +14,7 @@ import
|
||||||
strutils, lists, options, ast, astalgo, trees, treetab, nimsets, times,
|
strutils, lists, options, ast, astalgo, trees, treetab, nimsets, times,
|
||||||
nversion, platform, math, msgs, os, condsyms, idents, rnimsyn, types
|
nversion, platform, math, msgs, os, condsyms, idents, rnimsyn, types
|
||||||
|
|
||||||
proc getConstExpr*(module: PSym, n: PNode): PNode
|
proc getConstExpr*(m: PSym, n: PNode): PNode
|
||||||
# evaluates the constant expression or returns nil if it is no constant
|
# evaluates the constant expression or returns nil if it is no constant
|
||||||
# expression
|
# expression
|
||||||
proc evalOp*(m: TMagic, n, a, b, c: PNode): PNode
|
proc evalOp*(m: TMagic, n, a, b, c: PNode): PNode
|
||||||
|
|
@ -22,10 +22,7 @@ proc leValueConv*(a, b: PNode): bool
|
||||||
proc newIntNodeT*(intVal: BiggestInt, n: PNode): PNode
|
proc newIntNodeT*(intVal: BiggestInt, n: PNode): PNode
|
||||||
proc newFloatNodeT*(floatVal: BiggestFloat, n: PNode): PNode
|
proc newFloatNodeT*(floatVal: BiggestFloat, n: PNode): PNode
|
||||||
proc newStrNodeT*(strVal: string, n: PNode): PNode
|
proc newStrNodeT*(strVal: string, n: PNode): PNode
|
||||||
proc getInt*(a: PNode): biggestInt
|
|
||||||
proc getFloat*(a: PNode): biggestFloat
|
|
||||||
proc getStr*(a: PNode): string
|
|
||||||
proc getStrOrChar*(a: PNode): string
|
|
||||||
# implementation
|
# implementation
|
||||||
|
|
||||||
proc newIntNodeT(intVal: BiggestInt, n: PNode): PNode =
|
proc newIntNodeT(intVal: BiggestInt, n: PNode): PNode =
|
||||||
|
|
@ -46,35 +43,6 @@ proc newStrNodeT(strVal: string, n: PNode): PNode =
|
||||||
result.typ = n.typ
|
result.typ = n.typ
|
||||||
result.info = n.info
|
result.info = n.info
|
||||||
|
|
||||||
proc getInt(a: PNode): biggestInt =
|
|
||||||
case a.kind
|
|
||||||
of nkIntLit..nkInt64Lit: result = a.intVal
|
|
||||||
else:
|
|
||||||
internalError(a.info, "getInt")
|
|
||||||
result = 0
|
|
||||||
|
|
||||||
proc getFloat(a: PNode): biggestFloat =
|
|
||||||
case a.kind
|
|
||||||
of nkFloatLit..nkFloat64Lit: result = a.floatVal
|
|
||||||
else:
|
|
||||||
internalError(a.info, "getFloat")
|
|
||||||
result = 0.0
|
|
||||||
|
|
||||||
proc getStr(a: PNode): string =
|
|
||||||
case a.kind
|
|
||||||
of nkStrLit..nkTripleStrLit: result = a.strVal
|
|
||||||
else:
|
|
||||||
internalError(a.info, "getStr")
|
|
||||||
result = ""
|
|
||||||
|
|
||||||
proc getStrOrChar(a: PNode): string =
|
|
||||||
case a.kind
|
|
||||||
of nkStrLit..nkTripleStrLit: result = a.strVal
|
|
||||||
of nkCharLit: result = chr(int(a.intVal)) & ""
|
|
||||||
else:
|
|
||||||
internalError(a.info, "getStrOrChar")
|
|
||||||
result = ""
|
|
||||||
|
|
||||||
proc enumValToString(a: PNode): string =
|
proc enumValToString(a: PNode): string =
|
||||||
var
|
var
|
||||||
n: PNode
|
n: PNode
|
||||||
|
|
@ -93,56 +61,35 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
|
||||||
# b and c may be nil
|
# b and c may be nil
|
||||||
result = nil
|
result = nil
|
||||||
case m
|
case m
|
||||||
of mOrd:
|
of mOrd: result = newIntNodeT(getOrdValue(a), n)
|
||||||
result = newIntNodeT(getOrdValue(a), n)
|
of mChr: result = newIntNodeT(getInt(a), n)
|
||||||
of mChr:
|
of mUnaryMinusI, mUnaryMinusI64: result = newIntNodeT(- getInt(a), n)
|
||||||
result = newIntNodeT(getInt(a), n)
|
of mUnaryMinusF64: result = newFloatNodeT(- getFloat(a), n)
|
||||||
of mUnaryMinusI, mUnaryMinusI64:
|
of mNot: result = newIntNodeT(1 - getInt(a), n)
|
||||||
result = newIntNodeT(- getInt(a), n)
|
of mCard: result = newIntNodeT(nimsets.cardSet(a), n)
|
||||||
of mUnaryMinusF64:
|
of mBitnotI, mBitnotI64: result = newIntNodeT(not getInt(a), n)
|
||||||
result = newFloatNodeT(- getFloat(a), n)
|
of mLengthStr: result = newIntNodeT(len(getStr(a)), n)
|
||||||
of mNot:
|
of mLengthArray: result = newIntNodeT(lengthOrd(a.typ), n)
|
||||||
result = newIntNodeT(1 - getInt(a), n)
|
of mLengthSeq, mLengthOpenArray: result = newIntNodeT(sonsLen(a), n) # BUGFIX
|
||||||
of mCard:
|
of mUnaryPlusI, mUnaryPlusI64, mUnaryPlusF64: result = a # throw `+` away
|
||||||
result = newIntNodeT(nimsets.cardSet(a), n)
|
|
||||||
of mBitnotI, mBitnotI64:
|
|
||||||
result = newIntNodeT(not getInt(a), n)
|
|
||||||
of mLengthStr:
|
|
||||||
result = newIntNodeT(len(getStr(a)), n)
|
|
||||||
of mLengthArray:
|
|
||||||
result = newIntNodeT(lengthOrd(a.typ), n)
|
|
||||||
of mLengthSeq, mLengthOpenArray:
|
|
||||||
result = newIntNodeT(sonsLen(a), n) # BUGFIX
|
|
||||||
of mUnaryPlusI, mUnaryPlusI64, mUnaryPlusF64:
|
|
||||||
result = a # throw `+` away
|
|
||||||
of mToFloat, mToBiggestFloat:
|
of mToFloat, mToBiggestFloat:
|
||||||
result = newFloatNodeT(toFloat(int(getInt(a))), n)
|
result = newFloatNodeT(toFloat(int(getInt(a))), n)
|
||||||
of mToInt, mToBiggestInt:
|
of mToInt, mToBiggestInt: result = newIntNodeT(system.toInt(getFloat(a)), n)
|
||||||
result = newIntNodeT(system.toInt(getFloat(a)), n)
|
of mAbsF64: result = newFloatNodeT(abs(getFloat(a)), n)
|
||||||
of mAbsF64:
|
|
||||||
result = newFloatNodeT(abs(getFloat(a)), n)
|
|
||||||
of mAbsI, mAbsI64:
|
of mAbsI, mAbsI64:
|
||||||
if getInt(a) >= 0: result = a
|
if getInt(a) >= 0: result = a
|
||||||
else: result = newIntNodeT(- getInt(a), n)
|
else: result = newIntNodeT(- getInt(a), n)
|
||||||
of mZe8ToI, mZe8ToI64, mZe16ToI, mZe16ToI64, mZe32ToI64, mZeIToI64:
|
of mZe8ToI, mZe8ToI64, mZe16ToI, mZe16ToI64, mZe32ToI64, mZeIToI64:
|
||||||
# byte(-128) = 1...1..1000_0000'64 --> 0...0..1000_0000'64
|
# byte(-128) = 1...1..1000_0000'64 --> 0...0..1000_0000'64
|
||||||
result = newIntNodeT(getInt(a) and (`shl`(1, getSize(a.typ) * 8) - 1), n)
|
result = newIntNodeT(getInt(a) and (`shl`(1, getSize(a.typ) * 8) - 1), n)
|
||||||
of mToU8:
|
of mToU8: result = newIntNodeT(getInt(a) and 0x000000FF, n)
|
||||||
result = newIntNodeT(getInt(a) and 0x000000FF, n)
|
of mToU16: result = newIntNodeT(getInt(a) and 0x0000FFFF, n)
|
||||||
of mToU16:
|
of mToU32: result = newIntNodeT(getInt(a) and 0x00000000FFFFFFFF'i64, n)
|
||||||
result = newIntNodeT(getInt(a) and 0x0000FFFF, n)
|
of mSucc: result = newIntNodeT(getOrdValue(a) + getInt(b), n)
|
||||||
of mToU32:
|
of mPred: result = newIntNodeT(getOrdValue(a) - getInt(b), n)
|
||||||
result = newIntNodeT(getInt(a) and 0x00000000FFFFFFFF'i64, n)
|
of mAddI, mAddI64: result = newIntNodeT(getInt(a) + getInt(b), n)
|
||||||
of mSucc:
|
of mSubI, mSubI64: result = newIntNodeT(getInt(a) - getInt(b), n)
|
||||||
result = newIntNodeT(getOrdValue(a) + getInt(b), n)
|
of mMulI, mMulI64: result = newIntNodeT(getInt(a) * getInt(b), n)
|
||||||
of mPred:
|
|
||||||
result = newIntNodeT(getOrdValue(a) - getInt(b), n)
|
|
||||||
of mAddI, mAddI64:
|
|
||||||
result = newIntNodeT(getInt(a) + getInt(b), n)
|
|
||||||
of mSubI, mSubI64:
|
|
||||||
result = newIntNodeT(getInt(a) - getInt(b), n)
|
|
||||||
of mMulI, mMulI64:
|
|
||||||
result = newIntNodeT(getInt(a) * getInt(b), n)
|
|
||||||
of mMinI, mMinI64:
|
of mMinI, mMinI64:
|
||||||
if getInt(a) > getInt(b): result = newIntNodeT(getInt(b), n)
|
if getInt(a) > getInt(b): result = newIntNodeT(getInt(b), n)
|
||||||
else: result = newIntNodeT(getInt(a), n)
|
else: result = newIntNodeT(getInt(a), n)
|
||||||
|
|
@ -163,16 +110,11 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
|
||||||
of tyInt32: result = newIntNodeT(int32(getInt(a)) shr int32(getInt(b)), n)
|
of tyInt32: result = newIntNodeT(int32(getInt(a)) shr int32(getInt(b)), n)
|
||||||
of tyInt64, tyInt: result = newIntNodeT(`shr`(getInt(a), getInt(b)), n)
|
of tyInt64, tyInt: result = newIntNodeT(`shr`(getInt(a), getInt(b)), n)
|
||||||
else: InternalError(n.info, "constant folding for shl")
|
else: InternalError(n.info, "constant folding for shl")
|
||||||
of mDivI, mDivI64:
|
of mDivI, mDivI64: result = newIntNodeT(getInt(a) div getInt(b), n)
|
||||||
result = newIntNodeT(getInt(a) div getInt(b), n)
|
of mModI, mModI64: result = newIntNodeT(getInt(a) mod getInt(b), n)
|
||||||
of mModI, mModI64:
|
of mAddF64: result = newFloatNodeT(getFloat(a) + getFloat(b), n)
|
||||||
result = newIntNodeT(getInt(a) mod getInt(b), n)
|
of mSubF64: result = newFloatNodeT(getFloat(a) - getFloat(b), n)
|
||||||
of mAddF64:
|
of mMulF64: result = newFloatNodeT(getFloat(a) * getFloat(b), n)
|
||||||
result = newFloatNodeT(getFloat(a) + getFloat(b), n)
|
|
||||||
of mSubF64:
|
|
||||||
result = newFloatNodeT(getFloat(a) - getFloat(b), n)
|
|
||||||
of mMulF64:
|
|
||||||
result = newFloatNodeT(getFloat(a) * getFloat(b), n)
|
|
||||||
of mDivF64:
|
of mDivF64:
|
||||||
if getFloat(b) == 0.0:
|
if getFloat(b) == 0.0:
|
||||||
if getFloat(a) == 0.0: result = newFloatNodeT(NaN, n)
|
if getFloat(a) == 0.0: result = newFloatNodeT(NaN, n)
|
||||||
|
|
@ -185,50 +127,33 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
|
||||||
of mMinF64:
|
of mMinF64:
|
||||||
if getFloat(a) > getFloat(b): result = newFloatNodeT(getFloat(b), n)
|
if getFloat(a) > getFloat(b): result = newFloatNodeT(getFloat(b), n)
|
||||||
else: result = newFloatNodeT(getFloat(a), n)
|
else: result = newFloatNodeT(getFloat(a), n)
|
||||||
of mIsNil:
|
of mIsNil: result = newIntNodeT(ord(a.kind == nkNilLit), n)
|
||||||
result = newIntNodeT(ord(a.kind == nkNilLit), n)
|
|
||||||
of mLtI, mLtI64, mLtB, mLtEnum, mLtCh:
|
of mLtI, mLtI64, mLtB, mLtEnum, mLtCh:
|
||||||
result = newIntNodeT(ord(getOrdValue(a) < getOrdValue(b)), n)
|
result = newIntNodeT(ord(getOrdValue(a) < getOrdValue(b)), n)
|
||||||
of mLeI, mLeI64, mLeB, mLeEnum, mLeCh:
|
of mLeI, mLeI64, mLeB, mLeEnum, mLeCh:
|
||||||
result = newIntNodeT(ord(getOrdValue(a) <= getOrdValue(b)), n)
|
result = newIntNodeT(ord(getOrdValue(a) <= getOrdValue(b)), n)
|
||||||
of mEqI, mEqI64, mEqB, mEqEnum, mEqCh:
|
of mEqI, mEqI64, mEqB, mEqEnum, mEqCh:
|
||||||
result = newIntNodeT(ord(getOrdValue(a) == getOrdValue(b)), n) # operators for floats
|
result = newIntNodeT(ord(getOrdValue(a) == getOrdValue(b)), n)
|
||||||
of mLtF64:
|
of mLtF64: result = newIntNodeT(ord(getFloat(a) < getFloat(b)), n)
|
||||||
result = newIntNodeT(ord(getFloat(a) < getFloat(b)), n)
|
of mLeF64: result = newIntNodeT(ord(getFloat(a) <= getFloat(b)), n)
|
||||||
of mLeF64:
|
of mEqF64: result = newIntNodeT(ord(getFloat(a) == getFloat(b)), n)
|
||||||
result = newIntNodeT(ord(getFloat(a) <= getFloat(b)), n)
|
of mLtStr: result = newIntNodeT(ord(getStr(a) < getStr(b)), n)
|
||||||
of mEqF64:
|
of mLeStr: result = newIntNodeT(ord(getStr(a) <= getStr(b)), n)
|
||||||
result = newIntNodeT(ord(getFloat(a) == getFloat(b)), n) # operators for strings
|
of mEqStr: result = newIntNodeT(ord(getStr(a) == getStr(b)), n)
|
||||||
of mLtStr:
|
|
||||||
result = newIntNodeT(ord(getStr(a) < getStr(b)), n)
|
|
||||||
of mLeStr:
|
|
||||||
result = newIntNodeT(ord(getStr(a) <= getStr(b)), n)
|
|
||||||
of mEqStr:
|
|
||||||
result = newIntNodeT(ord(getStr(a) == getStr(b)), n)
|
|
||||||
of mLtU, mLtU64:
|
of mLtU, mLtU64:
|
||||||
result = newIntNodeT(ord(`<%`(getOrdValue(a), getOrdValue(b))), n)
|
result = newIntNodeT(ord(`<%`(getOrdValue(a), getOrdValue(b))), n)
|
||||||
of mLeU, mLeU64:
|
of mLeU, mLeU64:
|
||||||
result = newIntNodeT(ord(`<=%`(getOrdValue(a), getOrdValue(b))), n)
|
result = newIntNodeT(ord(`<=%`(getOrdValue(a), getOrdValue(b))), n)
|
||||||
of mBitandI, mBitandI64, mAnd:
|
of mBitandI, mBitandI64, mAnd: result = newIntNodeT(getInt(a) and getInt(b), n)
|
||||||
result = newIntNodeT(getInt(a) and getInt(b), n)
|
of mBitorI, mBitorI64, mOr: result = newIntNodeT(getInt(a) or getInt(b), n)
|
||||||
of mBitorI, mBitorI64, mOr:
|
of mBitxorI, mBitxorI64, mXor: result = newIntNodeT(getInt(a) xor getInt(b), n)
|
||||||
result = newIntNodeT(getInt(a) or getInt(b), n)
|
of mAddU, mAddU64: result = newIntNodeT(`+%`(getInt(a), getInt(b)), n)
|
||||||
of mBitxorI, mBitxorI64, mXor:
|
of mSubU, mSubU64: result = newIntNodeT(`-%`(getInt(a), getInt(b)), n)
|
||||||
result = newIntNodeT(getInt(a) xor getInt(b), n)
|
of mMulU, mMulU64: result = newIntNodeT(`*%`(getInt(a), getInt(b)), n)
|
||||||
of mAddU, mAddU64:
|
of mModU, mModU64: result = newIntNodeT(`%%`(getInt(a), getInt(b)), n)
|
||||||
result = newIntNodeT(`+%`(getInt(a), getInt(b)), n)
|
of mDivU, mDivU64: result = newIntNodeT(`/%`(getInt(a), getInt(b)), n)
|
||||||
of mSubU, mSubU64:
|
of mLeSet: result = newIntNodeT(Ord(containsSets(a, b)), n)
|
||||||
result = newIntNodeT(`-%`(getInt(a), getInt(b)), n)
|
of mEqSet: result = newIntNodeT(Ord(equalSets(a, b)), n)
|
||||||
of mMulU, mMulU64:
|
|
||||||
result = newIntNodeT(`*%`(getInt(a), getInt(b)), n)
|
|
||||||
of mModU, mModU64:
|
|
||||||
result = newIntNodeT(`%%`(getInt(a), getInt(b)), n)
|
|
||||||
of mDivU, mDivU64:
|
|
||||||
result = newIntNodeT(`/%`(getInt(a), getInt(b)), n)
|
|
||||||
of mLeSet:
|
|
||||||
result = newIntNodeT(Ord(containsSets(a, b)), n)
|
|
||||||
of mEqSet:
|
|
||||||
result = newIntNodeT(Ord(equalSets(a, b)), n)
|
|
||||||
of mLtSet:
|
of mLtSet:
|
||||||
result = newIntNodeT(Ord(containsSets(a, b) and not equalSets(a, b)), n)
|
result = newIntNodeT(Ord(containsSets(a, b) and not equalSets(a, b)), n)
|
||||||
of mMulSet:
|
of mMulSet:
|
||||||
|
|
@ -243,32 +168,24 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
|
||||||
of mSymDiffSet:
|
of mSymDiffSet:
|
||||||
result = nimsets.symdiffSets(a, b)
|
result = nimsets.symdiffSets(a, b)
|
||||||
result.info = n.info
|
result.info = n.info
|
||||||
of mConStrStr:
|
of mConStrStr: result = newStrNodeT(getStrOrChar(a) & getStrOrChar(b), n)
|
||||||
result = newStrNodeT(getStrOrChar(a) & getStrOrChar(b), n)
|
of mInSet: result = newIntNodeT(Ord(inSet(a, b)), n)
|
||||||
of mInSet:
|
|
||||||
result = newIntNodeT(Ord(inSet(a, b)), n)
|
|
||||||
of mRepr:
|
of mRepr:
|
||||||
# BUGFIX: we cannot eval mRepr here. But this means that it is not
|
# BUGFIX: we cannot eval mRepr here. But this means that it is not
|
||||||
# available for interpretation. I don't know how to fix this.
|
# available for interpretation. I don't know how to fix this.
|
||||||
#result := newStrNodeT(renderTree(a, {@set}[renderNoComments]), n);
|
#result := newStrNodeT(renderTree(a, {@set}[renderNoComments]), n);
|
||||||
of mIntToStr, mInt64ToStr:
|
of mIntToStr, mInt64ToStr: result = newStrNodeT($(getOrdValue(a)), n)
|
||||||
result = newStrNodeT($(getOrdValue(a)), n)
|
|
||||||
of mBoolToStr:
|
of mBoolToStr:
|
||||||
if getOrdValue(a) == 0: result = newStrNodeT("false", n)
|
if getOrdValue(a) == 0: result = newStrNodeT("false", n)
|
||||||
else: result = newStrNodeT("true", n)
|
else: result = newStrNodeT("true", n)
|
||||||
of mCopyStr:
|
of mCopyStr: result = newStrNodeT(copy(getStr(a), int(getOrdValue(b))), n)
|
||||||
result = newStrNodeT(copy(getStr(a), int(getOrdValue(b)) + 0), n)
|
|
||||||
of mCopyStrLast:
|
of mCopyStrLast:
|
||||||
result = newStrNodeT(copy(getStr(a), int(getOrdValue(b)) + 0,
|
result = newStrNodeT(copy(getStr(a), int(getOrdValue(b)),
|
||||||
int(getOrdValue(c)) + 0), n)
|
int(getOrdValue(c))), n)
|
||||||
of mFloatToStr:
|
of mFloatToStr: result = newStrNodeT($(getFloat(a)), n)
|
||||||
result = newStrNodeT($(getFloat(a)), n)
|
of mCStrToStr, mCharToStr: result = newStrNodeT(getStrOrChar(a), n)
|
||||||
of mCStrToStr, mCharToStr:
|
of mStrToStr: result = a
|
||||||
result = newStrNodeT(getStrOrChar(a), n)
|
of mEnumToStr: result = newStrNodeT(enumValToString(a), n)
|
||||||
of mStrToStr:
|
|
||||||
result = a
|
|
||||||
of mEnumToStr:
|
|
||||||
result = newStrNodeT(enumValToString(a), n)
|
|
||||||
of mArrToSeq:
|
of mArrToSeq:
|
||||||
result = copyTree(a)
|
result = copyTree(a)
|
||||||
result.typ = n.typ
|
result.typ = n.typ
|
||||||
|
|
@ -278,15 +195,13 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
|
||||||
else: InternalError(a.info, "evalOp(" & $m & ')')
|
else: InternalError(a.info, "evalOp(" & $m & ')')
|
||||||
|
|
||||||
proc getConstIfExpr(c: PSym, n: PNode): PNode =
|
proc getConstIfExpr(c: PSym, n: PNode): PNode =
|
||||||
var it, e: PNode
|
|
||||||
result = nil
|
result = nil
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
it = n.sons[i]
|
var it = n.sons[i]
|
||||||
case it.kind
|
case it.kind
|
||||||
of nkElifExpr:
|
of nkElifExpr:
|
||||||
e = getConstExpr(c, it.sons[0])
|
var e = getConstExpr(c, it.sons[0])
|
||||||
if e == nil:
|
if e == nil: return nil
|
||||||
return nil
|
|
||||||
if getOrdValue(e) != 0:
|
if getOrdValue(e) != 0:
|
||||||
if result == nil:
|
if result == nil:
|
||||||
result = getConstExpr(c, it.sons[1])
|
result = getConstExpr(c, it.sons[1])
|
||||||
|
|
@ -297,10 +212,9 @@ proc getConstIfExpr(c: PSym, n: PNode): PNode =
|
||||||
|
|
||||||
proc partialAndExpr(c: PSym, n: PNode): PNode =
|
proc partialAndExpr(c: PSym, n: PNode): PNode =
|
||||||
# partial evaluation
|
# partial evaluation
|
||||||
var a, b: PNode
|
|
||||||
result = n
|
result = n
|
||||||
a = getConstExpr(c, n.sons[1])
|
var a = getConstExpr(c, n.sons[1])
|
||||||
b = getConstExpr(c, n.sons[2])
|
var b = getConstExpr(c, n.sons[2])
|
||||||
if a != nil:
|
if a != nil:
|
||||||
if getInt(a) == 0: result = a
|
if getInt(a) == 0: result = a
|
||||||
elif b != nil: result = b
|
elif b != nil: result = b
|
||||||
|
|
@ -311,10 +225,9 @@ proc partialAndExpr(c: PSym, n: PNode): PNode =
|
||||||
|
|
||||||
proc partialOrExpr(c: PSym, n: PNode): PNode =
|
proc partialOrExpr(c: PSym, n: PNode): PNode =
|
||||||
# partial evaluation
|
# partial evaluation
|
||||||
var a, b: PNode
|
|
||||||
result = n
|
result = n
|
||||||
a = getConstExpr(c, n.sons[1])
|
var a = getConstExpr(c, n.sons[1])
|
||||||
b = getConstExpr(c, n.sons[2])
|
var b = getConstExpr(c, n.sons[2])
|
||||||
if a != nil:
|
if a != nil:
|
||||||
if getInt(a) != 0: result = a
|
if getInt(a) != 0: result = a
|
||||||
elif b != nil: result = b
|
elif b != nil: result = b
|
||||||
|
|
@ -338,20 +251,16 @@ proc leValueConv(a, b: PNode): bool =
|
||||||
else: InternalError(a.info, "leValueConv")
|
else: InternalError(a.info, "leValueConv")
|
||||||
else: InternalError(a.info, "leValueConv")
|
else: InternalError(a.info, "leValueConv")
|
||||||
|
|
||||||
proc getConstExpr(module: PSym, n: PNode): PNode =
|
proc getConstExpr(m: PSym, n: PNode): PNode =
|
||||||
var
|
|
||||||
s: PSym
|
|
||||||
a, b, c: PNode
|
|
||||||
result = nil
|
result = nil
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkSym:
|
of nkSym:
|
||||||
s = n.sym
|
var s = n.sym
|
||||||
if s.kind == skEnumField:
|
if s.kind == skEnumField:
|
||||||
result = newIntNodeT(s.position, n)
|
result = newIntNodeT(s.position, n)
|
||||||
elif (s.kind == skConst):
|
elif (s.kind == skConst):
|
||||||
case s.magic
|
case s.magic
|
||||||
of mIsMainModule: result = newIntNodeT(ord(sfMainModule in module.flags),
|
of mIsMainModule: result = newIntNodeT(ord(sfMainModule in m.flags), n)
|
||||||
n)
|
|
||||||
of mCompileDate: result = newStrNodeT(times.getDateStr(), n)
|
of mCompileDate: result = newStrNodeT(times.getDateStr(), n)
|
||||||
of mCompileTime: result = newStrNodeT(times.getClockStr(), n)
|
of mCompileTime: result = newStrNodeT(times.getClockStr(), n)
|
||||||
of mNimrodVersion: result = newStrNodeT(VersionAsString, n)
|
of mNimrodVersion: result = newStrNodeT(VersionAsString, n)
|
||||||
|
|
@ -364,29 +273,28 @@ proc getConstExpr(module: PSym, n: PNode): PNode =
|
||||||
of mNaN: result = newFloatNodeT(NaN, n)
|
of mNaN: result = newFloatNodeT(NaN, n)
|
||||||
of mInf: result = newFloatNodeT(Inf, n)
|
of mInf: result = newFloatNodeT(Inf, n)
|
||||||
of mNegInf: result = newFloatNodeT(NegInf, n)
|
of mNegInf: result = newFloatNodeT(NegInf, n)
|
||||||
else:
|
else: result = copyTree(s.ast)
|
||||||
result = copyTree(s.ast) # BUGFIX
|
|
||||||
elif s.kind in {skProc, skMethod}: # BUGFIX
|
elif s.kind in {skProc, skMethod}: # BUGFIX
|
||||||
result = n
|
result = n
|
||||||
of nkCharLit..nkNilLit:
|
of nkCharLit..nkNilLit:
|
||||||
result = copyNode(n)
|
result = copyNode(n)
|
||||||
of nkIfExpr:
|
of nkIfExpr:
|
||||||
result = getConstIfExpr(module, n)
|
result = getConstIfExpr(m, n)
|
||||||
of nkCall, nkCommand, nkCallStrLit:
|
of nkCall, nkCommand, nkCallStrLit:
|
||||||
if (n.sons[0].kind != nkSym): return
|
if (n.sons[0].kind != nkSym): return
|
||||||
s = n.sons[0].sym
|
var s = n.sons[0].sym
|
||||||
if (s.kind != skProc): return
|
if (s.kind != skProc): return
|
||||||
try:
|
try:
|
||||||
case s.magic
|
case s.magic
|
||||||
of mNone:
|
of mNone:
|
||||||
return # XXX: if it has no sideEffect, it should be evaluated
|
return # XXX: if it has no sideEffect, it should be evaluated
|
||||||
of mSizeOf:
|
of mSizeOf:
|
||||||
a = n.sons[1]
|
var a = n.sons[1]
|
||||||
if computeSize(a.typ) < 0:
|
if computeSize(a.typ) < 0:
|
||||||
liMessage(a.info, errCannotEvalXBecauseIncompletelyDefined, "sizeof")
|
liMessage(a.info, errCannotEvalXBecauseIncompletelyDefined, "sizeof")
|
||||||
if a.typ.kind in {tyArray, tyObject, tyTuple}:
|
if a.typ.kind in {tyArray, tyObject, tyTuple}:
|
||||||
result = nil # XXX: size computation for complex types
|
result = nil
|
||||||
# is still wrong
|
# XXX: size computation for complex types is still wrong
|
||||||
else:
|
else:
|
||||||
result = newIntNodeT(getSize(a.typ), n)
|
result = newIntNodeT(getSize(a.typ), n)
|
||||||
of mLow:
|
of mLow:
|
||||||
|
|
@ -396,13 +304,14 @@ proc getConstExpr(module: PSym, n: PNode): PNode =
|
||||||
{tyOpenArray, tySequence, tyString}):
|
{tyOpenArray, tySequence, tyString}):
|
||||||
result = newIntNodeT(lastOrd(skipTypes(n.sons[1].typ, abstractVar)), n)
|
result = newIntNodeT(lastOrd(skipTypes(n.sons[1].typ, abstractVar)), n)
|
||||||
else:
|
else:
|
||||||
a = getConstExpr(module, n.sons[1])
|
var a = getConstExpr(m, n.sons[1])
|
||||||
|
var b, c: PNode
|
||||||
if a == nil: return
|
if a == nil: return
|
||||||
if sonsLen(n) > 2:
|
if sonsLen(n) > 2:
|
||||||
b = getConstExpr(module, n.sons[2])
|
b = getConstExpr(m, n.sons[2])
|
||||||
if b == nil: return
|
if b == nil: return
|
||||||
if sonsLen(n) > 3:
|
if sonsLen(n) > 3:
|
||||||
c = getConstExpr(module, n.sons[3])
|
c = getConstExpr(m, n.sons[3])
|
||||||
if c == nil: return
|
if c == nil: return
|
||||||
else:
|
else:
|
||||||
b = nil
|
b = nil
|
||||||
|
|
@ -412,22 +321,21 @@ proc getConstExpr(module: PSym, n: PNode): PNode =
|
||||||
except EDivByZero:
|
except EDivByZero:
|
||||||
liMessage(n.info, errConstantDivisionByZero)
|
liMessage(n.info, errConstantDivisionByZero)
|
||||||
of nkAddr:
|
of nkAddr:
|
||||||
a = getConstExpr(module, n.sons[0])
|
var a = getConstExpr(m, n.sons[0])
|
||||||
if a != nil:
|
if a != nil:
|
||||||
result = n
|
result = n
|
||||||
n.sons[0] = a
|
n.sons[0] = a
|
||||||
of nkBracket:
|
of nkBracket:
|
||||||
result = copyTree(n)
|
result = copyTree(n)
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
a = getConstExpr(module, n.sons[i])
|
var a = getConstExpr(m, n.sons[i])
|
||||||
if a == nil:
|
if a == nil: return nil
|
||||||
return nil
|
|
||||||
result.sons[i] = a
|
result.sons[i] = a
|
||||||
incl(result.flags, nfAllConst)
|
incl(result.flags, nfAllConst)
|
||||||
of nkRange:
|
of nkRange:
|
||||||
a = getConstExpr(module, n.sons[0])
|
var a = getConstExpr(m, n.sons[0])
|
||||||
if a == nil: return
|
if a == nil: return
|
||||||
b = getConstExpr(module, n.sons[1])
|
var b = getConstExpr(m, n.sons[1])
|
||||||
if b == nil: return
|
if b == nil: return
|
||||||
result = copyNode(n)
|
result = copyNode(n)
|
||||||
addSon(result, a)
|
addSon(result, a)
|
||||||
|
|
@ -435,9 +343,8 @@ proc getConstExpr(module: PSym, n: PNode): PNode =
|
||||||
of nkCurly:
|
of nkCurly:
|
||||||
result = copyTree(n)
|
result = copyTree(n)
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
a = getConstExpr(module, n.sons[i])
|
var a = getConstExpr(m, n.sons[i])
|
||||||
if a == nil:
|
if a == nil: return nil
|
||||||
return nil
|
|
||||||
result.sons[i] = a
|
result.sons[i] = a
|
||||||
incl(result.flags, nfAllConst)
|
incl(result.flags, nfAllConst)
|
||||||
of nkPar:
|
of nkPar:
|
||||||
|
|
@ -445,19 +352,17 @@ proc getConstExpr(module: PSym, n: PNode): PNode =
|
||||||
result = copyTree(n)
|
result = copyTree(n)
|
||||||
if (sonsLen(n) > 0) and (n.sons[0].kind == nkExprColonExpr):
|
if (sonsLen(n) > 0) and (n.sons[0].kind == nkExprColonExpr):
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
a = getConstExpr(module, n.sons[i].sons[1])
|
var a = getConstExpr(m, n.sons[i].sons[1])
|
||||||
if a == nil:
|
if a == nil: return nil
|
||||||
return nil
|
|
||||||
result.sons[i].sons[1] = a
|
result.sons[i].sons[1] = a
|
||||||
else:
|
else:
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
a = getConstExpr(module, n.sons[i])
|
var a = getConstExpr(m, n.sons[i])
|
||||||
if a == nil:
|
if a == nil: return nil
|
||||||
return nil
|
|
||||||
result.sons[i] = a
|
result.sons[i] = a
|
||||||
incl(result.flags, nfAllConst)
|
incl(result.flags, nfAllConst)
|
||||||
of nkChckRangeF, nkChckRange64, nkChckRange:
|
of nkChckRangeF, nkChckRange64, nkChckRange:
|
||||||
a = getConstExpr(module, n.sons[0])
|
var a = getConstExpr(m, n.sons[0])
|
||||||
if a == nil: return
|
if a == nil: return
|
||||||
if leValueConv(n.sons[1], a) and leValueConv(a, n.sons[2]):
|
if leValueConv(n.sons[1], a) and leValueConv(a, n.sons[2]):
|
||||||
result = a # a <= x and x <= b
|
result = a # a <= x and x <= b
|
||||||
|
|
@ -467,12 +372,12 @@ proc getConstExpr(module: PSym, n: PNode): PNode =
|
||||||
msgKindToString(errIllegalConvFromXtoY),
|
msgKindToString(errIllegalConvFromXtoY),
|
||||||
[typeToString(n.sons[0].typ), typeToString(n.typ)]))
|
[typeToString(n.sons[0].typ), typeToString(n.typ)]))
|
||||||
of nkStringToCString, nkCStringToString:
|
of nkStringToCString, nkCStringToString:
|
||||||
a = getConstExpr(module, n.sons[0])
|
var a = getConstExpr(m, n.sons[0])
|
||||||
if a == nil: return
|
if a == nil: return
|
||||||
result = a
|
result = a
|
||||||
result.typ = n.typ
|
result.typ = n.typ
|
||||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv, nkCast:
|
of nkHiddenStdConv, nkHiddenSubConv, nkConv, nkCast:
|
||||||
a = getConstExpr(module, n.sons[1])
|
var a = getConstExpr(m, n.sons[1])
|
||||||
if a == nil: return
|
if a == nil: return
|
||||||
case skipTypes(n.typ, abstractRange).kind
|
case skipTypes(n.typ, abstractRange).kind
|
||||||
of tyInt..tyInt64:
|
of tyInt..tyInt64:
|
||||||
|
|
|
||||||
169
rod/transf.nim
169
rod/transf.nim
|
|
@ -118,11 +118,9 @@ proc newAsgnStmt(c: PTransf, le, ri: PNode): PNode =
|
||||||
addSon(result, ri)
|
addSon(result, ri)
|
||||||
|
|
||||||
proc transformSym(c: PTransf, n: PNode): PNode =
|
proc transformSym(c: PTransf, n: PNode): PNode =
|
||||||
var
|
var b: PNode
|
||||||
tc: PTransCon
|
|
||||||
b: PNode
|
|
||||||
if (n.kind != nkSym): internalError(n.info, "transformSym")
|
if (n.kind != nkSym): internalError(n.info, "transformSym")
|
||||||
tc = c.transCon
|
var tc = c.transCon
|
||||||
if sfBorrow in n.sym.flags:
|
if sfBorrow in n.sym.flags:
|
||||||
# simply exchange the symbol:
|
# simply exchange the symbol:
|
||||||
b = n.sym.ast.sons[codePos]
|
b = n.sym.ast.sons[codePos]
|
||||||
|
|
@ -162,19 +160,15 @@ proc transformContinueAux(c: PTransf, n: PNode, labl: PSym, counter: var int) =
|
||||||
|
|
||||||
proc transformContinue(c: PTransf, n: PNode): PNode =
|
proc transformContinue(c: PTransf, n: PNode): PNode =
|
||||||
# we transform the continue statement into a block statement
|
# we transform the continue statement into a block statement
|
||||||
var
|
|
||||||
counter: int
|
|
||||||
x: PNode
|
|
||||||
labl: PSym
|
|
||||||
result = n
|
result = n
|
||||||
for i in countup(0, sonsLen(n) - 1): result.sons[i] = transform(c, n.sons[i])
|
for i in countup(0, sonsLen(n) - 1): result.sons[i] = transform(c, n.sons[i])
|
||||||
counter = 0
|
var counter = 0
|
||||||
labl = newSym(skLabel, nil, getCurrOwner(c))
|
var labl = newSym(skLabel, nil, getCurrOwner(c))
|
||||||
labl.name = getIdent(genPrefix & $(labl.id))
|
labl.name = getIdent(genPrefix & $(labl.id))
|
||||||
labl.info = result.info
|
labl.info = result.info
|
||||||
transformContinueAux(c, result, labl, counter)
|
transformContinueAux(c, result, labl, counter)
|
||||||
if counter > 0:
|
if counter > 0:
|
||||||
x = newNodeI(nkBlockStmt, result.info)
|
var x = newNodeI(nkBlockStmt, result.info)
|
||||||
addSon(x, newSymNode(labl))
|
addSon(x, newSymNode(labl))
|
||||||
addSon(x, result)
|
addSon(x, result)
|
||||||
result = x
|
result = x
|
||||||
|
|
@ -189,10 +183,9 @@ proc skipConv(n: PNode): PNode =
|
||||||
else: result = n
|
else: result = n
|
||||||
|
|
||||||
proc newTupleAccess(tup: PNode, i: int): PNode =
|
proc newTupleAccess(tup: PNode, i: int): PNode =
|
||||||
var lit: PNode
|
|
||||||
result = newNodeIT(nkBracketExpr, tup.info, tup.typ.sons[i])
|
result = newNodeIT(nkBracketExpr, tup.info, tup.typ.sons[i])
|
||||||
addSon(result, copyTree(tup))
|
addSon(result, copyTree(tup))
|
||||||
lit = newNodeIT(nkIntLit, tup.info, getSysType(tyInt))
|
var lit = newNodeIT(nkIntLit, tup.info, getSysType(tyInt))
|
||||||
lit.intVal = i
|
lit.intVal = i
|
||||||
addSon(result, lit)
|
addSon(result, lit)
|
||||||
|
|
||||||
|
|
@ -203,9 +196,8 @@ proc unpackTuple(c: PTransf, n, father: PNode) =
|
||||||
transform(c, newTupleAccess(n, i))))
|
transform(c, newTupleAccess(n, i))))
|
||||||
|
|
||||||
proc transformYield(c: PTransf, n: PNode): PNode =
|
proc transformYield(c: PTransf, n: PNode): PNode =
|
||||||
var e: PNode
|
|
||||||
result = newNodeI(nkStmtList, n.info)
|
result = newNodeI(nkStmtList, n.info)
|
||||||
e = n.sons[0]
|
var e = n.sons[0]
|
||||||
if skipTypes(e.typ, {tyGenericInst}).kind == tyTuple:
|
if skipTypes(e.typ, {tyGenericInst}).kind == tyTuple:
|
||||||
e = skipConv(e)
|
e = skipConv(e)
|
||||||
if e.kind == nkPar:
|
if e.kind == nkPar:
|
||||||
|
|
@ -220,10 +212,6 @@ proc transformYield(c: PTransf, n: PNode): PNode =
|
||||||
addSon(result, transform(c, lastSon(c.transCon.forStmt)))
|
addSon(result, transform(c, lastSon(c.transCon.forStmt)))
|
||||||
|
|
||||||
proc inlineIter(c: PTransf, n: PNode): PNode =
|
proc inlineIter(c: PTransf, n: PNode): PNode =
|
||||||
var
|
|
||||||
L: int
|
|
||||||
it: PNode
|
|
||||||
newVar: PSym
|
|
||||||
result = n
|
result = n
|
||||||
if n == nil: return
|
if n == nil: return
|
||||||
case n.kind
|
case n.kind
|
||||||
|
|
@ -234,12 +222,13 @@ proc inlineIter(c: PTransf, n: PNode): PNode =
|
||||||
of nkVarSection:
|
of nkVarSection:
|
||||||
result = copyTree(n)
|
result = copyTree(n)
|
||||||
for i in countup(0, sonsLen(result) - 1):
|
for i in countup(0, sonsLen(result) - 1):
|
||||||
it = result.sons[i]
|
var it = result.sons[i]
|
||||||
if it.kind == nkCommentStmt: continue
|
if it.kind == nkCommentStmt: continue
|
||||||
if it.kind == nkIdentDefs:
|
if it.kind == nkIdentDefs:
|
||||||
if (it.sons[0].kind != nkSym): InternalError(it.info, "inlineIter")
|
if (it.sons[0].kind != nkSym): InternalError(it.info, "inlineIter")
|
||||||
newVar = copySym(it.sons[0].sym)
|
var newVar = copySym(it.sons[0].sym)
|
||||||
incl(newVar.flags, sfFromGeneric) # fixes a strange bug for rodgen:
|
incl(newVar.flags, sfFromGeneric)
|
||||||
|
# fixes a strange bug for rodgen:
|
||||||
#include(it.sons[0].sym.flags, sfFromGeneric);
|
#include(it.sons[0].sym.flags, sfFromGeneric);
|
||||||
newVar.owner = getCurrOwner(c)
|
newVar.owner = getCurrOwner(c)
|
||||||
IdNodeTablePut(c.transCon.mapping, it.sons[0].sym, newSymNode(newVar))
|
IdNodeTablePut(c.transCon.mapping, it.sons[0].sym, newSymNode(newVar))
|
||||||
|
|
@ -248,9 +237,9 @@ proc inlineIter(c: PTransf, n: PNode): PNode =
|
||||||
else:
|
else:
|
||||||
if it.kind != nkVarTuple:
|
if it.kind != nkVarTuple:
|
||||||
InternalError(it.info, "inlineIter: not nkVarTuple")
|
InternalError(it.info, "inlineIter: not nkVarTuple")
|
||||||
L = sonsLen(it)
|
var L = sonsLen(it)
|
||||||
for j in countup(0, L - 3):
|
for j in countup(0, L - 3):
|
||||||
newVar = copySym(it.sons[j].sym)
|
var newVar = copySym(it.sons[j].sym)
|
||||||
incl(newVar.flags, sfFromGeneric)
|
incl(newVar.flags, sfFromGeneric)
|
||||||
newVar.owner = getCurrOwner(c)
|
newVar.owner = getCurrOwner(c)
|
||||||
IdNodeTablePut(c.transCon.mapping, it.sons[j].sym, newSymNode(newVar))
|
IdNodeTablePut(c.transCon.mapping, it.sons[j].sym, newSymNode(newVar))
|
||||||
|
|
@ -263,25 +252,23 @@ proc inlineIter(c: PTransf, n: PNode): PNode =
|
||||||
result = transform(c, result)
|
result = transform(c, result)
|
||||||
|
|
||||||
proc addVar(father, v: PNode) =
|
proc addVar(father, v: PNode) =
|
||||||
var vpart: PNode
|
var vpart = newNodeI(nkIdentDefs, v.info)
|
||||||
vpart = newNodeI(nkIdentDefs, v.info)
|
|
||||||
addSon(vpart, v)
|
addSon(vpart, v)
|
||||||
addSon(vpart, nil)
|
addSon(vpart, nil)
|
||||||
addSon(vpart, nil)
|
addSon(vpart, nil)
|
||||||
addSon(father, vpart)
|
addSon(father, vpart)
|
||||||
|
|
||||||
proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PNode =
|
proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PNode =
|
||||||
var m: PNode
|
|
||||||
case n.sons[0].kind
|
case n.sons[0].kind
|
||||||
of nkObjUpConv, nkObjDownConv, nkPassAsOpenArray, nkChckRange, nkChckRangeF,
|
of nkObjUpConv, nkObjDownConv, nkPassAsOpenArray, nkChckRange, nkChckRangeF,
|
||||||
nkChckRange64:
|
nkChckRange64:
|
||||||
m = n.sons[0].sons[0]
|
var m = n.sons[0].sons[0]
|
||||||
if (m.kind == a) or (m.kind == b):
|
if (m.kind == a) or (m.kind == b):
|
||||||
# addr ( nkPassAsOpenArray ( deref ( x ) ) ) --> nkPassAsOpenArray(x)
|
# addr ( nkPassAsOpenArray ( deref ( x ) ) ) --> nkPassAsOpenArray(x)
|
||||||
n.sons[0].sons[0] = m.sons[0]
|
n.sons[0].sons[0] = m.sons[0]
|
||||||
return transform(c, n.sons[0])
|
return transform(c, n.sons[0])
|
||||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
||||||
m = n.sons[0].sons[1]
|
var m = n.sons[0].sons[1]
|
||||||
if (m.kind == a) or (m.kind == b):
|
if (m.kind == a) or (m.kind == b):
|
||||||
# addr ( nkConv ( deref ( x ) ) ) --> nkConv(x)
|
# addr ( nkConv ( deref ( x ) ) ) --> nkConv(x)
|
||||||
n.sons[0].sons[1] = m.sons[0]
|
n.sons[0].sons[1] = m.sons[0]
|
||||||
|
|
@ -294,13 +281,10 @@ proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PNode =
|
||||||
result = n
|
result = n
|
||||||
|
|
||||||
proc transformConv(c: PTransf, n: PNode): PNode =
|
proc transformConv(c: PTransf, n: PNode): PNode =
|
||||||
var
|
|
||||||
source, dest: PType
|
|
||||||
diff: int
|
|
||||||
n.sons[1] = transform(c, n.sons[1])
|
n.sons[1] = transform(c, n.sons[1])
|
||||||
result = n # numeric types need range checks:
|
result = n # numeric types need range checks:
|
||||||
dest = skipTypes(n.typ, abstractVarRange)
|
var dest = skipTypes(n.typ, abstractVarRange)
|
||||||
source = skipTypes(n.sons[1].typ, abstractVarRange)
|
var source = skipTypes(n.sons[1].typ, abstractVarRange)
|
||||||
case dest.kind
|
case dest.kind
|
||||||
of tyInt..tyInt64, tyEnum, tyChar, tyBool:
|
of tyInt..tyInt64, tyEnum, tyChar, tyBool:
|
||||||
if (firstOrd(dest) <= firstOrd(source)) and
|
if (firstOrd(dest) <= firstOrd(source)) and
|
||||||
|
|
@ -340,7 +324,7 @@ proc transformConv(c: PTransf, n: PNode): PNode =
|
||||||
dest = skipTypes(dest, abstractPtrs)
|
dest = skipTypes(dest, abstractPtrs)
|
||||||
source = skipTypes(source, abstractPtrs)
|
source = skipTypes(source, abstractPtrs)
|
||||||
if source.kind == tyObject:
|
if source.kind == tyObject:
|
||||||
diff = inheritanceDiff(dest, source)
|
var diff = inheritanceDiff(dest, source)
|
||||||
if diff < 0:
|
if diff < 0:
|
||||||
result = newNodeIT(nkObjUpConv, n.info, n.typ)
|
result = newNodeIT(nkObjUpConv, n.info, n.typ)
|
||||||
addSon(result, n.sons[1])
|
addSon(result, n.sons[1])
|
||||||
|
|
@ -350,7 +334,7 @@ proc transformConv(c: PTransf, n: PNode): PNode =
|
||||||
else:
|
else:
|
||||||
result = n.sons[1]
|
result = n.sons[1]
|
||||||
of tyObject:
|
of tyObject:
|
||||||
diff = inheritanceDiff(dest, source)
|
var diff = inheritanceDiff(dest, source)
|
||||||
if diff < 0:
|
if diff < 0:
|
||||||
result = newNodeIT(nkObjUpConv, n.info, n.typ)
|
result = newNodeIT(nkObjUpConv, n.info, n.typ)
|
||||||
addSon(result, n.sons[1])
|
addSon(result, n.sons[1])
|
||||||
|
|
@ -393,45 +377,42 @@ proc putArgInto(arg: PNode, formal: PType): TPutArgInto =
|
||||||
proc transformFor(c: PTransf, n: PNode): PNode =
|
proc transformFor(c: PTransf, n: PNode): PNode =
|
||||||
# generate access statements for the parameters (unless they are constant)
|
# generate access statements for the parameters (unless they are constant)
|
||||||
# put mapping from formal parameters to actual parameters
|
# put mapping from formal parameters to actual parameters
|
||||||
var
|
|
||||||
length: int
|
|
||||||
call, v, body, arg: PNode
|
|
||||||
newC: PTransCon
|
|
||||||
temp, formal: PSym
|
|
||||||
if (n.kind != nkForStmt): InternalError(n.info, "transformFor")
|
if (n.kind != nkForStmt): InternalError(n.info, "transformFor")
|
||||||
result = newNodeI(nkStmtList, n.info)
|
result = newNodeI(nkStmtList, n.info)
|
||||||
length = sonsLen(n)
|
var length = sonsLen(n)
|
||||||
n.sons[length - 1] = transformContinue(c, n.sons[length - 1])
|
n.sons[length - 1] = transformContinue(c, n.sons[length - 1])
|
||||||
v = newNodeI(nkVarSection, n.info)
|
var v = newNodeI(nkVarSection, n.info)
|
||||||
for i in countup(0, length - 3):
|
for i in countup(0, length - 3):
|
||||||
addVar(v, copyTree(n.sons[i])) # declare new vars
|
addVar(v, copyTree(n.sons[i])) # declare new vars
|
||||||
addSon(result, v)
|
addSon(result, v)
|
||||||
newC = newTransCon()
|
var newC = newTransCon()
|
||||||
call = n.sons[length - 2]
|
var call = n.sons[length - 2]
|
||||||
if (call.kind != nkCall) or (call.sons[0].kind != nkSym):
|
if (call.kind != nkCall) or (call.sons[0].kind != nkSym):
|
||||||
InternalError(call.info, "transformFor")
|
InternalError(call.info, "transformFor")
|
||||||
newC.owner = call.sons[0].sym
|
newC.owner = call.sons[0].sym
|
||||||
newC.forStmt = n
|
newC.forStmt = n
|
||||||
if (newC.owner.kind != skIterator):
|
if (newC.owner.kind != skIterator):
|
||||||
InternalError(call.info, "transformFor") # generate access statements for the parameters (unless they are constant)
|
InternalError(call.info, "transformFor")
|
||||||
|
# generate access statements for the parameters (unless they are constant)
|
||||||
pushTransCon(c, newC)
|
pushTransCon(c, newC)
|
||||||
for i in countup(1, sonsLen(call) - 1):
|
for i in countup(1, sonsLen(call) - 1):
|
||||||
arg = skipPassAsOpenArray(transform(c, call.sons[i]))
|
var arg = skipPassAsOpenArray(transform(c, call.sons[i]))
|
||||||
formal = skipTypes(newC.owner.typ, abstractInst).n.sons[i].sym #if IdentEq(newc.Owner.name, 'items') then
|
var formal = skipTypes(newC.owner.typ, abstractInst).n.sons[i].sym
|
||||||
|
#if IdentEq(newc.Owner.name, 'items') then
|
||||||
# liMessage(arg.info, warnUser, 'items: ' + nodeKindToStr[arg.kind]);
|
# liMessage(arg.info, warnUser, 'items: ' + nodeKindToStr[arg.kind]);
|
||||||
case putArgInto(arg, formal.typ)
|
case putArgInto(arg, formal.typ)
|
||||||
of paDirectMapping:
|
of paDirectMapping:
|
||||||
IdNodeTablePut(newC.mapping, formal, arg)
|
IdNodeTablePut(newC.mapping, formal, arg)
|
||||||
of paFastAsgn:
|
of paFastAsgn:
|
||||||
# generate a temporary and produce an assignment statement:
|
# generate a temporary and produce an assignment statement:
|
||||||
temp = newTemp(c, formal.typ, formal.info)
|
var temp = newTemp(c, formal.typ, formal.info)
|
||||||
addVar(v, newSymNode(temp))
|
addVar(v, newSymNode(temp))
|
||||||
addSon(result, newAsgnStmt(c, newSymNode(temp), arg))
|
addSon(result, newAsgnStmt(c, newSymNode(temp), arg))
|
||||||
IdNodeTablePut(newC.mapping, formal, newSymNode(temp))
|
IdNodeTablePut(newC.mapping, formal, newSymNode(temp))
|
||||||
of paVarAsgn:
|
of paVarAsgn:
|
||||||
assert(skipTypes(formal.typ, abstractInst).kind == tyVar)
|
assert(skipTypes(formal.typ, abstractInst).kind == tyVar)
|
||||||
InternalError(arg.info, "not implemented: pass to var parameter")
|
InternalError(arg.info, "not implemented: pass to var parameter")
|
||||||
body = newC.owner.ast.sons[codePos]
|
var body = newC.owner.ast.sons[codePos]
|
||||||
pushInfoContext(n.info)
|
pushInfoContext(n.info)
|
||||||
addSon(result, inlineIter(c, body))
|
addSon(result, inlineIter(c, body))
|
||||||
popInfoContext()
|
popInfoContext()
|
||||||
|
|
@ -447,14 +428,11 @@ proc getMagicOp(call: PNode): TMagic =
|
||||||
proc gatherVars(c: PTransf, n: PNode, marked: var TIntSet, owner: PSym,
|
proc gatherVars(c: PTransf, n: PNode, marked: var TIntSet, owner: PSym,
|
||||||
container: PNode) =
|
container: PNode) =
|
||||||
# gather used vars for closure generation
|
# gather used vars for closure generation
|
||||||
var
|
|
||||||
s: PSym
|
|
||||||
found: bool
|
|
||||||
if n == nil: return
|
if n == nil: return
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkSym:
|
of nkSym:
|
||||||
s = n.sym
|
var s = n.sym
|
||||||
found = false
|
var found = false
|
||||||
case s.kind
|
case s.kind
|
||||||
of skVar: found = not (sfGlobal in s.flags)
|
of skVar: found = not (sfGlobal in s.flags)
|
||||||
of skTemp, skForVar, skParam: found = true
|
of skTemp, skForVar, skParam: found = true
|
||||||
|
|
@ -476,10 +454,9 @@ proc addFormalParam(routine: PSym, param: PSym) =
|
||||||
|
|
||||||
proc indirectAccess(a, b: PSym): PNode =
|
proc indirectAccess(a, b: PSym): PNode =
|
||||||
# returns a^ .b as a node
|
# returns a^ .b as a node
|
||||||
var x, y, deref: PNode
|
var x = newSymNode(a)
|
||||||
x = newSymNode(a)
|
var y = newSymNode(b)
|
||||||
y = newSymNode(b)
|
var deref = newNodeI(nkDerefExpr, x.info)
|
||||||
deref = newNodeI(nkDerefExpr, x.info)
|
|
||||||
deref.typ = x.typ.sons[0]
|
deref.typ = x.typ.sons[0]
|
||||||
addSon(deref, x)
|
addSon(deref, x)
|
||||||
result = newNodeI(nkDotExpr, x.info)
|
result = newNodeI(nkDotExpr, x.info)
|
||||||
|
|
@ -488,29 +465,26 @@ proc indirectAccess(a, b: PSym): PNode =
|
||||||
result.typ = y.typ
|
result.typ = y.typ
|
||||||
|
|
||||||
proc transformLambda(c: PTransf, n: PNode): PNode =
|
proc transformLambda(c: PTransf, n: PNode): PNode =
|
||||||
var
|
var marked: TIntSet
|
||||||
marked: TIntSet
|
|
||||||
closure: PNode
|
|
||||||
s, param: PSym
|
|
||||||
cl, p: PType
|
|
||||||
newC: PTransCon
|
|
||||||
result = n
|
result = n
|
||||||
IntSetInit(marked)
|
IntSetInit(marked)
|
||||||
if (n.sons[namePos].kind != nkSym): InternalError(n.info, "transformLambda")
|
if (n.sons[namePos].kind != nkSym): InternalError(n.info, "transformLambda")
|
||||||
s = n.sons[namePos].sym
|
var s = n.sons[namePos].sym
|
||||||
closure = newNodeI(nkRecList, n.sons[codePos].info)
|
var closure = newNodeI(nkRecList, n.sons[codePos].info)
|
||||||
gatherVars(c, n.sons[codePos], marked, s, closure) # add closure type to the param list (even if closure is empty!):
|
gatherVars(c, n.sons[codePos], marked, s, closure)
|
||||||
cl = newType(tyObject, s)
|
# add closure type to the param list (even if closure is empty!):
|
||||||
|
var cl = newType(tyObject, s)
|
||||||
cl.n = closure
|
cl.n = closure
|
||||||
addSon(cl, nil) # no super class
|
addSon(cl, nil) # no super class
|
||||||
p = newType(tyRef, s)
|
var p = newType(tyRef, s)
|
||||||
addSon(p, cl)
|
addSon(p, cl)
|
||||||
param = newSym(skParam, getIdent(genPrefix & "Cl"), s)
|
var param = newSym(skParam, getIdent(genPrefix & "Cl"), s)
|
||||||
param.typ = p
|
param.typ = p
|
||||||
addFormalParam(s, param) # all variables that are accessed should be accessed by the new closure
|
addFormalParam(s, param)
|
||||||
|
# all variables that are accessed should be accessed by the new closure
|
||||||
# parameter:
|
# parameter:
|
||||||
if sonsLen(closure) > 0:
|
if sonsLen(closure) > 0:
|
||||||
newC = newTransCon()
|
var newC = newTransCon()
|
||||||
for i in countup(0, sonsLen(closure) - 1):
|
for i in countup(0, sonsLen(closure) - 1):
|
||||||
IdNodeTablePut(newC.mapping, closure.sons[i].sym,
|
IdNodeTablePut(newC.mapping, closure.sons[i].sym,
|
||||||
indirectAccess(param, closure.sons[i].sym))
|
indirectAccess(param, closure.sons[i].sym))
|
||||||
|
|
@ -521,18 +495,15 @@ proc transformLambda(c: PTransf, n: PNode): PNode =
|
||||||
proc transformCase(c: PTransf, n: PNode): PNode =
|
proc transformCase(c: PTransf, n: PNode): PNode =
|
||||||
# removes `elif` branches of a case stmt
|
# removes `elif` branches of a case stmt
|
||||||
# adds ``else: nil`` if needed for the code generator
|
# adds ``else: nil`` if needed for the code generator
|
||||||
var
|
var length = sonsLen(n)
|
||||||
length, i: int
|
var i = length - 1
|
||||||
ifs, elsen: PNode
|
|
||||||
length = sonsLen(n)
|
|
||||||
i = length - 1
|
|
||||||
if n.sons[i].kind == nkElse: dec(i)
|
if n.sons[i].kind == nkElse: dec(i)
|
||||||
if n.sons[i].kind == nkElifBranch:
|
if n.sons[i].kind == nkElifBranch:
|
||||||
while n.sons[i].kind == nkElifBranch: dec(i)
|
while n.sons[i].kind == nkElifBranch: dec(i)
|
||||||
if (n.sons[i].kind != nkOfBranch):
|
if (n.sons[i].kind != nkOfBranch):
|
||||||
InternalError(n.sons[i].info, "transformCase")
|
InternalError(n.sons[i].info, "transformCase")
|
||||||
ifs = newNodeI(nkIfStmt, n.sons[i + 1].info)
|
var ifs = newNodeI(nkIfStmt, n.sons[i + 1].info)
|
||||||
elsen = newNodeI(nkElse, ifs.info)
|
var elsen = newNodeI(nkElse, ifs.info)
|
||||||
for j in countup(i + 1, length - 1): addSon(ifs, n.sons[j])
|
for j in countup(i + 1, length - 1): addSon(ifs, n.sons[j])
|
||||||
setlen(n.sons, i + 2)
|
setlen(n.sons, i + 2)
|
||||||
addSon(elsen, ifs)
|
addSon(elsen, ifs)
|
||||||
|
|
@ -541,7 +512,7 @@ proc transformCase(c: PTransf, n: PNode): PNode =
|
||||||
not (skipTypes(n.sons[0].Typ, abstractVarRange).Kind in
|
not (skipTypes(n.sons[0].Typ, abstractVarRange).Kind in
|
||||||
{tyInt..tyInt64, tyChar, tyEnum}):
|
{tyInt..tyInt64, tyChar, tyEnum}):
|
||||||
#MessageOut(renderTree(n));
|
#MessageOut(renderTree(n));
|
||||||
elsen = newNodeI(nkElse, n.info)
|
var elsen = newNodeI(nkElse, n.info)
|
||||||
addSon(elsen, newNodeI(nkNilLit, n.info))
|
addSon(elsen, newNodeI(nkNilLit, n.info))
|
||||||
addSon(n, elsen)
|
addSon(n, elsen)
|
||||||
result = n
|
result = n
|
||||||
|
|
@ -566,20 +537,15 @@ proc getMergeOp(n: PNode): PSym =
|
||||||
nil
|
nil
|
||||||
|
|
||||||
proc flattenTreeAux(d, a: PNode, op: PSym) =
|
proc flattenTreeAux(d, a: PNode, op: PSym) =
|
||||||
var op2: PSym
|
var op2 = getMergeOp(a)
|
||||||
op2 = getMergeOp(a)
|
|
||||||
if (op2 != nil) and
|
if (op2 != nil) and
|
||||||
((op2.id == op.id) or (op.magic != mNone) and (op2.magic == op.magic)): # a is a
|
((op2.id == op.id) or (op.magic != mNone) and (op2.magic == op.magic)):
|
||||||
# "leaf", so
|
|
||||||
# add
|
|
||||||
# it:
|
|
||||||
for i in countup(1, sonsLen(a) - 1): flattenTreeAux(d, a.sons[i], op)
|
for i in countup(1, sonsLen(a) - 1): flattenTreeAux(d, a.sons[i], op)
|
||||||
else:
|
else:
|
||||||
addSon(d, copyTree(a))
|
addSon(d, copyTree(a))
|
||||||
|
|
||||||
proc flattenTree(root: PNode): PNode =
|
proc flattenTree(root: PNode): PNode =
|
||||||
var op: PSym
|
var op = getMergeOp(root)
|
||||||
op = getMergeOp(root)
|
|
||||||
if op != nil:
|
if op != nil:
|
||||||
result = copyNode(root)
|
result = copyNode(root)
|
||||||
addSon(result, copyTree(root.sons[0]))
|
addSon(result, copyTree(root.sons[0]))
|
||||||
|
|
@ -588,21 +554,17 @@ proc flattenTree(root: PNode): PNode =
|
||||||
result = root
|
result = root
|
||||||
|
|
||||||
proc transformCall(c: PTransf, n: PNode): PNode =
|
proc transformCall(c: PTransf, n: PNode): PNode =
|
||||||
var
|
|
||||||
j: int
|
|
||||||
m, a: PNode
|
|
||||||
op: PSym
|
|
||||||
result = flattenTree(n)
|
result = flattenTree(n)
|
||||||
for i in countup(0, sonsLen(result) - 1):
|
for i in countup(0, sonsLen(result) - 1):
|
||||||
result.sons[i] = transform(c, result.sons[i])
|
result.sons[i] = transform(c, result.sons[i])
|
||||||
op = getMergeOp(result)
|
var op = getMergeOp(result)
|
||||||
if (op != nil) and (op.magic != mNone) and (sonsLen(result) >= 3):
|
if (op != nil) and (op.magic != mNone) and (sonsLen(result) >= 3):
|
||||||
m = result
|
var m = result
|
||||||
result = newNodeIT(nkCall, m.info, m.typ)
|
result = newNodeIT(nkCall, m.info, m.typ)
|
||||||
addSon(result, copyTree(m.sons[0]))
|
addSon(result, copyTree(m.sons[0]))
|
||||||
j = 1
|
var j = 1
|
||||||
while j < sonsLen(m):
|
while j < sonsLen(m):
|
||||||
a = m.sons[j]
|
var a = m.sons[j]
|
||||||
inc(j)
|
inc(j)
|
||||||
if isConstExpr(a):
|
if isConstExpr(a):
|
||||||
while (j < sonsLen(m)) and isConstExpr(m.sons[j]):
|
while (j < sonsLen(m)) and isConstExpr(m.sons[j]):
|
||||||
|
|
@ -616,11 +578,8 @@ proc transformCall(c: PTransf, n: PNode): PNode =
|
||||||
result = methodCall(result)
|
result = methodCall(result)
|
||||||
|
|
||||||
proc transform(c: PTransf, n: PNode): PNode =
|
proc transform(c: PTransf, n: PNode): PNode =
|
||||||
var cnst: PNode
|
|
||||||
result = n
|
result = n
|
||||||
if n == nil:
|
if n == nil: return
|
||||||
return #if ToLinenumber(n.info) = 32 then
|
|
||||||
# MessageOut(RenderTree(n));
|
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkSym:
|
of nkSym:
|
||||||
return transformSym(c, n)
|
return transformSym(c, n)
|
||||||
|
|
@ -657,16 +616,16 @@ proc transform(c: PTransf, n: PNode): PNode =
|
||||||
of nkCommentStmt, nkTemplateDef:
|
of nkCommentStmt, nkTemplateDef:
|
||||||
return
|
return
|
||||||
of nkConstSection:
|
of nkConstSection:
|
||||||
return # do not replace ``const c = 3`` with ``const 3 = 3``
|
# do not replace ``const c = 3`` with ``const 3 = 3``
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
for i in countup(0, sonsLen(n) - 1): result.sons[i] = transform(c, n.sons[i])
|
for i in countup(0, sonsLen(n) - 1): result.sons[i] = transform(c, n.sons[i])
|
||||||
cnst = getConstExpr(c.module, result)
|
var cnst = getConstExpr(c.module, result)
|
||||||
if cnst != nil:
|
if cnst != nil:
|
||||||
result = cnst # do not miss an optimization
|
result = cnst # do not miss an optimization
|
||||||
|
|
||||||
proc processTransf(context: PPassContext, n: PNode): PNode =
|
proc processTransf(context: PPassContext, n: PNode): PNode =
|
||||||
var c: PTransf
|
var c = PTransf(context)
|
||||||
c = PTransf(context)
|
|
||||||
result = transform(c, n)
|
result = transform(c, n)
|
||||||
|
|
||||||
proc openTransf(module: PSym, filename: string): PPassContext =
|
proc openTransf(module: PSym, filename: string): PPassContext =
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import
|
||||||
ast, astalgo, scanner, msgs, strutils
|
ast, astalgo, scanner, msgs, strutils
|
||||||
|
|
||||||
proc getMagic*(op: PNode): TMagic
|
proc getMagic*(op: PNode): TMagic
|
||||||
# function getConstExpr(const t: TNode; out res: TNode): Boolean;
|
|
||||||
proc isConstExpr*(n: PNode): bool
|
proc isConstExpr*(n: PNode): bool
|
||||||
proc flattenTree*(root: PNode, op: TMagic): PNode
|
proc flattenTree*(root: PNode, op: TMagic): PNode
|
||||||
proc TreeToSym*(t: PNode): PSym
|
proc TreeToSym*(t: PNode): PSym
|
||||||
|
|
@ -32,12 +32,11 @@ proc hasSon(father, son: PNode): bool =
|
||||||
result = false
|
result = false
|
||||||
|
|
||||||
proc cyclicTreeAux(n, s: PNode): bool =
|
proc cyclicTreeAux(n, s: PNode): bool =
|
||||||
var m: int
|
|
||||||
if n == nil:
|
if n == nil:
|
||||||
return false
|
return false
|
||||||
if hasSon(s, n):
|
if hasSon(s, n):
|
||||||
return true
|
return true
|
||||||
m = sonsLen(s)
|
var m = sonsLen(s)
|
||||||
addSon(s, n)
|
addSon(s, n)
|
||||||
if not (n.kind in {nkEmpty..nkNilLit}):
|
if not (n.kind in {nkEmpty..nkNilLit}):
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
|
|
@ -47,8 +46,7 @@ proc cyclicTreeAux(n, s: PNode): bool =
|
||||||
delSon(s, m)
|
delSon(s, m)
|
||||||
|
|
||||||
proc cyclicTree(n: PNode): bool =
|
proc cyclicTree(n: PNode): bool =
|
||||||
var s: PNode
|
var s = newNodeI(nkEmpty, n.info)
|
||||||
s = newNodeI(nkEmpty, n.info)
|
|
||||||
result = cyclicTreeAux(n, s)
|
result = cyclicTreeAux(n, s)
|
||||||
|
|
||||||
proc ExprStructuralEquivalent(a, b: PNode): bool =
|
proc ExprStructuralEquivalent(a, b: PNode): bool =
|
||||||
|
|
@ -57,18 +55,14 @@ proc ExprStructuralEquivalent(a, b: PNode): bool =
|
||||||
result = true
|
result = true
|
||||||
elif (a != nil) and (b != nil) and (a.kind == b.kind):
|
elif (a != nil) and (b != nil) and (a.kind == b.kind):
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkSym: # don't go nuts here: same symbol as string is enough:
|
of nkSym:
|
||||||
|
# don't go nuts here: same symbol as string is enough:
|
||||||
result = a.sym.name.id == b.sym.name.id
|
result = a.sym.name.id == b.sym.name.id
|
||||||
of nkIdent:
|
of nkIdent: result = a.ident.id == b.ident.id
|
||||||
result = a.ident.id == b.ident.id
|
of nkCharLit..nkInt64Lit: result = a.intVal == b.intVal
|
||||||
of nkCharLit..nkInt64Lit:
|
of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal
|
||||||
result = a.intVal == b.intVal
|
of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
|
||||||
of nkFloatLit..nkFloat64Lit:
|
of nkEmpty, nkNilLit, nkType: result = true
|
||||||
result = a.floatVal == b.floatVal
|
|
||||||
of nkStrLit..nkTripleStrLit:
|
|
||||||
result = a.strVal == b.strVal
|
|
||||||
of nkEmpty, nkNilLit, nkType:
|
|
||||||
result = true
|
|
||||||
else:
|
else:
|
||||||
if sonsLen(a) == sonsLen(b):
|
if sonsLen(a) == sonsLen(b):
|
||||||
for i in countup(0, sonsLen(a) - 1):
|
for i in countup(0, sonsLen(a) - 1):
|
||||||
|
|
@ -85,18 +79,14 @@ proc sameTree(a, b: PNode): bool =
|
||||||
if a.info.col != b.info.col:
|
if a.info.col != b.info.col:
|
||||||
return #if a.info.fileIndex <> b.info.fileIndex then exit;
|
return #if a.info.fileIndex <> b.info.fileIndex then exit;
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkSym: # don't go nuts here: same symbol as string is enough:
|
of nkSym:
|
||||||
|
# don't go nuts here: same symbol as string is enough:
|
||||||
result = a.sym.name.id == b.sym.name.id
|
result = a.sym.name.id == b.sym.name.id
|
||||||
of nkIdent:
|
of nkIdent: result = a.ident.id == b.ident.id
|
||||||
result = a.ident.id == b.ident.id
|
of nkCharLit..nkInt64Lit: result = a.intVal == b.intVal
|
||||||
of nkCharLit..nkInt64Lit:
|
of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal
|
||||||
result = a.intVal == b.intVal
|
of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
|
||||||
of nkFloatLit..nkFloat64Lit:
|
of nkEmpty, nkNilLit, nkType: result = true
|
||||||
result = a.floatVal == b.floatVal
|
|
||||||
of nkStrLit..nkTripleStrLit:
|
|
||||||
result = a.strVal == b.strVal
|
|
||||||
of nkEmpty, nkNilLit, nkType:
|
|
||||||
result = true
|
|
||||||
else:
|
else:
|
||||||
if sonsLen(a) == sonsLen(b):
|
if sonsLen(a) == sonsLen(b):
|
||||||
for i in countup(0, sonsLen(a) - 1):
|
for i in countup(0, sonsLen(a) - 1):
|
||||||
|
|
@ -118,8 +108,7 @@ proc getMagic(op: PNode): TMagic =
|
||||||
case op.kind
|
case op.kind
|
||||||
of nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit:
|
of nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit:
|
||||||
case op.sons[0].Kind
|
case op.sons[0].Kind
|
||||||
of nkSym:
|
of nkSym: result = op.sons[0].sym.magic
|
||||||
result = op.sons[0].sym.magic
|
|
||||||
else: result = mNone
|
else: result = mNone
|
||||||
else: result = mNone
|
else: result = mNone
|
||||||
|
|
||||||
|
|
@ -146,7 +135,6 @@ proc flattenTree(root: PNode, op: TMagic): PNode =
|
||||||
flattenTreeAux(result, root, op)
|
flattenTreeAux(result, root, op)
|
||||||
|
|
||||||
proc SwapOperands(op: PNode) =
|
proc SwapOperands(op: PNode) =
|
||||||
var tmp: PNode
|
var tmp = op.sons[1]
|
||||||
tmp = op.sons[1]
|
|
||||||
op.sons[1] = op.sons[2]
|
op.sons[1] = op.sons[2]
|
||||||
op.sons[2] = tmp
|
op.sons[2] = tmp
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue