implemented 'emit' pragma

This commit is contained in:
Araq
2011-01-07 00:17:18 +01:00
parent 1e25aa365b
commit e008630838
10 changed files with 108 additions and 74 deletions

View File

@@ -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

View File

@@ -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:

View File

@@ -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),

View File

@@ -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) =

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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
1 tack.nim 125
19 tcontinuexc.nim ECcaught
20 tcopy.nim TEMP=C:\Programs\xyz\bin
21 tcurrncy.nim 25
22 temit.nim 509
23 texcsub.nim caught!
24 texplicitgeneric1.nim Key: 12 value: 12Key: 13 value: 13 Key: A value: 12 Key: B value: 13
25 tfinally.nim came here 3

View 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()

View File

@@ -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