diff options
author | Araq <rumpf_a@web.de> | 2012-08-25 01:34:50 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2012-08-25 01:34:50 +0200 |
commit | 9a7f0cd8510a534a3f1e9d4275b8abd7825a94c6 (patch) | |
tree | f862293603c58003d24997781959820366284e8e | |
parent | 8a92e95ccfb2653d8cea52a83c26ac8967557062 (diff) | |
download | Nim-9a7f0cd8510a534a3f1e9d4275b8abd7825a94c6.tar.gz |
bindSym suffices; no 'bind' for macros anymore
-rwxr-xr-x | compiler/ast.nim | 2 | ||||
-rwxr-xr-x | compiler/evals.nim | 43 | ||||
-rwxr-xr-x | compiler/semexprs.nim | 16 | ||||
-rw-r--r-- | compiler/semmagic.nim | 19 | ||||
-rwxr-xr-x | compiler/semstmts.nim | 18 | ||||
-rwxr-xr-x | doc/manual.txt | 17 | ||||
-rwxr-xr-x | lib/core/macros.nim | 2 | ||||
-rwxr-xr-x | lib/pure/terminal.nim | 3 | ||||
-rwxr-xr-x | web/news.txt | 1 |
9 files changed, 48 insertions, 73 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index ae8beace7..a6f169384 100755 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -440,7 +440,7 @@ type mNIntVal, mNFloatVal, mNSymbol, mNIdent, mNGetType, mNStrVal, mNSetIntVal, mNSetFloatVal, mNSetSymbol, mNSetIdent, mNSetType, mNSetStrVal, mNLineInfo, mNNewNimNode, mNCopyNimNode, mNCopyNimTree, mStrToIdent, mIdentToStr, - mNGetBoundSym, + mNBindSym, mEqIdent, mEqNimrodNode, mNHint, mNWarning, mNError, mInstantiationInfo, mGetTypeInfo diff --git a/compiler/evals.nim b/compiler/evals.nim index b107015eb..4ec6cb4d7 100755 --- a/compiler/evals.nim +++ b/compiler/evals.nim @@ -40,7 +40,6 @@ type lastException*: PNode mode*: TEvalMode globals*: TIdNodeTable # state of global vars - boundSyms: TStrTable # for 'bind' support within macros PEvalContext* = ref TEvalContext @@ -66,7 +65,6 @@ proc newEvalContext*(module: PSym, filename: string, result.module = module result.mode = mode initIdNodeTable(result.globals) - initStrTable(result.boundSyms) proc pushStackFrame*(c: PEvalContext, t: PStackFrame) {.inline.} = t.next = c.tos @@ -933,26 +931,6 @@ proc evalExpandToAst(c: PEvalContext, original: PNode): PNode = "ExpandToAst: expanded symbol is no macro or template") result = emptyNode -proc getBoundSym(c: PEvalContext, n: PNode): PNode = - # we return either an nkSym or an nkSymChoice; XXX we really need - # to distinguish between open and closed nkSymChoice somehow. - var ident = getIdent(n.strVal) - - # semantic checking requires a type; ``fitNode`` deals with it - # appropriately - result = newNodeIT(nkSymChoice, n.info, newType(tyNone, c.module)) - - var ii: TIdentIter - var a = InitIdentIter(ii, c.boundSyms, ident) - while a != nil: - incl(a.flags, sfUsed) - addSon(result, newSymNode(a, n.info)) - a = NextIdentIter(ii, c.boundSyms) - case result.len - of 0: stackTrace(c, n, errUndeclaredIdentifier, n.strVal) - of 1: result = result.sons[0] - else: nil - proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode = var m = getMagic(n) case m @@ -1173,13 +1151,9 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode = result = evalAux(c, n.sons[1], {efLValue}) if isSpecial(result): return result = copyTree(result) - of mNGetBoundSym: - result = evalAux(c, n.sons[1], {}) - if isSpecial(result): return - if not (result.kind in {nkStrLit..nkTripleStrLit}): - stackTrace(c, n, errFieldXNotFound, "getBoundSym") - return - result = getBoundSym(c, result) + of mNBindSym: + # trivial implementation: + result = n.sons[1] of mStrToIdent: result = evalAux(c, n.sons[1], {}) if isSpecial(result): return @@ -1268,12 +1242,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode = cc = result if isEmpty(a) or isEmpty(b) or isEmpty(cc): result = emptyNode else: result = evalOp(m, n, a, b, cc) - -proc evalBindStmt(c: PEvalContext, n: PNode) = - for i in 0 .. < n.len: - let a = n.sons[i] - if a.kind == nkSym: StrTableAdd(c.boundSyms, a.sym) - + proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode = result = emptyNode dec(gNestedEvals) @@ -1344,10 +1313,8 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode = result.typ = n.typ of nkPragmaBlock: result = evalAux(c, n.sons[1], flags) - of nkBindStmt: - evalBindStmt(c, n) of nkIdentDefs, nkCast, nkYieldStmt, nkAsmStmt, nkForStmt, nkPragmaExpr, - nkLambdaKinds, nkContinueStmt, nkIdent, nkParForStmt: + nkLambdaKinds, nkContinueStmt, nkIdent, nkParForStmt, nkBindStmt: result = raiseCannotEval(c, n.info) of nkRefTy: result = evalAux(c, n.sons[0], flags) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index e20a518e5..cd53d6501 100755 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -342,6 +342,19 @@ proc changeType(n: PNode, newType: PType) = else: nil n.typ = newType +proc arrayConstrType(c: PContext, n: PNode): PType = + var typ = newTypeS(tyArrayConstr, c) + rawAddSon(typ, nil) # index type + if sonsLen(n) == 0: + rawAddSon(typ, newTypeS(tyEmpty, c)) # needs an empty basetype! + else: + var x = n.sons[0] + var lastIndex: biggestInt = sonsLen(n) - 1 + var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyOrdinal}) + addSonSkipIntLit(typ, t) + typ.sons[0] = makeRangeType(c, 0, sonsLen(n) - 1, n.info) + result = typ + proc semArrayConstr(c: PContext, n: PNode): PNode = result = newNodeI(nkBracket, n.info) result.typ = newTypeS(tyArrayConstr, c) @@ -382,7 +395,8 @@ proc fixAbstractType(c: PContext, n: PNode) = case it.kind of nkHiddenStdConv, nkHiddenSubConv: if it.sons[1].kind == nkBracket: - it.sons[1] = semArrayConstr(c, it.sons[1]) + it.sons[1].typ = arrayConstrType(c, it.sons[1]) + #it.sons[1] = semArrayConstr(c, it.sons[1]) if skipTypes(it.typ, abstractVar).kind in {tyOpenArray, tyVarargs}: #if n.sons[0].kind == nkSym and IdentEq(n.sons[0].sym.name, "[]="): # debug(n) diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index c6a5aaa73..b4cc1727d 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -45,6 +45,24 @@ proc semOrd(c: PContext, n: PNode): PNode = result.typ = makeRangeType(c, firstOrd(n.sons[1].typ), lastOrd(n.sons[1].typ), n.info) +proc semBindSym(c: PContext, n: PNode): PNode = + result = copyNode(n) + result.add(n.sons[0]) + + let sl = c.semConstExpr(c, n.sons[1]) + if sl.kind notin {nkStrLit, nkRStrLit, nkTripleStrLit}: + LocalError(n.info, errStringLiteralExpected) + return errorNode(c, n) + + let id = newIdentNode(getIdent(sl.strVal), n.info) + let s = QualifiedLookUp(c, id) + if s != nil: + # we need to mark all symbols: + let sc = symChoice(c, id, s) + result.add(sc) + else: + LocalError(n.sons[1].info, errUndeclaredIdentifier, sl.strVal) + proc semShallowCopy(c: PContext, n: PNode, flags: TExprFlags): PNode proc magicsAfterOverloadResolution(c: PContext, n: PNode, flags: TExprFlags): PNode = @@ -57,5 +75,6 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode, of mInstantiationInfo: result = semInstantiationInfo(c, n) of mOrd: result = semOrd(c, n) of mShallowCopy: result = semShallowCopy(c, n, flags) + of mNBindSym: result = semBindSym(c, n) else: result = n diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 3bd368b7e..b8bf9e970 100755 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1118,22 +1118,6 @@ proc insertDestructors(c: PContext, varSection: PNode): return -proc semBindStmtForMacro(c: PContext, n: PNode): PNode = - if c.p.owner.kind != skMacro: - LocalError(n.info, errXNotAllowedHere, "bind") - result = newNodeI(nkBindStmt, n.info) - for i in 0 .. < n.len: - var a = n.sons[i] - let s = QualifiedLookUp(c, a) - if s != nil: - # we need to mark all symbols: - let sc = symChoice(c, a, s) - if sc.kind == nkSym: result.add(sc) - else: - for x in items(sc): result.add(x) - else: - illFormedAst(a) - proc SemStmt(c: PContext, n: PNode): PNode = const # must be last statements in a block: LastBlockStmts = {nkRaiseStmt, nkReturnStmt, nkBreakStmt, nkContinueStmt} @@ -1222,8 +1206,6 @@ proc SemStmt(c: PContext, n: PNode): PNode = result = semPragmaBlock(c, n) of nkStaticStmt: result = semStaticStmt(c, n) - of nkBindStmt: - result = semBindStmtForMacro(c, n) else: # in interactive mode, we embed the expression in an 'echo': if gCmd == cmdInteractive: diff --git a/doc/manual.txt b/doc/manual.txt index 6fccd0ca3..a78af89a6 100755 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -3154,27 +3154,22 @@ The macro call expands to: writeln(stdout, x) -Bind in macros -~~~~~~~~~~~~~~ +BindSym +~~~~~~~ The above ``debug`` macro relies on the fact that ``write``, ``writeln`` and ``stdout`` are declared in the system module and thus visible in the instantiating context. There is a way to use bound identifiers -(aka `symbols`:idx) instead of using unbound identifiers. The ``bind`` -statement plus the ``bindSym`` builtin can be used for that: +(aka `symbols`:idx) instead of using unbound identifiers. The ``bindSym`` +builtin can be used for that: .. code-block:: nimrod - # to work with Nimrod syntax trees, we need an API that is defined in the - # ``macros`` module: import macros macro debug(n: expr): stmt = - # we need to declare the used symbols here: - bind write, writeln, stdout result = newNimNode(nnkStmtList, n) - # iterate over any argument that is passed to this macro: for i in 1..n.len-1: - # we can access the bound symbol via 'bindSym': + # we can bind symbols in scope via 'bindSym': add(result, newCall(bindSym"write", bindSym"stdout", toStrLit(n[i]))) add(result, newCall(bindSym"write", bindSym"stdout", newStrLitNode(": "))) add(result, newCall(bindSym"writeln", bindSym"stdout", n[i])) @@ -3203,7 +3198,7 @@ The macro call expands to: writeln(stdout, x) However, the symbols ``write``, ``writeln`` and ``stdout`` are already bound -and are not looked up again. As the example shows, ``bind`` does work with +and are not looked up again. As the example shows, ``bindSym`` does work with overloaded symbols implicitely. diff --git a/lib/core/macros.nim b/lib/core/macros.nim index d02aba0ca..30248528e 100755 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -186,7 +186,7 @@ proc newIdentNode*(i: string): PNimrodNode {.compileTime.} = result = newNimNode(nnkIdent) result.ident = !i -proc bindSym*(ident: string): PNimrodNode {.magic: "NGetBoundSym".} +proc bindSym*(ident: string): PNimrodNode {.magic: "NBindSym".} ## creates a node that binds `ident` to a symbol node. The bound symbol ## needs to be predeclared in a ``bind`` statement! diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim index 5a82586cb..d24d81112 100755 --- a/lib/pure/terminal.nim +++ b/lib/pure/terminal.nim @@ -326,8 +326,7 @@ proc styledEchoProcessArg(color: TForegroundColor) = setForeGroundColor color proc styledEchoProcessArg(color: TBackgroundColor) = setBackGroundColor color macro styledEcho*(m: stmt): stmt = - bind styledEchoProcessArg, write, resetAttributes, stdout - + ## to be documented. result = newNimNode(nnkStmtList) for i in countup(1, m.len - 1): diff --git a/web/news.txt b/web/news.txt index f67e4d74b..e456f70f3 100755 --- a/web/news.txt +++ b/web/news.txt @@ -160,7 +160,6 @@ Language Additions in templates. - Comments can be continued with a backslash continuation character so that comment pieces don't have to align on the same column. -- Macros support the ``bind`` statement. 2012-02-09 Version 0.8.14 released |