fixed some newly introduced bugs
This commit is contained in:
parent
57f184cf48
commit
2359b8b107
9 changed files with 91 additions and 45 deletions
|
|
@ -169,7 +169,7 @@ proc semConv(c: PContext, n: PNode, s: PSym): PNode =
|
||||||
|
|
||||||
proc semCast(c: PContext, n: PNode): PNode =
|
proc semCast(c: PContext, n: PNode): PNode =
|
||||||
if optSafeCode in gGlobalOptions: localError(n.info, errCastNotInSafeMode)
|
if optSafeCode in gGlobalOptions: localError(n.info, errCastNotInSafeMode)
|
||||||
incl(c.p.owner.flags, sfSideEffect)
|
#incl(c.p.owner.flags, sfSideEffect)
|
||||||
checkSonsLen(n, 2)
|
checkSonsLen(n, 2)
|
||||||
result = newNodeI(nkCast, n.info)
|
result = newNodeI(nkCast, n.info)
|
||||||
result.typ = semTypeNode(c, n.sons[0], nil)
|
result.typ = semTypeNode(c, n.sons[0], nil)
|
||||||
|
|
@ -453,9 +453,8 @@ proc semDirectCallAnalyseEffects(c: PContext, n: PNode,
|
||||||
var callee = result.sons[0].sym
|
var callee = result.sons[0].sym
|
||||||
if (callee.kind == skIterator) and (callee.id == c.p.owner.id):
|
if (callee.kind == skIterator) and (callee.id == c.p.owner.id):
|
||||||
GlobalError(n.info, errRecursiveDependencyX, callee.name.s)
|
GlobalError(n.info, errRecursiveDependencyX, callee.name.s)
|
||||||
if not (sfNoSideEffect in callee.flags):
|
if sfNoSideEffect notin callee.flags:
|
||||||
if (sfForward in callee.flags) or
|
if {sfImportc, sfSideEffect} * callee.flags != {}:
|
||||||
({sfImportc, sfSideEffect} * callee.flags != {}):
|
|
||||||
incl(c.p.owner.flags, sfSideEffect)
|
incl(c.p.owner.flags, sfSideEffect)
|
||||||
|
|
||||||
proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,8 @@ simpleStmt ::= returnStmt
|
||||||
complexStmt ::= ifStmt | whileStmt | caseStmt | tryStmt | forStmt
|
complexStmt ::= ifStmt | whileStmt | caseStmt | tryStmt | forStmt
|
||||||
| blockStmt | asmStmt
|
| blockStmt | asmStmt
|
||||||
| procDecl | iteratorDecl | macroDecl | templateDecl | methodDecl
|
| procDecl | iteratorDecl | macroDecl | templateDecl | methodDecl
|
||||||
| constSection | typeSection | whenStmt | varSection
|
| constSection | letSection | varSection
|
||||||
|
| typeSection | whenStmt
|
||||||
|
|
||||||
indPush ::= IND # and push indentation onto the stack
|
indPush ::= IND # and push indentation onto the stack
|
||||||
indPop ::= # pop indentation from the stack
|
indPop ::= # pop indentation from the stack
|
||||||
|
|
@ -157,6 +158,8 @@ colonAndEquals ::= [':' typeDesc] '=' expr
|
||||||
constDecl ::= symbol ['*'] [pragma] colonAndEquals [COMMENT | IND COMMENT]
|
constDecl ::= symbol ['*'] [pragma] colonAndEquals [COMMENT | IND COMMENT]
|
||||||
| COMMENT
|
| COMMENT
|
||||||
constSection ::= 'const' indPush constDecl (SAD constDecl)* DED indPop
|
constSection ::= 'const' indPush constDecl (SAD constDecl)* DED indPop
|
||||||
|
letSection ::= 'let' indPush constDecl (SAD constDecl)* DED indPop
|
||||||
|
|
||||||
typeDef ::= typeDesc | objectDef | enumDef | 'distinct' typeDesc
|
typeDef ::= typeDesc | objectDef | enumDef | 'distinct' typeDesc
|
||||||
|
|
||||||
objectField ::= symbol ['*'] [pragma]
|
objectField ::= symbol ['*'] [pragma]
|
||||||
|
|
|
||||||
|
|
@ -442,6 +442,11 @@ The rules for compile-time computability are:
|
||||||
computable arguments.
|
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
|
Types
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
discard """
|
||||||
|
cmd: "nimrod cc --hints:on --threads:on $# $#"
|
||||||
|
"""
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Nimrod's Runtime Library
|
# Nimrod's Runtime Library
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,7 @@ proc documentElement*(doc: PDocument): PElement =
|
||||||
proc findNodes(nl: PNode, name: string): seq[PNode] =
|
proc findNodes(nl: PNode, name: string): seq[PNode] =
|
||||||
# Made for getElementsByTagName
|
# Made for getElementsByTagName
|
||||||
var r: seq[PNode] = @[]
|
var r: seq[PNode] = @[]
|
||||||
if nl.childNodes == nil: return @[]
|
if isNil(nl.childNodes): return @[]
|
||||||
if nl.childNodes.len() == 0: return @[]
|
if nl.childNodes.len() == 0: return @[]
|
||||||
|
|
||||||
for i in items(nl.childNodes):
|
for i in items(nl.childNodes):
|
||||||
|
|
@ -176,7 +176,7 @@ proc findNodes(nl: PNode, name: string): seq[PNode] =
|
||||||
if i.FNodeName == name or name == "*":
|
if i.FNodeName == name or name == "*":
|
||||||
r.add(i)
|
r.add(i)
|
||||||
|
|
||||||
if i.childNodes != nil:
|
if not isNil(i.childNodes):
|
||||||
if i.childNodes.len() != 0:
|
if i.childNodes.len() != 0:
|
||||||
r.add(findNodes(i, name))
|
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] =
|
proc findNodesNS(nl: PNode, namespaceURI: string, localName: string): seq[PNode] =
|
||||||
# Made for getElementsByTagNameNS
|
# Made for getElementsByTagNameNS
|
||||||
var r: seq[PNode] = @[]
|
var r: seq[PNode] = @[]
|
||||||
if nl.childNodes == nil: return @[]
|
if isNil(nl.childNodes): return @[]
|
||||||
if nl.childNodes.len() == 0: return @[]
|
if nl.childNodes.len() == 0: return @[]
|
||||||
|
|
||||||
for i in items(nl.childNodes):
|
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 == "*"):
|
if (i.FNamespaceURI == namespaceURI or namespaceURI == "*") and (i.FLocalName == localName or localName == "*"):
|
||||||
r.add(i)
|
r.add(i)
|
||||||
|
|
||||||
if i.childNodes != nil:
|
if not isNil(i.childNodes):
|
||||||
if i.childNodes.len() != 0:
|
if i.childNodes.len() != 0:
|
||||||
r.add(findNodesNS(i, namespaceURI, localName))
|
r.add(findNodesNS(i, namespaceURI, localName))
|
||||||
|
|
||||||
|
|
@ -403,7 +403,7 @@ proc importNode*(doc: PDocument, importedNode: PNode, deep: bool): PNode =
|
||||||
n.FParentNode = nil
|
n.FParentNode = nil
|
||||||
var tmp: seq[PNode] = n.childNodes
|
var tmp: seq[PNode] = n.childNodes
|
||||||
n.childNodes = @[]
|
n.childNodes = @[]
|
||||||
if deep == True:
|
if deep:
|
||||||
for i in low(tmp.len())..high(tmp.len()):
|
for i in low(tmp.len())..high(tmp.len()):
|
||||||
n.childNodes.add(importNode(doc, tmp[i], deep))
|
n.childNodes.add(importNode(doc, tmp[i], deep))
|
||||||
|
|
||||||
|
|
@ -423,7 +423,7 @@ proc importNode*(doc: PDocument, importedNode: PNode, deep: bool): PNode =
|
||||||
# Import the childNodes
|
# Import the childNodes
|
||||||
var tmp: seq[PNode] = n.childNodes
|
var tmp: seq[PNode] = n.childNodes
|
||||||
n.childNodes = @[]
|
n.childNodes = @[]
|
||||||
if deep == True:
|
if deep:
|
||||||
for i in low(tmp.len())..high(tmp.len()):
|
for i in low(tmp.len())..high(tmp.len()):
|
||||||
n.childNodes.add(importNode(doc, tmp[i], deep))
|
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.
|
## If the newChild is already in the tree, it is first removed.
|
||||||
|
|
||||||
# Check if n contains newChild
|
# Check if n contains newChild
|
||||||
if n.childNodes != nil:
|
if not IsNil(n.childNodes):
|
||||||
for i in low(n.childNodes)..high(n.childNodes):
|
for i in low(n.childNodes)..high(n.childNodes):
|
||||||
if n.childNodes[i] == newChild:
|
if n.childNodes[i] == newChild:
|
||||||
raise newException(EHierarchyRequestErr, "The node to append is already in this nodes children.")
|
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:
|
if n.nodeType in childlessObjects:
|
||||||
raise newException(ENoModificationAllowedErr, "Cannot append children to a childless node")
|
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
|
newChild.FParentNode = n
|
||||||
for i in low(n.childNodes)..high(n.childNodes):
|
for i in low(n.childNodes)..high(n.childNodes):
|
||||||
|
|
@ -586,7 +586,7 @@ proc cloneNode*(n: PNode, deep: bool): PNode =
|
||||||
# Import the childNodes
|
# Import the childNodes
|
||||||
var tmp: seq[PNode] = n.childNodes
|
var tmp: seq[PNode] = n.childNodes
|
||||||
n.childNodes = @[]
|
n.childNodes = @[]
|
||||||
if deep == True:
|
if deep:
|
||||||
for i in low(tmp.len())..high(tmp.len()):
|
for i in low(tmp.len())..high(tmp.len()):
|
||||||
n.childNodes.add(cloneNode(tmp[i], deep))
|
n.childNodes.add(cloneNode(tmp[i], deep))
|
||||||
return newNode
|
return newNode
|
||||||
|
|
@ -745,7 +745,7 @@ proc removeNamedItemNS*(NList: var seq[PNode], namespaceURI: string, localName:
|
||||||
proc setNamedItem*(NList: var seq[PNode], arg: PNode): PNode =
|
proc setNamedItem*(NList: var seq[PNode], arg: PNode): PNode =
|
||||||
## Adds ``arg`` as a ``Node`` to the ``NList``
|
## 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 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:
|
if NList.len() > 0:
|
||||||
#Check if newChild is from this nodes document
|
#Check if newChild is from this nodes document
|
||||||
if NList[0].FOwnerDocument != arg.FOwnerDocument:
|
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 =
|
proc setNamedItem*(NList: var seq[PAttr], arg: PAttr): PAttr =
|
||||||
## Adds ``arg`` as a ``Node`` to the ``NList``
|
## 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 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:
|
if NList.len() > 0:
|
||||||
# Check if newChild is from this nodes document
|
# Check if newChild is from this nodes document
|
||||||
if NList[0].FOwnerDocument != arg.FOwnerDocument:
|
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 =
|
proc setNamedItemNS*(NList: var seq[PNode], arg: PNode): PNode =
|
||||||
## Adds a node using its ``namespaceURI`` and ``localName``
|
## Adds a node using its ``namespaceURI`` and ``localName``
|
||||||
if NList != nil:
|
if not IsNil(NList):
|
||||||
if NList.len() > 0:
|
if NList.len() > 0:
|
||||||
# Check if newChild is from this nodes document
|
# Check if newChild is from this nodes document
|
||||||
if NList[0].FOwnerDocument != arg.FOwnerDocument:
|
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 =
|
proc setNamedItemNS*(NList: var seq[PAttr], arg: PAttr): PAttr =
|
||||||
## Adds a node using its ``namespaceURI`` and ``localName``
|
## Adds a node using its ``namespaceURI`` and ``localName``
|
||||||
if NList != nil:
|
if not isNil(NList):
|
||||||
if NList.len() > 0:
|
if NList.len() > 0:
|
||||||
# Check if newChild is from this nodes document
|
# Check if newChild is from this nodes document
|
||||||
if NList[0].FOwnerDocument != arg.FOwnerDocument:
|
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")
|
"This attribute is in use by another element, use cloneNode")
|
||||||
# Exceptions end
|
# Exceptions end
|
||||||
|
|
||||||
if el.attributes == nil: el.attributes = @[]
|
if isNil(el.attributes): el.attributes = @[]
|
||||||
return el.attributes.setNamedItem(newAttr)
|
return el.attributes.setNamedItem(newAttr)
|
||||||
|
|
||||||
proc setAttributeNodeNS*(el: PElement, newAttr: PAttr): PAttr =
|
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")
|
"This attribute is in use by another element, use cloneNode")
|
||||||
# Exceptions end
|
# Exceptions end
|
||||||
|
|
||||||
if el.attributes == nil: el.attributes = @[]
|
if isNil(el.attributes): el.attributes = @[]
|
||||||
return el.attributes.setNamedItemNS(newAttr)
|
return el.attributes.setNamedItemNS(newAttr)
|
||||||
|
|
||||||
proc setAttribute*(el: PElement, name: string, value: string) =
|
proc setAttribute*(el: PElement, name: string, value: string) =
|
||||||
|
|
|
||||||
|
|
@ -1288,8 +1288,7 @@ proc pop*[T](s: var seq[T]): T {.inline, noSideEffect.} =
|
||||||
result = s[L]
|
result = s[L]
|
||||||
setLen(s, L)
|
setLen(s, L)
|
||||||
|
|
||||||
proc each*[T, S](data: openArray[T], op: proc (x: T): S): seq[S] {.
|
proc each*[T, S](data: openArray[T], op: proc (x: T): S): seq[S] =
|
||||||
noSideEffect.} =
|
|
||||||
## The well-known ``map`` operation from functional programming. Applies
|
## The well-known ``map`` operation from functional programming. Applies
|
||||||
## `op` to every item in `data` and returns the result as a sequence.
|
## `op` to every item in `data` and returns the result as a sequence.
|
||||||
newSeq(result, data.len)
|
newSeq(result, data.len)
|
||||||
|
|
|
||||||
35
tests/accept/compile/tdumpast2.nim
Normal file
35
tests/accept/compile/tdumpast2.nim
Normal file
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2,24 +2,26 @@
|
||||||
|
|
||||||
import strutils
|
import strutils
|
||||||
|
|
||||||
proc parseInt(x: float): int = nil
|
proc parseInt(x: float): int {.noSideEffect.} = nil
|
||||||
proc parseInt(x: bool): int = nil
|
proc parseInt(x: bool): int {.noSideEffect.} = nil
|
||||||
proc parseInt(x: float32): int = nil
|
proc parseInt(x: float32): int {.noSideEffect.} = nil
|
||||||
proc parseInt(x: int8): int = nil
|
proc parseInt(x: int8): int {.noSideEffect.} = nil
|
||||||
proc parseInt(x: TFile): int = nil
|
proc parseInt(x: TFile): int {.noSideEffect.} = nil
|
||||||
proc parseInt(x: char): int = nil
|
proc parseInt(x: char): int {.noSideEffect.} = nil
|
||||||
proc parseInt(x: int16): int = nil
|
proc parseInt(x: int16): int {.noSideEffect.} = nil
|
||||||
|
|
||||||
type
|
type
|
||||||
TParseInt = proc (x: string): int
|
TParseInt = proc (x: string): int {.noSideEffect.}
|
||||||
|
|
||||||
var
|
var
|
||||||
q = TParseInt(parseInt)
|
q = TParseInt(parseInt)
|
||||||
p: TParseInt = parseInt
|
p: TParseInt = parseInt
|
||||||
|
|
||||||
proc takeParseInt(x: proc (y: string): int): int =
|
proc takeParseInt(x: proc (y: string): int {.noSideEffect.}): int =
|
||||||
result = x("123")
|
result = x("123")
|
||||||
|
|
||||||
echo "Give a list of numbers (separated by spaces): "
|
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)
|
var x = stdin.readline.split.each(parseInt).max
|
||||||
|
echo x, " is the maximum!"
|
||||||
|
echo "another number: ", takeParseInt(parseInt)
|
||||||
|
|
||||||
|
|
|
||||||
2
todo.txt
2
todo.txt
|
|
@ -1,6 +1,7 @@
|
||||||
Version 0.8.14
|
Version 0.8.14
|
||||||
==============
|
==============
|
||||||
|
|
||||||
|
- 'let x = y'
|
||||||
- threads should not have an inbox per default
|
- threads should not have an inbox per default
|
||||||
- make threadvar efficient again on linux after testing
|
- make threadvar efficient again on linux after testing
|
||||||
- fix the 'const' issues
|
- fix the 'const' issues
|
||||||
|
|
@ -8,7 +9,6 @@ Version 0.8.14
|
||||||
- optional indentation for 'case' statement
|
- optional indentation for 'case' statement
|
||||||
- taint mode
|
- taint mode
|
||||||
- const ptr/ref
|
- const ptr/ref
|
||||||
- 'let x = y'
|
|
||||||
- {.error.} pragma for proc headers
|
- {.error.} pragma for proc headers
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue