summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2012-09-17 20:30:15 +0200
committerAraq <rumpf_a@web.de>2012-09-17 20:30:15 +0200
commit391fb89a3ea848c78f55b207c270060d3f1b467e (patch)
treea97e10569ceefc9992c4c0a4c73d2462546280ee /compiler
parentb83dce728114bada9efc975de4fcb6e829781167 (diff)
downloadNim-391fb89a3ea848c78f55b207c270060d3f1b467e.tar.gz
some support for passing blocks to overloaded templates/macros
Diffstat (limited to 'compiler')
-rwxr-xr-xcompiler/sem.nim3
-rwxr-xr-xcompiler/semexprs.nim32
2 files changed, 29 insertions, 6 deletions
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 1ccc29577..d13609b8a 100755
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -22,7 +22,8 @@ proc semPass*(): TPass
 
 type 
   TExprFlag = enum 
-    efLValue, efWantIterator, efInTypeof, efWantStmt
+    efLValue, efWantIterator, efInTypeof, efWantStmt, 
+    efMacroStmt # expr to semcheck is a macro statement
   TExprFlags = set[TExprFlag]
 
 proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index d60879e0b..ae9cf26d6 100755
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -292,8 +292,8 @@ proc semIs(c: PContext, n: PNode): PNode =
     LocalError(n.info, errXExpectsTwoArguments, "is")
   result = n
 
-proc semOpAux(c: PContext, n: PNode) =
-  for i in countup(1, sonsLen(n) - 1):
+proc semOpAux(c: PContext, n: PNode, tailToExclude = 1) =
+  for i in countup(1, sonsLen(n) - tailToExclude):
     var a = n.sons[i]
     if a.kind == nkExprEqExpr and sonsLen(a) == 2: 
       var info = a.sons[0].info
@@ -654,7 +654,8 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
 proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = 
   # this seems to be a hotspot in the compiler!
   let nOrig = n.copyTree
-  semOpAux(c, n)
+  semOpAux(c, n, 1 + ord(efMacroStmt in flags))
+  let flags = flags - {efMacroStmt}
   result = semOverloadedCallAnalyseEffects(c, n, nOrig, flags)
   if result == nil:
     result = overloadedCallOpr(c, n)
@@ -1417,6 +1418,22 @@ proc semBlockExpr(c: PContext, n: PNode): PNode =
   closeScope(c.tab)
   Dec(c.p.nestedBlockCounter)
 
+proc buildCall(n: PNode): PNode =
+  if n.kind == nkDotExpr and n.len == 2:
+    # x.y --> y(x)
+    result = newNodeI(nkCall, n.info, 2)
+    result.sons[0] = n.sons[1]
+    result.sons[1] = n.sons[0]
+  elif n.kind in nkCallKinds and n.sons[0].kind == nkDotExpr:
+    # x.y(a) -> y(x, a)
+    let a = n.sons[0]
+    result = newNodeI(nkDotCall, n.info, n.len+1)
+    result.sons[0] = a.sons[1]
+    result.sons[1] = a.sons[0]
+    for i in 1 .. <n.len: result.sons[i+1] = n.sons[i]
+  else:
+    result = n
+
 proc semMacroStmt(c: PContext, n: PNode, flags: TExprFlags, 
                   semCheck = true): PNode =
   checkMinSonsLen(n, 2)
@@ -1442,17 +1459,22 @@ proc semMacroStmt(c: PContext, n: PNode, flags: TExprFlags,
     case s.kind
     of skMacro:
       if sfImmediate notin s.flags:
-        result = semDirectOp(c, result, flags)
+        result = semDirectOp(c, result, flags+{efMacroStmt})
       else:
         result = semMacroExpr(c, result, n, s, semCheck)
     of skTemplate: 
       if sfImmediate notin s.flags:
-        result = semDirectOp(c, result, flags)
+        result = semDirectOp(c, result, flags+{efMacroStmt})
       else:
         result = semTemplateExpr(c, result, s, semCheck)
     else:
       LocalError(n.info, errXisNoMacroOrTemplate, s.name.s)
       result = errorNode(c, n)
+  elif a.kind == nkDotExpr:
+    # 'x.m(y): stmt' ==  nkMacroStmt(nkCall(nkDotExpr(x, m), y), stmt)
+    # -->                nkMacroStmt(nkCall(m, x, y), stmt)
+    n.sons[0] = buildCall(n.sons[0])
+    result = semMacroStmt(c, n, flags, semCheck)
   else:
     LocalError(n.info, errInvalidExpressionX, 
                renderTree(a, {renderNoComments}))