diff options
-rwxr-xr-x | compiler/semexprs.nim | 7 | ||||
-rwxr-xr-x | doc/grammar.txt | 5 | ||||
-rwxr-xr-x | doc/manual.txt | 5 | ||||
-rw-r--r-- | lib/pure/actors.nim | 3 | ||||
-rwxr-xr-x | lib/pure/xmldom.nim | 30 | ||||
-rwxr-xr-x | lib/system.nim | 3 | ||||
-rw-r--r-- | tests/accept/compile/tdumpast2.nim | 35 | ||||
-rwxr-xr-x | tests/accept/compile/toverprc.nim | 46 | ||||
-rwxr-xr-x | todo.txt | 2 |
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 |