better integration of tyStatic into typeRel

This commit is contained in:
Zahary Karadjov 2013-12-25 22:29:44 +02:00
commit edab4aaad0
9 changed files with 66 additions and 58 deletions

View file

@ -399,6 +399,7 @@ type
tfHasMeta, # type has "typedesc" or "expr" somewhere; or uses '|' tfHasMeta, # type has "typedesc" or "expr" somewhere; or uses '|'
tfHasGCedMem, # type contains GC'ed memory tfHasGCedMem, # type contains GC'ed memory
tfGenericTypeParam tfGenericTypeParam
tfHasStatic
TTypeFlags* = set[TTypeFlag] TTypeFlags* = set[TTypeFlag]

View file

@ -91,7 +91,7 @@ proc evalMacroCall*(c: PEvalContext, n, nOrig: PNode, sym: PSym): PNode
proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode
proc raiseCannotEval(c: PEvalContext, info: TLineInfo): PNode = proc raiseCannotEval(c: PEvalContext, info: TLineInfo): PNode =
if defined(debug): writeStackTrace() if defined(debug) and gVerbosity >= 3: writeStackTrace()
result = newNodeI(nkExceptBranch, info) result = newNodeI(nkExceptBranch, info)
# creating a nkExceptBranch without sons # creating a nkExceptBranch without sons
# means that it could not be evaluated # means that it could not be evaluated

View file

@ -701,23 +701,21 @@ type
TErrorHandling = enum doNothing, doAbort, doRaise TErrorHandling = enum doNothing, doAbort, doRaise
proc handleError(msg: TMsgKind, eh: TErrorHandling, s: string) = proc handleError(msg: TMsgKind, eh: TErrorHandling, s: string) =
template maybeTrace = template quit =
if defined(debug) or gVerbosity >= 3: if defined(debug) or gVerbosity >= 3: writeStackTrace()
writeStackTrace() quit 1
if msg == errInternal: if msg == errInternal:
writeStackTrace() # we always want a stack trace here writeStackTrace() # we always want a stack trace here
if msg >= fatalMin and msg <= fatalMax: if msg >= fatalMin and msg <= fatalMax:
maybeTrace() quit()
quit(1)
if msg >= errMin and msg <= errMax: if msg >= errMin and msg <= errMax:
maybeTrace()
inc(gErrorCounter) inc(gErrorCounter)
options.gExitcode = 1'i8 options.gExitcode = 1'i8
if gErrorCounter >= gErrorMax: if gErrorCounter >= gErrorMax:
quit(1) quit()
elif eh == doAbort and gCmd != cmdIdeTools: elif eh == doAbort and gCmd != cmdIdeTools:
quit(1) quit()
elif eh == doRaise: elif eh == doRaise:
raiseRecoverableError(s) raiseRecoverableError(s)

View file

@ -189,6 +189,15 @@ proc evalConstExpr(c: PContext, module: PSym, e: PNode): PNode =
proc evalStaticExpr(c: PContext, module: PSym, e: PNode, prc: PSym): PNode = proc evalStaticExpr(c: PContext, module: PSym, e: PNode, prc: PSym): PNode =
result = evalConstExprAux(c.createEvalContext(emStatic), module, prc, e) result = evalConstExprAux(c.createEvalContext(emStatic), module, prc, e)
proc tryConstExpr(c: PContext, n: PNode): PNode =
var e = semExprWithType(c, n)
if e == nil: return
result = getConstExpr(c.module, e)
if result == nil:
result = evalConstExpr(c, c.module, e)
if result == nil or result.kind == nkEmpty:
return nil
proc semConstExpr(c: PContext, n: PNode): PNode = proc semConstExpr(c: PContext, n: PNode): PNode =
var e = semExprWithType(c, n) var e = semExprWithType(c, n)
if e == nil: if e == nil:
@ -282,6 +291,7 @@ proc myOpen(module: PSym): PPassContext =
c.semConstExpr = semConstExpr c.semConstExpr = semConstExpr
c.semExpr = semExpr c.semExpr = semExpr
c.semTryExpr = tryExpr c.semTryExpr = tryExpr
c.semTryConstExpr = tryConstExpr
c.semOperand = semOperand c.semOperand = semOperand
c.semConstBoolExpr = semConstBoolExpr c.semConstBoolExpr = semConstBoolExpr
c.semOverloadedCall = semOverloadedCall c.semOverloadedCall = semOverloadedCall

View file

@ -75,6 +75,7 @@ type
semExpr*: proc (c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.nimcall.} semExpr*: proc (c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.nimcall.}
semTryExpr*: proc (c: PContext, n: PNode,flags: TExprFlags = {}, semTryExpr*: proc (c: PContext, n: PNode,flags: TExprFlags = {},
bufferErrors = false): PNode {.nimcall.} bufferErrors = false): PNode {.nimcall.}
semTryConstExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.}
semOperand*: proc (c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.nimcall.} semOperand*: proc (c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.nimcall.}
semConstBoolExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # XXX bite the bullet semConstBoolExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # XXX bite the bullet
semOverloadedCall*: proc (c: PContext, n, nOrig: PNode, semOverloadedCall*: proc (c: PContext, n, nOrig: PNode,
@ -217,11 +218,15 @@ proc makeAndType*(c: PContext, t1, t2: PType): PType =
result = newTypeS(tyAnd, c) result = newTypeS(tyAnd, c)
result.sons = @[t1, t2] result.sons = @[t1, t2]
result.flags.incl tfHasMeta result.flags.incl tfHasMeta
if tfHasStatic in t1.flags or tfHasStatic in t2.flags:
result.flags.incl tfHasStatic
proc makeOrType*(c: PContext, t1, t2: PType): PType = proc makeOrType*(c: PContext, t1, t2: PType): PType =
result = newTypeS(tyOr, c) result = newTypeS(tyOr, c)
result.sons = @[t1, t2] result.sons = @[t1, t2]
result.flags.incl tfHasMeta result.flags.incl tfHasMeta
if tfHasStatic in t1.flags or tfHasStatic in t2.flags:
result.flags.incl tfHasStatic
proc makeNotType*(c: PContext, t1: PType): PType = proc makeNotType*(c: PContext, t1: PType): PType =
result = newTypeS(tyNot, c) result = newTypeS(tyNot, c)

View file

@ -678,12 +678,9 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
paramType.sons[i] = lifted paramType.sons[i] = lifted
result = paramType result = paramType
if paramType.lastSon.kind == tyTypeClass and false: if result == nil:
result = paramType result = liftingWalk(paramType.lastSon)
result.kind = tyParametricTypeClass else:
result = addImplicitGeneric(copyType(result,
getCurrOwner(), false))
elif result != nil:
result.kind = tyGenericInvokation result.kind = tyGenericInvokation
result.sons.setLen(result.sons.len - 1) result.sons.setLen(result.sons.len - 1)
of tyTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot: of tyTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot:
@ -1017,6 +1014,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
result = newOrPrevType(tyStatic, prev, c) result = newOrPrevType(tyStatic, prev, c)
var base = semTypeNode(c, n.sons[0], nil) var base = semTypeNode(c, n.sons[0], nil)
result.rawAddSon(base) result.rawAddSon(base)
result.flags.incl tfHasStatic
of nkProcTy, nkIteratorTy: of nkProcTy, nkIteratorTy:
if n.sonsLen == 0: if n.sonsLen == 0:
result = newConstraint(c, tyProc) result = newConstraint(c, tyProc)

View file

@ -195,15 +195,15 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType =
proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType = proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
result = t result = t
if t == nil: return if t == nil: return
if t.kind == tyStatic and t.sym != nil and t.sym.kind == skGenericParam:
return lookupTypeVar(cl, t)
case t.kind case t.kind
of tyTypeClass: nil of tyTypeClass: nil
of tyGenericParam: of tyGenericParam:
result = lookupTypeVar(cl, t) result = lookupTypeVar(cl, t)
if result.kind == tyGenericInvokation: if result.kind == tyGenericInvokation:
result = handleGenericInvokation(cl, result) result = handleGenericInvokation(cl, result)
of tyStatic:
if t.sym != nil and t.sym.kind == skGenericParam:
result = lookupTypeVar(cl, t)
of tyGenericInvokation: of tyGenericInvokation:
result = handleGenericInvokation(cl, t) result = handleGenericInvokation(cl, t)
of tyGenericBody: of tyGenericBody:

View file

@ -753,6 +753,14 @@ proc typeRel(c: var TCandidate, f, a: PType, doBind = true): TTypeRelation =
result = isGeneric result = isGeneric
else: else:
result = typeRel(c, x, a) # check if it fits result = typeRel(c, x, a) # check if it fits
of tyStatic:
if a.kind == tyStatic:
result = typeRel(c, f.lastSon, a.lastSon)
if result != isNone: put(c.bindings, f, a)
else:
result = isNone
of tyTypeDesc: of tyTypeDesc:
var prev = PType(idTableGet(c.bindings, f)) var prev = PType(idTableGet(c.bindings, f))
if prev == nil: if prev == nil:
@ -904,40 +912,28 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
proc ParamTypesMatchAux(m: var TCandidate, f, argType: PType, proc ParamTypesMatchAux(m: var TCandidate, f, argType: PType,
argSemantized, argOrig: PNode): PNode = argSemantized, argOrig: PNode): PNode =
var var
r: TTypeRelation
arg = argSemantized
let
c = m.c
a0 = if c.InTypeClass > 0: argType.skipTypes({tyTypeDesc})
else: argType
a = if a0 != nil: a0.skipTypes({tyStatic}) else: a0
fMaybeStatic = f.skipTypes({tyDistinct}) fMaybeStatic = f.skipTypes({tyDistinct})
arg = argSemantized
c = m.c
argType = argType
case fMaybeStatic.kind if tfHasStatic in fMaybeStatic.flags:
of tyStatic: # XXX: When implicit statics are the default
if a.kind == tyStatic: # this will be done earlier - we just have to
InternalAssert a.len > 0 # make sure that static types enter here
r = typeRel(m, f.lastSon, a.lastSon) var evaluated = c.semTryConstExpr(c, arg)
else:
r = typeRel(m, fMaybeStatic, a)
if r != isNone:
# XXX: Ideally, this should happen much earlier somewhere near
# semOpAux, but to do that, we need to be able to query the
# overload set to determine whether compile-time value is expected
# for the param before entering the full-blown sigmatch algorithm.
# This is related to the immediate pragma since querying the
# overload set could help there too.
var evaluated = c.semConstExpr(c, arg)
if evaluated != nil: if evaluated != nil:
r = isGeneric
arg.typ = newTypeS(tyStatic, c) arg.typ = newTypeS(tyStatic, c)
arg.typ.sons = @[evaluated.typ] arg.typ.sons = @[evaluated.typ]
arg.typ.n = evaluated arg.typ.n = evaluated
argType = arg.typ
if r == isGeneric: var
put(m.bindings, f, arg.typ) r: TTypeRelation
a = if c.InTypeClass > 0: argType.skipTypes({tyTypeDesc})
else: argType
case fMaybeStatic.kind
of tyTypeClass, tyParametricTypeClass: of tyTypeClass, tyParametricTypeClass:
if fMaybeStatic.n != nil: if fMaybeStatic.n != nil:
let match = matchUserTypeClass(c, m, arg, fMaybeStatic, a) let match = matchUserTypeClass(c, m, arg, fMaybeStatic, a)

View file

@ -434,10 +434,10 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
add(result, ']') add(result, ']')
of tyTypeDesc: of tyTypeDesc:
if t.len == 0: result = "typedesc" if t.len == 0: result = "typedesc"
else: result = "typedesc[" & typeToString(t) & "]" else: result = "typedesc[" & typeToString(t.sons[0]) & "]"
of tyStatic: of tyStatic:
InternalAssert t.len > 0 InternalAssert t.len > 0
result = "static[" & typeToString(t) & "]" result = "static[" & typeToString(t.sons[0]) & "]"
of tyTypeClass: of tyTypeClass:
InternalAssert t.sym != nil and t.sym.owner != nil InternalAssert t.sym != nil and t.sym.owner != nil
return t.sym.owner.name.s return t.sym.owner.name.s
@ -450,8 +450,8 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
of tyNot: of tyNot:
result = "not " & typeToString(t.sons[0]) result = "not " & typeToString(t.sons[0])
of tyExpr: of tyExpr:
if t.len == 0: result = "expr" InternalAssert t.len == 0
else: result = "expr[" & typeToString(t) & "]" result = "expr"
of tyArray: of tyArray:
if t.sons[0].kind == tyRange: if t.sons[0].kind == tyRange:
result = "array[" & rangeToStr(t.sons[0].n) & ", " & result = "array[" & rangeToStr(t.sons[0].n) & ", " &