From 430c8d8b526c6f94a789db3362e9d2807d81e61d Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 6 Dec 2013 20:29:37 +0100 Subject: [PATCH] new VM supports 'getAst' --- compiler/vm.nim | 15 ++++++++++++++- compiler/vmgen.nim | 15 ++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/compiler/vm.nim b/compiler/vm.nim index a6cdc81b2a..94ff8a4c7d 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -17,6 +17,7 @@ import parser, vmdeps, idents, trees, renderer, options from semfold import leValueConv, ordinalValToString +from evaltempl import evalTemplate when hasFFI: import evalffi @@ -625,7 +626,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode = regs[ra] = newValue else: globalError(c.debug[pc], errGenerated, "VM not built with FFI support") - else: + elif prc.kind != skTemplate: let newPc = compile(c, prc) #echo "new pc ", newPc, " calling: ", prc.name.s var newFrame = PStackFrame(prc: prc, comesFrom: pc, next: tos) @@ -644,6 +645,18 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode = move(regs, newFrame.slots) # -1 for the following 'inc pc' pc = newPc-1 + else: + # for 'getAst' support we need to support template expansion here: + let genSymOwner = if tos.next != nil and tos.next.prc != nil: + tos.next.prc + else: + c.module + var macroCall = newNodeI(nkCall, c.debug[pc]) + macroCall.add(newSymNode(prc)) + for i in 1 .. rc-1: macroCall.add(regs[rb+i].skipMeta) + let a = evalTemplate(macroCall, prc, genSymOwner) + ensureKind(nkMetaNode) + setMeta(regs[ra], a) of opcTJmp: # jump Bx if A != 0 let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc' diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 802fa17068..300ef2d71c 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -711,8 +711,6 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) = genUnaryABC(c, n, dest, opcParseExprToAst) of mParseStmtToAst: genUnaryABC(c, n, dest, opcParseStmtToAst) - of mExpandToAst: - InternalError(n.info, "cannot generate code for: " & $m) of mTypeTrait: let tmp = c.genx(n.sons[1]) if dest < 0: dest = c.getTemp(n.typ) @@ -786,6 +784,16 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) = of mNGenSym: genBinaryABC(c, n, dest, opcGenSym) of mMinI, mMaxI, mMinI64, mMaxI64, mAbsF64, mMinF64, mMaxF64, mAbsI, mAbsI64: c.genCall(n, dest) + of mExpandToAst: + if n.len != 2: + globalError(n.info, errGenerated, "expandToAst requires 1 argument") + let arg = n.sons[1] + if arg.kind in nkCallKinds: + #if arg[0].kind != nkSym or arg[0].sym.kind notin {skTemplate, skMacro}: + # "ExpandToAst: expanded symbol is no macro or template" + c.genCall(arg, dest) + else: + globalError(n.info, "expandToAst requires a call expression") else: # mGCref, mGCunref, InternalError(n.info, "cannot generate code for: " & $m) @@ -1140,7 +1148,8 @@ proc gen(c: PCtx; n: PNode; dest: var TDest) = case s.kind of skVar, skForVar, skTemp, skLet, skParam, skResult: genRdVar(c, n, dest) - of skProc, skConverter, skMacro, skMethod, skIterator: + of skProc, skConverter, skMacro, skTemplate, skMethod, skIterator: + # 'skTemplate' is only allowed for 'getAst' support: if sfImportc in s.flags: c.importcSym(n.info, s) genLit(c, n, dest) of skConst: