summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2011-01-07 00:17:18 +0100
committerAraq <rumpf_a@web.de>2011-01-07 00:17:18 +0100
commite008630838f545a04334ee71a5d6c52469fed056 (patch)
tree32fd06e7c0a4eb519d313c9535f0c61be0239378
parent1e25aa365b3eef6b8a52ca115a4f27e37432577a (diff)
downloadNim-e008630838f545a04334ee71a5d6c52469fed056.tar.gz
implemented 'emit' pragma
-rw-r--r--koch.nim4
-rwxr-xr-xrod/ccgstmts.nim68
-rwxr-xr-xrod/cgen.nim10
-rwxr-xr-xrod/commands.nim8
-rwxr-xr-xrod/pragmas.nim39
-rwxr-xr-xrod/semstmts.nim29
-rwxr-xr-xrod/wordrecg.nim6
-rwxr-xr-xtests/accept/run/spec.csv1
-rw-r--r--tests/accept/run/temit.nim14
-rwxr-xr-xweb/news.txt3
10 files changed, 108 insertions, 74 deletions
diff --git a/koch.nim b/koch.nim
index 4df8edbed..9e0ea1a54 100644
--- a/koch.nim
+++ b/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
 
diff --git a/rod/ccgstmts.nim b/rod/ccgstmts.nim
index b888b44c6..f98a59580 100755
--- a/rod/ccgstmts.nim
+++ b/rod/ccgstmts.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.
@@ -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: 
diff --git a/rod/cgen.nim b/rod/cgen.nim
index d4592c185..d57d5250a 100755
--- a/rod/cgen.nim
+++ b/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), 
diff --git a/rod/commands.nim b/rod/commands.nim
index b47bbf1bb..c5648afe5 100755
--- a/rod/commands.nim
+++ b/rod/commands.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.
@@ -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) = 
diff --git a/rod/pragmas.nim b/rod/pragmas.nim
index afbdbb5f4..d19c8d58e 100755
--- a/rod/pragmas.nim
+++ b/rod/pragmas.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.
@@ -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)
diff --git a/rod/semstmts.nim b/rod/semstmts.nim
index 95974e7be..0546c24dd 100755
--- a/rod/semstmts.nim
+++ b/rod/semstmts.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.
@@ -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
diff --git a/rod/wordrecg.nim b/rod/wordrecg.nim
index c64985846..42be7994b 100755
--- a/rod/wordrecg.nim
+++ b/rod/wordrecg.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.
@@ -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
diff --git a/tests/accept/run/spec.csv b/tests/accept/run/spec.csv
index 377c78a58..4bb94ed74 100755
--- a/tests/accept/run/spec.csv
+++ b/tests/accept/run/spec.csv
@@ -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
diff --git a/tests/accept/run/temit.nim b/tests/accept/run/temit.nim
new file mode 100644
index 000000000..81f9b53ae
--- /dev/null
+++ b/tests/accept/run/temit.nim
@@ -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()
+
+
diff --git a/web/news.txt b/web/news.txt
index 77b557558..80405e62e 100755
--- a/web/news.txt
+++ b/web/news.txt
@@ -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