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

View File

@@ -227,9 +227,9 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
var isConcrete = true # iterate over arguments:
for i in countup(1, sonsLen(n)-1):
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)
if isConcrete:
if isConcrete:
if s.ast == nil: GlobalError(n.info, errCannotInstantiateX, s.name.s)
result = instGenericContainer(c, n, result)

View File

@@ -14,10 +14,10 @@ import ast, astalgo, msgs, types, semdata
proc checkConstructedType*(info: TLineInfo, t: PType) =
if tfAcyclic in t.flags and skipTypes(t, abstractInst).kind != tyObject:
LocalError(info, errInvalidPragmaX, "acyclic")
elif computeSize(t) < 0:
LocalError(info, errIllegalRecursionInTypeX, typeToString(t))
elif t.kind == tyVar and t.sons[0].kind == tyVar:
LocalError(info, errVarVarTypeNotAllowed)
elif computeSize(t) < 0:
LocalError(info, errIllegalRecursionInTypeX, typeToString(t))
when false:
if t.kind == tyObject and t.sons[0] != nil:
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:
InternalError(cl.info, "substitution with generic parameter")
proc ReplaceTypeVarsT*(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]
if body.kind != tyGenericBody: InternalError(cl.info, "no generic body")
var header: PType = nil
for i in countup(1, sonsLen(t) - 1):
proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType =
var body = t.sons[0]
if body.kind != tyGenericBody: InternalError(cl.info, "no generic body")
var header: PType = nil
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
if t.sons[i].kind == tyGenericParam:
x = lookupTypeVar(cl, t.sons[i])
@@ -109,22 +108,33 @@ proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
header.sons[i] = x
else:
x = t.sons[i]
idTablePut(cl.typeMap, body.sons[i-1], x)
if header == nil: header = t
result = searchInstTypes(gInstTypes, header)
if result != nil: return
result = newType(tyGenericInst, t.sons[0].owner)
for i in countup(0, sonsLen(t) - 1):
# if one of the params is not concrete, we cannot do anything
# but we already raised an error!
addSon(result, header.sons[i])
idTablePut(gInstTypes, header, result)
var newbody = ReplaceTypeVarsT(cl, lastSon(body))
newbody.flags = newbody.flags + t.flags + body.flags
newbody.n = ReplaceTypeVarsN(cl, lastSon(body).n)
addSon(result, newbody)
#writeln(output, ropeToStr(Typetoyaml(newbody)));
checkConstructedType(cl.info, newbody)
idTablePut(cl.typeMap, body.sons[i-1], x)
if header == nil: header = t
result = searchInstTypes(gInstTypes, header)
if result != nil: return
result = newType(tyGenericInst, t.sons[0].owner)
for i in countup(0, sonsLen(t) - 1):
# if one of the params is not concrete, we cannot do anything
# but we already raised an error!
addSon(result, header.sons[i])
idTablePut(gInstTypes, header, result)
var newbody = ReplaceTypeVarsT(cl, lastSon(body))
newbody.flags = newbody.flags + t.flags + body.flags
newbody.n = ReplaceTypeVarsN(cl, lastSon(body).n)
addSon(result, newbody)
#writeln(output, ropeToStr(Typetoyaml(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:
InternalError(cl.info, "ReplaceTypeVarsT: tyGenericBody")
result = ReplaceTypeVarsT(cl, lastSon(t))

View File

@@ -96,23 +96,22 @@ proc inheritanceDiff(a, b: PType): int =
# conversion to superclass?
var x = a
result = 0
while (x != nil):
while x != nil:
if x.id == b.id: return
x = x.sons[0]
dec(result)
var y = b
result = 0
while (y != nil):
while y != nil:
if y.id == a.id: return
y = y.sons[0]
inc(result)
result = high(int)
proc isPureObject(typ: PType): bool =
var t: PType
t = typ
var t = typ
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 =
case n.kind
@@ -135,13 +134,13 @@ proc getProcHeader(sym: PSym): string =
var n = sym.typ.n
for i in countup(1, sonsLen(n) - 1):
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, ": ")
add(result, typeToString(p.sym.typ))
if i != sonsLen(n) - 1: add(result, ", ")
if i != sonsLen(n)-1: 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 =
assert(t != nil)
@@ -258,7 +257,8 @@ proc searchTypeNodeForAux(n: PNode, p: TTypePredicate,
result = searchTypeForAux(n.sym.typ, p, marker)
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!
result = false
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 (tfFinal in t.flags)
proc analyseObjectWithTypeFieldAux(t: PType, marker: var TIntSet): TTypeFieldResult =
proc analyseObjectWithTypeFieldAux(t: PType,
marker: var TIntSet): TTypeFieldResult =
var res: TTypeFieldResult
result = frNone
if t == nil: return
@@ -430,7 +431,7 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
var t = typ
result = ""
if t == nil: return
if (prefer == preferName) and (t.sym != nil):
if prefer == preferName and t.sym != nil:
return t.sym.Name.s
case t.Kind
of tyGenericBody, tyGenericInst, tyGenericInvokation:
@@ -506,12 +507,9 @@ proc base(t: PType): PType =
proc firstOrd(t: PType): biggestInt =
case t.kind
of tyBool, tyChar, tySequence, tyOpenArray, tyString:
result = 0
of tySet, tyVar:
result = firstOrd(t.sons[0])
of tyArray, tyArrayConstr:
result = firstOrd(t.sons[0])
of tyBool, tyChar, tySequence, tyOpenArray, tyString: result = 0
of tySet, tyVar: result = firstOrd(t.sons[0])
of tyArray, tyArrayConstr: result = firstOrd(t.sons[0])
of tyRange:
assert(t.n != nil) # range directly given:
assert(t.n.kind == nkRange)
@@ -519,14 +517,10 @@ proc firstOrd(t: PType): biggestInt =
of tyInt:
if platform.intSize == 4: result = - (2147483646) - 2
else: result = 0x8000000000000000'i64
of tyInt8:
result = - 128
of tyInt16:
result = - 32768
of tyInt32:
result = - 2147483646 - 2
of tyInt64:
result = 0x8000000000000000'i64
of tyInt8: result = - 128
of tyInt16: result = - 32768
of tyInt32: result = - 2147483646 - 2
of tyInt64: result = 0x8000000000000000'i64
of tyEnum:
# if basetype <> nil then return firstOrd of basetype
if (sonsLen(t) > 0) and (t.sons[0] != nil):
@@ -534,22 +528,17 @@ proc firstOrd(t: PType): biggestInt =
else:
assert(t.n.sons[0].kind == nkSym)
result = t.n.sons[0].sym.position
of tyGenericInst, tyDistinct:
result = firstOrd(lastSon(t))
of tyGenericInst, tyDistinct: result = firstOrd(lastSon(t))
else:
InternalError("invalid kind for first(" & $t.kind & ')')
result = 0
proc lastOrd(t: PType): biggestInt =
case t.kind
of tyBool:
result = 1
of tyChar:
result = 255
of tySet, tyVar:
result = lastOrd(t.sons[0])
of tyArray, tyArrayConstr:
result = lastOrd(t.sons[0])
of tyBool: result = 1
of tyChar: result = 255
of tySet, tyVar: result = lastOrd(t.sons[0])
of tyArray, tyArrayConstr: result = lastOrd(t.sons[0])
of tyRange:
assert(t.n != nil) # range directly given:
assert(t.n.kind == nkRange)
@@ -557,19 +546,14 @@ proc lastOrd(t: PType): biggestInt =
of tyInt:
if platform.intSize == 4: result = 0x7FFFFFFF
else: result = 0x7FFFFFFFFFFFFFFF'i64
of tyInt8:
result = 0x0000007F
of tyInt16:
result = 0x00007FFF
of tyInt32:
result = 0x7FFFFFFF
of tyInt64:
result = 0x7FFFFFFFFFFFFFFF'i64
of tyInt8: result = 0x0000007F
of tyInt16: result = 0x00007FFF
of tyInt32: result = 0x7FFFFFFF
of tyInt64: result = 0x7FFFFFFFFFFFFFFF'i64
of tyEnum:
assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym)
result = t.n.sons[sonsLen(t.n) - 1].sym.position
of tyGenericInst, tyDistinct:
result = firstOrd(lastSon(t))
of tyGenericInst, tyDistinct: result = lastOrd(lastSon(t))
else:
InternalError("invalid kind for last(" & $t.kind & ')')
result = 0
@@ -666,8 +650,7 @@ proc sameTuple(a, b: PType, DistinctOf: bool): bool =
result = false
proc SameType(x, y: PType): bool =
if x == y:
return true
if x == y: return true
var a = skipTypes(x, {tyGenericInst})
var b = skipTypes(y, {tyGenericInst})
assert(a != nil)
@@ -678,12 +661,9 @@ proc SameType(x, y: PType): bool =
of tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString,
tyInt..tyFloat128, tyExpr, tyStmt, tyTypeDesc:
result = true
of tyEnum, tyForward, tyObject, tyDistinct:
result = (a.id == b.id)
of tyTuple:
result = sameTuple(a, b, false)
of tyGenericInst:
result = sameType(lastSon(a), lastSon(b))
of tyEnum, tyForward, tyObject, tyDistinct: result = (a.id == b.id)
of tyTuple: result = sameTuple(a, b, false)
of tyGenericInst: result = sameType(lastSon(a), lastSon(b))
of tyGenericParam, tyGenericInvokation, tyGenericBody, tySequence, tyOrdinal,
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyArray, tyProc:
if sonsLen(a) == sonsLen(b):
@@ -699,14 +679,11 @@ proc SameType(x, y: PType): bool =
result = SameTypeOrNil(a.sons[0], b.sons[0]) and
SameValue(a.n.sons[0], b.n.sons[0]) and
SameValue(a.n.sons[1], b.n.sons[1])
of tyNone:
result = false
of tyNone: result = false
proc equalOrDistinctOf(x, y: PType): bool =
if x == y:
return true
if (x == nil) or (y == nil):
return false
if x == y: return true
if x == nil or y == nil: return false
var a = skipTypes(x, {tyGenericInst})
var b = skipTypes(y, {tyGenericInst})
assert(a != nil)
@@ -719,12 +696,9 @@ proc equalOrDistinctOf(x, y: PType): bool =
of tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString,
tyInt..tyFloat128, tyExpr, tyStmt, tyTypeDesc:
result = true
of tyEnum, tyForward, tyObject, tyDistinct:
result = (a.id == b.id)
of tyTuple:
result = sameTuple(a, b, true)
of tyGenericInst:
result = equalOrDistinctOf(lastSon(a), lastSon(b))
of tyEnum, tyForward, tyObject, tyDistinct: result = (a.id == b.id)
of tyTuple: result = sameTuple(a, b, true)
of tyGenericInst: result = equalOrDistinctOf(lastSon(a), lastSon(b))
of tyGenericParam, tyGenericInvokation, tyGenericBody, tySequence, tyOrdinal,
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyArray, tyProc:
if sonsLen(a) == sonsLen(b):
@@ -739,8 +713,7 @@ proc equalOrDistinctOf(x, y: PType): bool =
result = equalOrDistinctOf(a.sons[0], b.sons[0]) and
SameValue(a.n.sons[0], b.n.sons[0]) and
SameValue(a.n.sons[1], b.n.sons[1])
of tyNone:
result = false
of tyNone: result = false
proc typeAllowedAux(marker: var TIntSet, typ: PType, 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
of nkOfBranch, nkElse:
res = computeRecSizeAux(lastSon(n.sons[i]), b, currOffset)
if res < 0:
return res
if res < 0: return res
maxSize = max(maxSize, res)
maxAlign = max(maxAlign, b)
else: internalError("computeRecSizeAux(record case branch)")
@@ -848,8 +820,7 @@ proc computeRecSizeAux(n: PNode, a, currOffset: var biggestInt): biggestInt =
maxAlign = 1
for i in countup(0, sonsLen(n) - 1):
res = computeRecSizeAux(n.sons[i], b, currOffset)
if res < 0:
return res
if res < 0: return res
currOffset = align(currOffset, b) + res
result = align(result, b) + res
if b > maxAlign: maxAlign = b
@@ -914,18 +885,12 @@ proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt =
a = result
of tySet:
length = lengthOrd(typ.sons[0])
if length <= 8:
result = 1
elif length <= 16:
result = 2
elif length <= 32:
result = 4
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!
if length <= 8: result = 1
elif length <= 16: result = 2
elif length <= 32: result = 4
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
a = result
of tyRange:
result = computeSizeAux(typ.sons[0], a)
@@ -934,8 +899,7 @@ proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt =
maxAlign = 1
for i in countup(0, sonsLen(typ) - 1):
res = computeSizeAux(typ.sons[i], a)
if res < 0:
return res
if res < 0: return res
maxAlign = max(maxAlign, a)
result = align(result, a) + res
result = align(result, maxAlign)
@@ -959,7 +923,7 @@ proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt =
of tyGenericInst, tyDistinct, tyGenericBody:
result = computeSizeAux(lastSon(typ), a)
else:
#internalError('computeSizeAux()');
#internalError("computeSizeAux()")
result = - 1
typ.size = result
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: "pure/collections/tables;pure/collections/sets;pure/collections/lists"
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/sqlite3;wrappers/postgres;wrappers/tinyc"