diff --git a/compiler/sem.nim b/compiler/sem.nim index 1ccc295777..d13609b8a1 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 d60879e0b1..ae9cf26d68 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 .. 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})) diff --git a/todo.txt b/todo.txt index dda33cf0a2..1fb3621569 100755 --- a/todo.txt +++ b/todo.txt @@ -2,7 +2,6 @@ version 0.9.0 ============= - make 'bind' default for templates and introduce 'mixin' -- make 'm: stmt' use overloading resolution - implicit deref for parameter matching - optimize genericAssign in the code generator