Merge branch 'master' of github.com:Araq/Nimrod into upstream
This commit is contained in:
commit
8d698b2bdd
36 changed files with 1017 additions and 109 deletions
|
|
@ -227,9 +227,6 @@ type
|
|||
sfInnerProc, # proc is an inner proc
|
||||
sfThread, # proc will run as a thread
|
||||
# variable is a thread variable
|
||||
sfInline # forced-inline procs
|
||||
sfImmediate, # macro or template is immediately expanded without
|
||||
# considering any possible overloads
|
||||
sfCompileTime, # proc can be evaluated at compile time
|
||||
sfMerge, # proc can be merged with itself
|
||||
sfDeadCodeElim, # dead code elimination for the module is turned on
|
||||
|
|
@ -246,6 +243,8 @@ const
|
|||
sfFakeConst* = sfDeadCodeElim # const cannot be put into a data section
|
||||
sfDispatcher* = sfDeadCodeElim # copied method symbol is the dispatcher
|
||||
sfNoInit* = sfMainModule # don't generate code to init the variable
|
||||
sfImmediate* = sfDeadCodeElim # macro or template is immediately expanded
|
||||
# without considering any possible overloads
|
||||
|
||||
type
|
||||
TTypeKind* = enum # order is important!
|
||||
|
|
|
|||
|
|
@ -146,6 +146,14 @@ proc IITablePut*(t: var TIITable, key, val: int)
|
|||
|
||||
# implementation
|
||||
|
||||
proc skipConv*(n: PNode): PNode =
|
||||
case n.kind
|
||||
of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64:
|
||||
result = n.sons[0]
|
||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
||||
result = n.sons[1]
|
||||
else: result = n
|
||||
|
||||
proc SameValue*(a, b: PNode): bool =
|
||||
result = false
|
||||
case a.kind
|
||||
|
|
|
|||
|
|
@ -139,9 +139,9 @@ proc getStorageLoc(n: PNode): TStorageLoc =
|
|||
case n.kind
|
||||
of nkSym:
|
||||
case n.sym.kind
|
||||
of skParam, skForVar, skTemp:
|
||||
of skParam, skTemp:
|
||||
result = OnStack
|
||||
of skVar, skResult, skLet:
|
||||
of skVar, skForVar, skResult, skLet:
|
||||
if sfGlobal in n.sym.flags: result = OnHeap
|
||||
else: result = OnStack
|
||||
of skConst:
|
||||
|
|
@ -1652,7 +1652,7 @@ proc expr(p: BProc, e: PNode, d: var TLoc) =
|
|||
genComplexConst(p, sym, d)
|
||||
of skEnumField:
|
||||
putIntoDest(p, d, e.typ, toRope(sym.position))
|
||||
of skVar, skResult, skLet:
|
||||
of skVar, skForVar, skResult, skLet:
|
||||
if sfGlobal in sym.flags: genVarPrototype(p.module, sym)
|
||||
if sym.loc.r == nil or sym.loc.t == nil:
|
||||
InternalError(e.info, "expr: var not init " & sym.name.s)
|
||||
|
|
@ -1664,7 +1664,7 @@ proc expr(p: BProc, e: PNode, d: var TLoc) =
|
|||
putLocIntoDest(p, d, sym.loc)
|
||||
else:
|
||||
putLocIntoDest(p, d, sym.loc)
|
||||
of skForVar, skTemp:
|
||||
of skTemp:
|
||||
if sym.loc.r == nil or sym.loc.t == nil:
|
||||
InternalError(e.info, "expr: temp not init " & sym.name.s)
|
||||
putLocIntoDest(p, d, sym.loc)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ proc genVarTuple(p: BProc, n: PNode) =
|
|||
for i in countup(0, L-3):
|
||||
var v = n.sons[i].sym
|
||||
if sfCompileTime in v.flags: continue
|
||||
if sfGlobal in v.flags and v.kind != skForVar:
|
||||
if sfGlobal in v.flags:
|
||||
assignGlobalVar(p, v)
|
||||
genObjectInit(p, cpsInit, v.typ, v.loc, true)
|
||||
else:
|
||||
|
|
@ -49,7 +49,7 @@ proc genSingleVar(p: BProc, a: PNode) =
|
|||
var v = a.sons[0].sym
|
||||
if sfCompileTime in v.flags: return
|
||||
var immediateAsgn = a.sons[2].kind != nkEmpty
|
||||
if sfGlobal in v.flags and v.kind != skForVar:
|
||||
if sfGlobal in v.flags:
|
||||
assignGlobalVar(p, v)
|
||||
genObjectInit(p, cpsInit, v.typ, v.loc, true)
|
||||
else:
|
||||
|
|
@ -725,7 +725,10 @@ proc genStmts(p: BProc, t: PNode) =
|
|||
genLineDir(p, t)
|
||||
initLocExpr(p, t, a)
|
||||
of nkAsgn: genAsgn(p, t, fastAsgn=false)
|
||||
of nkFastAsgn: genAsgn(p, t, fastAsgn=true)
|
||||
of nkFastAsgn:
|
||||
# transf is overly aggressive with 'nkFastAsgn', so we work around here.
|
||||
# See tests/run/tcnstseq3 for an example that would fail otherwise.
|
||||
genAsgn(p, t, fastAsgn=p.prc != nil)
|
||||
of nkDiscardStmt:
|
||||
genLineDir(p, t)
|
||||
initLocExpr(p, t.sons[0], a)
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, typ: PType) =
|
|||
genTraverseProc(c, accessor.parentObj, typ.sons[i])
|
||||
if typ.n != nil: genTraverseProc(c, accessor, typ.n)
|
||||
of tyTuple:
|
||||
let typ = GetUniqueType(typ)
|
||||
if typ.n != nil:
|
||||
genTraverseProc(c, accessor, typ.n)
|
||||
else:
|
||||
|
|
@ -110,7 +111,11 @@ proc genTraverseProc(m: BModule, typ: PType, reason: TTypeInfoReason): PRope =
|
|||
if typ.kind == tySequence:
|
||||
genTraverseProcSeq(c, "a".toRope, typ)
|
||||
else:
|
||||
genTraverseProc(c, "(*a)".toRope, typ.sons[0])
|
||||
if skipTypes(typ.sons[0], abstractInst).kind in {tyArrayConstr, tyArray}:
|
||||
# C's arrays are broken beyond repair:
|
||||
genTraverseProc(c, "a".toRope, typ.sons[0])
|
||||
else:
|
||||
genTraverseProc(c, "(*a)".toRope, typ.sons[0])
|
||||
|
||||
let generatedProc = ropef("$1 {$n$2$3$4}$n",
|
||||
[header, p.s[cpsLocals], p.s[cpsInit], p.s[cpsStmts]])
|
||||
|
|
|
|||
|
|
@ -39,10 +39,10 @@ proc mangleName(s: PSym): PRope =
|
|||
case s.kind
|
||||
of skProc, skMethod, skConverter, skConst:
|
||||
result = toRope("@")
|
||||
of skVar, skResult, skLet:
|
||||
of skVar, skForVar, skResult, skLet:
|
||||
if sfGlobal in s.flags: result = toRope("@")
|
||||
else: result = toRope("%")
|
||||
of skForVar, skTemp, skParam, skType, skEnumField, skModule:
|
||||
of skTemp, skParam, skType, skEnumField, skModule:
|
||||
result = toRope("%")
|
||||
else: InternalError(s.info, "mangleName")
|
||||
app(result, toRope(mangle(s.name.s)))
|
||||
|
|
|
|||
|
|
@ -779,6 +779,9 @@ proc genMainProc(m: BModule) =
|
|||
PosixCMain = "int main(int argc, char** args, char** env) {$n" &
|
||||
" cmdLine = args;$n" & " cmdCount = argc;$n" & " gEnv = env;$n" &
|
||||
" NimMain();$n" & " return nim_program_result;$n" & "}$n"
|
||||
StandaloneCMain = "int main(void) {$n" &
|
||||
" NimMain();$n" &
|
||||
" return 0;$n" & "}$n"
|
||||
WinNimMain = "N_CDECL(void, NimMain)(void) {$n" &
|
||||
CommonMainBody & "}$n"
|
||||
WinCMain = "N_STDCALL(int, WinMain)(HINSTANCE hCurInstance, $n" &
|
||||
|
|
@ -808,7 +811,10 @@ proc genMainProc(m: BModule) =
|
|||
elif optGenDynLib in gGlobalOptions:
|
||||
nimMain = posixNimDllMain
|
||||
otherMain = posixCDllMain
|
||||
else:
|
||||
elif platform.targetOS == osStandalone:
|
||||
nimMain = PosixNimMain
|
||||
otherMain = StandaloneCMain
|
||||
else:
|
||||
nimMain = PosixNimMain
|
||||
otherMain = PosixCMain
|
||||
if gBreakpoints != nil: discard cgsym(m, "dbgRegisterBreakpoint")
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ type
|
|||
cfsDynLibInit, # section for init of dynamic library binding
|
||||
cfsDynLibDeinit # section for deinitialization of dynamic
|
||||
# libraries
|
||||
TCTypeKind* = enum # describes the type kind of a C type
|
||||
TCTypeKind* = enum # describes the type kind of a C type
|
||||
ctVoid, ctChar, ctBool, ctUInt, ctUInt8, ctUInt16, ctUInt32, ctUInt64,
|
||||
ctInt, ctInt8, ctInt16, ctInt32, ctInt64, ctFloat, ctFloat32, ctFloat64,
|
||||
ctFloat128, ctArray, ctStruct, ctPtr, ctNimStr, ctNimSeq, ctProc, ctCString
|
||||
|
|
|
|||
|
|
@ -11,8 +11,7 @@
|
|||
# included from transf.nim
|
||||
|
||||
const
|
||||
declarativeDefs = {nkProcDef, nkMethodDef, nkIteratorDef,
|
||||
nkConverterDef}
|
||||
declarativeDefs = {nkProcDef, nkMethodDef, nkIteratorDef, nkConverterDef}
|
||||
procDefs = nkLambdaKinds + declarativeDefs
|
||||
|
||||
proc indirectAccess(a, b: PSym, info: TLineInfo): PNode =
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ type
|
|||
# conditionals to condsyms (end of module).
|
||||
osNone, osDos, osWindows, osOs2, osLinux, osMorphos, osSkyos, osSolaris,
|
||||
osIrix, osNetbsd, osFreebsd, osOpenbsd, osAix, osPalmos, osQnx, osAmiga,
|
||||
osAtari, osNetware, osMacos, osMacosx, osEcmaScript, osNimrodVM
|
||||
osAtari, osNetware, osMacos, osMacosx, osEcmaScript, osNimrodVM,
|
||||
osStandalone
|
||||
|
||||
type
|
||||
TInfoOSProp* = enum
|
||||
|
|
@ -139,14 +140,18 @@ const
|
|||
exeExt: "", extSep: ".", props: {}),
|
||||
(name: "NimrodVM", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
|
||||
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
|
||||
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", props: {})]
|
||||
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", props: {}),
|
||||
(name: "Standalone", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
|
||||
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
|
||||
scriptExt: ".sh", curDir: ".", exeExt: ".elf", extSep: ".",
|
||||
props: {})]
|
||||
|
||||
type
|
||||
TSystemCPU* = enum # Also add CPU for in initialization section and
|
||||
# alias conditionals to condsyms (end of module).
|
||||
cpuNone, cpuI386, cpuM68k, cpuAlpha, cpuPowerpc, cpuPowerpc64,
|
||||
cpuSparc, cpuVm, cpuIa64, cpuAmd64, cpuMips, cpuArm,
|
||||
cpuEcmaScript, cpuNimrodVM
|
||||
cpuEcmaScript, cpuNimrodVM, cpuAVR
|
||||
|
||||
type
|
||||
TEndian* = enum
|
||||
|
|
@ -169,7 +174,8 @@ const
|
|||
(name: "mips", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32),
|
||||
(name: "arm", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
|
||||
(name: "ecmascript", intSize: 32, endian: bigEndian,floatSize: 64,bit: 32),
|
||||
(name: "nimrodvm", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32)]
|
||||
(name: "nimrodvm", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32),
|
||||
(name: "avr", intSize: 16, endian: littleEndian, floatSize: 32, bit: 16)]
|
||||
|
||||
var
|
||||
targetCPU*, hostCPU*: TSystemCPU
|
||||
|
|
|
|||
|
|
@ -535,7 +535,7 @@ proc cmdChangeTriggersRecompilation(old, new: TCommands): bool =
|
|||
proc processRodFile(r: PRodReader, crc: TCrc32) =
|
||||
var
|
||||
w: string
|
||||
d, L, inclCrc: int
|
||||
d, inclCrc: int
|
||||
while r.s[r.pos] != '\0':
|
||||
var section = rdWord(r)
|
||||
if r.reason != rrNone:
|
||||
|
|
@ -573,20 +573,17 @@ proc processRodFile(r: PRodReader, crc: TCrc32) =
|
|||
of "FILES":
|
||||
inc(r.pos, 2) # skip "(\10"
|
||||
inc(r.line)
|
||||
L = 0
|
||||
while r.s[r.pos] > '\x0A' and r.s[r.pos] != ')':
|
||||
setlen(r.files, L + 1)
|
||||
while r.s[r.pos] != ')':
|
||||
var relativePath = decodeStr(r.s, r.pos)
|
||||
var resolvedPath = relativePath.findModule
|
||||
r.files[L] = if resolvedPath.len > 0: resolvedPath else: relativePath
|
||||
r.files.add(if resolvedPath.len > 0: resolvedPath else: relativePath)
|
||||
inc(r.pos) # skip #10
|
||||
inc(r.line)
|
||||
inc(L)
|
||||
if r.s[r.pos] == ')': inc(r.pos)
|
||||
of "INCLUDES":
|
||||
inc(r.pos, 2) # skip "(\10"
|
||||
inc(r.line)
|
||||
while r.s[r.pos] > '\x0A' and r.s[r.pos] != ')':
|
||||
while r.s[r.pos] != ')':
|
||||
w = r.files[decodeVInt(r.s, r.pos)]
|
||||
inc(r.pos) # skip ' '
|
||||
inclCrc = decodeVInt(r.s, r.pos)
|
||||
|
|
@ -597,13 +594,10 @@ proc processRodFile(r: PRodReader, crc: TCrc32) =
|
|||
inc(r.pos)
|
||||
inc(r.line)
|
||||
if r.s[r.pos] == ')': inc(r.pos)
|
||||
of "DEPS":
|
||||
of "DEPS":
|
||||
inc(r.pos) # skip ':'
|
||||
L = 0
|
||||
while r.s[r.pos] > '\x0A':
|
||||
setlen(r.modDeps, L + 1)
|
||||
r.modDeps[L] = r.files[decodeVInt(r.s, r.pos)]
|
||||
inc(L)
|
||||
r.modDeps.add r.files[decodeVInt(r.s, r.pos)]
|
||||
if r.s[r.pos] == ' ': inc(r.pos)
|
||||
of "INTERF":
|
||||
r.interfIdx = r.pos + 2
|
||||
|
|
@ -629,9 +623,11 @@ proc processRodFile(r: PRodReader, crc: TCrc32) =
|
|||
of "INIT":
|
||||
r.initIdx = r.pos + 2 # "(\10"
|
||||
skipSection(r)
|
||||
else:
|
||||
MsgWriteln("skipping section: " & section &
|
||||
" at " & $r.pos & " in " & r.filename)
|
||||
else:
|
||||
InternalError("invalid section: '" & section &
|
||||
"' at " & $r.line & " in " & r.filename)
|
||||
#MsgWriteln("skipping section: " & section &
|
||||
# " at " & $r.line & " in " & r.filename)
|
||||
skipSection(r)
|
||||
if r.s[r.pos] == '\x0A':
|
||||
inc(r.pos)
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ proc semSlurp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
|||
result = newStrNode(nkStrLit, content)
|
||||
result.typ = getSysType(tyString)
|
||||
result.info = n.info
|
||||
c.slurpedFiles.add(filename)
|
||||
c.slurpedFiles.add(a.strVal)
|
||||
except EIO:
|
||||
GlobalError(a.info, errCannotOpenFile, a.strVal)
|
||||
|
||||
|
|
|
|||
|
|
@ -107,14 +107,14 @@ proc analyseSym(c: PProcCtx, n: PNode): TThreadOwner =
|
|||
result = c.mapping[v.id]
|
||||
if result != toUndefined: return
|
||||
case v.kind
|
||||
of skVar, skLet, skResult:
|
||||
of skVar, skForVar, skLet, skResult:
|
||||
result = toNil
|
||||
if sfGlobal in v.flags:
|
||||
if sfThread in v.flags:
|
||||
result = toMine
|
||||
elif containsGarbageCollectedRef(v.typ):
|
||||
result = toTheirs
|
||||
of skTemp, skForVar: result = toNil
|
||||
of skTemp: result = toNil
|
||||
of skConst: result = toMine
|
||||
of skParam:
|
||||
result = c.mapping[v.id]
|
||||
|
|
|
|||
|
|
@ -251,43 +251,38 @@ proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode,
|
|||
result = semIdentVis(c, kind, n, allowed)
|
||||
|
||||
proc checkForOverlap(c: PContext, t, ex: PNode, branchIndex: int) =
|
||||
let ex = ex.skipConv
|
||||
for i in countup(1, branchIndex - 1):
|
||||
for j in countup(0, sonsLen(t.sons[i]) - 2):
|
||||
if overlap(t.sons[i].sons[j], ex):
|
||||
if overlap(t.sons[i].sons[j].skipConv, ex):
|
||||
LocalError(ex.info, errDuplicateCaseLabel)
|
||||
|
||||
proc semBranchExpr(c: PContext, t, e: PNode): PNode =
|
||||
result = semConstExpr(c, e)
|
||||
proc semBranchRange(c: PContext, t, a, b: PNode, covered: var biggestInt): PNode =
|
||||
checkMinSonsLen(t, 1)
|
||||
result = fitNode(c, t.sons[0].typ, result)
|
||||
#if cmpTypes(t.sons[0].typ, result.typ) <= isConvertible:
|
||||
# typeMismatch(result, t.sons[0].typ, result.typ)
|
||||
let ac = semConstExpr(c, a)
|
||||
let bc = semConstExpr(c, b)
|
||||
let at = fitNode(c, t.sons[0].typ, ac)
|
||||
let bt = fitNode(c, t.sons[0].typ, bc)
|
||||
|
||||
result = newNodeI(nkRange, a.info)
|
||||
result.add(at)
|
||||
result.add(bt)
|
||||
if emptyRange(ac, bc): GlobalError(b.info, errRangeIsEmpty)
|
||||
covered = covered + getOrdValue(bc) - getOrdValue(ac) + 1
|
||||
|
||||
proc SemCaseBranchRange(c: PContext, t, b: PNode,
|
||||
covered: var biggestInt): PNode =
|
||||
checkSonsLen(b, 3)
|
||||
result = newNodeI(nkRange, b.info)
|
||||
result.add(semBranchExpr(c, t, b.sons[1]))
|
||||
result.add(semBranchExpr(c, t, b.sons[2]))
|
||||
if emptyRange(result[0], result[1]): GlobalError(b.info, errRangeIsEmpty)
|
||||
covered = covered + getOrdValue(result[1]) - getOrdValue(result[0]) + 1
|
||||
result = semBranchRange(c, t, b.sons[1], b.sons[2], covered)
|
||||
|
||||
proc semCaseBranchSetElem(c: PContext, t, b: PNode,
|
||||
covered: var biggestInt): PNode =
|
||||
if isRange(b):
|
||||
checkSonsLen(b, 3)
|
||||
result = newNodeI(nkRange, b.info)
|
||||
result.add(semBranchExpr(c, t, b.sons[1]))
|
||||
result.add(semBranchExpr(c, t, b.sons[2]))
|
||||
if emptyRange(result[0], result[1]): GlobalError(b.info, errRangeIsEmpty)
|
||||
covered = covered + getOrdValue(result[1]) - getOrdValue(result[0]) + 1
|
||||
result = semBranchRange(c, t, b.sons[1], b.sons[2], covered)
|
||||
elif b.kind == nkRange:
|
||||
checkSonsLen(b, 2)
|
||||
result = newNodeI(nkRange, b.info)
|
||||
result.add(semBranchExpr(c, t, b.sons[0]))
|
||||
result.add(semBranchExpr(c, t, b.sons[1]))
|
||||
if emptyRange(result[0], result[1]): GlobalError(b.info, errRangeIsEmpty)
|
||||
covered = covered + getOrdValue(result[1]) - getOrdValue(result[0]) + 1
|
||||
result = semBranchRange(c, t, b.sons[0], b.sons[1], covered)
|
||||
else:
|
||||
result = fitNode(c, t.sons[0].typ, b)
|
||||
inc(covered)
|
||||
|
|
|
|||
|
|
@ -267,14 +267,6 @@ proc transformLoopBody(c: PTransf, n: PNode): PTransNode =
|
|||
discard c.blockSyms.pop()
|
||||
else:
|
||||
result = transform(c, n)
|
||||
|
||||
proc skipConv(n: PNode): PNode =
|
||||
case n.kind
|
||||
of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64:
|
||||
result = n.sons[0]
|
||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
||||
result = n.sons[1]
|
||||
else: result = n
|
||||
|
||||
proc newTupleAccess(tup: PNode, i: int): PNode =
|
||||
result = newNodeIT(nkBracketExpr, tup.info, tup.typ.sons[i])
|
||||
|
|
|
|||
|
|
@ -869,9 +869,11 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool =
|
|||
of tyArray:
|
||||
result = t.sons[1].kind == tyEmpty or
|
||||
typeAllowedAux(marker, t.sons[1], skVar)
|
||||
of tyPtr, tyRef:
|
||||
of tyRef:
|
||||
if kind == skConst: return false
|
||||
result = typeAllowedAux(marker, t.sons[0], skVar)
|
||||
of tyPtr:
|
||||
result = typeAllowedAux(marker, t.sons[0], skVar)
|
||||
of tyArrayConstr, tyTuple, tySet, tyConst, tyMutable, tyIter, tyProxy:
|
||||
for i in countup(0, sonsLen(t) - 1):
|
||||
result = typeAllowedAux(marker, t.sons[i], kind)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue