makes Aporia build for 64bit archs
This commit is contained in:
parent
21ccc5d58e
commit
b870744d5d
2 changed files with 173 additions and 178 deletions
|
|
@ -56,11 +56,6 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): PRope =
|
||||||
case skipTypes(ty, abstractVarRange).kind
|
case skipTypes(ty, abstractVarRange).kind
|
||||||
of tyChar, tyNil:
|
of tyChar, tyNil:
|
||||||
result = intLiteral(n.intVal)
|
result = intLiteral(n.intVal)
|
||||||
of tyInt:
|
|
||||||
if n.intVal >= low(int32) and n.intVal <= high(int32):
|
|
||||||
result = int32Literal(int32(n.intVal))
|
|
||||||
else:
|
|
||||||
result = intLiteral(n.intVal)
|
|
||||||
of tyBool:
|
of tyBool:
|
||||||
if n.intVal != 0: result = ~"NIM_TRUE"
|
if n.intVal != 0: result = ~"NIM_TRUE"
|
||||||
else: result = ~"NIM_FALSE"
|
else: result = ~"NIM_FALSE"
|
||||||
|
|
@ -89,7 +84,7 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): PRope =
|
||||||
var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId)
|
var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId)
|
||||||
if id == gBackendId:
|
if id == gBackendId:
|
||||||
# string literal not found in the cache:
|
# string literal not found in the cache:
|
||||||
result = ropecg(p.module, "((#NimStringDesc*) &$1)",
|
result = ropecg(p.module, "((#NimStringDesc*) &$1)",
|
||||||
[getStrLit(p.module, n.strVal)])
|
[getStrLit(p.module, n.strVal)])
|
||||||
else:
|
else:
|
||||||
result = ropecg(p.module, "((#NimStringDesc*) &TMP$1)", [toRope(id)])
|
result = ropecg(p.module, "((#NimStringDesc*) &TMP$1)", [toRope(id)])
|
||||||
|
|
@ -158,7 +153,7 @@ proc getStorageLoc(n: PNode): TStorageLoc =
|
||||||
of skVar, skForVar, skResult, skLet:
|
of skVar, skForVar, skResult, skLet:
|
||||||
if sfGlobal in n.sym.flags: result = OnHeap
|
if sfGlobal in n.sym.flags: result = OnHeap
|
||||||
else: result = OnStack
|
else: result = OnStack
|
||||||
of skConst:
|
of skConst:
|
||||||
if sfGlobal in n.sym.flags: result = OnHeap
|
if sfGlobal in n.sym.flags: result = OnHeap
|
||||||
else: result = OnUnknown
|
else: result = OnUnknown
|
||||||
else: result = OnUnknown
|
else: result = OnUnknown
|
||||||
|
|
@ -236,7 +231,7 @@ proc genOptAsgnTuple(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||||
for i in 0 .. <t.len:
|
for i in 0 .. <t.len:
|
||||||
let t = t.sons[i]
|
let t = t.sons[i]
|
||||||
let field = ropef("Field$1", i.toRope)
|
let field = ropef("Field$1", i.toRope)
|
||||||
genAssignment(p, optAsgnLoc(dest, t, field),
|
genAssignment(p, optAsgnLoc(dest, t, field),
|
||||||
optAsgnLoc(src, t, field), newflags)
|
optAsgnLoc(src, t, field), newflags)
|
||||||
|
|
||||||
proc genOptAsgnObject(p: BProc, dest, src: TLoc, flags: TAssignmentFlags,
|
proc genOptAsgnObject(p: BProc, dest, src: TLoc, flags: TAssignmentFlags,
|
||||||
|
|
@ -252,20 +247,20 @@ proc genOptAsgnObject(p: BProc, dest, src: TLoc, flags: TAssignmentFlags,
|
||||||
case t.kind
|
case t.kind
|
||||||
of nkSym:
|
of nkSym:
|
||||||
let field = t.sym
|
let field = t.sym
|
||||||
genAssignment(p, optAsgnLoc(dest, field.typ, field.loc.r),
|
genAssignment(p, optAsgnLoc(dest, field.typ, field.loc.r),
|
||||||
optAsgnLoc(src, field.typ, field.loc.r), newflags)
|
optAsgnLoc(src, field.typ, field.loc.r), newflags)
|
||||||
of nkRecList:
|
of nkRecList:
|
||||||
for child in items(t): genOptAsgnObject(p, dest, src, newflags, child)
|
for child in items(t): genOptAsgnObject(p, dest, src, newflags, child)
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||||
# Consider:
|
# Consider:
|
||||||
# type TMyFastString {.shallow.} = string
|
# type TMyFastString {.shallow.} = string
|
||||||
# Due to the implementation of pragmas this would end up to set the
|
# Due to the implementation of pragmas this would end up to set the
|
||||||
# tfShallow flag for the built-in string type too! So we check only
|
# tfShallow flag for the built-in string type too! So we check only
|
||||||
# here for this flag, where it is reasonably safe to do so
|
# here for this flag, where it is reasonably safe to do so
|
||||||
# (for objects, etc.):
|
# (for objects, etc.):
|
||||||
if needToCopy notin flags or
|
if needToCopy notin flags or
|
||||||
tfShallow in skipTypes(dest.t, abstractVarRange).flags:
|
tfShallow in skipTypes(dest.t, abstractVarRange).flags:
|
||||||
if dest.s == OnStack or not usesNativeGC():
|
if dest.s == OnStack or not usesNativeGC():
|
||||||
useStringh(p.module)
|
useStringh(p.module)
|
||||||
|
|
@ -510,7 +505,7 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
|
||||||
var storage: PRope
|
var storage: PRope
|
||||||
var size = getSize(t)
|
var size = getSize(t)
|
||||||
if size < platform.intSize:
|
if size < platform.intSize:
|
||||||
storage = toRope("NI")
|
storage = toRope("NI")
|
||||||
else:
|
else:
|
||||||
storage = getTypeDesc(p.module, t)
|
storage = getTypeDesc(p.module, t)
|
||||||
var tmp = getTempName()
|
var tmp = getTempName()
|
||||||
|
|
@ -547,7 +542,7 @@ proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
"(($4)($1) - ($4)($2))", # SubF64
|
"(($4)($1) - ($4)($2))", # SubF64
|
||||||
"(($4)($1) * ($4)($2))", # MulF64
|
"(($4)($1) * ($4)($2))", # MulF64
|
||||||
"(($4)($1) / ($4)($2))", # DivF64
|
"(($4)($1) / ($4)($2))", # DivF64
|
||||||
|
|
||||||
"($4)((NU$3)($1) >> (NU$3)($2))", # ShrI
|
"($4)((NU$3)($1) >> (NU$3)($2))", # ShrI
|
||||||
"($4)((NU$3)($1) << (NU$3)($2))", # ShlI
|
"($4)((NU$3)($1) << (NU$3)($2))", # ShlI
|
||||||
"($4)($1 & $2)", # BitandI
|
"($4)($1 & $2)", # BitandI
|
||||||
|
|
@ -617,7 +612,7 @@ proc genEqProc(p: BProc, e: PNode, d: var TLoc) =
|
||||||
initLocExpr(p, e.sons[1], a)
|
initLocExpr(p, e.sons[1], a)
|
||||||
initLocExpr(p, e.sons[2], b)
|
initLocExpr(p, e.sons[2], b)
|
||||||
if a.t.callConv == ccClosure:
|
if a.t.callConv == ccClosure:
|
||||||
putIntoDest(p, d, e.typ,
|
putIntoDest(p, d, e.typ,
|
||||||
ropef("($1.ClPrc == $2.ClPrc && $1.ClEnv == $2.ClEnv)", [
|
ropef("($1.ClPrc == $2.ClPrc && $1.ClEnv == $2.ClEnv)", [
|
||||||
rdLoc(a), rdLoc(b)]))
|
rdLoc(a), rdLoc(b)]))
|
||||||
else:
|
else:
|
||||||
|
|
@ -721,7 +716,7 @@ template inheritLocation(d: var TLoc, a: TLoc) =
|
||||||
if d.k == locNone: d.s = a.s
|
if d.k == locNone: d.s = a.s
|
||||||
if d.heapRoot == nil:
|
if d.heapRoot == nil:
|
||||||
d.heapRoot = if a.heapRoot != nil: a.heapRoot else: a.r
|
d.heapRoot = if a.heapRoot != nil: a.heapRoot else: a.r
|
||||||
|
|
||||||
proc genRecordFieldAux(p: BProc, e: PNode, d, a: var TLoc): PType =
|
proc genRecordFieldAux(p: BProc, e: PNode, d, a: var TLoc): PType =
|
||||||
initLocExpr(p, e.sons[0], a)
|
initLocExpr(p, e.sons[0], a)
|
||||||
if e.sons[1].kind != nkSym: internalError(e.info, "genRecordFieldAux")
|
if e.sons[1].kind != nkSym: internalError(e.info, "genRecordFieldAux")
|
||||||
|
|
@ -1061,7 +1056,7 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) =
|
||||||
genAssignment(p, dest, b, {needToCopy, afDestIsNil})
|
genAssignment(p, dest, b, {needToCopy, afDestIsNil})
|
||||||
gcUsage(e)
|
gcUsage(e)
|
||||||
|
|
||||||
proc genReset(p: BProc, n: PNode) =
|
proc genReset(p: BProc, n: PNode) =
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
initLocExpr(p, n.sons[1], a)
|
initLocExpr(p, n.sons[1], a)
|
||||||
linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
|
linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
|
||||||
|
|
@ -1120,14 +1115,14 @@ proc genNewSeqAux(p: BProc, dest: TLoc, length: PRope) =
|
||||||
else:
|
else:
|
||||||
call.r = ropecg(p.module, "($1) #newSeq($2, $3)", args)
|
call.r = ropecg(p.module, "($1) #newSeq($2, $3)", args)
|
||||||
genAssignment(p, dest, call, {needToKeepAlive})
|
genAssignment(p, dest, call, {needToKeepAlive})
|
||||||
|
|
||||||
proc genNewSeq(p: BProc, e: PNode) =
|
proc genNewSeq(p: BProc, e: PNode) =
|
||||||
var a, b: TLoc
|
var a, b: TLoc
|
||||||
initLocExpr(p, e.sons[1], a)
|
initLocExpr(p, e.sons[1], a)
|
||||||
initLocExpr(p, e.sons[2], b)
|
initLocExpr(p, e.sons[2], b)
|
||||||
genNewSeqAux(p, a, b.rdLoc)
|
genNewSeqAux(p, a, b.rdLoc)
|
||||||
gcUsage(e)
|
gcUsage(e)
|
||||||
|
|
||||||
proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
|
proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
var tmp: TLoc
|
var tmp: TLoc
|
||||||
var t = e.typ.skipTypes(abstractInst)
|
var t = e.typ.skipTypes(abstractInst)
|
||||||
|
|
@ -1168,7 +1163,7 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
d = tmp
|
d = tmp
|
||||||
else:
|
else:
|
||||||
genAssignment(p, d, tmp, {})
|
genAssignment(p, d, tmp, {})
|
||||||
|
|
||||||
proc genSeqConstr(p: BProc, t: PNode, d: var TLoc) =
|
proc genSeqConstr(p: BProc, t: PNode, d: var TLoc) =
|
||||||
var arr: TLoc
|
var arr: TLoc
|
||||||
if d.k == locNone:
|
if d.k == locNone:
|
||||||
|
|
@ -1192,7 +1187,7 @@ proc genArrToSeq(p: BProc, t: PNode, d: var TLoc) =
|
||||||
getTemp(p, t.typ, d)
|
getTemp(p, t.typ, d)
|
||||||
# generate call to newSeq before adding the elements per hand:
|
# generate call to newSeq before adding the elements per hand:
|
||||||
var L = int(lengthOrd(t.sons[1].typ))
|
var L = int(lengthOrd(t.sons[1].typ))
|
||||||
|
|
||||||
genNewSeqAux(p, d, intLiteral(L))
|
genNewSeqAux(p, d, intLiteral(L))
|
||||||
initLocExpr(p, t.sons[1], a)
|
initLocExpr(p, t.sons[1], a)
|
||||||
for i in countup(0, L - 1):
|
for i in countup(0, L - 1):
|
||||||
|
|
@ -1202,7 +1197,7 @@ proc genArrToSeq(p: BProc, t: PNode, d: var TLoc) =
|
||||||
initLoc(arr, locExpr, elemType(skipTypes(t.sons[1].typ, abstractInst)), a.s)
|
initLoc(arr, locExpr, elemType(skipTypes(t.sons[1].typ, abstractInst)), a.s)
|
||||||
arr.r = rfmt(nil, "$1[$2]", rdLoc(a), intLiteral(i))
|
arr.r = rfmt(nil, "$1[$2]", rdLoc(a), intLiteral(i))
|
||||||
genAssignment(p, elem, arr, {afDestIsNil, needToCopy})
|
genAssignment(p, elem, arr, {afDestIsNil, needToCopy})
|
||||||
|
|
||||||
proc genNewFinalize(p: BProc, e: PNode) =
|
proc genNewFinalize(p: BProc, e: PNode) =
|
||||||
var
|
var
|
||||||
a, b, f: TLoc
|
a, b, f: TLoc
|
||||||
|
|
@ -1258,7 +1253,7 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
|
||||||
app(r, ~".Sup")
|
app(r, ~".Sup")
|
||||||
t = skipTypes(t.sons[0], typedescInst)
|
t = skipTypes(t.sons[0], typedescInst)
|
||||||
if isObjLackingTypeField(t):
|
if isObjLackingTypeField(t):
|
||||||
globalError(x.info, errGenerated,
|
globalError(x.info, errGenerated,
|
||||||
"no 'of' operator available for pure objects")
|
"no 'of' operator available for pure objects")
|
||||||
if nilCheck != nil:
|
if nilCheck != nil:
|
||||||
r = rfmt(p.module, "(($1) && ($2))", nilCheck, genOfHelper(p, dest, r))
|
r = rfmt(p.module, "(($1) && ($2))", nilCheck, genOfHelper(p, dest, r))
|
||||||
|
|
@ -1275,7 +1270,7 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
var t = skipTypes(e.sons[1].typ, abstractVarRange)
|
var t = skipTypes(e.sons[1].typ, abstractVarRange)
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyInt..tyInt64, tyUInt..tyUInt64:
|
of tyInt..tyInt64, tyUInt..tyUInt64:
|
||||||
putIntoDest(p, d, e.typ,
|
putIntoDest(p, d, e.typ,
|
||||||
ropecg(p.module, "#reprInt((NI64)$1)", [rdLoc(a)]))
|
ropecg(p.module, "#reprInt((NI64)$1)", [rdLoc(a)]))
|
||||||
of tyFloat..tyFloat128:
|
of tyFloat..tyFloat128:
|
||||||
putIntoDest(p, d, e.typ, ropecg(p.module, "#reprFloat($1)", [rdLoc(a)]))
|
putIntoDest(p, d, e.typ, ropecg(p.module, "#reprFloat($1)", [rdLoc(a)]))
|
||||||
|
|
@ -1298,13 +1293,13 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
of tyOpenArray, tyVarargs:
|
of tyOpenArray, tyVarargs:
|
||||||
putIntoDest(p, b, e.typ, ropef("$1, $1Len0", [rdLoc(a)]))
|
putIntoDest(p, b, e.typ, ropef("$1, $1Len0", [rdLoc(a)]))
|
||||||
of tyString, tySequence:
|
of tyString, tySequence:
|
||||||
putIntoDest(p, b, e.typ,
|
putIntoDest(p, b, e.typ,
|
||||||
ropef("$1->data, $1->$2", [rdLoc(a), lenField(p)]))
|
ropef("$1->data, $1->$2", [rdLoc(a), lenField(p)]))
|
||||||
of tyArray, tyArrayConstr:
|
of tyArray, tyArrayConstr:
|
||||||
putIntoDest(p, b, e.typ,
|
putIntoDest(p, b, e.typ,
|
||||||
ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))]))
|
ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))]))
|
||||||
else: internalError(e.sons[0].info, "genRepr()")
|
else: internalError(e.sons[0].info, "genRepr()")
|
||||||
putIntoDest(p, d, e.typ,
|
putIntoDest(p, d, e.typ,
|
||||||
ropecg(p.module, "#reprOpenArray($1, $2)", [rdLoc(b),
|
ropecg(p.module, "#reprOpenArray($1, $2)", [rdLoc(b),
|
||||||
genTypeInfo(p.module, elemType(t))]))
|
genTypeInfo(p.module, elemType(t))]))
|
||||||
of tyCString, tyArray, tyArrayConstr, tyRef, tyPtr, tyPointer, tyNil,
|
of tyCString, tyArray, tyArrayConstr, tyRef, tyPtr, tyPointer, tyNil,
|
||||||
|
|
@ -1433,7 +1428,7 @@ proc genInOp(p: BProc, e: PNode, d: var TLoc) =
|
||||||
# do not emit the set, but generate a bunch of comparisons; and if we do
|
# do not emit the set, but generate a bunch of comparisons; and if we do
|
||||||
# so, we skip the unnecessary range check: This is a semantical extension
|
# so, we skip the unnecessary range check: This is a semantical extension
|
||||||
# that code now relies on. :-/ XXX
|
# that code now relies on. :-/ XXX
|
||||||
let ea = if e.sons[2].kind in {nkChckRange, nkChckRange64}:
|
let ea = if e.sons[2].kind in {nkChckRange, nkChckRange64}:
|
||||||
e.sons[2].sons[0]
|
e.sons[2].sons[0]
|
||||||
else:
|
else:
|
||||||
e.sons[2]
|
e.sons[2]
|
||||||
|
|
@ -1518,7 +1513,7 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
initLocExpr(p, e.sons[2], b)
|
initLocExpr(p, e.sons[2], b)
|
||||||
if d.k == locNone: getTemp(p, a.t, d)
|
if d.k == locNone: getTemp(p, a.t, d)
|
||||||
lineF(p, cpsStmts,
|
lineF(p, cpsStmts,
|
||||||
"for ($1 = 0; $1 < $2; $1++) $n" &
|
"for ($1 = 0; $1 < $2; $1++) $n" &
|
||||||
" $3[$1] = $4[$1] $6 $5[$1];$n", [
|
" $3[$1] = $4[$1] $6 $5[$1];$n", [
|
||||||
rdLoc(i), toRope(size), rdLoc(d), rdLoc(a), rdLoc(b),
|
rdLoc(i), toRope(size), rdLoc(d), rdLoc(a), rdLoc(b),
|
||||||
toRope(lookupOpr[op])])
|
toRope(lookupOpr[op])])
|
||||||
|
|
@ -1549,7 +1544,7 @@ proc genSomeCast(p: BProc, e: PNode, d: var TLoc) =
|
||||||
|
|
||||||
proc genCast(p: BProc, e: PNode, d: var TLoc) =
|
proc genCast(p: BProc, e: PNode, d: var TLoc) =
|
||||||
const floatTypes = {tyFloat..tyFloat128}
|
const floatTypes = {tyFloat..tyFloat128}
|
||||||
let
|
let
|
||||||
destt = skipTypes(e.typ, abstractRange)
|
destt = skipTypes(e.typ, abstractRange)
|
||||||
srct = skipTypes(e.sons[1].typ, abstractRange)
|
srct = skipTypes(e.sons[1].typ, abstractRange)
|
||||||
if destt.kind in floatTypes or srct.kind in floatTypes:
|
if destt.kind in floatTypes or srct.kind in floatTypes:
|
||||||
|
|
@ -1656,7 +1651,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
of mRepr: genRepr(p, e, d)
|
of mRepr: genRepr(p, e, d)
|
||||||
of mGetTypeInfo: genGetTypeInfo(p, e, d)
|
of mGetTypeInfo: genGetTypeInfo(p, e, d)
|
||||||
of mSwap: genSwap(p, e, d)
|
of mSwap: genSwap(p, e, d)
|
||||||
of mUnaryLt:
|
of mUnaryLt:
|
||||||
if optOverflowCheck notin p.options: unaryExpr(p, e, d, "($1 - 1)")
|
if optOverflowCheck notin p.options: unaryExpr(p, e, d, "($1 - 1)")
|
||||||
else: unaryExpr(p, e, d, "#subInt($1, 1)")
|
else: unaryExpr(p, e, d, "#subInt($1, 1)")
|
||||||
of mPred:
|
of mPred:
|
||||||
|
|
@ -1830,10 +1825,10 @@ proc genTupleConstr(p: BProc, n: PNode, d: var TLoc) =
|
||||||
proc isConstClosure(n: PNode): bool {.inline.} =
|
proc isConstClosure(n: PNode): bool {.inline.} =
|
||||||
result = n.sons[0].kind == nkSym and isRoutine(n.sons[0].sym) and
|
result = n.sons[0].kind == nkSym and isRoutine(n.sons[0].sym) and
|
||||||
n.sons[1].kind == nkNilLit
|
n.sons[1].kind == nkNilLit
|
||||||
|
|
||||||
proc genClosure(p: BProc, n: PNode, d: var TLoc) =
|
proc genClosure(p: BProc, n: PNode, d: var TLoc) =
|
||||||
assert n.kind == nkClosure
|
assert n.kind == nkClosure
|
||||||
|
|
||||||
if isConstClosure(n):
|
if isConstClosure(n):
|
||||||
inc(p.labels)
|
inc(p.labels)
|
||||||
var tmp = con("LOC", toRope(p.labels))
|
var tmp = con("LOC", toRope(p.labels))
|
||||||
|
|
@ -1920,7 +1915,7 @@ proc downConv(p: BProc, n: PNode, d: var TLoc) =
|
||||||
if isRef:
|
if isRef:
|
||||||
# it can happen that we end up generating '&&x->Sup' here, so we pack
|
# it can happen that we end up generating '&&x->Sup' here, so we pack
|
||||||
# the '&x->Sup' into a temporary and then those address is taken
|
# the '&x->Sup' into a temporary and then those address is taken
|
||||||
# (see bug #837). However sometimes using a temporary is not correct:
|
# (see bug #837). However sometimes using a temporary is not correct:
|
||||||
# init(TFigure(my)) # where it is passed to a 'var TFigure'. We test
|
# init(TFigure(my)) # where it is passed to a 'var TFigure'. We test
|
||||||
# this by ensuring the destination is also a pointer:
|
# this by ensuring the destination is also a pointer:
|
||||||
if d.k == locNone and skipTypes(n.typ, abstractInst).kind in {tyRef, tyPtr, tyVar}:
|
if d.k == locNone and skipTypes(n.typ, abstractInst).kind in {tyRef, tyPtr, tyVar}:
|
||||||
|
|
@ -1937,13 +1932,13 @@ proc exprComplexConst(p: BProc, n: PNode, d: var TLoc) =
|
||||||
discard getTypeDesc(p.module, t) # so that any fields are initialized
|
discard getTypeDesc(p.module, t) # so that any fields are initialized
|
||||||
var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId)
|
var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId)
|
||||||
var tmp = con("TMP", toRope(id))
|
var tmp = con("TMP", toRope(id))
|
||||||
|
|
||||||
if id == gBackendId:
|
if id == gBackendId:
|
||||||
# expression not found in the cache:
|
# expression not found in the cache:
|
||||||
inc(gBackendId)
|
inc(gBackendId)
|
||||||
appf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n",
|
appf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n",
|
||||||
[getTypeDesc(p.module, t), tmp, genConstExpr(p, n)])
|
[getTypeDesc(p.module, t), tmp, genConstExpr(p, n)])
|
||||||
|
|
||||||
if d.k == locNone:
|
if d.k == locNone:
|
||||||
fillLoc(d, locData, t, tmp, OnHeap)
|
fillLoc(d, locData, t, tmp, OnHeap)
|
||||||
else:
|
else:
|
||||||
|
|
@ -1984,7 +1979,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
|
||||||
internalError n.info, "expr: var not init " & sym.name.s & "_" & $sym.id
|
internalError n.info, "expr: var not init " & sym.name.s & "_" & $sym.id
|
||||||
if sfThread in sym.flags:
|
if sfThread in sym.flags:
|
||||||
accessThreadLocalVar(p, sym)
|
accessThreadLocalVar(p, sym)
|
||||||
if emulatedThreadVars():
|
if emulatedThreadVars():
|
||||||
putIntoDest(p, d, sym.loc.t, con("NimTV->", sym.loc.r))
|
putIntoDest(p, d, sym.loc.t, con("NimTV->", sym.loc.r))
|
||||||
else:
|
else:
|
||||||
putLocIntoDest(p, d, sym.loc)
|
putLocIntoDest(p, d, sym.loc)
|
||||||
|
|
@ -2001,7 +1996,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
|
||||||
#echo "FAILED FOR PRCO ", p.prc.name.s
|
#echo "FAILED FOR PRCO ", p.prc.name.s
|
||||||
#debug p.prc.typ.n
|
#debug p.prc.typ.n
|
||||||
#echo renderTree(p.prc.ast, {renderIds})
|
#echo renderTree(p.prc.ast, {renderIds})
|
||||||
internalError(n.info, "expr: param not init " & sym.name.s & "_" & $sym.id)
|
internalError(n.info, "expr: param not init " & sym.name.s & "_" & $sym.id)
|
||||||
putLocIntoDest(p, d, sym.loc)
|
putLocIntoDest(p, d, sym.loc)
|
||||||
else: internalError(n.info, "expr(" & $sym.kind & "); unknown symbol")
|
else: internalError(n.info, "expr(" & $sym.kind & "); unknown symbol")
|
||||||
of nkNilLit:
|
of nkNilLit:
|
||||||
|
|
@ -2101,9 +2096,9 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
|
||||||
# we have to emit the type information for object types here to support
|
# we have to emit the type information for object types here to support
|
||||||
# separate compilation:
|
# separate compilation:
|
||||||
genTypeSection(p.module, n)
|
genTypeSection(p.module, n)
|
||||||
of nkCommentStmt, nkIteratorDef, nkIncludeStmt,
|
of nkCommentStmt, nkIteratorDef, nkIncludeStmt,
|
||||||
nkImportStmt, nkImportExceptStmt, nkExportStmt, nkExportExceptStmt,
|
nkImportStmt, nkImportExceptStmt, nkExportStmt, nkExportExceptStmt,
|
||||||
nkFromStmt, nkTemplateDef, nkMacroDef:
|
nkFromStmt, nkTemplateDef, nkMacroDef:
|
||||||
discard
|
discard
|
||||||
of nkPragma: genPragma(p, n)
|
of nkPragma: genPragma(p, n)
|
||||||
of nkPragmaBlock: expr(p, n.lastSon, d)
|
of nkPragmaBlock: expr(p, n.lastSon, d)
|
||||||
|
|
@ -2118,8 +2113,8 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
|
||||||
sfDeadCodeElim notin getModule(prc).flags) or
|
sfDeadCodeElim notin getModule(prc).flags) or
|
||||||
({sfExportc, sfCompilerProc} * prc.flags == {sfExportc}) or
|
({sfExportc, sfCompilerProc} * prc.flags == {sfExportc}) or
|
||||||
(sfExportc in prc.flags and lfExportLib in prc.loc.flags) or
|
(sfExportc in prc.flags and lfExportLib in prc.loc.flags) or
|
||||||
(prc.kind == skMethod):
|
(prc.kind == skMethod):
|
||||||
# we have not only the header:
|
# we have not only the header:
|
||||||
if prc.getBody.kind != nkEmpty or lfDynamicLib in prc.loc.flags:
|
if prc.getBody.kind != nkEmpty or lfDynamicLib in prc.loc.flags:
|
||||||
genProc(p.module, prc)
|
genProc(p.module, prc)
|
||||||
of nkParForStmt: genParForStmt(p, n)
|
of nkParForStmt: genParForStmt(p, n)
|
||||||
|
|
@ -2142,7 +2137,7 @@ proc genConstSimpleList(p: BProc, n: PNode): PRope =
|
||||||
|
|
||||||
proc genConstSeq(p: BProc, n: PNode, t: PType): PRope =
|
proc genConstSeq(p: BProc, n: PNode, t: PType): PRope =
|
||||||
var data = ropef("{{$1, $1}", n.len.toRope)
|
var data = ropef("{{$1, $1}", n.len.toRope)
|
||||||
if n.len > 0:
|
if n.len > 0:
|
||||||
# array part needs extra curlies:
|
# array part needs extra curlies:
|
||||||
data.app(", {")
|
data.app(", {")
|
||||||
for i in countup(0, n.len - 1):
|
for i in countup(0, n.len - 1):
|
||||||
|
|
@ -2150,14 +2145,14 @@ proc genConstSeq(p: BProc, n: PNode, t: PType): PRope =
|
||||||
data.app genConstExpr(p, n.sons[i])
|
data.app genConstExpr(p, n.sons[i])
|
||||||
data.app("}")
|
data.app("}")
|
||||||
data.app("}")
|
data.app("}")
|
||||||
|
|
||||||
inc(gBackendId)
|
inc(gBackendId)
|
||||||
result = con("CNSTSEQ", gBackendId.toRope)
|
result = con("CNSTSEQ", gBackendId.toRope)
|
||||||
|
|
||||||
appcg(p.module, cfsData,
|
appcg(p.module, cfsData,
|
||||||
"NIM_CONST struct {$n" &
|
"NIM_CONST struct {$n" &
|
||||||
" #TGenericSeq Sup;$n" &
|
" #TGenericSeq Sup;$n" &
|
||||||
" $1 data[$2];$n" &
|
" $1 data[$2];$n" &
|
||||||
"} $3 = $4;$n", [
|
"} $3 = $4;$n", [
|
||||||
getTypeDesc(p.module, t.sons[0]), n.len.toRope, result, data])
|
getTypeDesc(p.module, t.sons[0]), n.len.toRope, result, data])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,14 @@
|
||||||
# this module does the semantic checking of type declarations
|
# this module does the semantic checking of type declarations
|
||||||
# included from sem.nim
|
# included from sem.nim
|
||||||
|
|
||||||
proc newOrPrevType(kind: TTypeKind, prev: PType, c: PContext): PType =
|
proc newOrPrevType(kind: TTypeKind, prev: PType, c: PContext): PType =
|
||||||
if prev == nil:
|
if prev == nil:
|
||||||
result = newTypeS(kind, c)
|
result = newTypeS(kind, c)
|
||||||
else:
|
else:
|
||||||
result = prev
|
result = prev
|
||||||
if result.kind == tyForward: result.kind = kind
|
if result.kind == tyForward: result.kind = kind
|
||||||
|
|
||||||
proc newConstraint(c: PContext, k: TTypeKind): PType =
|
proc newConstraint(c: PContext, k: TTypeKind): PType =
|
||||||
result = newTypeS(tyBuiltInTypeClass, c)
|
result = newTypeS(tyBuiltInTypeClass, c)
|
||||||
result.addSonSkipIntLit(newTypeS(k, c))
|
result.addSonSkipIntLit(newTypeS(k, c))
|
||||||
|
|
||||||
|
|
@ -32,22 +32,22 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
|
||||||
result = newOrPrevType(tyEnum, prev, c)
|
result = newOrPrevType(tyEnum, prev, c)
|
||||||
result.n = newNodeI(nkEnumTy, n.info)
|
result.n = newNodeI(nkEnumTy, n.info)
|
||||||
checkMinSonsLen(n, 1)
|
checkMinSonsLen(n, 1)
|
||||||
if n.sons[0].kind != nkEmpty:
|
if n.sons[0].kind != nkEmpty:
|
||||||
base = semTypeNode(c, n.sons[0].sons[0], nil)
|
base = semTypeNode(c, n.sons[0].sons[0], nil)
|
||||||
if base.kind != tyEnum:
|
if base.kind != tyEnum:
|
||||||
localError(n.sons[0].info, errInheritanceOnlyWithEnums)
|
localError(n.sons[0].info, errInheritanceOnlyWithEnums)
|
||||||
counter = lastOrd(base) + 1
|
counter = lastOrd(base) + 1
|
||||||
rawAddSon(result, base)
|
rawAddSon(result, base)
|
||||||
let isPure = result.sym != nil and sfPure in result.sym.flags
|
let isPure = result.sym != nil and sfPure in result.sym.flags
|
||||||
var hasNull = false
|
var hasNull = false
|
||||||
for i in countup(1, sonsLen(n) - 1):
|
for i in countup(1, sonsLen(n) - 1):
|
||||||
case n.sons[i].kind
|
case n.sons[i].kind
|
||||||
of nkEnumFieldDef:
|
of nkEnumFieldDef:
|
||||||
e = newSymS(skEnumField, n.sons[i].sons[0], c)
|
e = newSymS(skEnumField, n.sons[i].sons[0], c)
|
||||||
var v = semConstExpr(c, n.sons[i].sons[1])
|
var v = semConstExpr(c, n.sons[i].sons[1])
|
||||||
var strVal: PNode = nil
|
var strVal: PNode = nil
|
||||||
case skipTypes(v.typ, abstractInst-{tyTypeDesc}).kind
|
case skipTypes(v.typ, abstractInst-{tyTypeDesc}).kind
|
||||||
of tyTuple:
|
of tyTuple:
|
||||||
if sonsLen(v) == 2:
|
if sonsLen(v) == 2:
|
||||||
strVal = v.sons[1] # second tuple part is the string value
|
strVal = v.sons[1] # second tuple part is the string value
|
||||||
if skipTypes(strVal.typ, abstractInst).kind in {tyString, tyCString}:
|
if skipTypes(strVal.typ, abstractInst).kind in {tyString, tyCString}:
|
||||||
|
|
@ -63,14 +63,14 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
|
||||||
x = getOrdValue(v)
|
x = getOrdValue(v)
|
||||||
if i != 1:
|
if i != 1:
|
||||||
if x != counter: incl(result.flags, tfEnumHasHoles)
|
if x != counter: incl(result.flags, tfEnumHasHoles)
|
||||||
if x < counter:
|
if x < counter:
|
||||||
localError(n.sons[i].info, errInvalidOrderInEnumX, e.name.s)
|
localError(n.sons[i].info, errInvalidOrderInEnumX, e.name.s)
|
||||||
x = counter
|
x = counter
|
||||||
e.ast = strVal # might be nil
|
e.ast = strVal # might be nil
|
||||||
counter = x
|
counter = x
|
||||||
of nkSym:
|
of nkSym:
|
||||||
e = n.sons[i].sym
|
e = n.sons[i].sym
|
||||||
of nkIdent, nkAccQuoted:
|
of nkIdent, nkAccQuoted:
|
||||||
e = newSymS(skEnumField, n.sons[i], c)
|
e = newSymS(skEnumField, n.sons[i], c)
|
||||||
else:
|
else:
|
||||||
illFormedAst(n[i])
|
illFormedAst(n[i])
|
||||||
|
|
@ -87,28 +87,28 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
|
||||||
inc(counter)
|
inc(counter)
|
||||||
if not hasNull: incl(result.flags, tfNeedsInit)
|
if not hasNull: incl(result.flags, tfNeedsInit)
|
||||||
|
|
||||||
proc semSet(c: PContext, n: PNode, prev: PType): PType =
|
proc semSet(c: PContext, n: PNode, prev: PType): PType =
|
||||||
result = newOrPrevType(tySet, prev, c)
|
result = newOrPrevType(tySet, prev, c)
|
||||||
if sonsLen(n) == 2:
|
if sonsLen(n) == 2:
|
||||||
var base = semTypeNode(c, n.sons[1], nil)
|
var base = semTypeNode(c, n.sons[1], nil)
|
||||||
addSonSkipIntLit(result, base)
|
addSonSkipIntLit(result, base)
|
||||||
if base.kind == tyGenericInst: base = lastSon(base)
|
if base.kind == tyGenericInst: base = lastSon(base)
|
||||||
if base.kind != tyGenericParam:
|
if base.kind != tyGenericParam:
|
||||||
if not isOrdinalType(base):
|
if not isOrdinalType(base):
|
||||||
localError(n.info, errOrdinalTypeExpected)
|
localError(n.info, errOrdinalTypeExpected)
|
||||||
elif lengthOrd(base) > MaxSetElements:
|
elif lengthOrd(base) > MaxSetElements:
|
||||||
localError(n.info, errSetTooBig)
|
localError(n.info, errSetTooBig)
|
||||||
else:
|
else:
|
||||||
localError(n.info, errXExpectsOneTypeParam, "set")
|
localError(n.info, errXExpectsOneTypeParam, "set")
|
||||||
addSonSkipIntLit(result, errorType(c))
|
addSonSkipIntLit(result, errorType(c))
|
||||||
|
|
||||||
proc semContainer(c: PContext, n: PNode, kind: TTypeKind, kindStr: string,
|
proc semContainer(c: PContext, n: PNode, kind: TTypeKind, kindStr: string,
|
||||||
prev: PType): PType =
|
prev: PType): PType =
|
||||||
result = newOrPrevType(kind, prev, c)
|
result = newOrPrevType(kind, prev, c)
|
||||||
if sonsLen(n) == 2:
|
if sonsLen(n) == 2:
|
||||||
var base = semTypeNode(c, n.sons[1], nil)
|
var base = semTypeNode(c, n.sons[1], nil)
|
||||||
addSonSkipIntLit(result, base)
|
addSonSkipIntLit(result, base)
|
||||||
else:
|
else:
|
||||||
localError(n.info, errXExpectsOneTypeParam, kindStr)
|
localError(n.info, errXExpectsOneTypeParam, kindStr)
|
||||||
addSonSkipIntLit(result, errorType(c))
|
addSonSkipIntLit(result, errorType(c))
|
||||||
|
|
||||||
|
|
@ -140,23 +140,23 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType =
|
||||||
var base = semTypeNode(c, n.lastSon, nil)
|
var base = semTypeNode(c, n.lastSon, nil)
|
||||||
addSonSkipIntLit(result, base)
|
addSonSkipIntLit(result, base)
|
||||||
|
|
||||||
proc semVarType(c: PContext, n: PNode, prev: PType): PType =
|
proc semVarType(c: PContext, n: PNode, prev: PType): PType =
|
||||||
if sonsLen(n) == 1:
|
if sonsLen(n) == 1:
|
||||||
result = newOrPrevType(tyVar, prev, c)
|
result = newOrPrevType(tyVar, prev, c)
|
||||||
var base = semTypeNode(c, n.sons[0], nil)
|
var base = semTypeNode(c, n.sons[0], nil)
|
||||||
if base.kind == tyVar:
|
if base.kind == tyVar:
|
||||||
localError(n.info, errVarVarTypeNotAllowed)
|
localError(n.info, errVarVarTypeNotAllowed)
|
||||||
base = base.sons[0]
|
base = base.sons[0]
|
||||||
addSonSkipIntLit(result, base)
|
addSonSkipIntLit(result, base)
|
||||||
else:
|
else:
|
||||||
result = newConstraint(c, tyVar)
|
result = newConstraint(c, tyVar)
|
||||||
|
|
||||||
proc semDistinct(c: PContext, n: PNode, prev: PType): PType =
|
proc semDistinct(c: PContext, n: PNode, prev: PType): PType =
|
||||||
if n.len == 0: return newConstraint(c, tyDistinct)
|
if n.len == 0: return newConstraint(c, tyDistinct)
|
||||||
result = newOrPrevType(tyDistinct, prev, c)
|
result = newOrPrevType(tyDistinct, prev, c)
|
||||||
addSonSkipIntLit(result, semTypeNode(c, n.sons[0], nil))
|
addSonSkipIntLit(result, semTypeNode(c, n.sons[0], nil))
|
||||||
if n.len > 1: result.n = n[1]
|
if n.len > 1: result.n = n[1]
|
||||||
|
|
||||||
proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
|
proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
|
||||||
assert isRange(n)
|
assert isRange(n)
|
||||||
checkSonsLen(n, 3)
|
checkSonsLen(n, 3)
|
||||||
|
|
@ -164,11 +164,11 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
|
||||||
result.n = newNodeI(nkRange, n.info)
|
result.n = newNodeI(nkRange, n.info)
|
||||||
if (n[1].kind == nkEmpty) or (n[2].kind == nkEmpty):
|
if (n[1].kind == nkEmpty) or (n[2].kind == nkEmpty):
|
||||||
localError(n.info, errRangeIsEmpty)
|
localError(n.info, errRangeIsEmpty)
|
||||||
|
|
||||||
var range: array[2, PNode]
|
var range: array[2, PNode]
|
||||||
range[0] = semExprWithType(c, n[1], {efDetermineType})
|
range[0] = semExprWithType(c, n[1], {efDetermineType})
|
||||||
range[1] = semExprWithType(c, n[2], {efDetermineType})
|
range[1] = semExprWithType(c, n[2], {efDetermineType})
|
||||||
|
|
||||||
var rangeT: array[2, PType]
|
var rangeT: array[2, PType]
|
||||||
for i in 0..1:
|
for i in 0..1:
|
||||||
rangeT[i] = range[i].typ.skipTypes({tyStatic}).skipIntLit
|
rangeT[i] = range[i].typ.skipTypes({tyStatic}).skipIntLit
|
||||||
|
|
@ -179,13 +179,13 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
|
||||||
localError(n.info, errOrdinalTypeExpected)
|
localError(n.info, errOrdinalTypeExpected)
|
||||||
elif enumHasHoles(rangeT[0]):
|
elif enumHasHoles(rangeT[0]):
|
||||||
localError(n.info, errEnumXHasHoles, rangeT[0].sym.name.s)
|
localError(n.info, errEnumXHasHoles, rangeT[0].sym.name.s)
|
||||||
|
|
||||||
for i in 0..1:
|
for i in 0..1:
|
||||||
if hasGenericArguments(range[i]):
|
if hasGenericArguments(range[i]):
|
||||||
result.n.addSon makeStaticExpr(c, range[i])
|
result.n.addSon makeStaticExpr(c, range[i])
|
||||||
else:
|
else:
|
||||||
result.n.addSon semConstExpr(c, range[i])
|
result.n.addSon semConstExpr(c, range[i])
|
||||||
|
|
||||||
if weakLeValue(result.n[0], result.n[1]) == impNo:
|
if weakLeValue(result.n[0], result.n[1]) == impNo:
|
||||||
localError(n.info, errRangeIsEmpty)
|
localError(n.info, errRangeIsEmpty)
|
||||||
|
|
||||||
|
|
@ -201,10 +201,10 @@ proc semRange(c: PContext, n: PNode, prev: PType): PType =
|
||||||
incl(result.flags, tfNeedsInit)
|
incl(result.flags, tfNeedsInit)
|
||||||
elif n.sons[1].kind in {nkCharLit..nkUInt64Lit} and n.sons[1].intVal < 0:
|
elif n.sons[1].kind in {nkCharLit..nkUInt64Lit} and n.sons[1].intVal < 0:
|
||||||
incl(result.flags, tfNeedsInit)
|
incl(result.flags, tfNeedsInit)
|
||||||
elif n.sons[0].kind in {nkFloatLit..nkFloat64Lit} and
|
elif n.sons[0].kind in {nkFloatLit..nkFloat64Lit} and
|
||||||
n.sons[0].floatVal > 0.0:
|
n.sons[0].floatVal > 0.0:
|
||||||
incl(result.flags, tfNeedsInit)
|
incl(result.flags, tfNeedsInit)
|
||||||
elif n.sons[1].kind in {nkFloatLit..nkFloat64Lit} and
|
elif n.sons[1].kind in {nkFloatLit..nkFloat64Lit} and
|
||||||
n.sons[1].floatVal < 0.0:
|
n.sons[1].floatVal < 0.0:
|
||||||
incl(result.flags, tfNeedsInit)
|
incl(result.flags, tfNeedsInit)
|
||||||
else:
|
else:
|
||||||
|
|
@ -243,13 +243,13 @@ proc semArrayIndex(c: PContext, n: PNode): PType =
|
||||||
else:
|
else:
|
||||||
let x = semConstExpr(c, e)
|
let x = semConstExpr(c, e)
|
||||||
if x.kind in {nkIntLit..nkUInt64Lit}:
|
if x.kind in {nkIntLit..nkUInt64Lit}:
|
||||||
result = makeRangeType(c, 0, x.intVal-1, n.info,
|
result = makeRangeType(c, 0, x.intVal-1, n.info,
|
||||||
x.typ.skipTypes({tyTypeDesc}))
|
x.typ.skipTypes({tyTypeDesc}))
|
||||||
else:
|
else:
|
||||||
result = x.typ.skipTypes({tyTypeDesc})
|
result = x.typ.skipTypes({tyTypeDesc})
|
||||||
#localError(n[1].info, errConstExprExpected)
|
#localError(n[1].info, errConstExprExpected)
|
||||||
|
|
||||||
proc semArray(c: PContext, n: PNode, prev: PType): PType =
|
proc semArray(c: PContext, n: PNode, prev: PType): PType =
|
||||||
var base: PType
|
var base: PType
|
||||||
result = newOrPrevType(tyArray, prev, c)
|
result = newOrPrevType(tyArray, prev, c)
|
||||||
if sonsLen(n) == 3:
|
if sonsLen(n) == 3:
|
||||||
|
|
@ -260,20 +260,20 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType =
|
||||||
if indx.kind notin {tyGenericParam, tyStatic, tyFromExpr}:
|
if indx.kind notin {tyGenericParam, tyStatic, tyFromExpr}:
|
||||||
if not isOrdinalType(indx):
|
if not isOrdinalType(indx):
|
||||||
localError(n.sons[1].info, errOrdinalTypeExpected)
|
localError(n.sons[1].info, errOrdinalTypeExpected)
|
||||||
elif enumHasHoles(indx):
|
elif enumHasHoles(indx):
|
||||||
localError(n.sons[1].info, errEnumXHasHoles, indx.sym.name.s)
|
localError(n.sons[1].info, errEnumXHasHoles, indx.sym.name.s)
|
||||||
base = semTypeNode(c, n.sons[2], nil)
|
base = semTypeNode(c, n.sons[2], nil)
|
||||||
addSonSkipIntLit(result, base)
|
addSonSkipIntLit(result, base)
|
||||||
else:
|
else:
|
||||||
localError(n.info, errArrayExpectsTwoTypeParams)
|
localError(n.info, errArrayExpectsTwoTypeParams)
|
||||||
result = newOrPrevType(tyError, prev, c)
|
result = newOrPrevType(tyError, prev, c)
|
||||||
|
|
||||||
proc semOrdinal(c: PContext, n: PNode, prev: PType): PType =
|
proc semOrdinal(c: PContext, n: PNode, prev: PType): PType =
|
||||||
result = newOrPrevType(tyOrdinal, prev, c)
|
result = newOrPrevType(tyOrdinal, prev, c)
|
||||||
if sonsLen(n) == 2:
|
if sonsLen(n) == 2:
|
||||||
var base = semTypeNode(c, n.sons[1], nil)
|
var base = semTypeNode(c, n.sons[1], nil)
|
||||||
if base.kind != tyGenericParam:
|
if base.kind != tyGenericParam:
|
||||||
if not isOrdinalType(base):
|
if not isOrdinalType(base):
|
||||||
localError(n.sons[1].info, errOrdinalTypeExpected)
|
localError(n.sons[1].info, errOrdinalTypeExpected)
|
||||||
addSonSkipIntLit(result, base)
|
addSonSkipIntLit(result, base)
|
||||||
else:
|
else:
|
||||||
|
|
@ -281,7 +281,7 @@ proc semOrdinal(c: PContext, n: PNode, prev: PType): PType =
|
||||||
result = newOrPrevType(tyError, prev, c)
|
result = newOrPrevType(tyError, prev, c)
|
||||||
|
|
||||||
proc semTypeIdent(c: PContext, n: PNode): PSym =
|
proc semTypeIdent(c: PContext, n: PNode): PSym =
|
||||||
if n.kind == nkSym:
|
if n.kind == nkSym:
|
||||||
result = n.sym
|
result = n.sym
|
||||||
else:
|
else:
|
||||||
when defined(nimfix):
|
when defined(nimfix):
|
||||||
|
|
@ -307,7 +307,7 @@ proc semTypeIdent(c: PContext, n: PNode): PSym =
|
||||||
result = result.typ.sym.copySym
|
result = result.typ.sym.copySym
|
||||||
result.typ = copyType(result.typ, result.typ.owner, true)
|
result.typ = copyType(result.typ, result.typ.owner, true)
|
||||||
result.typ.flags.incl tfUnresolved
|
result.typ.flags.incl tfUnresolved
|
||||||
|
|
||||||
if result.kind == skGenericParam:
|
if result.kind == skGenericParam:
|
||||||
if result.typ.kind == tyGenericParam and result.typ.len == 0 and
|
if result.typ.kind == tyGenericParam and result.typ.len == 0 and
|
||||||
tfWildcard in result.typ.flags:
|
tfWildcard in result.typ.flags:
|
||||||
|
|
@ -319,7 +319,7 @@ proc semTypeIdent(c: PContext, n: PNode): PSym =
|
||||||
localError(n.info, errTypeExpected)
|
localError(n.info, errTypeExpected)
|
||||||
return errorSym(c, n)
|
return errorSym(c, n)
|
||||||
|
|
||||||
if result.kind != skType:
|
if result.kind != skType:
|
||||||
# this implements the wanted ``var v: V, x: V`` feature ...
|
# this implements the wanted ``var v: V, x: V`` feature ...
|
||||||
var ov: TOverloadIter
|
var ov: TOverloadIter
|
||||||
var amb = initOverloadIter(ov, c, n)
|
var amb = initOverloadIter(ov, c, n)
|
||||||
|
|
@ -344,48 +344,48 @@ proc semTypeIdent(c: PContext, n: PNode): PSym =
|
||||||
else:
|
else:
|
||||||
localError(n.info, errIdentifierExpected)
|
localError(n.info, errIdentifierExpected)
|
||||||
result = errorSym(c, n)
|
result = errorSym(c, n)
|
||||||
|
|
||||||
proc semTuple(c: PContext, n: PNode, prev: PType): PType =
|
proc semTuple(c: PContext, n: PNode, prev: PType): PType =
|
||||||
if n.sonsLen == 0: return newConstraint(c, tyTuple)
|
if n.sonsLen == 0: return newConstraint(c, tyTuple)
|
||||||
var typ: PType
|
var typ: PType
|
||||||
result = newOrPrevType(tyTuple, prev, c)
|
result = newOrPrevType(tyTuple, prev, c)
|
||||||
result.n = newNodeI(nkRecList, n.info)
|
result.n = newNodeI(nkRecList, n.info)
|
||||||
var check = initIntSet()
|
var check = initIntSet()
|
||||||
var counter = 0
|
var counter = 0
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
var a = n.sons[i]
|
var a = n.sons[i]
|
||||||
if (a.kind != nkIdentDefs): illFormedAst(a)
|
if (a.kind != nkIdentDefs): illFormedAst(a)
|
||||||
checkMinSonsLen(a, 3)
|
checkMinSonsLen(a, 3)
|
||||||
var length = sonsLen(a)
|
var length = sonsLen(a)
|
||||||
if a.sons[length - 2].kind != nkEmpty:
|
if a.sons[length - 2].kind != nkEmpty:
|
||||||
typ = semTypeNode(c, a.sons[length - 2], nil)
|
typ = semTypeNode(c, a.sons[length - 2], nil)
|
||||||
else:
|
else:
|
||||||
localError(a.info, errTypeExpected)
|
localError(a.info, errTypeExpected)
|
||||||
typ = errorType(c)
|
typ = errorType(c)
|
||||||
if a.sons[length - 1].kind != nkEmpty:
|
if a.sons[length - 1].kind != nkEmpty:
|
||||||
localError(a.sons[length - 1].info, errInitHereNotAllowed)
|
localError(a.sons[length - 1].info, errInitHereNotAllowed)
|
||||||
for j in countup(0, length - 3):
|
for j in countup(0, length - 3):
|
||||||
var field = newSymG(skField, a.sons[j], c)
|
var field = newSymG(skField, a.sons[j], c)
|
||||||
field.typ = typ
|
field.typ = typ
|
||||||
field.position = counter
|
field.position = counter
|
||||||
inc(counter)
|
inc(counter)
|
||||||
if containsOrIncl(check, field.name.id):
|
if containsOrIncl(check, field.name.id):
|
||||||
localError(a.sons[j].info, errAttemptToRedefine, field.name.s)
|
localError(a.sons[j].info, errAttemptToRedefine, field.name.s)
|
||||||
else:
|
else:
|
||||||
addSon(result.n, newSymNode(field))
|
addSon(result.n, newSymNode(field))
|
||||||
addSonSkipIntLit(result, typ)
|
addSonSkipIntLit(result, typ)
|
||||||
if gCmd == cmdPretty: styleCheckDef(a.sons[j].info, field)
|
if gCmd == cmdPretty: styleCheckDef(a.sons[j].info, field)
|
||||||
|
|
||||||
proc semIdentVis(c: PContext, kind: TSymKind, n: PNode,
|
proc semIdentVis(c: PContext, kind: TSymKind, n: PNode,
|
||||||
allowed: TSymFlags): PSym =
|
allowed: TSymFlags): PSym =
|
||||||
# identifier with visibility
|
# identifier with visibility
|
||||||
if n.kind == nkPostfix:
|
if n.kind == nkPostfix:
|
||||||
if sonsLen(n) == 2 and n.sons[0].kind == nkIdent:
|
if sonsLen(n) == 2 and n.sons[0].kind == nkIdent:
|
||||||
# for gensym'ed identifiers the identifier may already have been
|
# for gensym'ed identifiers the identifier may already have been
|
||||||
# transformed to a symbol and we need to use that here:
|
# transformed to a symbol and we need to use that here:
|
||||||
result = newSymG(kind, n.sons[1], c)
|
result = newSymG(kind, n.sons[1], c)
|
||||||
var v = n.sons[0].ident
|
var v = n.sons[0].ident
|
||||||
if sfExported in allowed and v.id == ord(wStar):
|
if sfExported in allowed and v.id == ord(wStar):
|
||||||
incl(result.flags, sfExported)
|
incl(result.flags, sfExported)
|
||||||
else:
|
else:
|
||||||
localError(n.sons[0].info, errInvalidVisibilityX, v.s)
|
localError(n.sons[0].info, errInvalidVisibilityX, v.s)
|
||||||
|
|
@ -393,7 +393,7 @@ proc semIdentVis(c: PContext, kind: TSymKind, n: PNode,
|
||||||
illFormedAst(n)
|
illFormedAst(n)
|
||||||
else:
|
else:
|
||||||
result = newSymG(kind, n, c)
|
result = newSymG(kind, n, c)
|
||||||
|
|
||||||
proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode,
|
proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode,
|
||||||
allowed: TSymFlags): PSym =
|
allowed: TSymFlags): PSym =
|
||||||
if n.kind == nkPragmaExpr:
|
if n.kind == nkPragmaExpr:
|
||||||
|
|
@ -415,31 +415,31 @@ proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode,
|
||||||
proc checkForOverlap(c: PContext, t: PNode, currentEx, branchIndex: int) =
|
proc checkForOverlap(c: PContext, t: PNode, currentEx, branchIndex: int) =
|
||||||
let ex = t[branchIndex][currentEx].skipConv
|
let ex = t[branchIndex][currentEx].skipConv
|
||||||
for i in countup(1, branchIndex):
|
for i in countup(1, branchIndex):
|
||||||
for j in countup(0, sonsLen(t.sons[i]) - 2):
|
for j in countup(0, sonsLen(t.sons[i]) - 2):
|
||||||
if i == branchIndex and j == currentEx: break
|
if i == branchIndex and j == currentEx: break
|
||||||
if overlap(t.sons[i].sons[j].skipConv, ex):
|
if overlap(t.sons[i].sons[j].skipConv, ex):
|
||||||
localError(ex.info, errDuplicateCaseLabel)
|
localError(ex.info, errDuplicateCaseLabel)
|
||||||
|
|
||||||
proc semBranchRange(c: PContext, t, a, b: PNode, covered: var BiggestInt): PNode =
|
proc semBranchRange(c: PContext, t, a, b: PNode, covered: var BiggestInt): PNode =
|
||||||
checkMinSonsLen(t, 1)
|
checkMinSonsLen(t, 1)
|
||||||
let ac = semConstExpr(c, a)
|
let ac = semConstExpr(c, a)
|
||||||
let bc = semConstExpr(c, b)
|
let bc = semConstExpr(c, b)
|
||||||
let at = fitNode(c, t.sons[0].typ, ac).skipConvTakeType
|
let at = fitNode(c, t.sons[0].typ, ac).skipConvTakeType
|
||||||
let bt = fitNode(c, t.sons[0].typ, bc).skipConvTakeType
|
let bt = fitNode(c, t.sons[0].typ, bc).skipConvTakeType
|
||||||
|
|
||||||
result = newNodeI(nkRange, a.info)
|
result = newNodeI(nkRange, a.info)
|
||||||
result.add(at)
|
result.add(at)
|
||||||
result.add(bt)
|
result.add(bt)
|
||||||
if emptyRange(ac, bc): localError(b.info, errRangeIsEmpty)
|
if emptyRange(ac, bc): localError(b.info, errRangeIsEmpty)
|
||||||
else: covered = covered + getOrdValue(bc) - getOrdValue(ac) + 1
|
else: covered = covered + getOrdValue(bc) - getOrdValue(ac) + 1
|
||||||
|
|
||||||
proc semCaseBranchRange(c: PContext, t, b: PNode,
|
proc semCaseBranchRange(c: PContext, t, b: PNode,
|
||||||
covered: var BiggestInt): PNode =
|
covered: var BiggestInt): PNode =
|
||||||
checkSonsLen(b, 3)
|
checkSonsLen(b, 3)
|
||||||
result = semBranchRange(c, t, b.sons[1], b.sons[2], covered)
|
result = semBranchRange(c, t, b.sons[1], b.sons[2], covered)
|
||||||
|
|
||||||
proc semCaseBranchSetElem(c: PContext, t, b: PNode,
|
proc semCaseBranchSetElem(c: PContext, t, b: PNode,
|
||||||
covered: var BiggestInt): PNode =
|
covered: var BiggestInt): PNode =
|
||||||
if isRange(b):
|
if isRange(b):
|
||||||
checkSonsLen(b, 3)
|
checkSonsLen(b, 3)
|
||||||
result = semBranchRange(c, t, b.sons[1], b.sons[2], covered)
|
result = semBranchRange(c, t, b.sons[1], b.sons[2], covered)
|
||||||
|
|
@ -450,10 +450,10 @@ proc semCaseBranchSetElem(c: PContext, t, b: PNode,
|
||||||
result = fitNode(c, t.sons[0].typ, b)
|
result = fitNode(c, t.sons[0].typ, b)
|
||||||
inc(covered)
|
inc(covered)
|
||||||
|
|
||||||
proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int,
|
proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int,
|
||||||
covered: var BiggestInt) =
|
covered: var BiggestInt) =
|
||||||
|
|
||||||
for i in countup(0, sonsLen(branch) - 2):
|
for i in countup(0, sonsLen(branch) - 2):
|
||||||
var b = branch.sons[i]
|
var b = branch.sons[i]
|
||||||
if b.kind == nkRange:
|
if b.kind == nkRange:
|
||||||
branch.sons[i] = b
|
branch.sons[i] = b
|
||||||
|
|
@ -480,7 +480,7 @@ proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int,
|
||||||
var L = branch.len
|
var L = branch.len
|
||||||
swap(branch.sons[L-2], branch.sons[L-1])
|
swap(branch.sons[L-2], branch.sons[L-1])
|
||||||
checkForOverlap(c, t, i, branchIndex)
|
checkForOverlap(c, t, i, branchIndex)
|
||||||
|
|
||||||
proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
||||||
father: PNode, rectype: PType)
|
father: PNode, rectype: PType)
|
||||||
proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
||||||
|
|
@ -514,11 +514,11 @@ proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
||||||
else: illFormedAst(n)
|
else: illFormedAst(n)
|
||||||
delSon(b, sonsLen(b) - 1)
|
delSon(b, sonsLen(b) - 1)
|
||||||
semRecordNodeAux(c, lastSon(n.sons[i]), check, pos, b, rectype)
|
semRecordNodeAux(c, lastSon(n.sons[i]), check, pos, b, rectype)
|
||||||
if chckCovered and (covered != lengthOrd(a.sons[0].typ)):
|
if chckCovered and (covered != lengthOrd(a.sons[0].typ)):
|
||||||
localError(a.info, errNotAllCasesCovered)
|
localError(a.info, errNotAllCasesCovered)
|
||||||
addSon(father, a)
|
addSon(father, a)
|
||||||
|
|
||||||
proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
||||||
father: PNode, rectype: PType) =
|
father: PNode, rectype: PType) =
|
||||||
if n == nil: return
|
if n == nil: return
|
||||||
case n.kind
|
case n.kind
|
||||||
|
|
@ -556,12 +556,12 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
||||||
semRecordNodeAux(c, branch, check, pos, father, rectype)
|
semRecordNodeAux(c, branch, check, pos, father, rectype)
|
||||||
of nkRecCase:
|
of nkRecCase:
|
||||||
semRecordCase(c, n, check, pos, father, rectype)
|
semRecordCase(c, n, check, pos, father, rectype)
|
||||||
of nkNilLit:
|
of nkNilLit:
|
||||||
if father.kind != nkRecList: addSon(father, newNodeI(nkRecList, n.info))
|
if father.kind != nkRecList: addSon(father, newNodeI(nkRecList, n.info))
|
||||||
of nkRecList:
|
of nkRecList:
|
||||||
# attempt to keep the nesting at a sane level:
|
# attempt to keep the nesting at a sane level:
|
||||||
var a = if father.kind == nkRecList: father else: copyNode(n)
|
var a = if father.kind == nkRecList: father else: copyNode(n)
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
semRecordNodeAux(c, n.sons[i], check, pos, a, rectype)
|
semRecordNodeAux(c, n.sons[i], check, pos, a, rectype)
|
||||||
if a != father: addSon(father, a)
|
if a != father: addSon(father, a)
|
||||||
of nkIdentDefs:
|
of nkIdentDefs:
|
||||||
|
|
@ -570,10 +570,10 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
||||||
var a: PNode
|
var a: PNode
|
||||||
if father.kind != nkRecList and length>=4: a = newNodeI(nkRecList, n.info)
|
if father.kind != nkRecList and length>=4: a = newNodeI(nkRecList, n.info)
|
||||||
else: a = ast.emptyNode
|
else: a = ast.emptyNode
|
||||||
if n.sons[length-1].kind != nkEmpty:
|
if n.sons[length-1].kind != nkEmpty:
|
||||||
localError(n.sons[length-1].info, errInitHereNotAllowed)
|
localError(n.sons[length-1].info, errInitHereNotAllowed)
|
||||||
var typ: PType
|
var typ: PType
|
||||||
if n.sons[length-2].kind == nkEmpty:
|
if n.sons[length-2].kind == nkEmpty:
|
||||||
localError(n.info, errTypeExpected)
|
localError(n.info, errTypeExpected)
|
||||||
typ = errorType(c)
|
typ = errorType(c)
|
||||||
else:
|
else:
|
||||||
|
|
@ -586,7 +586,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
||||||
f.typ = typ
|
f.typ = typ
|
||||||
f.position = pos
|
f.position = pos
|
||||||
if (rec != nil) and ({sfImportc, sfExportc} * rec.flags != {}) and
|
if (rec != nil) and ({sfImportc, sfExportc} * rec.flags != {}) and
|
||||||
(f.loc.r == nil):
|
(f.loc.r == nil):
|
||||||
f.loc.r = toRope(f.name.s)
|
f.loc.r = toRope(f.name.s)
|
||||||
f.flags = f.flags + ({sfImportc, sfExportc} * rec.flags)
|
f.flags = f.flags + ({sfImportc, sfExportc} * rec.flags)
|
||||||
inc(pos)
|
inc(pos)
|
||||||
|
|
@ -598,8 +598,8 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
||||||
if a.kind != nkEmpty: addSon(father, a)
|
if a.kind != nkEmpty: addSon(father, a)
|
||||||
of nkEmpty: discard
|
of nkEmpty: discard
|
||||||
else: illFormedAst(n)
|
else: illFormedAst(n)
|
||||||
|
|
||||||
proc addInheritedFieldsAux(c: PContext, check: var IntSet, pos: var int,
|
proc addInheritedFieldsAux(c: PContext, check: var IntSet, pos: var int,
|
||||||
n: PNode) =
|
n: PNode) =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkRecCase:
|
of nkRecCase:
|
||||||
|
|
@ -618,31 +618,31 @@ proc addInheritedFieldsAux(c: PContext, check: var IntSet, pos: var int,
|
||||||
inc(pos)
|
inc(pos)
|
||||||
else: internalError(n.info, "addInheritedFieldsAux()")
|
else: internalError(n.info, "addInheritedFieldsAux()")
|
||||||
|
|
||||||
proc skipGenericInvocation(t: PType): PType {.inline.} =
|
proc skipGenericInvocation(t: PType): PType {.inline.} =
|
||||||
result = t
|
result = t
|
||||||
if result.kind == tyGenericInvocation:
|
if result.kind == tyGenericInvocation:
|
||||||
result = result.sons[0]
|
result = result.sons[0]
|
||||||
if result.kind == tyGenericBody:
|
if result.kind == tyGenericBody:
|
||||||
result = lastSon(result)
|
result = lastSon(result)
|
||||||
|
|
||||||
proc addInheritedFields(c: PContext, check: var IntSet, pos: var int,
|
proc addInheritedFields(c: PContext, check: var IntSet, pos: var int,
|
||||||
obj: PType) =
|
obj: PType) =
|
||||||
assert obj.kind == tyObject
|
assert obj.kind == tyObject
|
||||||
if (sonsLen(obj) > 0) and (obj.sons[0] != nil):
|
if (sonsLen(obj) > 0) and (obj.sons[0] != nil):
|
||||||
addInheritedFields(c, check, pos, obj.sons[0].skipGenericInvocation)
|
addInheritedFields(c, check, pos, obj.sons[0].skipGenericInvocation)
|
||||||
addInheritedFieldsAux(c, check, pos, obj.n)
|
addInheritedFieldsAux(c, check, pos, obj.n)
|
||||||
|
|
||||||
proc semObjectNode(c: PContext, n: PNode, prev: PType): PType =
|
proc semObjectNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
if n.sonsLen == 0: return newConstraint(c, tyObject)
|
if n.sonsLen == 0: return newConstraint(c, tyObject)
|
||||||
var check = initIntSet()
|
var check = initIntSet()
|
||||||
var pos = 0
|
var pos = 0
|
||||||
var base: PType = nil
|
var base: PType = nil
|
||||||
# n.sons[0] contains the pragmas (if any). We process these later...
|
# n.sons[0] contains the pragmas (if any). We process these later...
|
||||||
checkSonsLen(n, 3)
|
checkSonsLen(n, 3)
|
||||||
if n.sons[1].kind != nkEmpty:
|
if n.sons[1].kind != nkEmpty:
|
||||||
base = skipTypes(semTypeNode(c, n.sons[1].sons[0], nil), skipPtrs)
|
base = skipTypes(semTypeNode(c, n.sons[1].sons[0], nil), skipPtrs)
|
||||||
var concreteBase = skipGenericInvocation(base).skipTypes(skipPtrs)
|
var concreteBase = skipGenericInvocation(base).skipTypes(skipPtrs)
|
||||||
if concreteBase.kind == tyObject and tfFinal notin concreteBase.flags:
|
if concreteBase.kind == tyObject and tfFinal notin concreteBase.flags:
|
||||||
addInheritedFields(c, check, pos, concreteBase)
|
addInheritedFields(c, check, pos, concreteBase)
|
||||||
else:
|
else:
|
||||||
if concreteBase.kind != tyError:
|
if concreteBase.kind != tyError:
|
||||||
|
|
@ -723,7 +723,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||||
genericParams.addSon(newSymNode(s))
|
genericParams.addSon(newSymNode(s))
|
||||||
result = typeClass
|
result = typeClass
|
||||||
addDecl(c, s)
|
addDecl(c, s)
|
||||||
|
|
||||||
# XXX: There are codegen errors if this is turned into a nested proc
|
# XXX: There are codegen errors if this is turned into a nested proc
|
||||||
template liftingWalk(typ: PType, anonFlag = false): expr =
|
template liftingWalk(typ: PType, anonFlag = false): expr =
|
||||||
liftParamType(c, procKind, genericParams, typ, paramName, info, anonFlag)
|
liftParamType(c, procKind, genericParams, typ, paramName, info, anonFlag)
|
||||||
|
|
@ -742,7 +742,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||||
case paramType.kind:
|
case paramType.kind:
|
||||||
of tyAnything:
|
of tyAnything:
|
||||||
result = addImplicitGeneric(newTypeS(tyGenericParam, c))
|
result = addImplicitGeneric(newTypeS(tyGenericParam, c))
|
||||||
|
|
||||||
of tyStatic:
|
of tyStatic:
|
||||||
# proc(a: expr{string}, b: expr{nkLambda})
|
# proc(a: expr{string}, b: expr{nkLambda})
|
||||||
# overload on compile time values and AST trees
|
# overload on compile time values and AST trees
|
||||||
|
|
@ -753,7 +753,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||||
localError(info, errMacroBodyDependsOnGenericTypes, paramName)
|
localError(info, errMacroBodyDependsOnGenericTypes, paramName)
|
||||||
result = addImplicitGeneric(c.newTypeWithSons(tyStatic, @[base]))
|
result = addImplicitGeneric(c.newTypeWithSons(tyStatic, @[base]))
|
||||||
result.flags.incl({tfHasStatic, tfUnresolved})
|
result.flags.incl({tfHasStatic, tfUnresolved})
|
||||||
|
|
||||||
of tyTypeDesc:
|
of tyTypeDesc:
|
||||||
if tfUnresolved notin paramType.flags:
|
if tfUnresolved notin paramType.flags:
|
||||||
# naked typedescs are not bindOnce types
|
# naked typedescs are not bindOnce types
|
||||||
|
|
@ -761,12 +761,12 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||||
paramTypId.id == typedescId.id: paramTypId = nil
|
paramTypId.id == typedescId.id: paramTypId = nil
|
||||||
result = addImplicitGeneric(
|
result = addImplicitGeneric(
|
||||||
c.newTypeWithSons(tyTypeDesc, @[paramType.base]))
|
c.newTypeWithSons(tyTypeDesc, @[paramType.base]))
|
||||||
|
|
||||||
of tyDistinct:
|
of tyDistinct:
|
||||||
if paramType.sonsLen == 1:
|
if paramType.sonsLen == 1:
|
||||||
# disable the bindOnce behavior for the type class
|
# disable the bindOnce behavior for the type class
|
||||||
result = liftingWalk(paramType.sons[0], true)
|
result = liftingWalk(paramType.sons[0], true)
|
||||||
|
|
||||||
of tySequence, tySet, tyArray, tyOpenArray,
|
of tySequence, tySet, tyArray, tyOpenArray,
|
||||||
tyVar, tyPtr, tyRef, tyProc:
|
tyVar, tyPtr, tyRef, tyProc:
|
||||||
# XXX: this is a bit strange, but proc(s: seq)
|
# XXX: this is a bit strange, but proc(s: seq)
|
||||||
|
|
@ -785,22 +785,22 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||||
if lifted != nil:
|
if lifted != nil:
|
||||||
paramType.sons[i] = lifted
|
paramType.sons[i] = lifted
|
||||||
result = paramType
|
result = paramType
|
||||||
|
|
||||||
of tyGenericBody:
|
of tyGenericBody:
|
||||||
result = newTypeS(tyGenericInvocation, c)
|
result = newTypeS(tyGenericInvocation, c)
|
||||||
result.rawAddSon(paramType)
|
result.rawAddSon(paramType)
|
||||||
|
|
||||||
for i in 0 .. paramType.sonsLen - 2:
|
for i in 0 .. paramType.sonsLen - 2:
|
||||||
if paramType.sons[i].kind == tyStatic:
|
if paramType.sons[i].kind == tyStatic:
|
||||||
result.rawAddSon makeTypeFromExpr(c, ast.emptyNode) # aka 'tyUnknown'
|
result.rawAddSon makeTypeFromExpr(c, ast.emptyNode) # aka 'tyUnknown'
|
||||||
else:
|
else:
|
||||||
result.rawAddSon newTypeS(tyAnything, c)
|
result.rawAddSon newTypeS(tyAnything, c)
|
||||||
|
|
||||||
if paramType.lastSon.kind == tyUserTypeClass:
|
if paramType.lastSon.kind == tyUserTypeClass:
|
||||||
result.kind = tyUserTypeClassInst
|
result.kind = tyUserTypeClassInst
|
||||||
result.rawAddSon paramType.lastSon
|
result.rawAddSon paramType.lastSon
|
||||||
return addImplicitGeneric(result)
|
return addImplicitGeneric(result)
|
||||||
|
|
||||||
result = instGenericContainer(c, paramType.sym.info, result,
|
result = instGenericContainer(c, paramType.sym.info, result,
|
||||||
allowMetaTypes = true)
|
allowMetaTypes = true)
|
||||||
result = newTypeWithSons(c, tyCompositeTypeClass, @[paramType, result])
|
result = newTypeWithSons(c, tyCompositeTypeClass, @[paramType, result])
|
||||||
|
|
@ -832,7 +832,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||||
if liftBody != nil:
|
if liftBody != nil:
|
||||||
result = liftBody
|
result = liftBody
|
||||||
result.shouldHaveMeta
|
result.shouldHaveMeta
|
||||||
|
|
||||||
of tyGenericInvocation:
|
of tyGenericInvocation:
|
||||||
for i in 1 .. <paramType.sonsLen:
|
for i in 1 .. <paramType.sonsLen:
|
||||||
let lifted = liftingWalk(paramType.sons[i])
|
let lifted = liftingWalk(paramType.sons[i])
|
||||||
|
|
@ -844,18 +844,18 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||||
|
|
||||||
of tyUserTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot:
|
of tyUserTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot:
|
||||||
result = addImplicitGeneric(copyType(paramType, getCurrOwner(), true))
|
result = addImplicitGeneric(copyType(paramType, getCurrOwner(), true))
|
||||||
|
|
||||||
of tyExpr:
|
of tyExpr:
|
||||||
if procKind notin {skMacro, skTemplate}:
|
if procKind notin {skMacro, skTemplate}:
|
||||||
result = addImplicitGeneric(newTypeS(tyAnything, c))
|
result = addImplicitGeneric(newTypeS(tyAnything, c))
|
||||||
|
|
||||||
of tyGenericParam:
|
of tyGenericParam:
|
||||||
markUsed(info, paramType.sym)
|
markUsed(info, paramType.sym)
|
||||||
styleCheckUse(info, paramType.sym)
|
styleCheckUse(info, paramType.sym)
|
||||||
if tfWildcard in paramType.flags:
|
if tfWildcard in paramType.flags:
|
||||||
paramType.flags.excl tfWildcard
|
paramType.flags.excl tfWildcard
|
||||||
paramType.sym.kind = skType
|
paramType.sym.kind = skType
|
||||||
|
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
# result = liftingWalk(paramType)
|
# result = liftingWalk(paramType)
|
||||||
|
|
@ -872,7 +872,7 @@ proc newProcType(c: PContext; info: TLineInfo; prev: PType = nil): PType =
|
||||||
result.callConv = lastOptionEntry(c).defaultCC
|
result.callConv = lastOptionEntry(c).defaultCC
|
||||||
result.n = newNodeI(nkFormalParams, info)
|
result.n = newNodeI(nkFormalParams, info)
|
||||||
rawAddSon(result, nil) # return type
|
rawAddSon(result, nil) # return type
|
||||||
# result.n[0] used to be `nkType`, but now it's `nkEffectList` because
|
# result.n[0] used to be `nkType`, but now it's `nkEffectList` because
|
||||||
# the effects are now stored in there too ... this is a bit hacky, but as
|
# the effects are now stored in there too ... this is a bit hacky, but as
|
||||||
# usual we desperately try to save memory:
|
# usual we desperately try to save memory:
|
||||||
addSon(result.n, newNodeI(nkEffectList, info))
|
addSon(result.n, newNodeI(nkEffectList, info))
|
||||||
|
|
@ -909,7 +909,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
|
||||||
typ = semParamType(c, a.sons[length-2], constraint)
|
typ = semParamType(c, a.sons[length-2], constraint)
|
||||||
|
|
||||||
if hasDefault:
|
if hasDefault:
|
||||||
def = semExprWithType(c, a.sons[length-1])
|
def = semExprWithType(c, a.sons[length-1])
|
||||||
# check type compatibility between def.typ and typ:
|
# check type compatibility between def.typ and typ:
|
||||||
if typ == nil:
|
if typ == nil:
|
||||||
typ = def.typ
|
typ = def.typ
|
||||||
|
|
@ -927,7 +927,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
|
||||||
typ = newTypeS(tdef, c)
|
typ = newTypeS(tdef, c)
|
||||||
|
|
||||||
if skipTypes(typ, {tyGenericInst}).kind == tyEmpty: continue
|
if skipTypes(typ, {tyGenericInst}).kind == tyEmpty: continue
|
||||||
for j in countup(0, length-3):
|
for j in countup(0, length-3):
|
||||||
var arg = newSymG(skParam, a.sons[j], c)
|
var arg = newSymG(skParam, a.sons[j], c)
|
||||||
let lifted = liftParamType(c, kind, genericParams, typ,
|
let lifted = liftParamType(c, kind, genericParams, typ,
|
||||||
arg.name.s, arg.info)
|
arg.name.s, arg.info)
|
||||||
|
|
@ -937,7 +937,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
|
||||||
arg.constraint = constraint
|
arg.constraint = constraint
|
||||||
inc(counter)
|
inc(counter)
|
||||||
if def != nil and def.kind != nkEmpty: arg.ast = copyTree(def)
|
if def != nil and def.kind != nkEmpty: arg.ast = copyTree(def)
|
||||||
if containsOrIncl(check, arg.name.id):
|
if containsOrIncl(check, arg.name.id):
|
||||||
localError(a.sons[j].info, errAttemptToRedefine, arg.name.s)
|
localError(a.sons[j].info, errAttemptToRedefine, arg.name.s)
|
||||||
addSon(result.n, newSymNode(arg))
|
addSon(result.n, newSymNode(arg))
|
||||||
rawAddSon(result, finalType)
|
rawAddSon(result, finalType)
|
||||||
|
|
@ -950,9 +950,9 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
|
||||||
elif kind == skIterator:
|
elif kind == skIterator:
|
||||||
# XXX This is special magic we should likely get rid of
|
# XXX This is special magic we should likely get rid of
|
||||||
r = newTypeS(tyExpr, c)
|
r = newTypeS(tyExpr, c)
|
||||||
|
|
||||||
if r != nil:
|
if r != nil:
|
||||||
# turn explicit 'void' return type into 'nil' because the rest of the
|
# turn explicit 'void' return type into 'nil' because the rest of the
|
||||||
# compiler only checks for 'nil':
|
# compiler only checks for 'nil':
|
||||||
if skipTypes(r, {tyGenericInst}).kind != tyEmpty:
|
if skipTypes(r, {tyGenericInst}).kind != tyEmpty:
|
||||||
# 'auto' as a return type does not imply a generic:
|
# 'auto' as a return type does not imply a generic:
|
||||||
|
|
@ -988,8 +988,8 @@ proc semStmtListType(c: PContext, n: PNode, prev: PType): PType =
|
||||||
n.sons[length - 1].typ = result
|
n.sons[length - 1].typ = result
|
||||||
else:
|
else:
|
||||||
result = nil
|
result = nil
|
||||||
|
|
||||||
proc semBlockType(c: PContext, n: PNode, prev: PType): PType =
|
proc semBlockType(c: PContext, n: PNode, prev: PType): PType =
|
||||||
inc(c.p.nestedBlockCounter)
|
inc(c.p.nestedBlockCounter)
|
||||||
checkSonsLen(n, 2)
|
checkSonsLen(n, 2)
|
||||||
openScope(c)
|
openScope(c)
|
||||||
|
|
@ -1009,7 +1009,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
||||||
localError(n.info, "cannot instantiate the '$1' $2" %
|
localError(n.info, "cannot instantiate the '$1' $2" %
|
||||||
[s.name.s, ($s.kind).substr(2).toLower])
|
[s.name.s, ($s.kind).substr(2).toLower])
|
||||||
return newOrPrevType(tyError, prev, c)
|
return newOrPrevType(tyError, prev, c)
|
||||||
|
|
||||||
var t = s.typ
|
var t = s.typ
|
||||||
if t.kind == tyCompositeTypeClass and t.base.kind == tyGenericBody:
|
if t.kind == tyCompositeTypeClass and t.base.kind == tyGenericBody:
|
||||||
t = t.base
|
t = t.base
|
||||||
|
|
@ -1036,7 +1036,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
||||||
else:
|
else:
|
||||||
var m = newCandidate(c, t)
|
var m = newCandidate(c, t)
|
||||||
matches(c, n, copyTree(n), m)
|
matches(c, n, copyTree(n), m)
|
||||||
|
|
||||||
if m.state != csMatch:
|
if m.state != csMatch:
|
||||||
var err = "cannot instantiate " & typeToString(t) & "\n" &
|
var err = "cannot instantiate " & typeToString(t) & "\n" &
|
||||||
"got: (" & describeArgs(c, n) & ")\n" &
|
"got: (" & describeArgs(c, n) & ")\n" &
|
||||||
|
|
@ -1045,12 +1045,12 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
||||||
return newOrPrevType(tyError, prev, c)
|
return newOrPrevType(tyError, prev, c)
|
||||||
|
|
||||||
var isConcrete = true
|
var isConcrete = true
|
||||||
|
|
||||||
for i in 1 .. <m.call.len:
|
for i in 1 .. <m.call.len:
|
||||||
let typ = m.call[i].typ.skipTypes({tyTypeDesc})
|
let typ = m.call[i].typ.skipTypes({tyTypeDesc})
|
||||||
if containsGenericType(typ): isConcrete = false
|
if containsGenericType(typ): isConcrete = false
|
||||||
addToResult(typ)
|
addToResult(typ)
|
||||||
|
|
||||||
if isConcrete:
|
if isConcrete:
|
||||||
if s.ast == nil and s.typ.kind != tyCompositeTypeClass:
|
if s.ast == nil and s.typ.kind != tyCompositeTypeClass:
|
||||||
# XXX: What kind of error is this? is it still relevant?
|
# XXX: What kind of error is this? is it still relevant?
|
||||||
|
|
@ -1081,7 +1081,7 @@ proc semTypeClass(c: PContext, n: PNode, prev: PType): PType =
|
||||||
let
|
let
|
||||||
pragmas = n[1]
|
pragmas = n[1]
|
||||||
inherited = n[2]
|
inherited = n[2]
|
||||||
|
|
||||||
if inherited.kind != nkEmpty:
|
if inherited.kind != nkEmpty:
|
||||||
for n in inherited.sons:
|
for n in inherited.sons:
|
||||||
let typ = semTypeNode(c, n, nil)
|
let typ = semTypeNode(c, n, nil)
|
||||||
|
|
@ -1114,7 +1114,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
checkSonsLen(n, 1)
|
checkSonsLen(n, 1)
|
||||||
let typExpr = semExprWithType(c, n.sons[0], {efInTypeof})
|
let typExpr = semExprWithType(c, n.sons[0], {efInTypeof})
|
||||||
result = typExpr.typ.skipTypes({tyIter})
|
result = typExpr.typ.skipTypes({tyIter})
|
||||||
of nkPar:
|
of nkPar:
|
||||||
if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev)
|
if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev)
|
||||||
else:
|
else:
|
||||||
# XXX support anon tuple here
|
# XXX support anon tuple here
|
||||||
|
|
@ -1197,7 +1197,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
result = makeTypeFromExpr(c, preprocessed.copyTree)
|
result = makeTypeFromExpr(c, preprocessed.copyTree)
|
||||||
of nkIdent, nkAccQuoted:
|
of nkIdent, nkAccQuoted:
|
||||||
var s = semTypeIdent(c, n)
|
var s = semTypeIdent(c, n)
|
||||||
if s.typ == nil:
|
if s.typ == nil:
|
||||||
if s.kind != skError: localError(n.info, errTypeExpected)
|
if s.kind != skError: localError(n.info, errTypeExpected)
|
||||||
result = newOrPrevType(tyError, prev, c)
|
result = newOrPrevType(tyError, prev, c)
|
||||||
elif s.kind == skParam and s.typ.kind == tyTypeDesc:
|
elif s.kind == skParam and s.typ.kind == tyTypeDesc:
|
||||||
|
|
@ -1205,19 +1205,19 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
result = s.typ.base
|
result = s.typ.base
|
||||||
elif prev == nil:
|
elif prev == nil:
|
||||||
result = s.typ
|
result = s.typ
|
||||||
else:
|
else:
|
||||||
assignType(prev, s.typ)
|
assignType(prev, s.typ)
|
||||||
# bugfix: keep the fresh id for aliases to integral types:
|
# bugfix: keep the fresh id for aliases to integral types:
|
||||||
if s.typ.kind notin {tyBool, tyChar, tyInt..tyInt64, tyFloat..tyFloat128,
|
if s.typ.kind notin {tyBool, tyChar, tyInt..tyInt64, tyFloat..tyFloat128,
|
||||||
tyUInt..tyUInt64}:
|
tyUInt..tyUInt64}:
|
||||||
prev.id = s.typ.id
|
prev.id = s.typ.id
|
||||||
result = prev
|
result = prev
|
||||||
of nkSym:
|
of nkSym:
|
||||||
if n.sym.kind == skType and n.sym.typ != nil:
|
if n.sym.kind == skType and n.sym.typ != nil:
|
||||||
var t = n.sym.typ
|
var t = n.sym.typ
|
||||||
if prev == nil:
|
if prev == nil:
|
||||||
result = t
|
result = t
|
||||||
else:
|
else:
|
||||||
assignType(prev, t)
|
assignType(prev, t)
|
||||||
result = prev
|
result = prev
|
||||||
markUsed(n.info, n.sym)
|
markUsed(n.info, n.sym)
|
||||||
|
|
@ -1267,12 +1267,12 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
result = newOrPrevType(tyError, prev, c)
|
result = newOrPrevType(tyError, prev, c)
|
||||||
n.typ = result
|
n.typ = result
|
||||||
|
|
||||||
proc setMagicType(m: PSym, kind: TTypeKind, size: int) =
|
proc setMagicType(m: PSym, kind: TTypeKind, size: int) =
|
||||||
m.typ.kind = kind
|
m.typ.kind = kind
|
||||||
m.typ.align = size.int16
|
m.typ.align = size.int16
|
||||||
m.typ.size = size
|
m.typ.size = size
|
||||||
|
|
||||||
proc processMagicType(c: PContext, m: PSym) =
|
proc processMagicType(c: PContext, m: PSym) =
|
||||||
case m.magic
|
case m.magic
|
||||||
of mInt: setMagicType(m, tyInt, intSize)
|
of mInt: setMagicType(m, tyInt, intSize)
|
||||||
of mInt8: setMagicType(m, tyInt8, 1)
|
of mInt8: setMagicType(m, tyInt8, 1)
|
||||||
|
|
@ -1290,21 +1290,21 @@ proc processMagicType(c: PContext, m: PSym) =
|
||||||
of mFloat128: setMagicType(m, tyFloat128, 16)
|
of mFloat128: setMagicType(m, tyFloat128, 16)
|
||||||
of mBool: setMagicType(m, tyBool, 1)
|
of mBool: setMagicType(m, tyBool, 1)
|
||||||
of mChar: setMagicType(m, tyChar, 1)
|
of mChar: setMagicType(m, tyChar, 1)
|
||||||
of mString:
|
of mString:
|
||||||
setMagicType(m, tyString, ptrSize)
|
setMagicType(m, tyString, ptrSize)
|
||||||
rawAddSon(m.typ, getSysType(tyChar))
|
rawAddSon(m.typ, getSysType(tyChar))
|
||||||
of mCstring:
|
of mCstring:
|
||||||
setMagicType(m, tyCString, ptrSize)
|
setMagicType(m, tyCString, ptrSize)
|
||||||
rawAddSon(m.typ, getSysType(tyChar))
|
rawAddSon(m.typ, getSysType(tyChar))
|
||||||
of mPointer: setMagicType(m, tyPointer, ptrSize)
|
of mPointer: setMagicType(m, tyPointer, ptrSize)
|
||||||
of mEmptySet:
|
of mEmptySet:
|
||||||
setMagicType(m, tySet, 1)
|
setMagicType(m, tySet, 1)
|
||||||
rawAddSon(m.typ, newTypeS(tyEmpty, c))
|
rawAddSon(m.typ, newTypeS(tyEmpty, c))
|
||||||
of mIntSetBaseType: setMagicType(m, tyRange, intSize)
|
of mIntSetBaseType: setMagicType(m, tyRange, intSize)
|
||||||
of mNil: setMagicType(m, tyNil, ptrSize)
|
of mNil: setMagicType(m, tyNil, ptrSize)
|
||||||
of mExpr: setMagicType(m, tyExpr, 0)
|
of mExpr: setMagicType(m, tyExpr, 0)
|
||||||
of mStmt: setMagicType(m, tyStmt, 0)
|
of mStmt: setMagicType(m, tyStmt, 0)
|
||||||
of mTypeDesc:
|
of mTypeDesc:
|
||||||
setMagicType(m, tyTypeDesc, 0)
|
setMagicType(m, tyTypeDesc, 0)
|
||||||
rawAddSon(m.typ, newTypeS(tyNone, c))
|
rawAddSon(m.typ, newTypeS(tyNone, c))
|
||||||
of mVoidType: setMagicType(m, tyEmpty, 0)
|
of mVoidType: setMagicType(m, tyEmpty, 0)
|
||||||
|
|
@ -1318,8 +1318,8 @@ proc processMagicType(c: PContext, m: PSym) =
|
||||||
setMagicType(m, tyRange, 0)
|
setMagicType(m, tyRange, 0)
|
||||||
rawAddSon(m.typ, newTypeS(tyNone, c))
|
rawAddSon(m.typ, newTypeS(tyNone, c))
|
||||||
of mSet:
|
of mSet:
|
||||||
setMagicType(m, tySet, 0)
|
setMagicType(m, tySet, 0)
|
||||||
of mSeq:
|
of mSeq:
|
||||||
setMagicType(m, tySequence, 0)
|
setMagicType(m, tySequence, 0)
|
||||||
of mOrdinal:
|
of mOrdinal:
|
||||||
setMagicType(m, tyOrdinal, 0)
|
setMagicType(m, tyOrdinal, 0)
|
||||||
|
|
@ -1335,13 +1335,13 @@ proc processMagicType(c: PContext, m: PSym) =
|
||||||
incl m.typ.flags, tfShared
|
incl m.typ.flags, tfShared
|
||||||
rawAddSon(m.typ, sysTypeFromName"shared")
|
rawAddSon(m.typ, sysTypeFromName"shared")
|
||||||
else: localError(m.info, errTypeExpected)
|
else: localError(m.info, errTypeExpected)
|
||||||
|
|
||||||
proc semGenericConstraints(c: PContext, x: PType): PType =
|
proc semGenericConstraints(c: PContext, x: PType): PType =
|
||||||
result = newTypeWithSons(c, tyGenericParam, @[x])
|
result = newTypeWithSons(c, tyGenericParam, @[x])
|
||||||
|
|
||||||
proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode =
|
proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode =
|
||||||
result = copyNode(n)
|
result = copyNode(n)
|
||||||
if n.kind != nkGenericParams:
|
if n.kind != nkGenericParams:
|
||||||
illFormedAst(n)
|
illFormedAst(n)
|
||||||
return
|
return
|
||||||
for i in countup(0, sonsLen(n)-1):
|
for i in countup(0, sonsLen(n)-1):
|
||||||
|
|
@ -1351,7 +1351,7 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode =
|
||||||
var def = a{-1}
|
var def = a{-1}
|
||||||
let constraint = a{-2}
|
let constraint = a{-2}
|
||||||
var typ: PType
|
var typ: PType
|
||||||
|
|
||||||
if constraint.kind != nkEmpty:
|
if constraint.kind != nkEmpty:
|
||||||
typ = semTypeNode(c, constraint, nil)
|
typ = semTypeNode(c, constraint, nil)
|
||||||
if typ.kind != tyStatic or typ.len == 0:
|
if typ.kind != tyStatic or typ.len == 0:
|
||||||
|
|
@ -1360,7 +1360,7 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode =
|
||||||
typ = newTypeWithSons(c, tyTypeDesc, @[newTypeS(tyNone, c)])
|
typ = newTypeWithSons(c, tyTypeDesc, @[newTypeS(tyNone, c)])
|
||||||
else:
|
else:
|
||||||
typ = semGenericConstraints(c, typ)
|
typ = semGenericConstraints(c, typ)
|
||||||
|
|
||||||
if def.kind != nkEmpty:
|
if def.kind != nkEmpty:
|
||||||
def = semConstExpr(c, def)
|
def = semConstExpr(c, def)
|
||||||
if typ == nil:
|
if typ == nil:
|
||||||
|
|
@ -1372,7 +1372,7 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode =
|
||||||
def.typ = def.typ.skipTypes({tyTypeDesc})
|
def.typ = def.typ.skipTypes({tyTypeDesc})
|
||||||
if not containsGenericType(def.typ):
|
if not containsGenericType(def.typ):
|
||||||
def = fitNode(c, typ, def)
|
def = fitNode(c, typ, def)
|
||||||
|
|
||||||
if typ == nil:
|
if typ == nil:
|
||||||
typ = newTypeS(tyGenericParam, c)
|
typ = newTypeS(tyGenericParam, c)
|
||||||
if father == nil: typ.flags.incl tfWildcard
|
if father == nil: typ.flags.incl tfWildcard
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue