diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 10b5641c5..1838562d4 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -973,7 +973,11 @@ proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): Rope = r = mangleName(sym) sym.loc.r = r # but be consequent! res.add($r) - else: internalError(t.sons[i].info, "genAsmOrEmitStmt()") + else: + var a: TLoc + initLocExpr(p, t.sons[i], a) + res.add($a.rdLoc) + #internalError(t.sons[i].info, "genAsmOrEmitStmt()") if isAsmStmt and hasGnuAsm in CC[cCompiler].props: for x in splitLines(res): diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index ffb2aa812..f93d33353 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -460,8 +460,22 @@ proc semAsmOrEmit*(con: PContext, n: PNode, marker: char): PNode = result = newNode(nkAsmStmt, n.info) proc pragmaEmit(c: PContext, n: PNode) = - discard getStrLitNode(c, n) - n.sons[1] = semAsmOrEmit(c, n, '`') + if n.kind != nkExprColonExpr: + localError(n.info, errStringLiteralExpected) + else: + let n1 = n[1] + if n1.kind == nkBracket: + var b = newNodeI(nkBracket, n1.info, n1.len) + for i in 0..".}[T] = object + +template `[]=`*[T](v: var Vector[T], key: int, val: T) = + {.emit: [v, "[", key, "] = ", val, ";"].} + +proc setLen*[T](v: var Vector[T]; size: int) {.importcpp: "resize", nodecl.} +proc `[]`*[T](v: var Vector[T], key: int): T {.importcpp: "(#[#])", nodecl.} + +proc main = + var v: Vector[float] + v.setLen 1 + v[0] = 6.0 + echo v[0] + +main() diff --git a/web/news/e029_version_0_16_0.rst b/web/news/e029_version_0_16_0.rst index 2a0c81b46..905504791 100644 --- a/web/news/e029_version_0_16_0.rst +++ b/web/news/e029_version_0_16_0.rst @@ -55,6 +55,28 @@ Compiler Additions Language Additions ------------------ +- The ``emit`` pragma now takes a list of Nim expressions instead + of a single string literal. This list can easily contain non-strings + like template parameters. This means ``emit`` works out of the + box with templates and no new quoting rules needed to be introduced. + The old way with backtick quoting is still supported but will be + deprecated. + +.. code-block:: nim + type Vector* {.importcpp: "std::vector", header: "".}[T] = object + + template `[]=`*[T](v: var Vector[T], key: int, val: T) = + {.emit: [v, "[", key, "] = ", val, ";"].} + + proc setLen*[T](v: var Vector[T]; size: int) {.importcpp: "resize", nodecl.} + proc `[]`*[T](v: var Vector[T], key: int): T {.importcpp: "(#[#])", nodecl.} + + proc main = + var v: Vector[float] + v.setLen 1 + v[0] = 6.0 + echo v[0] + Bugfixes --------