parser support anon iterators

This commit is contained in:
Araq 2014-01-20 20:07:44 +01:00
commit 4a0aadef4d
8 changed files with 61 additions and 13 deletions

View file

@ -990,7 +990,7 @@ proc primary(p: var TParser, mode: TPrimaryMode): PNode =
of tkTuple: result = parseTuple(p, mode == pmTypeDef) of tkTuple: result = parseTuple(p, mode == pmTypeDef)
of tkProc: result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}) of tkProc: result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef})
of tkIterator: of tkIterator:
when true: when false:
if mode in {pmTypeDesc, pmTypeDef}: if mode in {pmTypeDesc, pmTypeDef}:
result = parseProcExpr(p, false) result = parseProcExpr(p, false)
result.kind = nkIteratorTy result.kind = nkIteratorTy
@ -1001,7 +1001,8 @@ proc primary(p: var TParser, mode: TPrimaryMode): PNode =
result = ast.emptyNode result = ast.emptyNode
else: else:
result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}) result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef})
result.kind = nkIteratorTy if result.kind == nkLambda: result.kind = nkIteratorDef
else: result.kind = nkIteratorTy
of tkEnum: of tkEnum:
if mode == pmTypeDef: if mode == pmTypeDef:
result = parseEnum(p) result = parseEnum(p)

View file

@ -922,7 +922,7 @@ proc activate(c: PContext, n: PNode) =
of nkCallKinds: of nkCallKinds:
for i in 1 .. <n.len: activate(c, n[i]) for i in 1 .. <n.len: activate(c, n[i])
else: else:
nil discard
proc maybeAddResult(c: PContext, s: PSym, n: PNode) = proc maybeAddResult(c: PContext, s: PSym, n: PNode) =
if s.typ.sons[0] != nil and if s.typ.sons[0] != nil and
@ -951,7 +951,11 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
var typeIsDetermined = false var typeIsDetermined = false
if n[namePos].kind != nkSym: if n[namePos].kind != nkSym:
assert phase == stepRegisterSymbol assert phase == stepRegisterSymbol
s = semIdentDef(c, n.sons[0], kind)
if n[namePos].kind == nkEmpty:
s = newSym(kind, idAnon, getCurrOwner(), n.info)
else:
s = semIdentDef(c, n.sons[0], kind)
n.sons[namePos] = newSymNode(s) n.sons[namePos] = newSymNode(s)
s.ast = n s.ast = n
s.scope = c.currentScope s.scope = c.currentScope

View file

@ -300,9 +300,12 @@ when not defined(booting):
## that should be inserted verbatim in the program ## that should be inserted verbatim in the program
## Example: ## Example:
## ##
## .. code-block:: nimrod
## emit("echo " & '"' & "hello world".toUpper & '"') ## emit("echo " & '"' & "hello world".toUpper & '"')
## ##
eval: result = e.parseStmt macro payload: stmt {.gensym.} =
result = e.parseStmt
payload()
proc expectKind*(n: PNimrodNode, k: TNimrodNodeKind) {.compileTime.} = proc expectKind*(n: PNimrodNode, k: TNimrodNodeKind) {.compileTime.} =
## checks that `n` is of kind `k`. If this is not the case, ## checks that `n` is of kind `k`. If this is not the case,
@ -645,10 +648,13 @@ iterator children*(n: PNimrodNode): PNimrodNode {.inline.}=
for i in 0 .. high(n): for i in 0 .. high(n):
yield n[i] yield n[i]
template findChild*(n: PNimrodNode; cond: expr): PNimrodNode {.immediate, dirty.} = template findChild*(n: PNimrodNode; cond: expr): PNimrodNode {.
## Find the first child node matching condition (or nil) immediate, dirty.} =
## var res = findChild(n, it.kind == nnkPostfix and it.basename.ident == !"foo") ## Find the first child node matching condition (or nil).
##
## .. code-block:: nimrod
## var res = findChild(n, it.kind == nnkPostfix and
## it.basename.ident == !"foo")
block: block:
var result: PNimrodNode var result: PNimrodNode
for it in n.children: for it in n.children:
@ -736,6 +742,6 @@ proc addIdentIfAbsent*(dest: PNimrodNode, ident: string) {.compiletime.} =
if ident.eqIdent($node): return if ident.eqIdent($node): return
of nnkExprColonExpr: of nnkExprColonExpr:
if ident.eqIdent($node[0]): return if ident.eqIdent($node[0]): return
else: nil else: discard
dest.add(ident(ident)) dest.add(ident(ident))

7
tests/macros/tmemit.nim Normal file
View file

@ -0,0 +1,7 @@
discard """
out: '''HELLO WORLD'''
"""
import macros, strutils
emit("echo " & '"' & "hello world".toUpper & '"')

View file

@ -0,0 +1,17 @@
discard """
file: "tdomulttest.nim"
output: "555\ntest\nmulti lines\n99999999\nend"
disabled: true
"""
proc foo(bar, baz: proc (x: int): int) =
echo bar(555)
echo baz(99999999)
foo do (x: int) -> int:
return x
do (x: int) -> int:
echo("test")
echo("multi lines")
return x
echo("end")

15
tests/parser/tinvwhen.nim Normal file
View file

@ -0,0 +1,15 @@
discard """
file: "tinvwhen.nim"
line: 11
errormsg: "invalid indentation"
"""
# This was parsed even though it should not!
proc chdir(path: cstring): cint {.importc: "chdir", header: "dirHeader".}
proc getcwd(buf: cstring, buflen: cint): cstring
when defined(unix): {.importc: "getcwd", header: "<unistd.h>".} #ERROR_MSG invalid indentation
elif defined(windows): {.importc: "getcwd", header: "<direct.h>"}
else: {.error: "os library not ported to your OS. Please help!".}

View file

@ -6,6 +6,7 @@ version 0.9.4
- ensure (ref T)(a, b) works as a type conversion and type constructor - ensure (ref T)(a, b) works as a type conversion and type constructor
- document new templating symbol binding rules - document new templating symbol binding rules
- make '--implicitStatic:on' the default - make '--implicitStatic:on' the default
- change comment handling in the AST
- special rule for ``[]=`` - special rule for ``[]=``
- ``=`` should be overloadable; requires specialization for ``=``; general - ``=`` should be overloadable; requires specialization for ``=``; general
@ -27,8 +28,6 @@ Bugs
- docgen: sometimes effects are listed twice - docgen: sometimes effects are listed twice
- 'result' is not properly cleaned for NRVO --> use uninit checking instead - 'result' is not properly cleaned for NRVO --> use uninit checking instead
- sneaking with qualifiedLookup() is really broken! - sneaking with qualifiedLookup() is really broken!
- aporia.nim(968, 5) Error: ambiguous identifier: 'DELETE' --
use a qualifier
- blocks can "export" an identifier but the CCG generates {} for them ... - blocks can "export" an identifier but the CCG generates {} for them ...
- osproc execProcesses can deadlock if all processes fail (as experienced - osproc execProcesses can deadlock if all processes fail (as experienced
in c++ mode) in c++ mode)
@ -54,7 +53,6 @@ version 0.9.X
- implement the missing features wrt inheritance - implement the missing features wrt inheritance
- better support for macros that rewrite procs - better support for macros that rewrite procs
- macros need access to types and symbols (partially implemented) - macros need access to types and symbols (partially implemented)
- perhaps: change comment handling in the AST
- enforce 'simpleExpr' more often --> doesn't work; tkProc is - enforce 'simpleExpr' more often --> doesn't work; tkProc is
part of primary! part of primary!
- the typeDesc/expr unification is weird and only necessary because of - the typeDesc/expr unification is weird and only necessary because of