diff options
author | Zahary Karadjov <zahary@gmail.com> | 2012-10-03 01:50:26 +0300 |
---|---|---|
committer | Zahary Karadjov <zahary@gmail.com> | 2012-10-03 01:59:50 +0300 |
commit | 2e5265bef54ef260213a2ad6ec417f48571c2824 (patch) | |
tree | d15efa6aaa2d30f9484026a5ee7c238fd85fb32f /compiler | |
parent | 9c8bc3a244b4bbcdc56fdd255bb4e1a7ed30f781 (diff) | |
download | Nim-2e5265bef54ef260213a2ad6ec417f48571c2824.tar.gz |
experimental support for querying the type of expressions within macros
normalised the line endings of macros.nim (minor edits otherwise)
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/evals.nim | 9 | ||||
-rwxr-xr-x | compiler/sem.nim | 11 | ||||
-rwxr-xr-x | compiler/semexprs.nim | 19 |
3 files changed, 29 insertions, 10 deletions
diff --git a/compiler/evals.nim b/compiler/evals.nim index 0886b1ef5..226415815 100755 --- a/compiler/evals.nim +++ b/compiler/evals.nim @@ -41,6 +41,7 @@ type callsite: PNode # for 'callsite' magic mode*: TEvalMode globals*: TIdNodeTable # state of global vars + getType*: proc(n: PNode): PNode PEvalContext* = ref TEvalContext @@ -1091,7 +1092,10 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode = result = evalAux(c, n.sons[1], {}) if isSpecial(result): return if result.kind != nkIdent: stackTrace(c, n, errFieldXNotFound, "ident") - of mNGetType: result = evalAux(c, n.sons[1], {}) + of mNGetType: + var ast = evalAux(c, n.sons[1], {}) + InternalAssert c.getType != nil + result = c.getType(ast) of mNStrVal: result = evalAux(c, n.sons[1], {}) if isSpecial(result): return @@ -1152,7 +1156,8 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode = var a = result result = evalAux(c, n.sons[2], {efLValue}) if isSpecial(result): return - a.typ = result.typ # XXX: exception handling? + InternalAssert result.kind == nkSym and result.sym.kind == skType + a.typ = result.sym.typ result = emptyNode of mNSetStrVal: result = evalAux(c, n.sons[1], {efLValue}) diff --git a/compiler/sem.nim b/compiler/sem.nim index 397581f63..0a6159dfa 100755 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -43,6 +43,7 @@ proc addParams(c: PContext, n: PNode, kind: TSymKind) proc addResult(c: PContext, t: PType, info: TLineInfo, owner: TSymKind) proc addResultNode(c: PContext, n: PNode) proc instGenericContainer(c: PContext, n: PNode, header: PType): PType +proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode proc typeMismatch(n: PNode, formal, actual: PType) = if formal.kind != tyError and actual.kind != tyError: @@ -156,8 +157,18 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, markUsed(n, sym) if sym == c.p.owner: GlobalError(n.info, errRecursiveDependencyX, sym.name.s) + if c.evalContext == nil: c.evalContext = newEvalContext(c.module, "", emStatic) + c.evalContext.getType = proc (n: PNode): PNode = + var e = tryExpr(c, n) + if e == nil: + result = symNodeFromType(c, errorType(c), n.info) + elif e.typ == nil: + result = newSymNode(getSysSym"void") + else: + result = symNodeFromType(c, e.typ, n.info) + result = evalMacroCall(c.evalContext, n, nOrig, sym) if semCheck: result = semAfterMacroCall(c, result, sym) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 51ede1614..e9dc5a8e9 100755 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1237,12 +1237,7 @@ proc semExpandToAst(c: PContext, n: PNode, magicSym: PSym, else: result = semDirectOp(c, n, flags) -proc semCompiles(c: PContext, n: PNode, flags: TExprFlags): PNode = - # we replace this node by a 'true' or 'false' node: - if sonsLen(n) != 2: return semDirectOp(c, n, flags) - result = newIntNode(nkIntLit, 0) - result.info = n.info - result.typ = getSysType(tyBool) +proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = # watch out, hacks ahead: let oldErrorCount = msgs.gErrorCounter let oldErrorMax = msgs.gErrorMax @@ -1264,8 +1259,8 @@ proc semCompiles(c: PContext, n: PNode, flags: TExprFlags): PNode = let oldProcCon = c.p c.generics = newGenericsCache() try: - discard semExpr(c, n.sons[1]) - result.intVal = ord(msgs.gErrorCounter == oldErrorCount) + result = semExpr(c, n, flags) + if msgs.gErrorCounter != oldErrorCount: result = nil except ERecoverableError: nil # undo symbol table changes (as far as it's possible): @@ -1282,6 +1277,14 @@ proc semCompiles(c: PContext, n: PNode, flags: TExprFlags): PNode = msgs.gErrorCounter = oldErrorCount msgs.gErrorMax = oldErrorMax +proc semCompiles(c: PContext, n: PNode, flags: TExprFlags): PNode = + # we replace this node by a 'true' or 'false' node: + if sonsLen(n) != 2: return semDirectOp(c, n, flags) + + result = newIntNode(nkIntLit, ord(tryExpr(c, n, flags) != nil)) + result.info = n.info + result.typ = getSysType(tyBool) + proc semShallowCopy(c: PContext, n: PNode, flags: TExprFlags): PNode = if sonsLen(n) == 3: # XXX ugh this is really a hack: shallowCopy() can be overloaded only |