summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xcompiler/semexprs.nim7
-rwxr-xr-xdoc/grammar.txt5
-rwxr-xr-xdoc/manual.txt5
-rw-r--r--lib/pure/actors.nim3
-rwxr-xr-xlib/pure/xmldom.nim30
-rwxr-xr-xlib/system.nim3
-rw-r--r--tests/accept/compile/tdumpast2.nim35
-rwxr-xr-xtests/accept/compile/toverprc.nim46
-rwxr-xr-xtodo.txt2
9 files changed, 91 insertions, 45 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 6dbbba7b8..3a8b827a0 100755
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -169,7 +169,7 @@ proc semConv(c: PContext, n: PNode, s: PSym): PNode =
 
 proc semCast(c: PContext, n: PNode): PNode = 
   if optSafeCode in gGlobalOptions: localError(n.info, errCastNotInSafeMode)
-  incl(c.p.owner.flags, sfSideEffect)
+  #incl(c.p.owner.flags, sfSideEffect)
   checkSonsLen(n, 2)
   result = newNodeI(nkCast, n.info)
   result.typ = semTypeNode(c, n.sons[0], nil)
@@ -453,9 +453,8 @@ proc semDirectCallAnalyseEffects(c: PContext, n: PNode,
     var callee = result.sons[0].sym
     if (callee.kind == skIterator) and (callee.id == c.p.owner.id): 
       GlobalError(n.info, errRecursiveDependencyX, callee.name.s)
-    if not (sfNoSideEffect in callee.flags): 
-      if (sfForward in callee.flags) or
-          ({sfImportc, sfSideEffect} * callee.flags != {}): 
+    if sfNoSideEffect notin callee.flags: 
+      if {sfImportc, sfSideEffect} * callee.flags != {}:
         incl(c.p.owner.flags, sfSideEffect)
   
 proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = 
diff --git a/doc/grammar.txt b/doc/grammar.txt
index 3e8c89a2e..9df8f57f4 100755
--- a/doc/grammar.txt
+++ b/doc/grammar.txt
@@ -96,7 +96,8 @@ simpleStmt ::= returnStmt
 complexStmt ::= ifStmt | whileStmt | caseStmt | tryStmt | forStmt
               | blockStmt | asmStmt
               | procDecl | iteratorDecl | macroDecl | templateDecl | methodDecl
-              | constSection | typeSection | whenStmt | varSection
+              | constSection | letSection | varSection
+              | typeSection | whenStmt
 
 indPush ::= IND # and push indentation onto the stack
 indPop ::= # pop indentation from the stack
@@ -157,6 +158,8 @@ colonAndEquals ::= [':' typeDesc] '=' expr
 constDecl ::= symbol ['*'] [pragma] colonAndEquals [COMMENT | IND COMMENT]
             | COMMENT
 constSection ::= 'const' indPush constDecl (SAD constDecl)* DED indPop
+letSection ::= 'let' indPush constDecl (SAD constDecl)* DED indPop
+
 typeDef ::= typeDesc | objectDef | enumDef | 'distinct' typeDesc
 
 objectField ::= symbol ['*'] [pragma]
diff --git a/doc/manual.txt b/doc/manual.txt
index 2002a2461..56c1fa95c 100755
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -442,6 +442,11 @@ The rules for compile-time computability are:
    computable arguments.

 

 

+Constants cannot be of type ``var`` or ``object``, nor can 

+they contain such a type. For the types ``ptr`` and ``ref`` only the

+constant literal ``nil`` is possible.

+

+

 Types

 -----

 

diff --git a/lib/pure/actors.nim b/lib/pure/actors.nim
index 4576cb602..091abc050 100644
--- a/lib/pure/actors.nim
+++ b/lib/pure/actors.nim
@@ -1,3 +1,6 @@
+discard """
+  cmd: "nimrod cc --hints:on --threads:on $# $#"
+"""
 #
 #
 #            Nimrod's Runtime Library
diff --git a/lib/pure/xmldom.nim b/lib/pure/xmldom.nim
index 923fc9e18..97cf3caeb 100755
--- a/lib/pure/xmldom.nim
+++ b/lib/pure/xmldom.nim
@@ -168,7 +168,7 @@ proc documentElement*(doc: PDocument): PElement =
 proc findNodes(nl: PNode, name: string): seq[PNode] =
   # Made for getElementsByTagName
   var r: seq[PNode] = @[]
-  if nl.childNodes == nil: return @[]
+  if isNil(nl.childNodes): return @[]
   if nl.childNodes.len() == 0: return @[]
 
   for i in items(nl.childNodes):
@@ -176,7 +176,7 @@ proc findNodes(nl: PNode, name: string): seq[PNode] =
       if i.FNodeName == name or name == "*":
         r.add(i)
         
-      if i.childNodes != nil:
+      if not isNil(i.childNodes):
         if i.childNodes.len() != 0:
           r.add(findNodes(i, name))
     
@@ -185,7 +185,7 @@ proc findNodes(nl: PNode, name: string): seq[PNode] =
 proc findNodesNS(nl: PNode, namespaceURI: string, localName: string): seq[PNode] =
   # Made for getElementsByTagNameNS
   var r: seq[PNode] = @[]
-  if nl.childNodes == nil: return @[]
+  if isNil(nl.childNodes): return @[]
   if nl.childNodes.len() == 0: return @[]
 
   for i in items(nl.childNodes):
@@ -193,7 +193,7 @@ proc findNodesNS(nl: PNode, namespaceURI: string, localName: string): seq[PNode]
       if (i.FNamespaceURI == namespaceURI or namespaceURI == "*") and (i.FLocalName == localName or localName == "*"):
         r.add(i)
         
-      if i.childNodes != nil:
+      if not isNil(i.childNodes):
         if i.childNodes.len() != 0:
           r.add(findNodesNS(i, namespaceURI, localName))
     
@@ -403,7 +403,7 @@ proc importNode*(doc: PDocument, importedNode: PNode, deep: bool): PNode =
     n.FParentNode = nil
     var tmp: seq[PNode] = n.childNodes
     n.childNodes = @[]
-    if deep == True:
+    if deep:
       for i in low(tmp.len())..high(tmp.len()):
         n.childNodes.add(importNode(doc, tmp[i], deep))
         
@@ -423,7 +423,7 @@ proc importNode*(doc: PDocument, importedNode: PNode, deep: bool): PNode =
     # Import the childNodes
     var tmp: seq[PNode] = n.childNodes
     n.childNodes = @[]
-    if deep == True:
+    if deep:
       for i in low(tmp.len())..high(tmp.len()):
         n.childNodes.add(importNode(doc, tmp[i], deep))
         
@@ -545,7 +545,7 @@ proc appendChild*(n: PNode, newChild: PNode) =
   ## If the newChild is already in the tree, it is first removed.
   
   # Check if n contains newChild
-  if n.childNodes != nil:
+  if not IsNil(n.childNodes):
     for i in low(n.childNodes)..high(n.childNodes):
       if n.childNodes[i] == newChild:
         raise newException(EHierarchyRequestErr, "The node to append is already in this nodes children.")
@@ -560,7 +560,7 @@ proc appendChild*(n: PNode, newChild: PNode) =
   if n.nodeType in childlessObjects:
     raise newException(ENoModificationAllowedErr, "Cannot append children to a childless node")
   
-  if n.childNodes == nil: n.childNodes = @[]
+  if isNil(n.childNodes): n.childNodes = @[]
     
   newChild.FParentNode = n
   for i in low(n.childNodes)..high(n.childNodes):
@@ -586,7 +586,7 @@ proc cloneNode*(n: PNode, deep: bool): PNode =
     # Import the childNodes
     var tmp: seq[PNode] = n.childNodes
     n.childNodes = @[]
-    if deep == True:
+    if deep:
       for i in low(tmp.len())..high(tmp.len()):
         n.childNodes.add(cloneNode(tmp[i], deep))
     return newNode
@@ -745,7 +745,7 @@ proc removeNamedItemNS*(NList: var seq[PNode], namespaceURI: string, localName:
 proc setNamedItem*(NList: var seq[PNode], arg: PNode): PNode =
   ## Adds ``arg`` as a ``Node`` to the ``NList``
   ## If a node with the same name is already present in this map, it is replaced by the new one.
-  if NList != nil:
+  if not isNil(NList):
     if NList.len() > 0:
       #Check if newChild is from this nodes document
       if NList[0].FOwnerDocument != arg.FOwnerDocument:
@@ -769,7 +769,7 @@ proc setNamedItem*(NList: var seq[PNode], arg: PNode): PNode =
 proc setNamedItem*(NList: var seq[PAttr], arg: PAttr): PAttr =
   ## Adds ``arg`` as a ``Node`` to the ``NList``
   ## If a node with the same name is already present in this map, it is replaced by the new one.
-  if NList != nil:
+  if not IsNil(NList):
     if NList.len() > 0:
       # Check if newChild is from this nodes document
       if NList[0].FOwnerDocument != arg.FOwnerDocument:
@@ -795,7 +795,7 @@ proc setNamedItem*(NList: var seq[PAttr], arg: PAttr): PAttr =
     
 proc setNamedItemNS*(NList: var seq[PNode], arg: PNode): PNode =
   ## Adds a node using its ``namespaceURI`` and ``localName``
-  if NList != nil:
+  if not IsNil(NList):
     if NList.len() > 0:
       # Check if newChild is from this nodes document
       if NList[0].FOwnerDocument != arg.FOwnerDocument:
@@ -818,7 +818,7 @@ proc setNamedItemNS*(NList: var seq[PNode], arg: PNode): PNode =
     
 proc setNamedItemNS*(NList: var seq[PAttr], arg: PAttr): PAttr =
   ## Adds a node using its ``namespaceURI`` and ``localName``
-  if NList != nil:
+  if not isNil(NList):
     if NList.len() > 0:
       # Check if newChild is from this nodes document
       if NList[0].FOwnerDocument != arg.FOwnerDocument:
@@ -957,7 +957,7 @@ proc setAttributeNode*(el: PElement, newAttr: PAttr): PAttr =
       "This attribute is in use by another element, use cloneNode")
   # Exceptions end
   
-  if el.attributes == nil: el.attributes = @[]
+  if isNil(el.attributes): el.attributes = @[]
   return el.attributes.setNamedItem(newAttr)
   
 proc setAttributeNodeNS*(el: PElement, newAttr: PAttr): PAttr =
@@ -975,7 +975,7 @@ proc setAttributeNodeNS*(el: PElement, newAttr: PAttr): PAttr =
       "This attribute is in use by another element, use cloneNode")
   # Exceptions end
   
-  if el.attributes == nil: el.attributes = @[]
+  if isNil(el.attributes): el.attributes = @[]
   return el.attributes.setNamedItemNS(newAttr)
 
 proc setAttribute*(el: PElement, name: string, value: string) =
diff --git a/lib/system.nim b/lib/system.nim
index 3fc4733b2..ea004b925 100755
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -1288,8 +1288,7 @@ proc pop*[T](s: var seq[T]): T {.inline, noSideEffect.} =
   result = s[L]
   setLen(s, L)
 
-proc each*[T, S](data: openArray[T], op: proc (x: T): S): seq[S] {.
-    noSideEffect.} = 
+proc each*[T, S](data: openArray[T], op: proc (x: T): S): seq[S] = 
   ## The well-known ``map`` operation from functional programming. Applies
   ## `op` to every item in `data` and returns the result as a sequence.
   newSeq(result, data.len)
diff --git a/tests/accept/compile/tdumpast2.nim b/tests/accept/compile/tdumpast2.nim
new file mode 100644
index 000000000..fb31af0ec
--- /dev/null
+++ b/tests/accept/compile/tdumpast2.nim
@@ -0,0 +1,35 @@
+# Dump the contents of a PNimrodNode
+
+import macros
+
+proc dumpit(n: PNimrodNode): string {.compileTime.} = 
+  if n == nil: return "nil"
+  result = $n.kind
+  add(result, "(")
+  case n.kind
+  of nnkEmpty: nil # same as nil node in this representation 
+  of nnkNilLit:                  add(result, "nil")
+  of nnkCharLit..nnkInt64Lit:    add(result, $n.intVal)
+  of nnkFloatLit..nnkFloat64Lit: add(result, $n.floatVal)
+  of nnkStrLit..nnkTripleStrLit: add(result, $n.strVal)
+  of nnkIdent:                   add(result, $n.ident)
+  of nnkSym, nnkNone:            assert false
+  else:
+    add(result, dumpit(n[0]))
+    for j in 1..n.len-1:
+      add(result, ", ")
+      add(result, dumpit(n[j]))
+  add(result, ")")
+  
+macro dumpAST(n: stmt): stmt = 
+  # dump AST as a side-effect and return the inner node
+  echo dumpit(n)
+  result = n[1]
+  
+dumpAST:
+  proc add(x, y: int): int =
+    return x + y
+  
+  proc sub(x, y: int): int = return x - y
+
+
diff --git a/tests/accept/compile/toverprc.nim b/tests/accept/compile/toverprc.nim
index f35528ace..43271b684 100755
--- a/tests/accept/compile/toverprc.nim
+++ b/tests/accept/compile/toverprc.nim
@@ -1,25 +1,27 @@
 # Test overloading of procs when used as function pointers

 

 import strutils

-
-proc parseInt(x: float): int = nil
-proc parseInt(x: bool): int = nil
-proc parseInt(x: float32): int = nil
-proc parseInt(x: int8): int = nil
-proc parseInt(x: TFile): int = nil
-proc parseInt(x: char): int = nil
-proc parseInt(x: int16): int = nil
-
-type
-  TParseInt = proc (x: string): int
-
-var
-  q = TParseInt(parseInt)
-  p: TParseInt = parseInt
-
-proc takeParseInt(x: proc (y: string): int): int = 
-  result = x("123")
-  
-echo "Give a list of numbers (separated by spaces): "
-var x = stdin.readline.split.each(parseInt).max
echo x, " is the maximum!"
echo "another number: ", takeParseInt(parseInt)
-
+

+proc parseInt(x: float): int {.noSideEffect.} = nil

+proc parseInt(x: bool): int {.noSideEffect.} = nil

+proc parseInt(x: float32): int {.noSideEffect.} = nil

+proc parseInt(x: int8): int {.noSideEffect.} = nil

+proc parseInt(x: TFile): int {.noSideEffect.} = nil

+proc parseInt(x: char): int {.noSideEffect.} = nil

+proc parseInt(x: int16): int {.noSideEffect.} = nil

+

+type

+  TParseInt = proc (x: string): int {.noSideEffect.}

+

+var

+  q = TParseInt(parseInt)

+  p: TParseInt = parseInt

+

+proc takeParseInt(x: proc (y: string): int {.noSideEffect.}): int = 

+  result = x("123")

+  

+echo "Give a list of numbers (separated by spaces): "

+var x = stdin.readline.split.each(parseInt).max

+echo x, " is the maximum!"

+echo "another number: ", takeParseInt(parseInt)

+

diff --git a/todo.txt b/todo.txt
index d8f0ac65a..6fff06b95 100755
--- a/todo.txt
+++ b/todo.txt
@@ -1,6 +1,7 @@
 Version 0.8.14
 ==============
 
+- 'let x = y'
 - threads should not have an inbox per default
 - make threadvar efficient again on linux after testing
 - fix the 'const' issues
@@ -8,7 +9,6 @@ Version 0.8.14
 - optional indentation for 'case' statement
 - taint mode
 - const ptr/ref
-- 'let x = y'
 - {.error.} pragma for proc headers