fixes #42
This commit is contained in:
parent
f0145ba7c5
commit
7a6140e3a4
5 changed files with 127 additions and 118 deletions
|
|
@ -227,9 +227,9 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
||||||
var isConcrete = true # iterate over arguments:
|
var isConcrete = true # iterate over arguments:
|
||||||
for i in countup(1, sonsLen(n)-1):
|
for i in countup(1, sonsLen(n)-1):
|
||||||
var elem = semTypeNode(c, n.sons[i], nil)
|
var elem = semTypeNode(c, n.sons[i], nil)
|
||||||
if elem.kind == tyGenericParam: isConcrete = false
|
if elem.kind in {tyGenericParam, tyGenericInvokation}: isConcrete = false
|
||||||
addSon(result, elem)
|
addSon(result, elem)
|
||||||
if isConcrete:
|
if isConcrete:
|
||||||
if s.ast == nil: GlobalError(n.info, errCannotInstantiateX, s.name.s)
|
if s.ast == nil: GlobalError(n.info, errCannotInstantiateX, s.name.s)
|
||||||
result = instGenericContainer(c, n, result)
|
result = instGenericContainer(c, n, result)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,10 @@ import ast, astalgo, msgs, types, semdata
|
||||||
proc checkConstructedType*(info: TLineInfo, t: PType) =
|
proc checkConstructedType*(info: TLineInfo, t: PType) =
|
||||||
if tfAcyclic in t.flags and skipTypes(t, abstractInst).kind != tyObject:
|
if tfAcyclic in t.flags and skipTypes(t, abstractInst).kind != tyObject:
|
||||||
LocalError(info, errInvalidPragmaX, "acyclic")
|
LocalError(info, errInvalidPragmaX, "acyclic")
|
||||||
elif computeSize(t) < 0:
|
|
||||||
LocalError(info, errIllegalRecursionInTypeX, typeToString(t))
|
|
||||||
elif t.kind == tyVar and t.sons[0].kind == tyVar:
|
elif t.kind == tyVar and t.sons[0].kind == tyVar:
|
||||||
LocalError(info, errVarVarTypeNotAllowed)
|
LocalError(info, errVarVarTypeNotAllowed)
|
||||||
|
elif computeSize(t) < 0:
|
||||||
|
LocalError(info, errIllegalRecursionInTypeX, typeToString(t))
|
||||||
when false:
|
when false:
|
||||||
if t.kind == tyObject and t.sons[0] != nil:
|
if t.kind == tyObject and t.sons[0] != nil:
|
||||||
if t.sons[0].kind != tyObject or tfFinal in t.sons[0].flags:
|
if t.sons[0].kind != tyObject or tfFinal in t.sons[0].flags:
|
||||||
|
|
@ -91,17 +91,16 @@ proc lookupTypeVar(cl: TReplTypeVars, t: PType): PType =
|
||||||
elif result.kind == tyGenericParam:
|
elif result.kind == tyGenericParam:
|
||||||
InternalError(cl.info, "substitution with generic parameter")
|
InternalError(cl.info, "substitution with generic parameter")
|
||||||
|
|
||||||
proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
|
proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType =
|
||||||
result = t
|
var body = t.sons[0]
|
||||||
if t == nil: return
|
if body.kind != tyGenericBody: InternalError(cl.info, "no generic body")
|
||||||
case t.kind
|
var header: PType = nil
|
||||||
of tyGenericParam:
|
for i in countup(1, sonsLen(t) - 1):
|
||||||
result = lookupTypeVar(cl, t)
|
var x = replaceTypeVarsT(cl, t.sons[i])
|
||||||
of tyGenericInvokation:
|
if t.sons[i].kind == tyGenericParam:
|
||||||
var body = t.sons[0]
|
if header == nil: header = copyType(t, t.owner, false)
|
||||||
if body.kind != tyGenericBody: InternalError(cl.info, "no generic body")
|
header.sons[i] = x
|
||||||
var header: PType = nil
|
when false:
|
||||||
for i in countup(1, sonsLen(t) - 1):
|
|
||||||
var x: PType
|
var x: PType
|
||||||
if t.sons[i].kind == tyGenericParam:
|
if t.sons[i].kind == tyGenericParam:
|
||||||
x = lookupTypeVar(cl, t.sons[i])
|
x = lookupTypeVar(cl, t.sons[i])
|
||||||
|
|
@ -109,22 +108,33 @@ proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
|
||||||
header.sons[i] = x
|
header.sons[i] = x
|
||||||
else:
|
else:
|
||||||
x = t.sons[i]
|
x = t.sons[i]
|
||||||
idTablePut(cl.typeMap, body.sons[i-1], x)
|
idTablePut(cl.typeMap, body.sons[i-1], x)
|
||||||
if header == nil: header = t
|
if header == nil: header = t
|
||||||
result = searchInstTypes(gInstTypes, header)
|
result = searchInstTypes(gInstTypes, header)
|
||||||
if result != nil: return
|
if result != nil: return
|
||||||
result = newType(tyGenericInst, t.sons[0].owner)
|
result = newType(tyGenericInst, t.sons[0].owner)
|
||||||
for i in countup(0, sonsLen(t) - 1):
|
for i in countup(0, sonsLen(t) - 1):
|
||||||
# if one of the params is not concrete, we cannot do anything
|
# if one of the params is not concrete, we cannot do anything
|
||||||
# but we already raised an error!
|
# but we already raised an error!
|
||||||
addSon(result, header.sons[i])
|
addSon(result, header.sons[i])
|
||||||
idTablePut(gInstTypes, header, result)
|
idTablePut(gInstTypes, header, result)
|
||||||
var newbody = ReplaceTypeVarsT(cl, lastSon(body))
|
var newbody = ReplaceTypeVarsT(cl, lastSon(body))
|
||||||
newbody.flags = newbody.flags + t.flags + body.flags
|
newbody.flags = newbody.flags + t.flags + body.flags
|
||||||
newbody.n = ReplaceTypeVarsN(cl, lastSon(body).n)
|
newbody.n = ReplaceTypeVarsN(cl, lastSon(body).n)
|
||||||
addSon(result, newbody)
|
addSon(result, newbody)
|
||||||
#writeln(output, ropeToStr(Typetoyaml(newbody)));
|
#writeln(output, ropeToStr(Typetoyaml(newbody)));
|
||||||
checkConstructedType(cl.info, newbody)
|
checkConstructedType(cl.info, newbody)
|
||||||
|
|
||||||
|
proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
|
||||||
|
result = t
|
||||||
|
if t == nil: return
|
||||||
|
case t.kind
|
||||||
|
of tyGenericParam:
|
||||||
|
result = lookupTypeVar(cl, t)
|
||||||
|
if result.kind == tyGenericInvokation:
|
||||||
|
result = handleGenericInvokation(cl, result)
|
||||||
|
of tyGenericInvokation:
|
||||||
|
result = handleGenericInvokation(cl, t)
|
||||||
of tyGenericBody:
|
of tyGenericBody:
|
||||||
InternalError(cl.info, "ReplaceTypeVarsT: tyGenericBody")
|
InternalError(cl.info, "ReplaceTypeVarsT: tyGenericBody")
|
||||||
result = ReplaceTypeVarsT(cl, lastSon(t))
|
result = ReplaceTypeVarsT(cl, lastSon(t))
|
||||||
|
|
|
||||||
|
|
@ -96,23 +96,22 @@ proc inheritanceDiff(a, b: PType): int =
|
||||||
# conversion to superclass?
|
# conversion to superclass?
|
||||||
var x = a
|
var x = a
|
||||||
result = 0
|
result = 0
|
||||||
while (x != nil):
|
while x != nil:
|
||||||
if x.id == b.id: return
|
if x.id == b.id: return
|
||||||
x = x.sons[0]
|
x = x.sons[0]
|
||||||
dec(result)
|
dec(result)
|
||||||
var y = b
|
var y = b
|
||||||
result = 0
|
result = 0
|
||||||
while (y != nil):
|
while y != nil:
|
||||||
if y.id == a.id: return
|
if y.id == a.id: return
|
||||||
y = y.sons[0]
|
y = y.sons[0]
|
||||||
inc(result)
|
inc(result)
|
||||||
result = high(int)
|
result = high(int)
|
||||||
|
|
||||||
proc isPureObject(typ: PType): bool =
|
proc isPureObject(typ: PType): bool =
|
||||||
var t: PType
|
var t = typ
|
||||||
t = typ
|
|
||||||
while t.sons[0] != nil: t = t.sons[0]
|
while t.sons[0] != nil: t = t.sons[0]
|
||||||
result = (t.sym != nil) and (sfPure in t.sym.flags)
|
result = t.sym != nil and sfPure in t.sym.flags
|
||||||
|
|
||||||
proc getOrdValue(n: PNode): biggestInt =
|
proc getOrdValue(n: PNode): biggestInt =
|
||||||
case n.kind
|
case n.kind
|
||||||
|
|
@ -135,13 +134,13 @@ proc getProcHeader(sym: PSym): string =
|
||||||
var n = sym.typ.n
|
var n = sym.typ.n
|
||||||
for i in countup(1, sonsLen(n) - 1):
|
for i in countup(1, sonsLen(n) - 1):
|
||||||
var p = n.sons[i]
|
var p = n.sons[i]
|
||||||
if (p.kind != nkSym): InternalError("getProcHeader")
|
if p.kind != nkSym: InternalError("getProcHeader")
|
||||||
add(result, p.sym.name.s)
|
add(result, p.sym.name.s)
|
||||||
add(result, ": ")
|
add(result, ": ")
|
||||||
add(result, typeToString(p.sym.typ))
|
add(result, typeToString(p.sym.typ))
|
||||||
if i != sonsLen(n) - 1: add(result, ", ")
|
if i != sonsLen(n)-1: add(result, ", ")
|
||||||
add(result, ')')
|
add(result, ')')
|
||||||
if n.sons[0].typ != nil: result = result & ": " & typeToString(n.sons[0].typ)
|
if n.sons[0].typ != nil: result.add(": " & typeToString(n.sons[0].typ))
|
||||||
|
|
||||||
proc elemType(t: PType): PType =
|
proc elemType(t: PType): PType =
|
||||||
assert(t != nil)
|
assert(t != nil)
|
||||||
|
|
@ -258,7 +257,8 @@ proc searchTypeNodeForAux(n: PNode, p: TTypePredicate,
|
||||||
result = searchTypeForAux(n.sym.typ, p, marker)
|
result = searchTypeForAux(n.sym.typ, p, marker)
|
||||||
else: internalError(n.info, "searchTypeNodeForAux()")
|
else: internalError(n.info, "searchTypeNodeForAux()")
|
||||||
|
|
||||||
proc searchTypeForAux(t: PType, predicate: TTypePredicate, marker: var TIntSet): bool =
|
proc searchTypeForAux(t: PType, predicate: TTypePredicate,
|
||||||
|
marker: var TIntSet): bool =
|
||||||
# iterates over VALUE types!
|
# iterates over VALUE types!
|
||||||
result = false
|
result = false
|
||||||
if t == nil: return
|
if t == nil: return
|
||||||
|
|
@ -293,7 +293,8 @@ proc isObjectWithTypeFieldPredicate(t: PType): bool =
|
||||||
not ((t.sym != nil) and (sfPure in t.sym.flags)) and
|
not ((t.sym != nil) and (sfPure in t.sym.flags)) and
|
||||||
not (tfFinal in t.flags)
|
not (tfFinal in t.flags)
|
||||||
|
|
||||||
proc analyseObjectWithTypeFieldAux(t: PType, marker: var TIntSet): TTypeFieldResult =
|
proc analyseObjectWithTypeFieldAux(t: PType,
|
||||||
|
marker: var TIntSet): TTypeFieldResult =
|
||||||
var res: TTypeFieldResult
|
var res: TTypeFieldResult
|
||||||
result = frNone
|
result = frNone
|
||||||
if t == nil: return
|
if t == nil: return
|
||||||
|
|
@ -430,7 +431,7 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||||
var t = typ
|
var t = typ
|
||||||
result = ""
|
result = ""
|
||||||
if t == nil: return
|
if t == nil: return
|
||||||
if (prefer == preferName) and (t.sym != nil):
|
if prefer == preferName and t.sym != nil:
|
||||||
return t.sym.Name.s
|
return t.sym.Name.s
|
||||||
case t.Kind
|
case t.Kind
|
||||||
of tyGenericBody, tyGenericInst, tyGenericInvokation:
|
of tyGenericBody, tyGenericInst, tyGenericInvokation:
|
||||||
|
|
@ -506,12 +507,9 @@ proc base(t: PType): PType =
|
||||||
|
|
||||||
proc firstOrd(t: PType): biggestInt =
|
proc firstOrd(t: PType): biggestInt =
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyBool, tyChar, tySequence, tyOpenArray, tyString:
|
of tyBool, tyChar, tySequence, tyOpenArray, tyString: result = 0
|
||||||
result = 0
|
of tySet, tyVar: result = firstOrd(t.sons[0])
|
||||||
of tySet, tyVar:
|
of tyArray, tyArrayConstr: result = firstOrd(t.sons[0])
|
||||||
result = firstOrd(t.sons[0])
|
|
||||||
of tyArray, tyArrayConstr:
|
|
||||||
result = firstOrd(t.sons[0])
|
|
||||||
of tyRange:
|
of tyRange:
|
||||||
assert(t.n != nil) # range directly given:
|
assert(t.n != nil) # range directly given:
|
||||||
assert(t.n.kind == nkRange)
|
assert(t.n.kind == nkRange)
|
||||||
|
|
@ -519,14 +517,10 @@ proc firstOrd(t: PType): biggestInt =
|
||||||
of tyInt:
|
of tyInt:
|
||||||
if platform.intSize == 4: result = - (2147483646) - 2
|
if platform.intSize == 4: result = - (2147483646) - 2
|
||||||
else: result = 0x8000000000000000'i64
|
else: result = 0x8000000000000000'i64
|
||||||
of tyInt8:
|
of tyInt8: result = - 128
|
||||||
result = - 128
|
of tyInt16: result = - 32768
|
||||||
of tyInt16:
|
of tyInt32: result = - 2147483646 - 2
|
||||||
result = - 32768
|
of tyInt64: result = 0x8000000000000000'i64
|
||||||
of tyInt32:
|
|
||||||
result = - 2147483646 - 2
|
|
||||||
of tyInt64:
|
|
||||||
result = 0x8000000000000000'i64
|
|
||||||
of tyEnum:
|
of tyEnum:
|
||||||
# if basetype <> nil then return firstOrd of basetype
|
# if basetype <> nil then return firstOrd of basetype
|
||||||
if (sonsLen(t) > 0) and (t.sons[0] != nil):
|
if (sonsLen(t) > 0) and (t.sons[0] != nil):
|
||||||
|
|
@ -534,22 +528,17 @@ proc firstOrd(t: PType): biggestInt =
|
||||||
else:
|
else:
|
||||||
assert(t.n.sons[0].kind == nkSym)
|
assert(t.n.sons[0].kind == nkSym)
|
||||||
result = t.n.sons[0].sym.position
|
result = t.n.sons[0].sym.position
|
||||||
of tyGenericInst, tyDistinct:
|
of tyGenericInst, tyDistinct: result = firstOrd(lastSon(t))
|
||||||
result = firstOrd(lastSon(t))
|
|
||||||
else:
|
else:
|
||||||
InternalError("invalid kind for first(" & $t.kind & ')')
|
InternalError("invalid kind for first(" & $t.kind & ')')
|
||||||
result = 0
|
result = 0
|
||||||
|
|
||||||
proc lastOrd(t: PType): biggestInt =
|
proc lastOrd(t: PType): biggestInt =
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyBool:
|
of tyBool: result = 1
|
||||||
result = 1
|
of tyChar: result = 255
|
||||||
of tyChar:
|
of tySet, tyVar: result = lastOrd(t.sons[0])
|
||||||
result = 255
|
of tyArray, tyArrayConstr: result = lastOrd(t.sons[0])
|
||||||
of tySet, tyVar:
|
|
||||||
result = lastOrd(t.sons[0])
|
|
||||||
of tyArray, tyArrayConstr:
|
|
||||||
result = lastOrd(t.sons[0])
|
|
||||||
of tyRange:
|
of tyRange:
|
||||||
assert(t.n != nil) # range directly given:
|
assert(t.n != nil) # range directly given:
|
||||||
assert(t.n.kind == nkRange)
|
assert(t.n.kind == nkRange)
|
||||||
|
|
@ -557,19 +546,14 @@ proc lastOrd(t: PType): biggestInt =
|
||||||
of tyInt:
|
of tyInt:
|
||||||
if platform.intSize == 4: result = 0x7FFFFFFF
|
if platform.intSize == 4: result = 0x7FFFFFFF
|
||||||
else: result = 0x7FFFFFFFFFFFFFFF'i64
|
else: result = 0x7FFFFFFFFFFFFFFF'i64
|
||||||
of tyInt8:
|
of tyInt8: result = 0x0000007F
|
||||||
result = 0x0000007F
|
of tyInt16: result = 0x00007FFF
|
||||||
of tyInt16:
|
of tyInt32: result = 0x7FFFFFFF
|
||||||
result = 0x00007FFF
|
of tyInt64: result = 0x7FFFFFFFFFFFFFFF'i64
|
||||||
of tyInt32:
|
|
||||||
result = 0x7FFFFFFF
|
|
||||||
of tyInt64:
|
|
||||||
result = 0x7FFFFFFFFFFFFFFF'i64
|
|
||||||
of tyEnum:
|
of tyEnum:
|
||||||
assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym)
|
assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym)
|
||||||
result = t.n.sons[sonsLen(t.n) - 1].sym.position
|
result = t.n.sons[sonsLen(t.n) - 1].sym.position
|
||||||
of tyGenericInst, tyDistinct:
|
of tyGenericInst, tyDistinct: result = lastOrd(lastSon(t))
|
||||||
result = firstOrd(lastSon(t))
|
|
||||||
else:
|
else:
|
||||||
InternalError("invalid kind for last(" & $t.kind & ')')
|
InternalError("invalid kind for last(" & $t.kind & ')')
|
||||||
result = 0
|
result = 0
|
||||||
|
|
@ -666,8 +650,7 @@ proc sameTuple(a, b: PType, DistinctOf: bool): bool =
|
||||||
result = false
|
result = false
|
||||||
|
|
||||||
proc SameType(x, y: PType): bool =
|
proc SameType(x, y: PType): bool =
|
||||||
if x == y:
|
if x == y: return true
|
||||||
return true
|
|
||||||
var a = skipTypes(x, {tyGenericInst})
|
var a = skipTypes(x, {tyGenericInst})
|
||||||
var b = skipTypes(y, {tyGenericInst})
|
var b = skipTypes(y, {tyGenericInst})
|
||||||
assert(a != nil)
|
assert(a != nil)
|
||||||
|
|
@ -678,12 +661,9 @@ proc SameType(x, y: PType): bool =
|
||||||
of tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString,
|
of tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString,
|
||||||
tyInt..tyFloat128, tyExpr, tyStmt, tyTypeDesc:
|
tyInt..tyFloat128, tyExpr, tyStmt, tyTypeDesc:
|
||||||
result = true
|
result = true
|
||||||
of tyEnum, tyForward, tyObject, tyDistinct:
|
of tyEnum, tyForward, tyObject, tyDistinct: result = (a.id == b.id)
|
||||||
result = (a.id == b.id)
|
of tyTuple: result = sameTuple(a, b, false)
|
||||||
of tyTuple:
|
of tyGenericInst: result = sameType(lastSon(a), lastSon(b))
|
||||||
result = sameTuple(a, b, false)
|
|
||||||
of tyGenericInst:
|
|
||||||
result = sameType(lastSon(a), lastSon(b))
|
|
||||||
of tyGenericParam, tyGenericInvokation, tyGenericBody, tySequence, tyOrdinal,
|
of tyGenericParam, tyGenericInvokation, tyGenericBody, tySequence, tyOrdinal,
|
||||||
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyArray, tyProc:
|
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyArray, tyProc:
|
||||||
if sonsLen(a) == sonsLen(b):
|
if sonsLen(a) == sonsLen(b):
|
||||||
|
|
@ -699,14 +679,11 @@ proc SameType(x, y: PType): bool =
|
||||||
result = SameTypeOrNil(a.sons[0], b.sons[0]) and
|
result = SameTypeOrNil(a.sons[0], b.sons[0]) and
|
||||||
SameValue(a.n.sons[0], b.n.sons[0]) and
|
SameValue(a.n.sons[0], b.n.sons[0]) and
|
||||||
SameValue(a.n.sons[1], b.n.sons[1])
|
SameValue(a.n.sons[1], b.n.sons[1])
|
||||||
of tyNone:
|
of tyNone: result = false
|
||||||
result = false
|
|
||||||
|
|
||||||
proc equalOrDistinctOf(x, y: PType): bool =
|
proc equalOrDistinctOf(x, y: PType): bool =
|
||||||
if x == y:
|
if x == y: return true
|
||||||
return true
|
if x == nil or y == nil: return false
|
||||||
if (x == nil) or (y == nil):
|
|
||||||
return false
|
|
||||||
var a = skipTypes(x, {tyGenericInst})
|
var a = skipTypes(x, {tyGenericInst})
|
||||||
var b = skipTypes(y, {tyGenericInst})
|
var b = skipTypes(y, {tyGenericInst})
|
||||||
assert(a != nil)
|
assert(a != nil)
|
||||||
|
|
@ -719,12 +696,9 @@ proc equalOrDistinctOf(x, y: PType): bool =
|
||||||
of tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString,
|
of tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString,
|
||||||
tyInt..tyFloat128, tyExpr, tyStmt, tyTypeDesc:
|
tyInt..tyFloat128, tyExpr, tyStmt, tyTypeDesc:
|
||||||
result = true
|
result = true
|
||||||
of tyEnum, tyForward, tyObject, tyDistinct:
|
of tyEnum, tyForward, tyObject, tyDistinct: result = (a.id == b.id)
|
||||||
result = (a.id == b.id)
|
of tyTuple: result = sameTuple(a, b, true)
|
||||||
of tyTuple:
|
of tyGenericInst: result = equalOrDistinctOf(lastSon(a), lastSon(b))
|
||||||
result = sameTuple(a, b, true)
|
|
||||||
of tyGenericInst:
|
|
||||||
result = equalOrDistinctOf(lastSon(a), lastSon(b))
|
|
||||||
of tyGenericParam, tyGenericInvokation, tyGenericBody, tySequence, tyOrdinal,
|
of tyGenericParam, tyGenericInvokation, tyGenericBody, tySequence, tyOrdinal,
|
||||||
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyArray, tyProc:
|
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyArray, tyProc:
|
||||||
if sonsLen(a) == sonsLen(b):
|
if sonsLen(a) == sonsLen(b):
|
||||||
|
|
@ -739,8 +713,7 @@ proc equalOrDistinctOf(x, y: PType): bool =
|
||||||
result = equalOrDistinctOf(a.sons[0], b.sons[0]) and
|
result = equalOrDistinctOf(a.sons[0], b.sons[0]) and
|
||||||
SameValue(a.n.sons[0], b.n.sons[0]) and
|
SameValue(a.n.sons[0], b.n.sons[0]) and
|
||||||
SameValue(a.n.sons[1], b.n.sons[1])
|
SameValue(a.n.sons[1], b.n.sons[1])
|
||||||
of tyNone:
|
of tyNone: result = false
|
||||||
result = false
|
|
||||||
|
|
||||||
proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool
|
proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool
|
||||||
proc typeAllowedNode(marker: var TIntSet, n: PNode, kind: TSymKind): bool =
|
proc typeAllowedNode(marker: var TIntSet, n: PNode, kind: TSymKind): bool =
|
||||||
|
|
@ -835,8 +808,7 @@ proc computeRecSizeAux(n: PNode, a, currOffset: var biggestInt): biggestInt =
|
||||||
case n.sons[i].kind
|
case n.sons[i].kind
|
||||||
of nkOfBranch, nkElse:
|
of nkOfBranch, nkElse:
|
||||||
res = computeRecSizeAux(lastSon(n.sons[i]), b, currOffset)
|
res = computeRecSizeAux(lastSon(n.sons[i]), b, currOffset)
|
||||||
if res < 0:
|
if res < 0: return res
|
||||||
return res
|
|
||||||
maxSize = max(maxSize, res)
|
maxSize = max(maxSize, res)
|
||||||
maxAlign = max(maxAlign, b)
|
maxAlign = max(maxAlign, b)
|
||||||
else: internalError("computeRecSizeAux(record case branch)")
|
else: internalError("computeRecSizeAux(record case branch)")
|
||||||
|
|
@ -848,8 +820,7 @@ proc computeRecSizeAux(n: PNode, a, currOffset: var biggestInt): biggestInt =
|
||||||
maxAlign = 1
|
maxAlign = 1
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
res = computeRecSizeAux(n.sons[i], b, currOffset)
|
res = computeRecSizeAux(n.sons[i], b, currOffset)
|
||||||
if res < 0:
|
if res < 0: return res
|
||||||
return res
|
|
||||||
currOffset = align(currOffset, b) + res
|
currOffset = align(currOffset, b) + res
|
||||||
result = align(result, b) + res
|
result = align(result, b) + res
|
||||||
if b > maxAlign: maxAlign = b
|
if b > maxAlign: maxAlign = b
|
||||||
|
|
@ -914,18 +885,12 @@ proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt =
|
||||||
a = result
|
a = result
|
||||||
of tySet:
|
of tySet:
|
||||||
length = lengthOrd(typ.sons[0])
|
length = lengthOrd(typ.sons[0])
|
||||||
if length <= 8:
|
if length <= 8: result = 1
|
||||||
result = 1
|
elif length <= 16: result = 2
|
||||||
elif length <= 16:
|
elif length <= 32: result = 4
|
||||||
result = 2
|
elif length <= 64: result = 8
|
||||||
elif length <= 32:
|
elif align(length, 8) mod 8 == 0: result = align(length, 8) div 8
|
||||||
result = 4
|
else: result = align(length, 8) div 8 + 1
|
||||||
elif length <= 64:
|
|
||||||
result = 8
|
|
||||||
elif align(length, 8) mod 8 == 0:
|
|
||||||
result = align(length, 8) div 8
|
|
||||||
else:
|
|
||||||
result = align(length, 8) div 8 + 1 # BUGFIX!
|
|
||||||
a = result
|
a = result
|
||||||
of tyRange:
|
of tyRange:
|
||||||
result = computeSizeAux(typ.sons[0], a)
|
result = computeSizeAux(typ.sons[0], a)
|
||||||
|
|
@ -934,8 +899,7 @@ proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt =
|
||||||
maxAlign = 1
|
maxAlign = 1
|
||||||
for i in countup(0, sonsLen(typ) - 1):
|
for i in countup(0, sonsLen(typ) - 1):
|
||||||
res = computeSizeAux(typ.sons[i], a)
|
res = computeSizeAux(typ.sons[i], a)
|
||||||
if res < 0:
|
if res < 0: return res
|
||||||
return res
|
|
||||||
maxAlign = max(maxAlign, a)
|
maxAlign = max(maxAlign, a)
|
||||||
result = align(result, a) + res
|
result = align(result, a) + res
|
||||||
result = align(result, maxAlign)
|
result = align(result, maxAlign)
|
||||||
|
|
@ -959,7 +923,7 @@ proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt =
|
||||||
of tyGenericInst, tyDistinct, tyGenericBody:
|
of tyGenericInst, tyDistinct, tyGenericBody:
|
||||||
result = computeSizeAux(lastSon(typ), a)
|
result = computeSizeAux(lastSon(typ), a)
|
||||||
else:
|
else:
|
||||||
#internalError('computeSizeAux()');
|
#internalError("computeSizeAux()")
|
||||||
result = - 1
|
result = - 1
|
||||||
typ.size = result
|
typ.size = result
|
||||||
typ.align = int(a)
|
typ.align = int(a)
|
||||||
|
|
|
||||||
35
tests/accept/compile/tthread_generic.nim
Normal file
35
tests/accept/compile/tthread_generic.nim
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
type
|
||||||
|
TThreadFuncArgs[T] = object of TObject
|
||||||
|
a: proc(): T {.thread.}
|
||||||
|
b: proc(val: T) {.thread.}
|
||||||
|
|
||||||
|
proc handleThreadFunc(arg: TThreadFuncArgs[int]){.thread.} =
|
||||||
|
var func = arg.a
|
||||||
|
var callback = arg.b
|
||||||
|
var output = func()
|
||||||
|
callback(output)
|
||||||
|
|
||||||
|
proc `@||->`*[T](func: proc(): T {.thread.},
|
||||||
|
callback: proc(val: T){.thread.}): TThread[TThreadFuncArgs[T]] =
|
||||||
|
var thr: TThread[TThreadFuncArgs[T]]
|
||||||
|
var args: TThreadFuncArgs[T]
|
||||||
|
args.a = func
|
||||||
|
args.b = callback
|
||||||
|
createThread(thr, handleThreadFunc, args)
|
||||||
|
return thr
|
||||||
|
|
||||||
|
proc `||->`*[T](func: proc(): T{.thread.}, callback: proc(val: T){.thread.}) =
|
||||||
|
discard func @||-> callback
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
import os
|
||||||
|
proc testFunc(): int {.thread.} =
|
||||||
|
return 1
|
||||||
|
proc callbackFunc(val: int) {.thread.} =
|
||||||
|
echo($(val))
|
||||||
|
|
||||||
|
var thr = (testFunc @||-> callbackFunc)
|
||||||
|
echo("test")
|
||||||
|
joinThread(thr)
|
||||||
|
os.sleep(3000)
|
||||||
|
|
||||||
|
|
@ -41,7 +41,7 @@ srcdoc: "pure/json;pure/base64;pure/scgi;pure/redis;impure/graphics"
|
||||||
srcdoc: "impure/rdstdin;wrappers/zmq;wrappers/sphinx"
|
srcdoc: "impure/rdstdin;wrappers/zmq;wrappers/sphinx"
|
||||||
srcdoc: "pure/collections/tables;pure/collections/sets;pure/collections/lists"
|
srcdoc: "pure/collections/tables;pure/collections/sets;pure/collections/lists"
|
||||||
srcdoc: "pure/collections/intsets;pure/collections/queues;pure/encodings"
|
srcdoc: "pure/collections/intsets;pure/collections/queues;pure/encodings"
|
||||||
srcdoc: "pure/lib/events;pure/collections/sequtils"
|
srcdoc: "pure/events;pure/collections/sequtils"
|
||||||
|
|
||||||
webdoc: "wrappers/libcurl;pure/md5;wrappers/mysql;wrappers/iup"
|
webdoc: "wrappers/libcurl;pure/md5;wrappers/mysql;wrappers/iup"
|
||||||
webdoc: "wrappers/sqlite3;wrappers/postgres;wrappers/tinyc"
|
webdoc: "wrappers/sqlite3;wrappers/postgres;wrappers/tinyc"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue