summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2012-08-25 01:34:50 +0200
committerAraq <rumpf_a@web.de>2012-08-25 01:34:50 +0200
commit9a7f0cd8510a534a3f1e9d4275b8abd7825a94c6 (patch)
treef862293603c58003d24997781959820366284e8e
parent8a92e95ccfb2653d8cea52a83c26ac8967557062 (diff)
downloadNim-9a7f0cd8510a534a3f1e9d4275b8abd7825a94c6.tar.gz
bindSym suffices; no 'bind' for macros anymore
-rwxr-xr-xcompiler/ast.nim2
-rwxr-xr-xcompiler/evals.nim43
-rwxr-xr-xcompiler/semexprs.nim16
-rw-r--r--compiler/semmagic.nim19
-rwxr-xr-xcompiler/semstmts.nim18
-rwxr-xr-xdoc/manual.txt17
-rwxr-xr-xlib/core/macros.nim2
-rwxr-xr-xlib/pure/terminal.nim3
-rwxr-xr-xweb/news.txt1
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