summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2012-07-20 08:49:42 +0200
committerAraq <rumpf_a@web.de>2012-07-20 08:49:42 +0200
commit1c6f14deeeb3dc6acb41efba886e4999a8621a4a (patch)
treefc7d16bef573ed2423bc8961f9b6ebba681ea4ed /compiler
parent43f057c5aa23cf2cc441906737cd53fda90811c7 (diff)
downloadNim-1c6f14deeeb3dc6acb41efba886e4999a8621a4a.tar.gz
added system.compiles
Diffstat (limited to 'compiler')
-rwxr-xr-xcompiler/ast.nim3
-rwxr-xr-xcompiler/msgs.nim8
-rwxr-xr-xcompiler/semdata.nim3
-rwxr-xr-xcompiler/semexprs.nim30
4 files changed, 39 insertions, 5 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index c826dfad9..669b45159 100755
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -381,7 +381,8 @@ const
 type
   TMagic* = enum # symbols that require compiler magic:
     mNone,
-    mDefined, mDefinedInScope, mLow, mHigh, mSizeOf, mTypeTrait, mIs, mOf,
+    mDefined, mDefinedInScope, mCompiles,
+    mLow, mHigh, mSizeOf, mTypeTrait, mIs, mOf,
     mEcho, mShallowCopy, mSlurp, mStaticExec,
     mParseExprToAst, mParseStmtToAst, mExpandToAst,
     mUnaryLt, mSucc, 
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index a661da0e1..30066d376 100755
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -458,6 +458,7 @@ var
   gHintCounter*: int = 0
   gWarnCounter*: int = 0
   gErrorMax*: int = 1         # stop after gErrorMax errors
+  gSilence*: int              # == 0 if we produce any output at all 
   
 # this format is understood by many text editors: it is the same that
 # Borland and Freepascal use
@@ -528,12 +529,13 @@ proc addCheckpoint*(filename: string, line: int) =
 
 proc OutWriteln*(s: string) = 
   ## Writes to stdout. Always.
-  Writeln(stdout, s)
+  if gSilence == 0: Writeln(stdout, s)
  
 proc MsgWriteln*(s: string) = 
   ## Writes to stdout. If --stdout option is given, writes to stderr instead.
-  if optStdout in gGlobalOptions: Writeln(stderr, s)
-  else: Writeln(stdout, s)
+  if gSilence == 0:
+    if optStdout in gGlobalOptions: Writeln(stderr, s)
+    else: Writeln(stdout, s)
 
 proc coordToStr(coord: int): string = 
   if coord == -1: result = "???"
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index 74e82db61..76ceafecf 100755
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -63,6 +63,7 @@ type
                                # store this info in the syms themselves!)
     InGenericContext*: int     # > 0 if we are in a generic
     InUnrolledContext*: int    # > 0 if we are unrolling a loop
+    InCompilesContext*: int    # > 0 if we are in a ``compiles`` magic
     converters*: TSymSeq       # sequence of converters
     optionStack*: TLinkedList
     libs*: TLinkedList         # all libs used by this module
@@ -100,7 +101,7 @@ proc PushOwner*(owner: PSym)
 proc PopOwner*()
 # implementation
 
-var gOwners: seq[PSym] = @[]
+var gOwners*: seq[PSym] = @[]
 
 proc getCurrOwner(): PSym = 
   # owner stack (used for initializing the
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index a0e7c329c..63a19c879 100755
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1103,12 +1103,42 @@ proc semExpandToAst(c: PContext, n: PNode, magicSym: PSym,
   else:
     result = semDirectOp(c, n, flags)
 
+proc semCompiles(c: PContext, n: PNode, flags: TExprFlags): PNode =
+  # we replace this node by a 'true' or 'false' node:
+  if sonsLen(n) != 2: return semDirectOp(c, n, flags)
+  result = newIntNode(nkIntLit, 0)
+  result.info = n.info
+  result.typ = getSysType(tyBool)
+  # watch out, hacks ahead:
+  let oldErrorCount = msgs.gErrorCounter
+  let oldErrorMax = msgs.gErrorMax
+  inc c.InCompilesContext
+  inc msgs.gSilence
+  # do not halt after first error:
+  msgs.gErrorMax = high(int)
+  
+  let oldTos = c.tab.tos
+  let oldOwnerLen = len(gOwners)
+  try:
+    discard semExpr(c, n.sons[1])
+    result.intVal = ord(msgs.gErrorCounter == oldErrorCount)
+  except ERecoverableError:
+    nil
+  # undo symbol table changes (as far as it's possible):
+  setlen(gOwners, oldOwnerLen)
+  while c.tab.tos > oldTos: rawCloseScope(c.tab)
+  dec c.InCompilesContext
+  dec msgs.gSilence
+  msgs.gErrorCounter = oldErrorCount
+  msgs.gErrorMax = oldErrorMax
+
 proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = 
   # this is a hotspot in the compiler!
   result = n
   case s.magic # magics that need special treatment
   of mDefined: result = semDefined(c, setMs(n, s), false)
   of mDefinedInScope: result = semDefined(c, setMs(n, s), true)
+  of mCompiles: result = semCompiles(c, setMs(n, s), flags)
   of mLow: result = semLowHigh(c, setMs(n, s), mLow)
   of mHigh: result = semLowHigh(c, setMs(n, s), mHigh)
   of mSizeOf: result = semSizeof(c, setMs(n, s))