diff options
-rwxr-xr-x | compiler/semtypes.nim | 4 | ||||
-rwxr-xr-x | compiler/semtypinst.nim | 68 | ||||
-rwxr-xr-x | compiler/types.nim | 136 | ||||
-rw-r--r-- | tests/accept/compile/tthread_generic.nim | 35 | ||||
-rwxr-xr-x | web/nimrod.ini | 2 |
5 files changed, 127 insertions, 118 deletions
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 5d4515cd9..894dec1cb 100755 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -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) diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index fe45e7517..7cdc81b94 100755 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -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)) diff --git a/compiler/types.nim b/compiler/types.nim index bfa20066f..692b7f61b 100755 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -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) diff --git a/tests/accept/compile/tthread_generic.nim b/tests/accept/compile/tthread_generic.nim new file mode 100644 index 000000000..4ef939408 --- /dev/null +++ b/tests/accept/compile/tthread_generic.nim @@ -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) + diff --git a/web/nimrod.ini b/web/nimrod.ini index b0c6d0139..156bc5221 100755 --- a/web/nimrod.ini +++ b/web/nimrod.ini @@ -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" |