From a6a18be0899ff0445128c614f285be1924ec5281 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Fri, 24 Jan 2014 14:13:32 +0200 Subject: [PATCH] support for parametric user-defined type classes --- compiler/ast.nim | 21 +++++-- compiler/semexprs.nim | 4 +- compiler/semtypes.nim | 9 ++- compiler/semtypinst.nim | 5 +- compiler/sigmatch.nim | 129 ++++++++++++++++++++++------------------ compiler/types.nim | 5 +- 6 files changed, 102 insertions(+), 71 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 0e351a31ac..4a3f1e8949 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -337,12 +337,20 @@ type tyIter, # unused tyProxy # used as errornous type (for idetools) tyTypeClass - tyParametricTypeClass # structured similarly to tyGenericInst - # lastSon is the body of the type class + tyBuiltInTypeClass # Type such as the catch-all object, tuple, seq, etc + tyUserTypeClass + tyUserTypeClassInst # \ + # Instance of a parametric user-defined type class. + # Structured similarly to tyGenericInst. + # tyGenericInst represents concrete types, while + # this is still a "generic param" that will bind types + # and resolves them during sigmatch and instantiation. - tyBuiltInTypeClass # Type such as the catch-all object, tuple, seq, etc - - tyCompositeTypeClass # + tyCompositeTypeClass # Type such as seq[Number] + # The notes for tyUserTypeClassInst apply here as well + # sons[0]: the original expression used by the user. + # sons[1]: fully expanded and instantiated meta type + # (potentially following aliases) tyAnd, tyOr, tyNot # boolean type classes such as `string|int`,`not seq`, # `Sortable and Enumable`, etc @@ -365,7 +373,8 @@ const tyUnknownTypes* = {tyError, tyFromExpr} tyTypeClasses* = {tyTypeClass, tyBuiltInTypeClass, tyCompositeTypeClass, - tyParametricTypeClass, tyAnd, tyOr, tyNot, tyAnything} + tyUserTypeClass, tyUserTypeClassInst, + tyAnd, tyOr, tyNot, tyAnything} tyMetaTypes* = {tyGenericParam, tyTypeDesc, tyStatic, tyExpr} + tyTypeClasses diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 6e2d777fb0..37fdf8b34b 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -322,12 +322,12 @@ proc isOpImpl(c: PContext, n: PNode): PNode = tfIterator in t.flags)) else: var match: bool - let t2 = n[2].typ + let t2 = n[2].typ.skipTypes({tyTypeDesc}) case t2.kind of tyTypeClasses: var m: TCandidate initCandidate(c, m, t2) - match = matchUserTypeClass(c, m, emptyNode, t2, t1) != nil + match = typeRel(m, t2, t1) != isNone of tyOrdinal: var m: TCandidate initCandidate(c, m, t2) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index d5a938a12d..4bcaf55d6f 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -710,6 +710,11 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, result = addImplicitGeneric(result) of tyGenericInst: + if paramType.lastSon.kind == tyUserTypeClass: + var cp = copyType(paramType, getCurrOwner(), false) + cp.kind = tyUserTypeClassInst + return addImplicitGeneric(cp) + for i in 1 .. (paramType.sons.len - 2): var lifted = liftingWalk(paramType.sons[i]) if lifted != nil: @@ -731,7 +736,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, allowMetaTypes = true) result = liftingWalk(expanded) - of tyTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot: + of tyUserTypeClass, tyTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot: result = addImplicitGeneric(copyType(paramType, getCurrOwner(), true)) of tyExpr: @@ -923,7 +928,7 @@ proc freshType(res, prev: PType): PType {.inline.} = proc semTypeClass(c: PContext, n: PNode, prev: PType): PType = # if n.sonsLen == 0: return newConstraint(c, tyTypeClass) - result = newOrPrevType(tyTypeClass, prev, c) + result = newOrPrevType(tyUserTypeClass, prev, c) result.n = n let diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index ac14179cd5..a9322c1f40 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -360,7 +360,10 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType = if tfUnresolved in t.flags: result = result.base elif t.sonsLen > 0: result = makeTypeDesc(cl.c, replaceTypeVarsT(cl, t.sons[0])) - + + of tyUserTypeClass: + result = t + of tyGenericInst: result = instCopyType(cl, t) for i in 1 ..