mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-18 21:40:32 +00:00
implemented 'emit' pragma
This commit is contained in:
4
koch.nim
4
koch.nim
@@ -1,7 +1,7 @@
|
||||
#
|
||||
#
|
||||
# Maintenance program for Nimrod
|
||||
# (c) Copyright 2010 Andreas Rumpf
|
||||
# (c) Copyright 2011 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
@@ -18,7 +18,7 @@ const
|
||||
+-----------------------------------------------------------------+
|
||||
| Maintenance program for Nimrod |
|
||||
| Version $1|
|
||||
| (c) 2010 Andreas Rumpf |
|
||||
| (c) 2011 Andreas Rumpf |
|
||||
+-----------------------------------------------------------------+
|
||||
Build time: $2, $3
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
#
|
||||
# The Nimrod Compiler
|
||||
# (c) Copyright 2010 Andreas Rumpf
|
||||
# (c) Copyright 2011 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
@@ -213,34 +213,6 @@ proc genBreakStmt(p: BProc, t: PNode) =
|
||||
genLineDir(p, t)
|
||||
appf(p.s[cpsStmts], "goto LA$1;$n", [toRope(p.blocks[idx].id)])
|
||||
|
||||
proc genAsmStmt(p: BProc, t: PNode) =
|
||||
var
|
||||
sym: PSym
|
||||
r, s: PRope
|
||||
a: TLoc
|
||||
genLineDir(p, t)
|
||||
assert(t.kind == nkAsmStmt)
|
||||
s = nil
|
||||
for i in countup(0, sonsLen(t) - 1):
|
||||
case t.sons[i].Kind
|
||||
of nkStrLit..nkTripleStrLit:
|
||||
app(s, t.sons[i].strVal)
|
||||
of nkSym:
|
||||
sym = t.sons[i].sym
|
||||
if sym.kind in {skProc, skMethod}:
|
||||
initLocExpr(p, t.sons[i], a)
|
||||
app(s, rdLoc(a))
|
||||
else:
|
||||
r = sym.loc.r
|
||||
if r == nil:
|
||||
# if no name has already been given,
|
||||
# it doesn't matter much:
|
||||
r = mangleName(sym)
|
||||
sym.loc.r = r # but be consequent!
|
||||
app(s, r)
|
||||
else: InternalError(t.sons[i].info, "genAsmStmt()")
|
||||
appf(p.s[cpsStmts], CC[ccompiler].asmStmtFrmt, [s])
|
||||
|
||||
proc getRaiseFrmt(p: BProc): string =
|
||||
if gCmd == cmdCompileToCpp:
|
||||
result = "throw #nimException($1, $2);$n"
|
||||
@@ -605,6 +577,42 @@ proc genTryStmt(p: BProc, t: PNode) =
|
||||
genStmts(p, t.sons[i].sons[0])
|
||||
appcg(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", [safePoint])
|
||||
|
||||
proc genAsmOrEmitStmt(p: BProc, t: PNode): PRope =
|
||||
for i in countup(0, sonsLen(t) - 1):
|
||||
case t.sons[i].Kind
|
||||
of nkStrLit..nkTripleStrLit:
|
||||
app(result, t.sons[i].strVal)
|
||||
of nkSym:
|
||||
var sym = t.sons[i].sym
|
||||
if sym.kind in {skProc, skMethod}:
|
||||
var a: TLoc
|
||||
initLocExpr(p, t.sons[i], a)
|
||||
app(result, rdLoc(a))
|
||||
else:
|
||||
var r = sym.loc.r
|
||||
if r == nil:
|
||||
# if no name has already been given,
|
||||
# it doesn't matter much:
|
||||
r = mangleName(sym)
|
||||
sym.loc.r = r # but be consequent!
|
||||
app(result, r)
|
||||
else: InternalError(t.sons[i].info, "genAsmOrEmitStmt()")
|
||||
|
||||
proc genAsmStmt(p: BProc, t: PNode) =
|
||||
assert(t.kind == nkAsmStmt)
|
||||
genLineDir(p, t)
|
||||
var s = genAsmOrEmitStmt(p, t)
|
||||
appf(p.s[cpsStmts], CC[ccompiler].asmStmtFrmt, [s])
|
||||
|
||||
proc genEmit(p: BProc, t: PNode) =
|
||||
genLineDir(p, t)
|
||||
var s = genAsmOrEmitStmt(p, t.sons[1])
|
||||
if p.prc == nil:
|
||||
# top level emit pragma?
|
||||
app(p.module.s[cfsProcs], s)
|
||||
else:
|
||||
app(p.s[cpsStmts], s)
|
||||
|
||||
var
|
||||
breakPointId: int = 0
|
||||
gBreakpoints: PRope # later the breakpoints are inserted into the main proc
|
||||
@@ -630,6 +638,8 @@ proc genPragma(p: BProc, n: PNode) =
|
||||
var key = if it.kind == nkExprColonExpr: it.sons[0] else: it
|
||||
if key.kind == nkIdent:
|
||||
case whichKeyword(key.ident)
|
||||
of wEmit:
|
||||
genEmit(p, it)
|
||||
of wBreakpoint:
|
||||
genBreakPoint(p, it)
|
||||
of wDeadCodeElim:
|
||||
|
||||
10
rod/cgen.nim
10
rod/cgen.nim
@@ -1,7 +1,7 @@
|
||||
#
|
||||
#
|
||||
# The Nimrod Compiler
|
||||
# (c) Copyright 2010 Andreas Rumpf
|
||||
# (c) Copyright 2011 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
@@ -715,15 +715,15 @@ proc genConstPrototype(m: BModule, sym: PSym) =
|
||||
proc getFileHeader(cfilenoext: string): PRope =
|
||||
if optCompileOnly in gGlobalOptions:
|
||||
result = ropeff("/* Generated by Nimrod Compiler v$1 */$n" &
|
||||
"/* (c) 2010 Andreas Rumpf */$n",
|
||||
"/* (c) 2011 Andreas Rumpf */$n",
|
||||
"; Generated by Nimrod Compiler v$1$n" &
|
||||
"; (c) 2010 Andreas Rumpf$n", [toRope(versionAsString)])
|
||||
"; (c) 2011 Andreas Rumpf$n", [toRope(versionAsString)])
|
||||
else:
|
||||
result = ropeff("/* Generated by Nimrod Compiler v$1 */$n" &
|
||||
"/* (c) 2010 Andreas Rumpf */$n" & "/* Compiled for: $2, $3, $4 */$n" &
|
||||
"/* (c) 2011 Andreas Rumpf */$n" & "/* Compiled for: $2, $3, $4 */$n" &
|
||||
"/* Command for C compiler:$n $5 */$n",
|
||||
"; Generated by Nimrod Compiler v$1$n" &
|
||||
"; (c) 2010 Andreas Rumpf$n" & "; Compiled for: $2, $3, $4$n" &
|
||||
"; (c) 2011 Andreas Rumpf$n" & "; Compiled for: $2, $3, $4$n" &
|
||||
"; Command for LLVM compiler:$n $5$n", [toRope(versionAsString),
|
||||
toRope(platform.OS[targetOS].name),
|
||||
toRope(platform.CPU[targetCPU].name),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
#
|
||||
# The Nimrod Compiler
|
||||
# (c) Copyright 2010 Andreas Rumpf
|
||||
# (c) Copyright 2011 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
@@ -27,7 +27,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdlinePass, info: TLineInfo)
|
||||
|
||||
const
|
||||
HelpMessage = "Nimrod Compiler Version $1 (" & compileDate & ") [$2: $3]" &
|
||||
"\n" & "Copyright (c) 2004-2010 by Andreas Rumpf" & "\n"
|
||||
"\n" & "Copyright (c) 2004-2011 by Andreas Rumpf" & "\n"
|
||||
|
||||
const
|
||||
Usage = """
|
||||
@@ -182,10 +182,10 @@ proc ProcessOnOffSwitchG(op: TGlobalOptions, arg: string, pass: TCmdlinePass,
|
||||
else: liMessage(info, errOnOrOffExpectedButXFound, arg)
|
||||
|
||||
proc ExpectArg(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
|
||||
if (arg == ""): liMessage(info, errCmdLineArgExpected, switch)
|
||||
if arg == "": liMessage(info, errCmdLineArgExpected, switch)
|
||||
|
||||
proc ExpectNoArg(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
|
||||
if (arg != ""): liMessage(info, errCmdLineNoArgExpected, switch)
|
||||
if arg != "": liMessage(info, errCmdLineNoArgExpected, switch)
|
||||
|
||||
proc ProcessSpecificNote(arg: string, state: TSpecialWord, pass: TCmdlinePass,
|
||||
info: TLineInfo) =
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
#
|
||||
# The Nimrod Compiler
|
||||
# (c) Copyright 2010 Andreas Rumpf
|
||||
# (c) Copyright 2011 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
@@ -11,7 +11,8 @@
|
||||
|
||||
import
|
||||
os, platform, condsyms, ast, astalgo, idents, semdata, msgs, rnimsyn,
|
||||
wordrecg, ropes, options, strutils, lists, extccomp, math, magicsys, trees
|
||||
wordrecg, ropes, options, strutils, lists, extccomp, math, magicsys, trees,
|
||||
rodread
|
||||
|
||||
const
|
||||
FirstCallConv* = wNimcall
|
||||
@@ -33,7 +34,7 @@ const
|
||||
wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError, wFatal,
|
||||
wDefine, wUndef, wCompile, wLink, wLinkSys, wPure, wPush, wPop, wBreakpoint,
|
||||
wCheckpoint, wPassL, wPassC, wDeadCodeElim, wDeprecated, wFloatChecks,
|
||||
wInfChecks, wNanChecks, wPragma}
|
||||
wInfChecks, wNanChecks, wPragma, wEmit}
|
||||
lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
|
||||
wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, wPure,
|
||||
wDeprecated, wExtern}
|
||||
@@ -323,6 +324,37 @@ proc PragmaCheckpoint(c: PContext, n: PNode) =
|
||||
inc(info.line) # next line is affected!
|
||||
msgs.addCheckpoint(info)
|
||||
|
||||
proc semAsmOrEmit*(con: PContext, n: PNode, marker: char): PNode =
|
||||
case n.sons[1].kind
|
||||
of nkStrLit, nkRStrLit, nkTripleStrLit:
|
||||
result = copyNode(n)
|
||||
var str = n.sons[1].strVal
|
||||
if str == "": liMessage(n.info, errEmptyAsm)
|
||||
# now parse the string literal and substitute symbols:
|
||||
var a = 0
|
||||
while true:
|
||||
var b = strutils.find(str, marker, a)
|
||||
var sub = if b < 0: copy(str, a) else: copy(str, a, b - 1)
|
||||
if sub != "": addSon(result, newStrNode(nkStrLit, sub))
|
||||
if b < 0: break
|
||||
var c = strutils.find(str, marker, b + 1)
|
||||
if c < 0: sub = copy(str, b + 1)
|
||||
else: sub = copy(str, b + 1, c - 1)
|
||||
if sub != "":
|
||||
var e = SymtabGet(con.tab, getIdent(sub))
|
||||
if e != nil:
|
||||
if e.kind == skStub: loadStub(e)
|
||||
addSon(result, newSymNode(e))
|
||||
else:
|
||||
addSon(result, newStrNode(nkStrLit, sub))
|
||||
if c < 0: break
|
||||
a = c + 1
|
||||
else: illFormedAst(n)
|
||||
|
||||
proc PragmaEmit(c: PContext, n: PNode) =
|
||||
discard getStrLitNode(c, n)
|
||||
n.sons[1] = semAsmOrEmit(c, n, '`')
|
||||
|
||||
proc noVal(n: PNode) =
|
||||
if n.kind == nkExprColonExpr: invalidPragma(n)
|
||||
|
||||
@@ -477,6 +509,7 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
|
||||
assert(sym != nil)
|
||||
if sym.typ == nil: invalidPragma(it)
|
||||
sym.typ.callConv = wordToCallConv(k)
|
||||
of wEmit: PragmaEmit(c, it)
|
||||
else: invalidPragma(it)
|
||||
else: invalidPragma(it)
|
||||
else: processNote(c, it)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
#
|
||||
# The Nimrod Compiler
|
||||
# (c) Copyright 2010 Andreas Rumpf
|
||||
# (c) Copyright 2011 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
@@ -96,35 +96,10 @@ proc semBlock(c: PContext, n: PNode): PNode =
|
||||
Dec(c.p.nestedBlockCounter)
|
||||
|
||||
proc semAsm(con: PContext, n: PNode): PNode =
|
||||
result = n
|
||||
checkSonsLen(n, 2)
|
||||
var marker = pragmaAsm(con, n.sons[0])
|
||||
if marker == '\0': marker = '`' # default marker
|
||||
case n.sons[1].kind
|
||||
of nkStrLit, nkRStrLit, nkTripleStrLit:
|
||||
result = copyNode(n)
|
||||
var str = n.sons[1].strVal
|
||||
if str == "": liMessage(n.info, errEmptyAsm)
|
||||
# now parse the string literal and substitute symbols:
|
||||
var a = 0
|
||||
while true:
|
||||
var b = strutils.find(str, marker, a)
|
||||
var sub = if b < 0: copy(str, a) else: copy(str, a, b - 1)
|
||||
if sub != "": addSon(result, newStrNode(nkStrLit, sub))
|
||||
if b < 0: break
|
||||
var c = strutils.find(str, marker, b + 1)
|
||||
if c < 0: sub = copy(str, b + 1)
|
||||
else: sub = copy(str, b + 1, c - 1)
|
||||
if sub != "":
|
||||
var e = SymtabGet(con.tab, getIdent(sub))
|
||||
if e != nil:
|
||||
if e.kind == skStub: loadStub(e)
|
||||
addSon(result, newSymNode(e))
|
||||
else:
|
||||
addSon(result, newStrNode(nkStrLit, sub))
|
||||
if c < 0: break
|
||||
a = c + 1
|
||||
else: illFormedAst(n)
|
||||
result = semAsmOrEmit(con, n, marker)
|
||||
|
||||
proc semWhile(c: PContext, n: PNode): PNode =
|
||||
result = n
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
#
|
||||
# The Nimrod Compiler
|
||||
# (c) Copyright 2010 Andreas Rumpf
|
||||
# (c) Copyright 2011 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
@@ -57,7 +57,7 @@ type
|
||||
wCompileToC, wCompileToCpp, wCompileToEcmaScript, wCompileToLLVM, wPretty,
|
||||
wDoc, wGenDepend, wListDef, wCheck, wParse, wScan, wJs,
|
||||
wRst2html, wRst2tex, wI,
|
||||
wWrite, wPutEnv, wPrependEnv, wAppendEnv, wThreadVar
|
||||
wWrite, wPutEnv, wPrependEnv, wAppendEnv, wThreadVar, wEmit
|
||||
|
||||
TSpecialWords* = set[TSpecialWord]
|
||||
|
||||
@@ -104,7 +104,7 @@ const
|
||||
"compiletoc", "compiletocpp", "compiletoecmascript", "compiletollvm",
|
||||
"pretty", "doc", "gendepend", "listdef", "check", "parse", "scan",
|
||||
"js", "rst2html", "rst2tex", "i",
|
||||
"write", "putenv", "prependenv", "appendenv", "threadvar"]
|
||||
"write", "putenv", "prependenv", "appendenv", "threadvar", "emit"]
|
||||
|
||||
proc whichKeyword*(id: PIdent): TSpecialWord
|
||||
proc whichKeyword*(id: String): TSpecialWord
|
||||
|
||||
@@ -19,6 +19,7 @@ tconstr2.nim;69
|
||||
tcontinuexc.nim;ECcaught
|
||||
tcopy.nim;TEMP=C:\Programs\xyz\bin
|
||||
tcurrncy.nim;25
|
||||
temit.nim;509
|
||||
texcsub.nim;caught!
|
||||
texplicitgeneric1.nim;Key: 12 value: 12Key: 13 value: 13 Key: A value: 12 Key: B value: 13
|
||||
tfinally.nim;came here 3
|
||||
|
||||
|
14
tests/accept/run/temit.nim
Normal file
14
tests/accept/run/temit.nim
Normal file
@@ -0,0 +1,14 @@
|
||||
# Test the new ``emit`` pragma:
|
||||
|
||||
{.emit: """
|
||||
static int cvariable = 420;
|
||||
|
||||
""".}
|
||||
|
||||
proc embedsC() {.pure.} =
|
||||
var nimrodVar = 89
|
||||
{.emit: """fprintf(stdout, "%d\n", cvariable + (int)`nimrodVar`);""".}
|
||||
|
||||
embedsC()
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ News
|
||||
====
|
||||
|
||||
|
||||
2010-XX-XX Version 0.8.12 released
|
||||
2011-XX-XX Version 0.8.12 released
|
||||
==================================
|
||||
|
||||
Version 0.8.12 has been released! Get it `here <download.html>`_.
|
||||
@@ -32,6 +32,7 @@ Additions
|
||||
``\title``, ``\white``.
|
||||
- Pegs support the new built-in ``\skip`` operation.
|
||||
- Source code filters are now properly documented.
|
||||
- Added ``emit`` pragma for direct code generator control.
|
||||
|
||||
|
||||
2010-10-20 Version 0.8.10 released
|
||||
|
||||
Reference in New Issue
Block a user