variable dynamic lib names

This commit is contained in:
Andreas Rumpf
2009-12-15 01:50:26 +01:00
parent 3b7ef2288f
commit 7063670a2c
14 changed files with 504 additions and 766 deletions

View File

@@ -145,12 +145,12 @@ type
E_Base* {.compilerproc.} = object of TObject ## base exception class;
## each exception has to
## 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
## ``raise`` statement.
msg* {.exportc: "message".}: cstring ## the exception's message. Not
## providing an
## exception message is bad style.
msg* {.exportc: "message".}: string ## the exception's message. Not
## providing an exception message
## is bad style.
EAsynch* = object of E_Base ## Abstract exception class for
## *asynchronous exceptions* (interrupts).

View File

@@ -41,8 +41,8 @@ when defined(MACOSX):
LUA_LIB_NAME* = "liblua(|5.2|5.1|5.0).dylib"
elif defined(UNIX):
const
LUA_NAME* = "liblua(|5.2|5.1|5.0).so.(|0)"
LUA_LIB_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)"
else:
const
LUA_NAME* = "lua(|5.2|5.1|5.0).dll"

View File

@@ -409,7 +409,8 @@ type
kind*: TLibKind
generated*: bool # needed for the backends:
name*: PRope
path*: string
path*: PNode # can be a string literal!
PLib* = ref TLib
TSym* = object of TIdObj
@@ -949,6 +950,35 @@ proc sonsNotNil(n: PNode): bool =
proc addSonIfNotNil(father, n: PNode) =
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 =
assert(length > counter)
result = (length * 2 < counter * 3) or (length - counter < 4)

View File

@@ -219,8 +219,7 @@ proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
# This function replaces all other methods for generating
# the assignment operation in C.
var ty: PType
ty = skipTypes(dest.t, abstractVarRange)
var ty = skipTypes(dest.t, abstractVarRange)
case ty.kind
of tyRef:
genRefAssign(p, dest, src, flags)

View File

@@ -164,11 +164,11 @@ proc isSimpleConst(typ: PType): bool =
proc useHeader(m: BModule, sym: PSym) =
if lfHeader in sym.loc.Flags:
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)
include
"ccgtypes.nim"
include "ccgtypes.nim"
# ------------------------------ Manager of temporaries ------------------
@@ -333,32 +333,36 @@ proc libCandidates(s: string, dest: var TStringSeq) =
add(dest, s)
proc loadDynamicLib(m: BModule, lib: PLib) =
var
tmp, loadlib: PRope
s: TStringSeq
assert(lib != nil)
if not lib.generated:
lib.generated = true
tmp = getGlobalTempName()
var tmp = getGlobalTempName()
assert(lib.name == nil)
lib.name = tmp # BUGFIX: useMagic has awful side-effects
appff(m.s[cfsVars], "static void* $1;$n",
"$1 = linkonce global i8* zeroinitializer$n", [tmp])
s = @[]
libCandidates(lib.path, s)
loadlib = nil
for i in countup(0, high(s)):
inc(m.labels)
if i > 0: app(loadlib, "||")
appff(loadlib, "($1 = nimLoadLibrary((NimStringDesc*) &$2))$n",
"%MOC$4 = call i8* @nimLoadLibrary($3 $2)$n" &
"store i8* %MOC$4, i8** $1$n", [tmp, getStrLit(m, s[i]),
getTypeDesc(m, getSysType(tyString)), toRope(m.labels)])
appff(m.s[cfsDynLibInit],
"if (!($1)) nimLoadLibraryError((NimStringDesc*) &$2);$n",
"XXX too implement", [loadlib, getStrLit(m, lib.path)])
#appf(m.s[cfsDynLibDeinit], "if ($1 != NIM_NIL) nimUnloadLibrary($1);$n",
# [tmp])
lib.name = tmp # BUGFIX: useMagic has awful side-effects
appf(m.s[cfsVars], "static void* $1;$n", [tmp])
if lib.path.kind in {nkStrLit..nkTripleStrLit}:
var s: TStringSeq = @[]
libCandidates(lib.path.strVal, s)
var loadlib: PRope = nil
for i in countup(0, high(s)):
inc(m.labels)
if i > 0: app(loadlib, "||")
appf(loadlib, "($1 = nimLoadLibrary((NimStringDesc*) &$2))$n",
[tmp, getStrLit(m, s[i])])
appf(m.s[cfsDynLibInit],
"if (!($1)) nimLoadLibraryError((NimStringDesc*) &$2);$n",
[loadlib, getStrLit(m, lib.path.strVal)])
else:
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, "nimUnloadLibrary")
useMagic(m, "NimStringDesc")

View File

@@ -54,9 +54,10 @@ var emptyNode: PNode
proc newStackFrame(): PStackFrame =
new(result)
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)
result.module = module
result.optEval = optEval
@@ -70,6 +71,7 @@ proc popStackFrame(c: PEvalContext) =
c.tos = c.tos.next
proc evalAux(c: PEvalContext, n: PNode): PNode
proc stackTraceAux(x: PStackFrame) =
if x != nil:
stackTraceAux(x.next)
@@ -85,9 +87,8 @@ proc isSpecial(n: PNode): bool =
result = (n.kind == nkExceptBranch) or (n.kind == nkEmpty)
proc evalIf(c: PEvalContext, n: PNode): PNode =
var i, length: int
i = 0
length = sonsLen(n)
var i = 0
var length = sonsLen(n)
while (i < length) and (sonsLen(n.sons[i]) >= 2):
result = evalAux(c, n.sons[i].sons[0])
if isSpecial(result): return
@@ -100,10 +101,9 @@ proc evalIf(c: PEvalContext, n: PNode): PNode =
result = emptyNode
proc evalCase(c: PEvalContext, n: PNode): PNode =
var res: PNode
result = evalAux(c, n.sons[0])
if isSpecial(result): return
res = result
var res = result
result = emptyNode
for i in countup(1, sonsLen(n) - 1):
if n.sons[i].kind == nkOfBranch:
@@ -114,11 +114,11 @@ proc evalCase(c: PEvalContext, n: PNode): PNode =
result = evalAux(c, lastSon(n.sons[i]))
var
gWhileCounter: int # Use a counter to prevent endless loops!
# We make this counter global, because otherwise
# nested loops could make the compiler extremely slow.
gNestedEvals: int # count the recursive calls to ``evalAux`` to prevent
# endless recursion
gWhileCounter: int # Use a counter to prevent endless loops!
# We make this counter global, because otherwise
# nested loops could make the compiler extremely slow.
gNestedEvals: int # count the recursive calls to ``evalAux`` to prevent
# endless recursion
proc evalWhile(c: PEvalContext, n: PNode): PNode =
while true:
@@ -152,8 +152,7 @@ proc evalBlock(c: PEvalContext, n: PNode): PNode =
result = emptyNode # consume ``break`` token
proc evalFinally(c: PEvalContext, n, exc: PNode): PNode =
var finallyNode: PNode
finallyNode = lastSon(n)
var finallyNode = lastSon(n)
if finallyNode.kind == nkFinally:
result = evalAux(c, finallyNode)
if result.kind != nkExceptBranch: result = exc
@@ -161,9 +160,6 @@ proc evalFinally(c: PEvalContext, n, exc: PNode): PNode =
result = exc
proc evalTry(c: PEvalContext, n: PNode): PNode =
var
exc: PNode
i, length, blen: int
result = evalAux(c, n.sons[0])
case result.kind
of nkBreakStmt, nkReturnToken:
@@ -172,11 +168,11 @@ proc evalTry(c: PEvalContext, n: PNode): PNode =
if sonsLen(result) >= 1:
# creating a nkExceptBranch without sons means that it could not be
# evaluated
exc = result
i = 1
length = sonsLen(n)
var exc = result
var i = 1
var length = sonsLen(n)
while (i < length) and (n.sons[i].kind == nkExceptBranch):
blen = sonsLen(n.sons[i])
var blen = sonsLen(n.sons[i])
if blen == 1:
# general except section:
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)
proc getNullValue(typ: PType, info: TLineInfo): PNode =
var t: PType
t = skipTypes(typ, abstractRange)
var t = skipTypes(typ, abstractRange)
result = emptyNode
case t.kind
of tyBool, tyChar, tyInt..tyInt64:
@@ -219,15 +214,12 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
else: InternalError("getNullValue")
proc evalVar(c: PEvalContext, n: PNode): PNode =
var
v: PSym
a: PNode
for i in countup(0, sonsLen(n) - 1):
a = n.sons[i]
var a = n.sons[i]
if a.kind == nkCommentStmt: continue
assert(a.kind == nkIdentDefs)
assert(a.sons[0].kind == nkSym)
v = a.sons[0].sym
var v = a.sons[0].sym
if a.sons[2] != nil:
result = evalAux(c, a.sons[2])
if isSpecial(result): return
@@ -237,14 +229,11 @@ proc evalVar(c: PEvalContext, n: PNode): PNode =
result = emptyNode
proc evalCall(c: PEvalContext, n: PNode): PNode =
var
d: PStackFrame
prc: PNode
result = evalAux(c, n.sons[0])
if isSpecial(result): return
prc = result # bind the actual params to the local parameter
# of a new binding
d = newStackFrame()
var prc = result
# bind the actual params to the local parameter of a new binding
var d = newStackFrame()
d.call = n
if prc.kind == nkSym:
d.prc = prc.sym
@@ -265,8 +254,7 @@ proc evalCall(c: PEvalContext, n: PNode): PNode =
proc evalVariable(c: PStackFrame, sym: PSym): PNode =
# We need to return a node to the actual value,
# which can be modified.
var x: PStackFrame
x = c
var x = c
while x != nil:
if sfResult in sym.flags:
return x.params[0]
@@ -276,15 +264,12 @@ proc evalVariable(c: PStackFrame, sym: PSym): PNode =
result = emptyNode
proc evalArrayAccess(c: PEvalContext, n: PNode): PNode =
var
x: PNode
idx: biggestInt
result = evalAux(c, n.sons[0])
if isSpecial(result): return
x = result
var x = result
result = evalAux(c, n.sons[1])
if isSpecial(result): return
idx = getOrdValue(result)
var idx = getOrdValue(result)
result = emptyNode
case x.kind
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])
proc evalNoOpt(c: PEvalContext, n: PNode): PNode =
result = newNodeI(nkExceptBranch, n.info) # creating a nkExceptBranch without sons means that it could not be
# evaluated
result = newNodeI(nkExceptBranch, n.info)
# creating a nkExceptBranch without sons means that it could not be evaluated
proc evalNew(c: PEvalContext, n: PNode): PNode =
var t: PType
if c.optEval:
result = evalNoOpt(c, n)
else:
t = skipTypes(n.sons[1].typ, abstractVar)
var t = skipTypes(n.sons[1].typ, abstractVar)
result = newNodeIT(nkRefTy, n.info, t)
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)
proc evalAddr(c: PEvalContext, n: PNode): PNode =
var
a: PNode
t: PType
result = evalAux(c, n.sons[0])
if isSpecial(result): return
a = result
t = newType(tyPtr, c.module)
var a = result
var t = newType(tyPtr, c.module)
addSon(t, a.typ)
result = newNodeIT(nkRefTy, n.info, t)
addSon(result, a)
@@ -477,11 +458,10 @@ proc evalCheckedFieldAccess(c: PEvalContext, n: PNode): PNode =
result = evalAux(c, n.sons[0])
proc evalUpConv(c: PEvalContext, n: PNode): PNode =
var dest, src: PType
result = evalAux(c, n.sons[0])
if isSpecial(result): return
dest = skipTypes(n.typ, abstractPtrs)
src = skipTypes(result.typ, abstractPtrs)
var dest = skipTypes(n.typ, abstractPtrs)
var src = skipTypes(result.typ, abstractPtrs)
if inheritanceDiff(src, dest) > 0:
stackTrace(c, n, errInvalidConversionFromTypeX, typeToString(src))
@@ -710,48 +690,27 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
k: biggestInt
m = getMagic(n)
case m
of mNone:
result = evalCall(c, n)
of mIs:
result = evalIs(c, n)
of mSizeOf:
internalError(n.info, "sizeof() should have been evaluated")
of mHigh:
result = evalHigh(c, n)
of mAssert:
result = evalAssert(c, n)
of mExit:
result = evalExit(c, n)
of mNew, mNewFinalize:
result = evalNew(c, n)
of mNewSeq:
result = evalNewSeq(c, n)
of mSwap:
result = evalSwap(c, n)
of mInc:
result = evalIncDec(c, n, 1)
of ast.mDec:
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 mNone: result = evalCall(c, n)
of mIs: result = evalIs(c, n)
of mSizeOf: internalError(n.info, "sizeof() should have been evaluated")
of mHigh: result = evalHigh(c, n)
of mAssert: result = evalAssert(c, n)
of mExit: result = evalExit(c, n)
of mNew, mNewFinalize: result = evalNew(c, n)
of mNewSeq: result = evalNewSeq(c, n)
of mSwap: result = evalSwap(c, n)
of mInc: result = evalIncDec(c, n, 1)
of ast.mDec: 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:
result = evalAux(c, n.sons[1])
if isSpecial(result): return
@@ -848,8 +807,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
result = evalAux(c, n.sons[1])
if isSpecial(result): return
if result.kind != nkIdent: InternalError(n.info, "no symbol")
of mNGetType:
result = evalAux(c, n.sons[1])
of mNGetType: result = evalAux(c, n.sons[1])
of mNStrVal:
result = evalAux(c, n.sons[1])
if isSpecial(result): return
@@ -1009,14 +967,10 @@ proc evalAux(c: PEvalContext, n: PNode): PNode =
dec(gNestedEvals)
if gNestedEvals <= 0: stackTrace(c, n, errTooManyIterations)
case n.kind # atoms:
of nkEmpty:
result = n
of nkSym:
result = evalSym(c, n)
of nkType..pred(nkNilLit):
result = copyNode(n)
of nkNilLit:
result = n # end of atoms
of nkEmpty: result = n
of nkSym: result = evalSym(c, n)
of nkType..pred(nkNilLit): result = copyNode(n)
of nkNilLit: result = n # end of atoms
of nkCall, nkHiddenCallConv, nkMacroStmt, nkCommand, nkCallStrLit:
result = evalMagicOrCall(c, n)
of nkCurly, nkBracket, nkRange:
@@ -1033,52 +987,29 @@ proc evalAux(c: PEvalContext, n: PNode): PNode =
if isSpecial(result): return
a.sons[i].sons[1] = result
result = a
of nkBracketExpr:
result = evalArrayAccess(c, n)
of nkDotExpr:
result = evalFieldAccess(c, n)
of nkDerefExpr, nkHiddenDeref:
result = evalDeref(c, n)
of nkAddr, nkHiddenAddr:
result = evalAddr(c, n)
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
result = evalConv(c, n)
of nkAsgn, nkFastAsgn:
result = evalAsgn(c, n)
of nkWhenStmt, nkIfStmt, nkIfExpr:
result = evalIf(c, n)
of nkWhileStmt:
result = evalWhile(c, n)
of nkCaseStmt:
result = evalCase(c, n)
of nkVarSection:
result = evalVar(c, n)
of nkTryStmt:
result = evalTry(c, n)
of nkRaiseStmt:
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 nkBracketExpr: result = evalArrayAccess(c, n)
of nkDotExpr: result = evalFieldAccess(c, n)
of nkDerefExpr, nkHiddenDeref: result = evalDeref(c, n)
of nkAddr, nkHiddenAddr: result = evalAddr(c, n)
of nkHiddenStdConv, nkHiddenSubConv, nkConv: result = evalConv(c, n)
of nkAsgn, nkFastAsgn: result = evalAsgn(c, n)
of nkWhenStmt, nkIfStmt, nkIfExpr: result = evalIf(c, n)
of nkWhileStmt: result = evalWhile(c, n)
of nkCaseStmt: result = evalCase(c, n)
of nkVarSection: result = evalVar(c, n)
of nkTryStmt: result = evalTry(c, n)
of nkRaiseStmt: 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:
for i in countup(0, sonsLen(n) - 1):
result = evalAux(c, n.sons[i])
@@ -1106,11 +1037,8 @@ proc eval(c: PEvalContext, n: PNode): PNode =
stackTrace(c, n, errUnhandledExceptionX, typeToString(result.typ))
proc evalConstExpr(module: PSym, e: PNode): PNode =
var
p: PEvalContext
s: PStackFrame
p = newEvalContext(module, "", true)
s = newStackFrame()
var p = newEvalContext(module, "", true)
var s = newStackFrame()
s.call = e
pushStackFrame(p, s)
result = eval(p, e)
@@ -1118,8 +1046,7 @@ proc evalConstExpr(module: PSym, e: PNode): PNode =
popStackFrame(p)
proc myOpen(module: PSym, filename: string): PPassContext =
var c: PEvalContext
c = newEvalContext(module, filename, false)
var c = newEvalContext(module, filename, false)
pushStackFrame(c, newStackFrame())
result = c

View File

@@ -11,7 +11,7 @@
import
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
FirstCallConv* = wNimcall
@@ -78,17 +78,17 @@ proc MakeExternExport(s: PSym, extname: string) =
s.loc.r = toRope(extname)
incl(s.flags, sfExportc)
proc expectStrLit(c: PContext, n: PNode): string =
proc getStrLitNode(c: PContext, n: PNode): PNode =
if n.kind != nkExprColonExpr:
liMessage(n.info, errStringLiteralExpected)
result = ""
else:
n.sons[1] = c.semConstExpr(c, n.sons[1])
case n.sons[1].kind
of nkStrLit, nkRStrLit, nkTripleStrLit: result = n.sons[1].strVal
else:
liMessage(n.info, errStringLiteralExpected)
result = ""
of nkStrLit, nkRStrLit, nkTripleStrLit: result = n.sons[1]
else: liMessage(n.info, errStringLiteralExpected)
proc expectStrLit(c: PContext, n: PNode): string =
result = getStrLitNode(c, n).strVal
proc expectIntLit(c: PContext, n: PNode): int =
if n.kind != nkExprColonExpr:
@@ -128,23 +128,22 @@ proc wordToCallConv(sw: TSpecialWord): TCallingConvention =
# the same
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):
case whichKeyword(n.sons[1].ident)
of wOn: gOptions = gOptions + op
of wOff: gOptions = gOptions - op
of wOn: result = true
of wOff: result = false
else: liMessage(n.info, errOnOrOffExpected)
else:
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) =
if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent):
case whichKeyword(n.sons[1].ident)
of wOn: incl(c.module.flags, sfDeadCodeElim)
of wOff: excl(c.module.flags, sfDeadCodeElim)
else: liMessage(n.info, errOnOrOffExpected)
else:
liMessage(n.info, errOnOrOffExpected)
if IsTurnedOn(c, n): incl(c.module.flags, sfDeadCodeElim)
else: excl(c.module.flags, sfDeadCodeElim)
proc processCallConv(c: PContext, n: PNode) =
if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent):
@@ -156,27 +155,31 @@ proc processCallConv(c: PContext, n: PNode) =
else:
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)
while it != nil:
if it.kind == kind:
if ospCaseInsensitive in platform.OS[targetOS].props:
if cmpIgnoreCase(it.path, path) == 0:
return it
else:
if it.path == path:
return it
if trees.ExprStructuralEquivalent(it.path, path): return it
it = PLib(it.next)
result = newLib(kind)
result.path = path
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) =
if (sym == nil) or (sym.kind == skModule):
POptionEntry(c.optionStack.tail).dynlib = getLib(c, libDynamic,
expectStrLit(c, n))
expectDynlibNode(c, n))
elif n.kind == nkExprColonExpr:
var lib = getLib(c, libDynamic, expectStrLit(c, n))
var lib = getLib(c, libDynamic, expectDynlibNode(c, n))
addToLib(lib, sym)
incl(sym.loc.flags, lfDynamicLib)
else:
@@ -366,7 +369,7 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
noval(it)
incl(sym.flags, sfMerge)
of wHeader:
var lib = getLib(c, libHeader, expectStrLit(c, it))
var lib = getLib(c, libHeader, getStrLitNode(c, it))
addToLib(lib, sym)
incl(sym.flags, sfImportc)
incl(sym.loc.flags, lfHeader)

View File

@@ -146,9 +146,9 @@ proc rrGetType(r: PRodReader, id: int, info: TLineInfo): PType
proc decode(r: PRodReader): string
proc decodeInt(r: PRodReader): int
proc decodeBInt(r: PRodReader): biggestInt
proc encode(s: string): PRope =
var res: string
res = ""
var res = ""
for i in countup(0, len(s) + 0 - 1):
case 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)
proc encodeIntAux(str: var string, x: BiggestInt) =
const
chars: string = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
var
v, rem: biggestInt
d: char
idx: int
v = x
rem = v mod 190
const chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
var d: char
var v = x
var rem: biggestInt = v mod 190
if (rem < 0):
str = str & '-'
add(str, '-')
v = - (v div 190)
rem = - rem
else:
v = v div 190
idx = int(rem)
var idx = int(rem)
if idx < 62: d = chars[idx + 0]
else: d = chr(idx - 62 + 128)
if (v != 0): encodeIntAux(str, v)
add(str, d)
proc encodeInt(x: BiggestInt): PRope =
var res: string
res = ""
var res = ""
encodeIntAux(res, x)
result = toRope(res)
@@ -303,8 +298,8 @@ proc decodeType(r: PRodReader, info: TLineInfo): PType =
if debugIds: registerID(result)
else:
InternalError(info, "decodeType: no id")
IdTablePut(gTypeTable, result, result) # here this also
# avoids endless recursion for recursive type
# here this also 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] == '$':
inc(r.pos)
@@ -343,7 +338,7 @@ proc decodeType(r: PRodReader, info: TLineInfo): PType =
d = decodeInt(r)
addSon(result, rrGetType(r, d, info))
proc decodeLib(r: PRodReader): PLib =
proc decodeLib(r: PRodReader, info: TLineInfo): PLib =
result = nil
if r.s[r.pos] == '|':
new(result)
@@ -354,11 +349,10 @@ proc decodeLib(r: PRodReader): PLib =
result.name = toRope(decode(r))
if r.s[r.pos] != '|': InternalError("decodeLib: 2")
inc(r.pos)
result.path = decode(r)
result.path = decodeNode(r, info)
proc decodeSym(r: PRodReader, info: TLineInfo): PSym =
var
k: TSymKind
id: int
ident: PIdent
result = nil
@@ -367,7 +361,7 @@ proc decodeSym(r: PRodReader, info: TLineInfo): PSym =
if r.s[r.pos] == '}':
inc(r.pos)
return # nil sym
k = TSymKind(decodeInt(r))
var k = TSymKind(decodeInt(r))
if r.s[r.pos] == '+':
inc(r.pos)
id = decodeInt(r)
@@ -412,22 +406,20 @@ proc decodeSym(r: PRodReader, info: TLineInfo): PSym =
inc(r.pos)
result.position = decodeInt(r)
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] == '`':
inc(r.pos)
result.offset = decodeInt(r)
else:
result.offset = - 1
decodeLoc(r, result.loc, result.info)
result.annex = decodeLib(r)
result.annex = decodeLib(r, info)
proc decodeInt(r: PRodReader): int =
# base 190 numbers
var
i: int
sign: int
i = r.pos
sign = - 1
var i = r.pos
var sign = - 1
assert(r.s[i] in {'a'..'z', 'A'..'Z', '0'..'9', '-', '\x80'..'\xFF'})
if r.s[i] == '-':
inc(i)
@@ -445,11 +437,8 @@ proc decodeInt(r: PRodReader): int =
r.pos = i
proc decodeBInt(r: PRodReader): biggestInt =
var
i: int
sign: biggestInt
i = r.pos
sign = - 1
var i = r.pos
var sign: biggestInt = - 1
assert(r.s[i] in {'a'..'z', 'A'..'Z', '0'..'9', '-', '\x80'..'\xFF'})
if r.s[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 '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:
nil
else: nil
proc decode(r: PRodReader): string =
var i, xi: int
i = r.pos
var i = r.pos
result = ""
while true:
case r.s[i]
of '\\':
inc(i, 3)
xi = 0
var xi = 0
hexChar(r.s[i - 2], xi)
hexChar(r.s[i - 1], xi)
add(result, chr(xi))
@@ -493,28 +480,23 @@ proc decode(r: PRodReader): string =
r.pos = i
proc skipSection(r: PRodReader) =
var c: int
if r.s[r.pos] == ':':
while r.s[r.pos] > '\x0A': inc(r.pos)
elif r.s[r.pos] == '(':
c = 0 # count () pairs
var c = 0 # count () pairs
inc(r.pos)
while true:
case r.s[r.pos]
of '\x0A':
inc(r.line)
of '(':
inc(c)
of '\x0A': inc(r.line)
of '(': inc(c)
of ')':
if c == 0:
inc(r.pos)
break
elif c > 0:
dec(c)
of '\0':
break # end of file
else:
nil
of '\0': break # end of file
else: nil
inc(r.pos)
else:
InternalError("skipSection " & $(r.line))
@@ -535,18 +517,14 @@ proc newStub(r: PRodReader, name: string, id: int): PSym =
if debugIds: registerID(result)
proc processInterf(r: PRodReader, module: PSym) =
var
s: PSym
w: string
key: int
if r.interfIdx == 0: InternalError("processInterf")
r.pos = r.interfIdx
while (r.s[r.pos] > '\x0A') and (r.s[r.pos] != ')'):
w = decode(r)
var w = decode(r)
inc(r.pos)
key = decodeInt(r)
var key = decodeInt(r)
inc(r.pos) # #10
s = newStub(r, w, key)
var s = newStub(r, w, key)
s.owner = module
StrTableAdd(module.tab, s)
IdTablePut(r.syms, s, s)
@@ -669,8 +647,8 @@ proc processRodFile(r: PRodReader, crc: TCrc32) =
skipSection(r)
elif section == "DATA":
r.dataIdx = r.pos + 2 # "(\10"
# We do not read the DATA section here! We read the needed objects on
# demand.
# We do not read the DATA section here! We read the needed objects on
# demand.
skipSection(r)
elif section == "INIT":
r.initIdx = r.pos + 2 # "(\10"
@@ -685,14 +663,12 @@ proc processRodFile(r: PRodReader, crc: TCrc32) =
inc(r.pos)
inc(r.line)
proc newRodReader(modfilename: string, crc: TCrc32, readerIndex: int): PRodReader =
var
version: string
r: PRodReader
proc newRodReader(modfilename: string, crc: TCrc32,
readerIndex: int): PRodReader =
new(result)
result.files = @ []
result.modDeps = @ []
r = result
result.files = @[]
result.modDeps = @[]
var r = result
r.reason = rrNone
r.pos = 0
r.line = 1
@@ -704,7 +680,7 @@ proc newRodReader(modfilename: string, crc: TCrc32, readerIndex: int): PRodReade
initIITable(r.index.tab)
initIITable(r.imports.tab) # looks like a ROD file
inc(r.pos, 4)
version = ""
var version = ""
while not (r.s[r.pos] in {'\0', '\x0A'}):
add(version, r.s[r.pos])
inc(r.pos)
@@ -719,12 +695,11 @@ proc newRodReader(modfilename: string, crc: TCrc32, readerIndex: int): PRodReade
result = nil
proc rrGetType(r: PRodReader, id: int, info: TLineInfo): PType =
var oldPos, d: int
result = PType(IdTableGet(gTypeTable, id))
if result == nil:
# load the type:
oldPos = r.pos
d = IITableGet(r.index.tab, id)
var oldPos = r.pos
var d = IITableGet(r.index.tab, id)
if d == invalidKey: InternalError(info, "rrGetType")
r.pos = d + r.dataIdx
result = decodeType(r, info)
@@ -739,39 +714,29 @@ type
TFileModuleMap = seq[TFileModuleRec]
var gMods: TFileModuleMap = @ []
var gMods: TFileModuleMap = @[]
proc decodeSymSafePos(rd: PRodReader, offset: int, info: TLineInfo): PSym =
# all compiled modules
var oldPos: int
if rd.dataIdx == 0: InternalError(info, "dataIdx == 0")
oldPos = rd.pos
var oldPos = rd.pos
rd.pos = offset + rd.dataIdx
result = decodeSym(rd, info)
rd.pos = oldPos
proc rrGetSym(r: PRodReader, id: int, info: TLineInfo): PSym =
var
d, moduleID: int
rd: PRodReader
result = PSym(IdTableGet(r.syms, id))
if result == nil:
# load the symbol:
d = IITableGet(r.index.tab, id)
var d = IITableGet(r.index.tab, id)
if d == invalidKey:
moduleID = IiTableGet(r.imports.tab, id)
var moduleID = IiTableGet(r.imports.tab, id)
if moduleID < 0:
InternalError(info,
"missing from both indexes: +" & ropeToStr(encodeInt(id))) #
# find
# the
# reader
# with
# the
# correct
# moduleID:
"missing from both indexes: +" & ropeToStr(encodeInt(id)))
# find the reader with the correct moduleID:
for i in countup(0, high(gMods)):
rd = gMods[i].rd
var rd = gMods[i].rd
if (rd != nil):
if (rd.moduleID == moduleID):
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)
proc loadInitSection(r: PRodReader): PNode =
var d, oldPos, p: int
if (r.initIdx == 0) or (r.dataIdx == 0): InternalError("loadInitSection")
oldPos = r.pos
var oldPos = r.pos
r.pos = r.initIdx
result = newNode(nkStmtList)
while (r.s[r.pos] > '\x0A') and (r.s[r.pos] != ')'):
d = decodeInt(r)
var d = decodeInt(r)
inc(r.pos) # #10
p = r.pos
var p = r.pos
r.pos = d + r.dataIdx
addSon(result, decodeNode(r, UnknownLineInfo()))
r.pos = p
r.pos = oldPos
proc loadConverters(r: PRodReader) =
var d: int
# We have to ensure that no exported converter is a stub anymore.
if (r.convertersIdx == 0) or (r.dataIdx == 0):
InternalError("importConverters")
r.pos = r.convertersIdx
while (r.s[r.pos] > '\x0A'):
d = decodeInt(r)
var d = decodeInt(r)
discard rrGetSym(r, d, UnknownLineInfo())
if r.s[r.pos] == ' ': inc(r.pos)
proc getModuleIdx(filename: string): int =
for i in countup(0, high(gMods)):
if sameFile(gMods[i].filename, filename):
return i
if sameFile(gMods[i].filename, filename): return i
result = len(gMods)
setlen(gMods, result + 1)
proc checkDep(filename: string): TReasonForRecompile =
var
crc: TCrc32
r: PRodReader
rodfile: string
idx: int
res: TReasonForRecompile
idx = getModuleIdx(filename)
var idx = getModuleIdx(filename)
if gMods[idx].reason != rrEmpty:
# reason has already been computed for this module:
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].filename = filename
gMods[idx].crc = crc
result = rrNone
r = nil
rodfile = toGeneratedFile(filename, RodExt)
var r: PRodReader = nil
var rodfile = toGeneratedFile(filename, RodExt)
if ExistsFile(rodfile):
r = newRodReader(rodfile, crc, idx)
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
# be used twice! However, compilation speed does not suffer much from
# 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
for i in countup(0, high(r.modDeps)):
res = checkDep(r.modDeps[i])
@@ -870,12 +826,11 @@ proc checkDep(filename: string): TReasonForRecompile =
gMods[idx].reason = result # now we know better
proc handleSymbolFile(module: PSym, filename: string): PRodReader =
var idx: int
if not (optSymbolFiles in gGlobalOptions):
module.id = getID()
return nil
discard checkDep(filename)
idx = getModuleIdx(filename)
var idx = getModuleIdx(filename)
if gMods[idx].reason == rrEmpty: InternalError("handleSymbolFile")
result = gMods[idx].rd
if result != nil:
@@ -888,26 +843,22 @@ proc handleSymbolFile(module: PSym, filename: string): PRodReader =
module.id = getID()
proc GetCRC(filename: string): TCrc32 =
var idx: int
idx = getModuleIdx(filename)
var idx = getModuleIdx(filename)
result = gMods[idx].crc
proc loadStub(s: PSym) =
var
rd: PRodReader
d, theId: int
rs: PSym
if s.kind != skStub:
InternalError("loadStub") #MessageOut('loading stub: ' + s.name.s);
rd = gMods[s.position].rd
theId = s.id # used for later check
d = IITableGet(rd.index.tab, s.id)
var rd = gMods[s.position].rd
var theId = s.id # used for later check
var d = IITableGet(rd.index.tab, s.id)
if d == invalidKey: InternalError("loadStub: invalid key")
rs = decodeSymSafePos(rd, d, UnknownLineInfo())
var rs = decodeSymSafePos(rd, d, UnknownLineInfo())
if rs != s:
InternalError(rs.info, "loadStub: wrong symbol")
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)
InitStrTable(rodCompilerProcs)
InitStrTable(rodCompilerProcs)

View File

@@ -49,11 +49,10 @@ proc encodeStr(w: PRodWriter, s: string): PRope =
result = encode(s)
proc processStacks(w: PRodWriter)
proc getDefines(): PRope =
var
it: TTabIter
s: PSym
s = InitTabIter(it, gSymbols)
var it: TTabIter
var s = InitTabIter(it, gSymbols)
result = nil
while s != nil:
if s.position == 1:
@@ -96,39 +95,38 @@ proc addInclDep(w: PRodWriter, dep: string) =
app(w.inclDeps, rodNL)
proc pushType(w: PRodWriter, t: PType) =
var L: int
# check so that the stack does not grow too large:
if IiTableGet(w.index.tab, t.id) == invalidKey:
L = len(w.tstack)
var L = len(w.tstack)
setlen(w.tstack, L + 1)
w.tstack[L] = t
proc pushSym(w: PRodWriter, s: PSym) =
var L: int
# check so that the stack does not grow too large:
if IiTableGet(w.index.tab, s.id) == invalidKey:
L = len(w.sstack)
var L = len(w.sstack)
setlen(w.sstack, L + 1)
w.sstack[L] = s
proc encodeNode(w: PRodWriter, fInfo: TLineInfo, n: PNode): PRope =
var f: TNodeFlags
if n == nil:
# nil nodes have to be stored too:
return toRope("()")
result = toRope("(")
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
# omit line information if it is the same as the father's line information:
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
# omit line information if it is the same as the father's line information:
if (finfo.fileIndex != n.info.fileIndex):
appf(result, "?$1,$2,$3", [encodeInt(n.info.col), encodeInt(n.info.line),
encodeInt(fileIdx(w, toFilename(n.info)))])
elif (finfo.line != n.info.line):
appf(result, "?$1,$2", [encodeInt(n.info.col), encodeInt(n.info.line)])
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
# file.
f = n.flags * PersistentNodeFlags
appf(result, "?$1", [encodeInt(n.info.col)])
# No need to output the file index, as this is the serialization of one
# file.
var f = n.flags * PersistentNodeFlags
if f != {}: appf(result, "$$$1", [encodeInt(cast[int32](f))])
if n.typ != nil:
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)])
pushType(w, t.sons[i])
proc encodeLib(w: PRodWriter, lib: PLib): PRope =
proc encodeLib(w: PRodWriter, lib: PLib, info: TLineInfo): PRope =
result = nil
appf(result, "|$1", [encodeInt(ord(lib.kind))])
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 =
var
@@ -235,7 +233,7 @@ proc encodeSym(w: PRodWriter, s: PSym): PRope =
if s.position != 0: appf(result, "%$1", [encodeInt(s.position)])
if s.offset != - 1: appf(result, "`$1", [encodeInt(s.offset)])
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) =
if key - w.lastIdxKey == 1:
@@ -367,10 +365,11 @@ proc writeRod(w: PRodWriter) =
app(content, toRope(')' & rodNL))
app(content, toRope("DATA(" & rodNL))
app(content, w.data)
app(content, toRope(')' & rodNL)) #MessageOut('interf ' + ToString(ropeLen(w.interf)));
#MessageOut('index ' + ToString(ropeLen(w.indexRope)));
#MessageOut('init ' + ToString(ropeLen(w.init)));
#MessageOut('data ' + ToString(ropeLen(w.data)));
app(content, toRope(')' & rodNL))
#MessageOut('interf ' + ToString(ropeLen(w.interf)));
#MessageOut('index ' + ToString(ropeLen(w.indexRope)));
#MessageOut('init ' + ToString(ropeLen(w.init)));
#MessageOut('data ' + ToString(ropeLen(w.data)));
writeRope(content, completeGeneratedFilePath(changeFileExt(w.filename, "rod")))
proc process(c: PPassContext, n: PNode): PNode =
@@ -411,16 +410,17 @@ proc process(c: PPassContext, n: PNode): PNode =
if a.kind == nkCommentStmt: continue
if a.sons[0].kind != nkSym: InternalError(a.info, "rodwrite.process")
s = a.sons[0].sym
addInterfaceSym(w, s) # this takes care of enum fields too
# Note: The check for ``s.typ.kind = tyEnum`` is wrong for enum
# type aliasing! Otherwise the same enum symbol would be included
# several times!
#
# if (a.sons[2] <> nil) and (a.sons[2].kind = nkEnumTy) then begin
# a := s.typ.n;
# for j := 0 to sonsLen(a)-1 do
# addInterfaceSym(w, a.sons[j].sym);
# end
addInterfaceSym(w, s)
# this takes care of enum fields too
# Note: The check for ``s.typ.kind = tyEnum`` is wrong for enum
# type aliasing! Otherwise the same enum symbol would be included
# several times!
#
# if (a.sons[2] <> nil) and (a.sons[2].kind = nkEnumTy) then begin
# a := s.typ.n;
# for j := 0 to sonsLen(a)-1 do
# addInterfaceSym(w, a.sons[j].sym);
# end
of nkImportStmt:
for i in countup(0, sonsLen(n) - 1): addModDep(w, getModuleFile(n.sons[i]))
addStmt(w, n)
@@ -435,15 +435,13 @@ proc process(c: PPassContext, n: PNode): PNode =
nil
proc myOpen(module: PSym, filename: string): PPassContext =
var w: PRodWriter
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)
result = w
proc myClose(c: PPassContext, n: PNode): PNode =
var w: PRodWriter
w = PRodWriter(c)
var w = PRodWriter(c)
writeRod(w)
result = n
@@ -454,4 +452,4 @@ proc rodwritePass(): TPass =
result.close = myClose
result.process = process
IntSetInit(debugWritten)
IntSetInit(debugWritten)

View File

@@ -9,8 +9,7 @@
# This module implements the semantic checking pass.
import #var
# point: array [0..3] of int;
import
strutils, nhashes, lists, options, scanner, ast, astalgo, trees, treetab,
wordrecg, ropes, msgs, os, condsyms, idents, rnimsyn, types, platform, math,
magicsys, pnimsyn, nversion, nimsets, semdata, evals, semfold, importer,
@@ -20,8 +19,7 @@ proc semPass*(): TPass
# implementation
proc considerAcc(n: PNode): PIdent =
var x: PNode
x = n
var x = n
if x.kind == nkAccQuoted: x = x.sons[0]
case x.kind
of nkIdent: result = x.ident
@@ -62,6 +60,7 @@ proc addParams(c: PContext, n: PNode)
proc addResult(c: PContext, t: PType, info: TLineInfo)
proc addResultNode(c: PContext, n: PNode)
proc instGenericContainer(c: PContext, n: PNode, header: PType): PType
proc semConstExpr(c: PContext, n: PNode): PNode =
result = semExprWithType(c, n)
if result == nil:
@@ -71,8 +70,7 @@ proc semConstExpr(c: PContext, n: PNode): PNode =
if result == nil: liMessage(n.info, errConstExprExpected)
proc semAndEvalConstExpr(c: PContext, n: PNode): PNode =
var e: PNode
e = semExprWithType(c, n)
var e = semExprWithType(c, n)
if e == nil:
liMessage(n.info, errConstExprExpected)
return nil
@@ -91,19 +89,16 @@ proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode =
of tyTypeDesc: result.typ = semTypeNode(c, result, nil)
else: liMessage(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0]))
include
"semtempl.nim"
include "semtempl.nim"
proc semMacroExpr(c: PContext, n: PNode, sym: PSym, semCheck: bool = true): PNode =
var
p: PEvalContext
s: PStackFrame
proc semMacroExpr(c: PContext, n: PNode, sym: PSym,
semCheck: bool = true): PNode =
inc(evalTemplateCounter)
if evalTemplateCounter > 100:
liMessage(n.info, errTemplateInstantiationTooNested)
markUsed(n, sym)
p = newEvalContext(c.module, "", false)
s = newStackFrame()
var p = newEvalContext(c.module, "", false)
var s = newStackFrame()
s.call = n
setlen(s.params, 2)
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)
dec(evalTemplateCounter)
include
"seminst.nim"
include
"sigmatch.nim"
include "seminst.nim", "sigmatch.nim"
proc CheckBool(t: PNode) =
if (t.Typ == nil) or
@@ -132,37 +123,27 @@ proc typeMismatch(n: PNode, formal, actual: PType) =
typeToString(actual) & ") " &
`%`(msgKindToString(errButExpectedX), [typeToString(formal)]))
include
"semtypes.nim"
include
"semexprs.nim"
include
"semgnrc.nim"
include
"semstmts.nim"
include "semtypes.nim", "semexprs.nim", "semgnrc.nim", "semstmts.nim"
proc addCodeForGenerics(c: PContext, n: PNode) =
var
prc: PSym
it: PNode
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")
prc = it.sym
var prc = it.sym
if (prc.kind in {skProc, skMethod, skConverter}) and (prc.magic == mNone):
if (prc.ast == nil) or (prc.ast.sons[codePos] == nil):
InternalError(prc.info, "no code for " & prc.name.s)
addSon(n, prc.ast)
c.lastGenericIdx = sonsLen(c.generics)
proc semExprNoFlags(c: PContext, n: PNode): PNode =
result = semExpr(c, n, {})
proc myOpen(module: PSym, filename: string): PPassContext =
var c: PContext
c = newContext(module, filename)
var c = newContext(module, filename)
if (c.p != nil): InternalError(module.info, "sem.myOpen")
c.semConstExpr = semConstExpr
c.semExpr = semExprNoFlags
c.p = newProcCon(module)
pushOwner(c.module)
openScope(c.tab) # scope for imported symbols
@@ -177,20 +158,17 @@ proc myOpen(module: PSym, filename: string): PPassContext =
result = c
proc myOpenCached(module: PSym, filename: string, rd: PRodReader): PPassContext =
var c: PContext
c = PContext(myOpen(module, filename))
var c = PContext(myOpen(module, filename))
c.fromCache = true
result = c
proc myProcess(context: PPassContext, n: PNode): PNode =
var
c: PContext
a: PNode
result = nil
c = PContext(context)
result = semStmt(c, n) # BUGFIX: process newly generated generics here, not at the end!
var c = PContext(context)
result = semStmt(c, n)
# BUGFIX: process newly generated generics here, not at the end!
if sonsLen(c.generics) > 0:
a = newNodeI(nkStmtList, n.info)
var a = newNodeI(nkStmtList, n.info)
addCodeForGenerics(c, a)
if sonsLen(a) > 0:
# a generic has been added to `a`:
@@ -198,8 +176,7 @@ proc myProcess(context: PPassContext, n: PNode): PNode =
result = a
proc myClose(context: PPassContext, n: PNode): PNode =
var c: PContext
c = PContext(context)
var c = PContext(context)
closeScope(c.tab) # close module's scope
rawCloseScope(c.tab) # imported symbols; don't check for unused ones!
if n == nil:

View File

@@ -15,7 +15,8 @@ import
magicsys, nversion, nimsets, pnimsyn, times, passes, rodread
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
defaultCC*: TCallingConvention
dynlib*: PLib
@@ -46,15 +47,16 @@ type
optionStack*: TLinkedList
libs*: TLinkedList # all libs used by this module
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
filename*: string # the module's filename
var gInstTypes*: TIdTable
var gInstTypes*: TIdTable # map PType to PType
proc newContext*(module: PSym, nimfile: string): PContext
# map PType to PType
proc newProcCon*(owner: PSym): PProcCon
proc lastOptionEntry*(c: PContext): POptionEntry
proc newOptionEntry*(): POptionEntry
@@ -70,15 +72,15 @@ proc illFormedAst*(n: PNode)
proc getSon*(n: PNode, indx: int): PNode
proc checkSonsLen*(n: PNode, length: int)
proc checkMinSonsLen*(n: PNode, length: int)
# owner handling:
# owner handling:
proc getCurrOwner*(): PSym
proc PushOwner*(owner: PSym)
proc PopOwner*()
# implementation
var gOwners: seq[PSym]
var gOwners: seq[PSym] = @[]
gOwners = @ []
proc getCurrOwner(): PSym =
# owner stack (used for initializing the
# owner field of syms)
@@ -88,14 +90,10 @@ proc getCurrOwner(): PSym =
result = gOwners[high(gOwners)]
proc PushOwner(owner: PSym) =
var length: int
length = len(gOwners)
setlen(gOwners, length + 1)
gOwners[length] = owner
add(gOwners, owner)
proc PopOwner() =
var length: int
length = len(gOwners)
var length = len(gOwners)
if (length <= 0): InternalError("popOwner")
setlen(gOwners, length - 1)
@@ -128,8 +126,7 @@ proc newContext(module: PSym, nimfile: string): PContext =
IntSetInit(result.includedFiles)
proc addConverter(c: PContext, conv: PSym) =
var L: int
L = len(c.converters)
var L = len(c.converters)
for i in countup(0, L - 1):
if c.converters[i].id == conv.id: return
setlen(c.converters, L + 1)
@@ -162,9 +159,9 @@ proc fillTypeS(dest: PType, kind: TTypeKind, c: PContext) =
dest.owner = getCurrOwner()
dest.size = - 1
proc makeRangeType(c: PContext, first, last: biggestInt, info: TLineInfo): PType =
var n: PNode
n = newNodeI(nkRange, info)
proc makeRangeType(c: PContext, first, last: biggestInt,
info: TLineInfo): PType =
var n = newNodeI(nkRange, info)
addSon(n, newIntNode(nkIntLit, first))
addSon(n, newIntNode(nkIntLit, last))
result = newTypeS(tyRange, c)
@@ -187,4 +184,4 @@ proc checkSonsLen(n: PNode, length: int) =
proc checkMinSonsLen(n: PNode, length: int) =
if (n == nil) or (sonsLen(n) < length): illFormedAst(n)
initIdTable(gInstTypes)
initIdTable(gInstTypes)

View File

@@ -14,7 +14,7 @@ import
strutils, lists, options, ast, astalgo, trees, treetab, nimsets, times,
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
# expression
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 newFloatNodeT*(floatVal: BiggestFloat, 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
proc newIntNodeT(intVal: BiggestInt, n: PNode): PNode =
@@ -46,35 +43,6 @@ proc newStrNodeT(strVal: string, n: PNode): PNode =
result.typ = n.typ
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 =
var
n: PNode
@@ -93,56 +61,35 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
# b and c may be nil
result = nil
case m
of mOrd:
result = newIntNodeT(getOrdValue(a), n)
of mChr:
result = newIntNodeT(getInt(a), n)
of mUnaryMinusI, mUnaryMinusI64:
result = newIntNodeT(- getInt(a), n)
of mUnaryMinusF64:
result = newFloatNodeT(- getFloat(a), n)
of mNot:
result = newIntNodeT(1 - getInt(a), n)
of mCard:
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 mOrd: result = newIntNodeT(getOrdValue(a), n)
of mChr: result = newIntNodeT(getInt(a), n)
of mUnaryMinusI, mUnaryMinusI64: result = newIntNodeT(- getInt(a), n)
of mUnaryMinusF64: result = newFloatNodeT(- getFloat(a), n)
of mNot: result = newIntNodeT(1 - getInt(a), n)
of mCard: 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:
result = newFloatNodeT(toFloat(int(getInt(a))), n)
of mToInt, mToBiggestInt:
result = newIntNodeT(system.toInt(getFloat(a)), n)
of mAbsF64:
result = newFloatNodeT(abs(getFloat(a)), n)
of mToInt, mToBiggestInt: result = newIntNodeT(system.toInt(getFloat(a)), n)
of mAbsF64: result = newFloatNodeT(abs(getFloat(a)), n)
of mAbsI, mAbsI64:
if getInt(a) >= 0: result = a
else: result = newIntNodeT(- getInt(a), n)
of mZe8ToI, mZe8ToI64, mZe16ToI, mZe16ToI64, mZe32ToI64, mZeIToI64:
# 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)
of mToU8:
result = newIntNodeT(getInt(a) and 0x000000FF, n)
of mToU16:
result = newIntNodeT(getInt(a) and 0x0000FFFF, n)
of mToU32:
result = newIntNodeT(getInt(a) and 0x00000000FFFFFFFF'i64, n)
of mSucc:
result = newIntNodeT(getOrdValue(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 mToU8: result = newIntNodeT(getInt(a) and 0x000000FF, n)
of mToU16: result = newIntNodeT(getInt(a) and 0x0000FFFF, n)
of mToU32: result = newIntNodeT(getInt(a) and 0x00000000FFFFFFFF'i64, n)
of mSucc: result = newIntNodeT(getOrdValue(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:
if getInt(a) > getInt(b): result = newIntNodeT(getInt(b), 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 tyInt64, tyInt: result = newIntNodeT(`shr`(getInt(a), getInt(b)), n)
else: InternalError(n.info, "constant folding for shl")
of mDivI, mDivI64:
result = newIntNodeT(getInt(a) div getInt(b), n)
of mModI, mModI64:
result = newIntNodeT(getInt(a) mod getInt(b), n)
of mAddF64:
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 mDivI, mDivI64: result = newIntNodeT(getInt(a) div getInt(b), n)
of mModI, mModI64: result = newIntNodeT(getInt(a) mod getInt(b), n)
of mAddF64: 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:
if getFloat(b) == 0.0:
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:
if getFloat(a) > getFloat(b): result = newFloatNodeT(getFloat(b), n)
else: result = newFloatNodeT(getFloat(a), n)
of mIsNil:
result = newIntNodeT(ord(a.kind == nkNilLit), n)
of mIsNil: result = newIntNodeT(ord(a.kind == nkNilLit), n)
of mLtI, mLtI64, mLtB, mLtEnum, mLtCh:
result = newIntNodeT(ord(getOrdValue(a) < getOrdValue(b)), n)
of mLeI, mLeI64, mLeB, mLeEnum, mLeCh:
result = newIntNodeT(ord(getOrdValue(a) <= getOrdValue(b)), n)
of mEqI, mEqI64, mEqB, mEqEnum, mEqCh:
result = newIntNodeT(ord(getOrdValue(a) == getOrdValue(b)), n) # operators for floats
of mLtF64:
result = newIntNodeT(ord(getFloat(a) < getFloat(b)), n)
of mLeF64:
result = newIntNodeT(ord(getFloat(a) <= getFloat(b)), n)
of mEqF64:
result = newIntNodeT(ord(getFloat(a) == getFloat(b)), n) # operators for strings
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)
result = newIntNodeT(ord(getOrdValue(a) == getOrdValue(b)), n)
of mLtF64: result = newIntNodeT(ord(getFloat(a) < getFloat(b)), n)
of mLeF64: result = newIntNodeT(ord(getFloat(a) <= getFloat(b)), n)
of mEqF64: result = newIntNodeT(ord(getFloat(a) == getFloat(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:
result = newIntNodeT(ord(`<%`(getOrdValue(a), getOrdValue(b))), n)
of mLeU, mLeU64:
result = newIntNodeT(ord(`<=%`(getOrdValue(a), getOrdValue(b))), n)
of mBitandI, mBitandI64, mAnd:
result = newIntNodeT(getInt(a) and getInt(b), n)
of mBitorI, mBitorI64, mOr:
result = newIntNodeT(getInt(a) or getInt(b), n)
of mBitxorI, mBitxorI64, mXor:
result = newIntNodeT(getInt(a) xor getInt(b), n)
of mAddU, mAddU64:
result = newIntNodeT(`+%`(getInt(a), getInt(b)), n)
of mSubU, mSubU64:
result = newIntNodeT(`-%`(getInt(a), getInt(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 mBitandI, mBitandI64, mAnd: result = newIntNodeT(getInt(a) and getInt(b), n)
of mBitorI, mBitorI64, mOr: result = newIntNodeT(getInt(a) or getInt(b), n)
of mBitxorI, mBitxorI64, mXor: result = newIntNodeT(getInt(a) xor getInt(b), n)
of mAddU, mAddU64: result = newIntNodeT(`+%`(getInt(a), getInt(b)), n)
of mSubU, mSubU64: result = newIntNodeT(`-%`(getInt(a), getInt(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:
result = newIntNodeT(Ord(containsSets(a, b) and not equalSets(a, b)), n)
of mMulSet:
@@ -243,32 +168,24 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
of mSymDiffSet:
result = nimsets.symdiffSets(a, b)
result.info = n.info
of mConStrStr:
result = newStrNodeT(getStrOrChar(a) & getStrOrChar(b), n)
of mInSet:
result = newIntNodeT(Ord(inSet(a, b)), n)
of mConStrStr: result = newStrNodeT(getStrOrChar(a) & getStrOrChar(b), n)
of mInSet: result = newIntNodeT(Ord(inSet(a, b)), n)
of mRepr:
# BUGFIX: we cannot eval mRepr here. But this means that it is not
# available for interpretation. I don't know how to fix this.
#result := newStrNodeT(renderTree(a, {@set}[renderNoComments]), n);
of mIntToStr, mInt64ToStr:
result = newStrNodeT($(getOrdValue(a)), n)
of mIntToStr, mInt64ToStr: result = newStrNodeT($(getOrdValue(a)), n)
of mBoolToStr:
if getOrdValue(a) == 0: result = newStrNodeT("false", n)
else: result = newStrNodeT("true", n)
of mCopyStr:
result = newStrNodeT(copy(getStr(a), int(getOrdValue(b)) + 0), n)
of mCopyStr: result = newStrNodeT(copy(getStr(a), int(getOrdValue(b))), n)
of mCopyStrLast:
result = newStrNodeT(copy(getStr(a), int(getOrdValue(b)) + 0,
int(getOrdValue(c)) + 0), n)
of mFloatToStr:
result = newStrNodeT($(getFloat(a)), n)
of mCStrToStr, mCharToStr:
result = newStrNodeT(getStrOrChar(a), n)
of mStrToStr:
result = a
of mEnumToStr:
result = newStrNodeT(enumValToString(a), n)
result = newStrNodeT(copy(getStr(a), int(getOrdValue(b)),
int(getOrdValue(c))), n)
of mFloatToStr: result = newStrNodeT($(getFloat(a)), n)
of mCStrToStr, mCharToStr: result = newStrNodeT(getStrOrChar(a), n)
of mStrToStr: result = a
of mEnumToStr: result = newStrNodeT(enumValToString(a), n)
of mArrToSeq:
result = copyTree(a)
result.typ = n.typ
@@ -278,15 +195,13 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
else: InternalError(a.info, "evalOp(" & $m & ')')
proc getConstIfExpr(c: PSym, n: PNode): PNode =
var it, e: PNode
result = nil
for i in countup(0, sonsLen(n) - 1):
it = n.sons[i]
var it = n.sons[i]
case it.kind
of nkElifExpr:
e = getConstExpr(c, it.sons[0])
if e == nil:
return nil
var e = getConstExpr(c, it.sons[0])
if e == nil: return nil
if getOrdValue(e) != 0:
if result == nil:
result = getConstExpr(c, it.sons[1])
@@ -297,10 +212,9 @@ proc getConstIfExpr(c: PSym, n: PNode): PNode =
proc partialAndExpr(c: PSym, n: PNode): PNode =
# partial evaluation
var a, b: PNode
result = n
a = getConstExpr(c, n.sons[1])
b = getConstExpr(c, n.sons[2])
var a = getConstExpr(c, n.sons[1])
var b = getConstExpr(c, n.sons[2])
if a != nil:
if getInt(a) == 0: result = a
elif b != nil: result = b
@@ -311,10 +225,9 @@ proc partialAndExpr(c: PSym, n: PNode): PNode =
proc partialOrExpr(c: PSym, n: PNode): PNode =
# partial evaluation
var a, b: PNode
result = n
a = getConstExpr(c, n.sons[1])
b = getConstExpr(c, n.sons[2])
var a = getConstExpr(c, n.sons[1])
var b = getConstExpr(c, n.sons[2])
if a != nil:
if getInt(a) != 0: result = a
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")
proc getConstExpr(module: PSym, n: PNode): PNode =
var
s: PSym
a, b, c: PNode
proc getConstExpr(m: PSym, n: PNode): PNode =
result = nil
case n.kind
of nkSym:
s = n.sym
var s = n.sym
if s.kind == skEnumField:
result = newIntNodeT(s.position, n)
elif (s.kind == skConst):
case s.magic
of mIsMainModule: result = newIntNodeT(ord(sfMainModule in module.flags),
n)
of mIsMainModule: result = newIntNodeT(ord(sfMainModule in m.flags), n)
of mCompileDate: result = newStrNodeT(times.getDateStr(), n)
of mCompileTime: result = newStrNodeT(times.getClockStr(), 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 mInf: result = newFloatNodeT(Inf, n)
of mNegInf: result = newFloatNodeT(NegInf, n)
else:
result = copyTree(s.ast) # BUGFIX
else: result = copyTree(s.ast)
elif s.kind in {skProc, skMethod}: # BUGFIX
result = n
of nkCharLit..nkNilLit:
result = copyNode(n)
of nkIfExpr:
result = getConstIfExpr(module, n)
result = getConstIfExpr(m, n)
of nkCall, nkCommand, nkCallStrLit:
if (n.sons[0].kind != nkSym): return
s = n.sons[0].sym
var s = n.sons[0].sym
if (s.kind != skProc): return
try:
case s.magic
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:
a = n.sons[1]
var a = n.sons[1]
if computeSize(a.typ) < 0:
liMessage(a.info, errCannotEvalXBecauseIncompletelyDefined, "sizeof")
if a.typ.kind in {tyArray, tyObject, tyTuple}:
result = nil # XXX: size computation for complex types
# is still wrong
result = nil
# XXX: size computation for complex types is still wrong
else:
result = newIntNodeT(getSize(a.typ), n)
of mLow:
@@ -396,13 +304,14 @@ proc getConstExpr(module: PSym, n: PNode): PNode =
{tyOpenArray, tySequence, tyString}):
result = newIntNodeT(lastOrd(skipTypes(n.sons[1].typ, abstractVar)), n)
else:
a = getConstExpr(module, n.sons[1])
var a = getConstExpr(m, n.sons[1])
var b, c: PNode
if a == nil: return
if sonsLen(n) > 2:
b = getConstExpr(module, n.sons[2])
b = getConstExpr(m, n.sons[2])
if b == nil: return
if sonsLen(n) > 3:
c = getConstExpr(module, n.sons[3])
c = getConstExpr(m, n.sons[3])
if c == nil: return
else:
b = nil
@@ -412,22 +321,21 @@ proc getConstExpr(module: PSym, n: PNode): PNode =
except EDivByZero:
liMessage(n.info, errConstantDivisionByZero)
of nkAddr:
a = getConstExpr(module, n.sons[0])
var a = getConstExpr(m, n.sons[0])
if a != nil:
result = n
n.sons[0] = a
of nkBracket:
result = copyTree(n)
for i in countup(0, sonsLen(n) - 1):
a = getConstExpr(module, n.sons[i])
if a == nil:
return nil
var a = getConstExpr(m, n.sons[i])
if a == nil: return nil
result.sons[i] = a
incl(result.flags, nfAllConst)
of nkRange:
a = getConstExpr(module, n.sons[0])
var a = getConstExpr(m, n.sons[0])
if a == nil: return
b = getConstExpr(module, n.sons[1])
var b = getConstExpr(m, n.sons[1])
if b == nil: return
result = copyNode(n)
addSon(result, a)
@@ -435,9 +343,8 @@ proc getConstExpr(module: PSym, n: PNode): PNode =
of nkCurly:
result = copyTree(n)
for i in countup(0, sonsLen(n) - 1):
a = getConstExpr(module, n.sons[i])
if a == nil:
return nil
var a = getConstExpr(m, n.sons[i])
if a == nil: return nil
result.sons[i] = a
incl(result.flags, nfAllConst)
of nkPar:
@@ -445,19 +352,17 @@ proc getConstExpr(module: PSym, n: PNode): PNode =
result = copyTree(n)
if (sonsLen(n) > 0) and (n.sons[0].kind == nkExprColonExpr):
for i in countup(0, sonsLen(n) - 1):
a = getConstExpr(module, n.sons[i].sons[1])
if a == nil:
return nil
var a = getConstExpr(m, n.sons[i].sons[1])
if a == nil: return nil
result.sons[i].sons[1] = a
else:
for i in countup(0, sonsLen(n) - 1):
a = getConstExpr(module, n.sons[i])
if a == nil:
return nil
var a = getConstExpr(m, n.sons[i])
if a == nil: return nil
result.sons[i] = a
incl(result.flags, nfAllConst)
of nkChckRangeF, nkChckRange64, nkChckRange:
a = getConstExpr(module, n.sons[0])
var a = getConstExpr(m, n.sons[0])
if a == nil: return
if leValueConv(n.sons[1], a) and leValueConv(a, n.sons[2]):
result = a # a <= x and x <= b
@@ -467,12 +372,12 @@ proc getConstExpr(module: PSym, n: PNode): PNode =
msgKindToString(errIllegalConvFromXtoY),
[typeToString(n.sons[0].typ), typeToString(n.typ)]))
of nkStringToCString, nkCStringToString:
a = getConstExpr(module, n.sons[0])
var a = getConstExpr(m, n.sons[0])
if a == nil: return
result = a
result.typ = n.typ
of nkHiddenStdConv, nkHiddenSubConv, nkConv, nkCast:
a = getConstExpr(module, n.sons[1])
var a = getConstExpr(m, n.sons[1])
if a == nil: return
case skipTypes(n.typ, abstractRange).kind
of tyInt..tyInt64:

View File

@@ -118,11 +118,9 @@ proc newAsgnStmt(c: PTransf, le, ri: PNode): PNode =
addSon(result, ri)
proc transformSym(c: PTransf, n: PNode): PNode =
var
tc: PTransCon
b: PNode
var b: PNode
if (n.kind != nkSym): internalError(n.info, "transformSym")
tc = c.transCon
var tc = c.transCon
if sfBorrow in n.sym.flags:
# simply exchange the symbol:
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 =
# we transform the continue statement into a block statement
var
counter: int
x: PNode
labl: PSym
result = n
for i in countup(0, sonsLen(n) - 1): result.sons[i] = transform(c, n.sons[i])
counter = 0
labl = newSym(skLabel, nil, getCurrOwner(c))
var counter = 0
var labl = newSym(skLabel, nil, getCurrOwner(c))
labl.name = getIdent(genPrefix & $(labl.id))
labl.info = result.info
transformContinueAux(c, result, labl, counter)
if counter > 0:
x = newNodeI(nkBlockStmt, result.info)
var x = newNodeI(nkBlockStmt, result.info)
addSon(x, newSymNode(labl))
addSon(x, result)
result = x
@@ -189,10 +183,9 @@ proc skipConv(n: PNode): PNode =
else: result = n
proc newTupleAccess(tup: PNode, i: int): PNode =
var lit: PNode
result = newNodeIT(nkBracketExpr, tup.info, tup.typ.sons[i])
addSon(result, copyTree(tup))
lit = newNodeIT(nkIntLit, tup.info, getSysType(tyInt))
var lit = newNodeIT(nkIntLit, tup.info, getSysType(tyInt))
lit.intVal = i
addSon(result, lit)
@@ -203,9 +196,8 @@ proc unpackTuple(c: PTransf, n, father: PNode) =
transform(c, newTupleAccess(n, i))))
proc transformYield(c: PTransf, n: PNode): PNode =
var e: PNode
result = newNodeI(nkStmtList, n.info)
e = n.sons[0]
var e = n.sons[0]
if skipTypes(e.typ, {tyGenericInst}).kind == tyTuple:
e = skipConv(e)
if e.kind == nkPar:
@@ -220,10 +212,6 @@ proc transformYield(c: PTransf, n: PNode): PNode =
addSon(result, transform(c, lastSon(c.transCon.forStmt)))
proc inlineIter(c: PTransf, n: PNode): PNode =
var
L: int
it: PNode
newVar: PSym
result = n
if n == nil: return
case n.kind
@@ -234,13 +222,14 @@ proc inlineIter(c: PTransf, n: PNode): PNode =
of nkVarSection:
result = copyTree(n)
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 == nkIdentDefs:
if (it.sons[0].kind != nkSym): InternalError(it.info, "inlineIter")
newVar = copySym(it.sons[0].sym)
incl(newVar.flags, sfFromGeneric) # fixes a strange bug for rodgen:
#include(it.sons[0].sym.flags, sfFromGeneric);
var newVar = copySym(it.sons[0].sym)
incl(newVar.flags, sfFromGeneric)
# fixes a strange bug for rodgen:
#include(it.sons[0].sym.flags, sfFromGeneric);
newVar.owner = getCurrOwner(c)
IdNodeTablePut(c.transCon.mapping, it.sons[0].sym, newSymNode(newVar))
it.sons[0] = newSymNode(newVar)
@@ -248,9 +237,9 @@ proc inlineIter(c: PTransf, n: PNode): PNode =
else:
if it.kind != nkVarTuple:
InternalError(it.info, "inlineIter: not nkVarTuple")
L = sonsLen(it)
var L = sonsLen(it)
for j in countup(0, L - 3):
newVar = copySym(it.sons[j].sym)
var newVar = copySym(it.sons[j].sym)
incl(newVar.flags, sfFromGeneric)
newVar.owner = getCurrOwner(c)
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)
proc addVar(father, v: PNode) =
var vpart: PNode
vpart = newNodeI(nkIdentDefs, v.info)
var vpart = newNodeI(nkIdentDefs, v.info)
addSon(vpart, v)
addSon(vpart, nil)
addSon(vpart, nil)
addSon(father, vpart)
proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PNode =
var m: PNode
case n.sons[0].kind
of nkObjUpConv, nkObjDownConv, nkPassAsOpenArray, nkChckRange, nkChckRangeF,
nkChckRange64:
m = n.sons[0].sons[0]
var m = n.sons[0].sons[0]
if (m.kind == a) or (m.kind == b):
# addr ( nkPassAsOpenArray ( deref ( x ) ) ) --> nkPassAsOpenArray(x)
n.sons[0].sons[0] = m.sons[0]
return transform(c, n.sons[0])
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):
# addr ( nkConv ( deref ( x ) ) ) --> nkConv(x)
n.sons[0].sons[1] = m.sons[0]
@@ -294,13 +281,10 @@ proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PNode =
result = n
proc transformConv(c: PTransf, n: PNode): PNode =
var
source, dest: PType
diff: int
n.sons[1] = transform(c, n.sons[1])
result = n # numeric types need range checks:
dest = skipTypes(n.typ, abstractVarRange)
source = skipTypes(n.sons[1].typ, abstractVarRange)
var dest = skipTypes(n.typ, abstractVarRange)
var source = skipTypes(n.sons[1].typ, abstractVarRange)
case dest.kind
of tyInt..tyInt64, tyEnum, tyChar, tyBool:
if (firstOrd(dest) <= firstOrd(source)) and
@@ -340,7 +324,7 @@ proc transformConv(c: PTransf, n: PNode): PNode =
dest = skipTypes(dest, abstractPtrs)
source = skipTypes(source, abstractPtrs)
if source.kind == tyObject:
diff = inheritanceDiff(dest, source)
var diff = inheritanceDiff(dest, source)
if diff < 0:
result = newNodeIT(nkObjUpConv, n.info, n.typ)
addSon(result, n.sons[1])
@@ -350,7 +334,7 @@ proc transformConv(c: PTransf, n: PNode): PNode =
else:
result = n.sons[1]
of tyObject:
diff = inheritanceDiff(dest, source)
var diff = inheritanceDiff(dest, source)
if diff < 0:
result = newNodeIT(nkObjUpConv, n.info, n.typ)
addSon(result, n.sons[1])
@@ -360,7 +344,7 @@ proc transformConv(c: PTransf, n: PNode): PNode =
else:
result = n.sons[1]
of tyGenericParam, tyOrdinal:
result = n.sons[1] # happens sometimes for generated assignments, etc.
result = n.sons[1] # happens sometimes for generated assignments, etc.
else:
nil
@@ -393,45 +377,42 @@ proc putArgInto(arg: PNode, formal: PType): TPutArgInto =
proc transformFor(c: PTransf, n: PNode): PNode =
# generate access statements for the parameters (unless they are constant)
# 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")
result = newNodeI(nkStmtList, n.info)
length = sonsLen(n)
var length = sonsLen(n)
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):
addVar(v, copyTree(n.sons[i])) # declare new vars
addSon(result, v)
newC = newTransCon()
call = n.sons[length - 2]
var newC = newTransCon()
var call = n.sons[length - 2]
if (call.kind != nkCall) or (call.sons[0].kind != nkSym):
InternalError(call.info, "transformFor")
newC.owner = call.sons[0].sym
newC.forStmt = n
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)
for i in countup(1, sonsLen(call) - 1):
arg = skipPassAsOpenArray(transform(c, call.sons[i]))
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]);
var arg = skipPassAsOpenArray(transform(c, call.sons[i]))
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]);
case putArgInto(arg, formal.typ)
of paDirectMapping:
IdNodeTablePut(newC.mapping, formal, arg)
of paFastAsgn:
# 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))
addSon(result, newAsgnStmt(c, newSymNode(temp), arg))
IdNodeTablePut(newC.mapping, formal, newSymNode(temp))
of paVarAsgn:
assert(skipTypes(formal.typ, abstractInst).kind == tyVar)
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)
addSon(result, inlineIter(c, body))
popInfoContext()
@@ -447,14 +428,11 @@ proc getMagicOp(call: PNode): TMagic =
proc gatherVars(c: PTransf, n: PNode, marked: var TIntSet, owner: PSym,
container: PNode) =
# gather used vars for closure generation
var
s: PSym
found: bool
if n == nil: return
case n.kind
of nkSym:
s = n.sym
found = false
var s = n.sym
var found = false
case s.kind
of skVar: found = not (sfGlobal in s.flags)
of skTemp, skForVar, skParam: found = true
@@ -476,10 +454,9 @@ proc addFormalParam(routine: PSym, param: PSym) =
proc indirectAccess(a, b: PSym): PNode =
# returns a^ .b as a node
var x, y, deref: PNode
x = newSymNode(a)
y = newSymNode(b)
deref = newNodeI(nkDerefExpr, x.info)
var x = newSymNode(a)
var y = newSymNode(b)
var deref = newNodeI(nkDerefExpr, x.info)
deref.typ = x.typ.sons[0]
addSon(deref, x)
result = newNodeI(nkDotExpr, x.info)
@@ -488,29 +465,26 @@ proc indirectAccess(a, b: PSym): PNode =
result.typ = y.typ
proc transformLambda(c: PTransf, n: PNode): PNode =
var
marked: TIntSet
closure: PNode
s, param: PSym
cl, p: PType
newC: PTransCon
var marked: TIntSet
result = n
IntSetInit(marked)
if (n.sons[namePos].kind != nkSym): InternalError(n.info, "transformLambda")
s = n.sons[namePos].sym
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!):
cl = newType(tyObject, s)
var s = n.sons[namePos].sym
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!):
var cl = newType(tyObject, s)
cl.n = closure
addSon(cl, nil) # no super class
p = newType(tyRef, s)
var p = newType(tyRef, s)
addSon(p, cl)
param = newSym(skParam, getIdent(genPrefix & "Cl"), s)
var param = newSym(skParam, getIdent(genPrefix & "Cl"), s)
param.typ = p
addFormalParam(s, param) # all variables that are accessed should be accessed by the new closure
# parameter:
addFormalParam(s, param)
# all variables that are accessed should be accessed by the new closure
# parameter:
if sonsLen(closure) > 0:
newC = newTransCon()
var newC = newTransCon()
for i in countup(0, sonsLen(closure) - 1):
IdNodeTablePut(newC.mapping, 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 =
# removes `elif` branches of a case stmt
# adds ``else: nil`` if needed for the code generator
var
length, i: int
ifs, elsen: PNode
length = sonsLen(n)
i = length - 1
var length = sonsLen(n)
var i = length - 1
if n.sons[i].kind == nkElse: dec(i)
if n.sons[i].kind == nkElifBranch:
while n.sons[i].kind == nkElifBranch: dec(i)
if (n.sons[i].kind != nkOfBranch):
InternalError(n.sons[i].info, "transformCase")
ifs = newNodeI(nkIfStmt, n.sons[i + 1].info)
elsen = newNodeI(nkElse, ifs.info)
var ifs = newNodeI(nkIfStmt, n.sons[i + 1].info)
var elsen = newNodeI(nkElse, ifs.info)
for j in countup(i + 1, length - 1): addSon(ifs, n.sons[j])
setlen(n.sons, i + 2)
addSon(elsen, ifs)
@@ -541,7 +512,7 @@ proc transformCase(c: PTransf, n: PNode): PNode =
not (skipTypes(n.sons[0].Typ, abstractVarRange).Kind in
{tyInt..tyInt64, tyChar, tyEnum}):
#MessageOut(renderTree(n));
elsen = newNodeI(nkElse, n.info)
var elsen = newNodeI(nkElse, n.info)
addSon(elsen, newNodeI(nkNilLit, n.info))
addSon(n, elsen)
result = n
@@ -566,20 +537,15 @@ proc getMergeOp(n: PNode): PSym =
nil
proc flattenTreeAux(d, a: PNode, op: PSym) =
var op2: PSym
op2 = getMergeOp(a)
var op2 = getMergeOp(a)
if (op2 != nil) and
((op2.id == op.id) or (op.magic != mNone) and (op2.magic == op.magic)): # a is a
# "leaf", so
# add
# it:
((op2.id == op.id) or (op.magic != mNone) and (op2.magic == op.magic)):
for i in countup(1, sonsLen(a) - 1): flattenTreeAux(d, a.sons[i], op)
else:
addSon(d, copyTree(a))
proc flattenTree(root: PNode): PNode =
var op: PSym
op = getMergeOp(root)
var op = getMergeOp(root)
if op != nil:
result = copyNode(root)
addSon(result, copyTree(root.sons[0]))
@@ -588,21 +554,17 @@ proc flattenTree(root: PNode): PNode =
result = root
proc transformCall(c: PTransf, n: PNode): PNode =
var
j: int
m, a: PNode
op: PSym
result = flattenTree(n)
for i in countup(0, sonsLen(result) - 1):
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):
m = result
var m = result
result = newNodeIT(nkCall, m.info, m.typ)
addSon(result, copyTree(m.sons[0]))
j = 1
var j = 1
while j < sonsLen(m):
a = m.sons[j]
var a = m.sons[j]
inc(j)
if isConstExpr(a):
while (j < sonsLen(m)) and isConstExpr(m.sons[j]):
@@ -616,11 +578,8 @@ proc transformCall(c: PTransf, n: PNode): PNode =
result = methodCall(result)
proc transform(c: PTransf, n: PNode): PNode =
var cnst: PNode
result = n
if n == nil:
return #if ToLinenumber(n.info) = 32 then
# MessageOut(RenderTree(n));
if n == nil: return
case n.kind
of nkSym:
return transformSym(c, n)
@@ -657,16 +616,16 @@ proc transform(c: PTransf, n: PNode): PNode =
of nkCommentStmt, nkTemplateDef:
return
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:
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:
result = cnst # do not miss an optimization
proc processTransf(context: PPassContext, n: PNode): PNode =
var c: PTransf
c = PTransf(context)
var c = PTransf(context)
result = transform(c, n)
proc openTransf(module: PSym, filename: string): PPassContext =
@@ -680,4 +639,4 @@ proc transfPass(): TPass =
result.open = openTransf
result.process = processTransf
result.close = processTransf # we need to process generics too!

View File

@@ -13,7 +13,7 @@ import
ast, astalgo, scanner, msgs, strutils
proc getMagic*(op: PNode): TMagic
# function getConstExpr(const t: TNode; out res: TNode): Boolean;
proc isConstExpr*(n: PNode): bool
proc flattenTree*(root: PNode, op: TMagic): PNode
proc TreeToSym*(t: PNode): PSym
@@ -32,12 +32,11 @@ proc hasSon(father, son: PNode): bool =
result = false
proc cyclicTreeAux(n, s: PNode): bool =
var m: int
if n == nil:
return false
if hasSon(s, n):
return true
m = sonsLen(s)
var m = sonsLen(s)
addSon(s, n)
if not (n.kind in {nkEmpty..nkNilLit}):
for i in countup(0, sonsLen(n) - 1):
@@ -47,8 +46,7 @@ proc cyclicTreeAux(n, s: PNode): bool =
delSon(s, m)
proc cyclicTree(n: PNode): bool =
var s: PNode
s = newNodeI(nkEmpty, n.info)
var s = newNodeI(nkEmpty, n.info)
result = cyclicTreeAux(n, s)
proc ExprStructuralEquivalent(a, b: PNode): bool =
@@ -57,18 +55,14 @@ proc ExprStructuralEquivalent(a, b: PNode): bool =
result = true
elif (a != nil) and (b != nil) and (a.kind == b.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
of nkIdent:
result = a.ident.id == b.ident.id
of nkCharLit..nkInt64Lit:
result = a.intVal == b.intVal
of nkFloatLit..nkFloat64Lit:
result = a.floatVal == b.floatVal
of nkStrLit..nkTripleStrLit:
result = a.strVal == b.strVal
of nkEmpty, nkNilLit, nkType:
result = true
of nkIdent: result = a.ident.id == b.ident.id
of nkCharLit..nkInt64Lit: result = a.intVal == b.intVal
of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal
of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
of nkEmpty, nkNilLit, nkType: result = true
else:
if sonsLen(a) == sonsLen(b):
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:
return #if a.info.fileIndex <> b.info.fileIndex then exit;
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
of nkIdent:
result = a.ident.id == b.ident.id
of nkCharLit..nkInt64Lit:
result = a.intVal == b.intVal
of nkFloatLit..nkFloat64Lit:
result = a.floatVal == b.floatVal
of nkStrLit..nkTripleStrLit:
result = a.strVal == b.strVal
of nkEmpty, nkNilLit, nkType:
result = true
of nkIdent: result = a.ident.id == b.ident.id
of nkCharLit..nkInt64Lit: result = a.intVal == b.intVal
of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal
of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
of nkEmpty, nkNilLit, nkType: result = true
else:
if sonsLen(a) == sonsLen(b):
for i in countup(0, sonsLen(a) - 1):
@@ -118,8 +108,7 @@ proc getMagic(op: PNode): TMagic =
case op.kind
of nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit:
case op.sons[0].Kind
of nkSym:
result = op.sons[0].sym.magic
of nkSym: result = op.sons[0].sym.magic
else: result = mNone
else: result = mNone
@@ -146,7 +135,6 @@ proc flattenTree(root: PNode, op: TMagic): PNode =
flattenTreeAux(result, root, op)
proc SwapOperands(op: PNode) =
var tmp: PNode
tmp = op.sons[1]
var tmp = op.sons[1]
op.sons[1] = op.sons[2]
op.sons[2] = tmp