This commit is contained in:
Araq 2011-08-04 19:47:35 +02:00
commit 7a6140e3a4
5 changed files with 127 additions and 118 deletions

View file

@ -227,7 +227,7 @@ 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)

View file

@ -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
if t == nil: return
case t.kind
of tyGenericParam:
result = lookupTypeVar(cl, t)
of tyGenericInvokation:
var body = t.sons[0] var body = t.sons[0]
if body.kind != tyGenericBody: InternalError(cl.info, "no generic body") if body.kind != tyGenericBody: InternalError(cl.info, "no generic body")
var header: PType = nil var header: PType = nil
for i in countup(1, sonsLen(t) - 1): for i in countup(1, sonsLen(t) - 1):
var x = replaceTypeVarsT(cl, t.sons[i])
if t.sons[i].kind == tyGenericParam:
if header == nil: header = copyType(t, t.owner, false)
header.sons[i] = x
when false:
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])
@ -125,6 +124,17 @@ proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
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))

View file

@ -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)

View 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)

View file

@ -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"