diff options
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/ast.nim | 2 | ||||
-rwxr-xr-x | compiler/evals.nim | 44 | ||||
-rwxr-xr-x | compiler/renderer.nim | 2 | ||||
-rwxr-xr-x | compiler/sem.nim | 6 | ||||
-rwxr-xr-x | compiler/semexprs.nim | 15 | ||||
-rwxr-xr-x | compiler/semgnrc.nim | 4 | ||||
-rwxr-xr-x | compiler/semstmts.nim | 3 | ||||
-rwxr-xr-x | compiler/semtypes.nim | 8 |
8 files changed, 54 insertions, 30 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 79adafcf8..a8176501f 100755 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -441,7 +441,7 @@ type mNIntVal, mNFloatVal, mNSymbol, mNIdent, mNGetType, mNStrVal, mNSetIntVal, mNSetFloatVal, mNSetSymbol, mNSetIdent, mNSetType, mNSetStrVal, mNLineInfo, mNNewNimNode, mNCopyNimNode, mNCopyNimTree, mStrToIdent, mIdentToStr, - mNBindSym, + mNBindSym, mNCallSite, mEqIdent, mEqNimrodNode, mNHint, mNWarning, mNError, mInstantiationInfo, mGetTypeInfo diff --git a/compiler/evals.nim b/compiler/evals.nim index 4ec6cb4d7..bb0e5936d 100755 --- a/compiler/evals.nim +++ b/compiler/evals.nim @@ -38,6 +38,7 @@ type module*: PSym tos*: PStackFrame # top of stack lastException*: PNode + callsite: PNode # for 'callsite' magic mode*: TEvalMode globals*: TIdNodeTable # state of global vars @@ -74,7 +75,7 @@ proc popStackFrame*(c: PEvalContext) {.inline.} = if c.tos != nil: c.tos = c.tos.next else: InternalError("popStackFrame") -proc evalMacroCall*(c: PEvalContext, n: PNode, sym: PSym): PNode +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 = @@ -106,8 +107,11 @@ proc stackTrace(c: PEvalContext, n: PNode, msg: TMsgKind, arg = "") = proc isSpecial(n: PNode): bool {.inline.} = result = n.kind == nkExceptBranch -proc myreset(n: PNode) {.inline.} = - when defined(system.reset): reset(n[]) +proc myreset(n: PNode) = + when defined(system.reset): + var oldInfo = n.info + reset(n[]) + n.info = oldInfo proc evalIf(c: PEvalContext, n: PNode): PNode = var i = 0 @@ -245,6 +249,11 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode = of tyObject: result = newNodeIT(nkPar, info, t) getNullValueAux(t.n, result) + # initialize inherited fields: + var base = t.sons[0] + while base != nil: + getNullValueAux(skipTypes(base, skipPtrs).n, result) + base = base.sons[0] of tyArray, tyArrayConstr: result = newNodeIT(nkBracket, info, t) for i in countup(0, int(lengthOrd(t)) - 1): @@ -925,7 +934,7 @@ proc evalExpandToAst(c: PEvalContext, original: PNode): PNode = # we want to replace it with nkIdent node featuring # the original unmangled macro name. macroCall.sons[0] = newIdentNode(expandedSym.name, expandedSym.info) - result = evalMacroCall(c, macroCall, expandedSym) + result = evalMacroCall(c, macroCall, original, expandedSym) else: InternalError(macroCall.info, "ExpandToAst: expanded symbol is no macro or template") @@ -1166,10 +1175,13 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode = of mIdentToStr: result = evalAux(c, n.sons[1], {}) if isSpecial(result): return - if result.kind != nkIdent: InternalError(n.info, "no ident node") var a = result result = newNodeIT(nkStrLit, n.info, n.typ) - result.strVal = a.ident.s + if a.kind == nkSym: + result.strVal = a.sym.name.s + else: + if a.kind != nkIdent: InternalError(n.info, "no ident node") + result.strVal = a.ident.s of mEqIdent: result = evalAux(c, n.sons[1], {}) if isSpecial(result): return @@ -1226,6 +1238,9 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode = var a = result result = newNodeIT(nkStrLit, n.info, n.typ) result.strVal = newString(0) + of mNCallSite: + if c.callsite != nil: result = c.callsite + else: stackTrace(c, n, errFieldXNotFound, "callsite") else: result = evalAux(c, n.sons[1], {}) if isSpecial(result): return @@ -1355,24 +1370,31 @@ proc evalConstExpr*(module: PSym, e: PNode): PNode = proc evalStaticExpr*(module: PSym, e: PNode): PNode = result = evalConstExprAux(module, e, emStatic) -proc evalMacroCall*(c: PEvalContext, n: PNode, sym: PSym): PNode = +proc setupMacroParam(x: PNode): PNode = + result = x + if result.kind == nkHiddenStdConv: result = result.sons[1] + +proc evalMacroCall(c: PEvalContext, n, nOrig: PNode, sym: PSym): PNode = # XXX GlobalError() is ugly here, but I don't know a better solution for now inc(evalTemplateCounter) - if evalTemplateCounter > 100: + if evalTemplateCounter > 100: GlobalError(n.info, errTemplateInstantiationTooNested) - #inc genSymBaseId + c.callsite = nOrig var s = newStackFrame() s.call = n - setlen(s.params, 2) + setlen(s.params, n.len) + # return value: s.params[0] = newNodeIT(nkNilLit, n.info, sym.typ.sons[0]) - s.params[1] = n + # setup parameters: + for i in 1 .. < n.len: s.params[i] = setupMacroParam(n.sons[i]) pushStackFrame(c, s) discard eval(c, sym.getBody) result = s.params[0] popStackFrame(c) if cyclicTree(result): GlobalError(n.info, errCyclicTree) dec(evalTemplateCounter) + c.callsite = nil proc myOpen(module: PSym, filename: string): PPassContext = var c = newEvalContext(module, filename, emRepl) diff --git a/compiler/renderer.nim b/compiler/renderer.nim index c24a22fd5..b6b34287a 100755 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -774,7 +774,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = put(g, tkRStrLit, '\"' & replace(n[1].strVal, "\"", "\"\"") & '\"') else: gsub(g, n.sons[1]) - of nkHiddenStdConv, nkHiddenSubConv, nkHiddenCallConv: gsub(g, n.sons[0]) + of nkHiddenStdConv, nkHiddenSubConv, nkHiddenCallConv: gsub(g, n.sons[1]) of nkCast: put(g, tkCast, "cast") put(g, tkBracketLe, "[") diff --git a/compiler/sem.nim b/compiler/sem.nim index 34b6f1f78..d92c1657d 100755 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -81,7 +81,7 @@ proc expectMacroOrTemplateCall(c: PContext, n: PNode): PSym proc semTemplateExpr(c: PContext, n: PNode, s: PSym, semCheck = true): PNode -proc semMacroExpr(c: PContext, n: PNode, sym: PSym, +proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, semCheck: bool = true): PNode proc semWhen(c: PContext, n: PNode, semCheck: bool = true): PNode @@ -127,14 +127,14 @@ proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode = #GlobalError(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0])) dec(evalTemplateCounter) -proc semMacroExpr(c: PContext, n: PNode, sym: PSym, +proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, semCheck: bool = true): PNode = 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) - result = evalMacroCall(c.evalContext, n, sym) + result = evalMacroCall(c.evalContext, n, nOrig, sym) if semCheck: result = semAfterMacroCall(c, result, sym) proc forceBool(c: PContext, n: PNode): PNode = diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 06014bf6f..9219cacf6 100755 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -98,7 +98,7 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = else: result = newSymNode(s, n.info) else: result = newSymNode(s, n.info) - of skMacro: result = semMacroExpr(c, n, s) + of skMacro: result = semMacroExpr(c, n, n, s) of skTemplate: result = semTemplateExpr(c, n, s) of skVar, skLet, skResult, skParam, skForVar: markUsed(n, s) @@ -705,7 +705,7 @@ proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = return errorNode(c, n) let callee = result.sons[0].sym case callee.kind - of skMacro: result = semMacroExpr(c, nOrig, callee) + of skMacro: result = semMacroExpr(c, result, nOrig, callee) of skTemplate: result = semTemplateExpr(c, nOrig, callee) else: fixAbstractType(c, result) @@ -1398,7 +1398,8 @@ proc semBlockExpr(c: PContext, n: PNode): PNode = closeScope(c.tab) Dec(c.p.nestedBlockCounter) -proc semMacroStmt(c: PContext, n: PNode, semCheck = true): PNode = +proc semMacroStmt(c: PContext, n: PNode, semCheck = true): PNode = + # XXX why no overloading here? checkMinSonsLen(n, 2) var a: PNode if isCallExpr(n.sons[0]): a = n.sons[0].sons[0] @@ -1407,7 +1408,7 @@ proc semMacroStmt(c: PContext, n: PNode, semCheck = true): PNode = if s != nil: case s.kind of skMacro: - result = semMacroExpr(c, n, s, semCheck) + result = semMacroExpr(c, n, n, s, semCheck) of skTemplate: # transform # nkMacroStmt(nkCall(a...), stmt, b...) @@ -1499,16 +1500,16 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = if s != nil: case s.kind of skMacro: - if false and sfImmediate notin s.flags: # XXX not yet enabled + if sfImmediate notin s.flags: result = semDirectOp(c, n, flags) else: - result = semMacroExpr(c, n, s) + result = semMacroExpr(c, n, n, s) of skTemplate: if sfImmediate notin s.flags: result = semDirectOp(c, n, flags) else: result = semTemplateExpr(c, n, s) - of skType: + of skType: # XXX think about this more (``set`` procs) if n.len == 2: result = semConv(c, n, s) diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 849d04fb1..ea3eebc3a 100755 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -51,7 +51,7 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym): PNode = of skTemplate: result = semTemplateExpr(c, n, s, false) of skMacro: - result = semMacroExpr(c, n, s, false) + result = semMacroExpr(c, n, n, s, false) of skGenericParam: result = newSymNode(s, n.info) of skParam: @@ -97,7 +97,7 @@ proc semGenericStmt(c: PContext, n: PNode, incl(s.flags, sfUsed) case s.kind of skMacro: - result = semMacroExpr(c, n, s, false) + result = semMacroExpr(c, n, n, s, false) of skTemplate: result = semTemplateExpr(c, n, s, false) # BUGFIX: we must not return here, we need to do first phase of diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index d12ad23cf..3a8424d9e 100755 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -892,13 +892,10 @@ proc semConverterDef(c: PContext, n: PNode): PNode = proc semMacroDef(c: PContext, n: PNode): PNode = checkSonsLen(n, bodyPos + 1) - if n.sons[genericParamsPos].kind != nkEmpty: - LocalError(n.info, errNoGenericParamsAllowedForX, "macro") result = semProcAux(c, n, skMacro, macroPragmas) var s = result.sons[namePos].sym var t = s.typ if t.sons[0] == nil: LocalError(n.info, errXNeedsReturnType, "macro") - if sonsLen(t) != 2: LocalError(n.info, errXRequiresOneArgument, "macro") if n.sons[bodyPos].kind == nkEmpty: LocalError(n.info, errImplOfXexpected, s.name.s) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 5b6183005..8ec3c337c 100755 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -237,9 +237,11 @@ proc semTypeIdent(c: PContext, n: PNode): PSym = return errorSym(c, n) if result.typ.kind != tyGenericParam: # XXX get rid of this hack! + var oldInfo = n.info reset(n[]) n.kind = nkSym n.sym = result + n.info = oldInfo else: LocalError(n.info, errIdentifierExpected) result = errorSym(c, n) @@ -549,7 +551,9 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType): PType = incl(result.flags, tfFinal) proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) = - if kind == skMacro and param.typ.kind in {tyTypeDesc, tyExpr, tyStmt}: + if kind == skMacro: + # within a macro, every param has the type PNimrodNode! + # and param.typ.kind in {tyTypeDesc, tyExpr, tyStmt}: let nn = getSysSym"PNimrodNode" var a = copySym(param) a.typ = nn.typ @@ -779,7 +783,7 @@ proc semTypeFromMacro(c: PContext, n: PNode): PType = markUsed(n, sym) case sym.kind of skMacro: - result = semTypeNode(c, semMacroExpr(c, n, sym), nil) + result = semTypeNode(c, semMacroExpr(c, n, n, sym), nil) of skTemplate: result = semTypeNode(c, semTemplateExpr(c, n, sym), nil) else: |