diff --git a/compiler/sem.nim b/compiler/sem.nim index 57b87e0bb..ab3c5cec8 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -45,7 +45,7 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode proc activate(c: PContext, n: PNode) proc semQuoteAst(c: PContext, n: PNode): PNode proc finishMethod(c: PContext, s: PSym) - +proc evalAtCompileTime(c: PContext, n: PNode): PNode proc indexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode proc isArrayConstr(n: PNode): bool {.inline.} = @@ -328,6 +328,20 @@ proc semConstExpr(c: PContext, n: PNode): PNode = else: result = fixupTypeAfterEval(c, result, e) +proc semExprFlagDispatched(c: PContext, n: PNode, flags: TExprFlags): PNode = + if efNeedStatic in flags: + if efPreferNilResult in flags: + return tryConstExpr(c, n) + else: + return semConstExpr(c, n) + else: + result = semExprWithType(c, n, flags) + if efPreferStatic in flags: + var evaluated = getConstExpr(c.module, result) + if evaluated != nil: return evaluated + evaluated = evalAtCompileTime(c, result) + if evaluated != nil: return evaluated + include hlo, seminst, semcall when false: diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 023b85802..8f2c802de 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -46,6 +46,17 @@ type TExprFlag* = enum efLValue, efWantIterator, efInTypeof, + efNeedStatic, + # Use this in contexts where a static value is mandatory + efPreferStatic, + # Use this in contexts where a static value could bring more + # information, but it's not strictly mandatory. This may become + # the default with implicit statics in the future. + efPreferNilResult, + # Use this if you want a certain result (e.g. static value), + # but you don't want to trigger a hard error. For example, + # you may be in position to supply a better error message + # to the user. efWantStmt, efAllowStmt, efDetermineType, efExplain, efAllowDestructor, efWantValue, efOperand, efNoSemCheck, efNoProcvarCheck, efNoEvaluateGeneric, efInCall, efFromHlo, diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 5f9263645..316cf55c8 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -2097,75 +2097,7 @@ proc isTupleType(n: PNode): bool = return false return true -proc checkInitialized(n: PNode, ids: IntSet, info: TLineInfo) = - case n.kind - of nkRecList: - for i in countup(0, sonsLen(n) - 1): - checkInitialized(n.sons[i], ids, info) - of nkRecCase: - if (n.sons[0].kind != nkSym): internalError(info, "checkInitialized") - checkInitialized(n.sons[0], ids, info) - when false: - # XXX we cannot check here, as we don't know the branch! - for i in countup(1, sonsLen(n) - 1): - case n.sons[i].kind - of nkOfBranch, nkElse: checkInitialized(lastSon(n.sons[i]), ids, info) - else: internalError(info, "checkInitialized") - of nkSym: - if {tfNotNil, tfNeedsInit} * n.sym.typ.flags != {} and - n.sym.name.id notin ids: - message(info, errGenerated, "field not initialized: " & n.sym.name.s) - else: internalError(info, "checkInitialized") - -proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = - var t = semTypeNode(c, n.sons[0], nil) - result = newNodeIT(nkObjConstr, n.info, t) - result.add n.sons[0] - t = skipTypes(t, {tyGenericInst, tyAlias}) - if t.kind == tyRef: t = skipTypes(t.sons[0], {tyGenericInst, tyAlias}) - if t.kind != tyObject: - localError(n.info, errGenerated, "object constructor needs an object type") - return - var objType = t - var ids = initIntSet() - for i in 1..