better integration of tyStatic into typeRel

This commit is contained in:
Zahary Karadjov
2013-12-25 22:29:44 +02:00
parent 1d02f2ea53
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 '|'
tfHasGCedMem, # type contains GC'ed memory
tfGenericTypeParam
tfHasStatic
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 raiseCannotEval(c: PEvalContext, info: TLineInfo): PNode =
if defined(debug): writeStackTrace()
if defined(debug) and gVerbosity >= 3: writeStackTrace()
result = newNodeI(nkExceptBranch, info)
# creating a nkExceptBranch without sons
# means that it could not be evaluated

View File

@@ -701,23 +701,21 @@ type
TErrorHandling = enum doNothing, doAbort, doRaise
proc handleError(msg: TMsgKind, eh: TErrorHandling, s: string) =
template maybeTrace =
if defined(debug) or gVerbosity >= 3:
writeStackTrace()
template quit =
if defined(debug) or gVerbosity >= 3: writeStackTrace()
quit 1
if msg == errInternal:
writeStackTrace() # we always want a stack trace here
if msg >= fatalMin and msg <= fatalMax:
maybeTrace()
quit(1)
quit()
if msg >= errMin and msg <= errMax:
maybeTrace()
inc(gErrorCounter)
options.gExitcode = 1'i8
if gErrorCounter >= gErrorMax:
quit(1)
quit()
elif eh == doAbort and gCmd != cmdIdeTools:
quit(1)
quit()
elif eh == doRaise:
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 =
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 =
var e = semExprWithType(c, n)
if e == nil:
@@ -282,6 +291,7 @@ proc myOpen(module: PSym): PPassContext =
c.semConstExpr = semConstExpr
c.semExpr = semExpr
c.semTryExpr = tryExpr
c.semTryConstExpr = tryConstExpr
c.semOperand = semOperand
c.semConstBoolExpr = semConstBoolExpr
c.semOverloadedCall = semOverloadedCall

View File

@@ -75,6 +75,7 @@ type
semExpr*: proc (c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.nimcall.}
semTryExpr*: proc (c: PContext, n: PNode,flags: TExprFlags = {},
bufferErrors = false): PNode {.nimcall.}
semTryConstExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.}
semOperand*: proc (c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.nimcall.}
semConstBoolExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # XXX bite the bullet
semOverloadedCall*: proc (c: PContext, n, nOrig: PNode,
@@ -217,11 +218,15 @@ proc makeAndType*(c: PContext, t1, t2: PType): PType =
result = newTypeS(tyAnd, c)
result.sons = @[t1, t2]
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 =
result = newTypeS(tyOr, c)
result.sons = @[t1, t2]
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 =
result = newTypeS(tyNot, c)

View File

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

View File

@@ -194,16 +194,16 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType =
proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
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
of tyTypeClass: nil
of tyGenericParam:
result = lookupTypeVar(cl, t)
if result.kind == tyGenericInvokation:
result = handleGenericInvokation(cl, result)
of tyStatic:
if t.sym != nil and t.sym.kind == skGenericParam:
result = lookupTypeVar(cl, t)
of tyGenericInvokation:
result = handleGenericInvokation(cl, t)
of tyGenericBody:

View File

@@ -753,6 +753,14 @@ proc typeRel(c: var TCandidate, f, a: PType, doBind = true): TTypeRelation =
result = isGeneric
else:
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:
var prev = PType(idTableGet(c.bindings, f))
if prev == nil:
@@ -904,40 +912,28 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
proc ParamTypesMatchAux(m: var TCandidate, f, argType: PType,
argSemantized, argOrig: PNode): PNode =
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})
arg = argSemantized
c = m.c
argType = argType
if tfHasStatic in fMaybeStatic.flags:
# XXX: When implicit statics are the default
# this will be done earlier - we just have to
# make sure that static types enter here
var evaluated = c.semTryConstExpr(c, arg)
if evaluated != nil:
arg.typ = newTypeS(tyStatic, c)
arg.typ.sons = @[evaluated.typ]
arg.typ.n = evaluated
argType = arg.typ
var
r: TTypeRelation
a = if c.InTypeClass > 0: argType.skipTypes({tyTypeDesc})
else: argType
case fMaybeStatic.kind
of tyStatic:
if a.kind == tyStatic:
InternalAssert a.len > 0
r = typeRel(m, f.lastSon, a.lastSon)
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:
r = isGeneric
arg.typ = newTypeS(tyStatic, c)
arg.typ.sons = @[evaluated.typ]
arg.typ.n = evaluated
if r == isGeneric:
put(m.bindings, f, arg.typ)
of tyTypeClass, tyParametricTypeClass:
if fMaybeStatic.n != nil:
let match = matchUserTypeClass(c, m, arg, fMaybeStatic, a)
@@ -955,7 +951,7 @@ proc ParamTypesMatchAux(m: var TCandidate, f, argType: PType,
r = typeRel(m, f, a)
case r
of isConvertible:
of isConvertible:
inc(m.convMatches)
result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c)
of isIntConv:

View File

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