diff options
-rwxr-xr-x | compiler/ast.nim | 7 | ||||
-rwxr-xr-x | compiler/parser.nim | 31 | ||||
-rwxr-xr-x | compiler/renderer.nim | 26 | ||||
-rwxr-xr-x | compiler/semexprs.nim | 3 | ||||
-rwxr-xr-x | compiler/semstmts.nim | 4 | ||||
-rwxr-xr-x | web/news.txt | 3 |
6 files changed, 55 insertions, 19 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 897501ee5..972ba7924 100755 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -143,7 +143,7 @@ type nkPragma, # a pragma statement nkPragmaBlock, # a pragma with a block nkIfStmt, # an if statement - nkWhenStmt, # a when statement + nkWhenStmt, # a when expression or statement nkForStmt, # a for statement nkWhileStmt, # a while statement nkCaseStmt, # a case statement @@ -246,6 +246,11 @@ const sfImmediate* = sfDeadCodeElim # macro or template is immediately expanded # without considering any possible overloads +const + # getting ready for the future expr/stmt merge + nkWhen* = nkWhenStmt + nkWhenExpr* = nkWhenStmt + type TTypeKind* = enum # order is important! # Don't forget to change hti.nim if you make a change here diff --git a/compiler/parser.nim b/compiler/parser.nim index 2ba04ed1b..9563849c6 100755 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -264,16 +264,26 @@ proc exprList(p: var TParser, endTok: TTokType, result: PNode) = optInd(p, a) eat(p, endTok) -proc newDotExpr(p: var TParser, a: PNode): PNode = +proc dotExpr(p: var TParser, a: PNode): PNode = getTok(p) optInd(p, a) - result = newNodeI(nkDotExpr, a.info) - addSon(result, a) - addSon(result, parseSymbol(p)) + case p.tok.tokType + of tkType: + result = newNodeP(nkTypeOfExpr, p) + getTok(p) + addSon(result, a) + of tkAddr: + result = newNodeP(nkAddr, p) + getTok(p) + addSon(result, a) + else: + result = newNodeI(nkDotExpr, a.info) + addSon(result, a) + addSon(result, parseSymbol(p)) proc qualifiedIdent(p: var TParser): PNode = result = parseSymbol(p) #optInd(p, result); - if p.tok.tokType == tkDot: result = newDotExpr(p, result) + if p.tok.tokType == tkDot: result = dotExpr(p, result) proc qualifiedIdentListAux(p: var TParser, endTok: TTokType, result: PNode) = getTok(p) @@ -477,7 +487,7 @@ proc primary(p: var TParser): PNode = exprColonEqExprListAux(p, nkExprEqExpr, tkParRi, tkEquals, result) parseDoBlocks(p, result) of tkDot: - result = newDotExpr(p, result) + result = dotExpr(p, result) result = parseGStrLit(p, result) of tkBracketLe: result = indexExprList(p, result, nkBracketExpr, tkBracketRi) @@ -506,8 +516,8 @@ proc lowestExprAux(p: var TParser, limit: int): PNode = proc lowestExpr(p: var TParser): PNode = result = lowestExprAux(p, -1) -proc parseIfExpr(p: var TParser): PNode = - result = newNodeP(nkIfExpr, p) +proc parseIfExpr(p: var TParser, kind: TNodeKind): PNode = + result = newNodeP(kind, p) while true: getTok(p) # skip `if`, `elif` var branch = newNodeP(nkElifExpr, p) @@ -707,7 +717,8 @@ proc parseExpr(p: var TParser): PNode = of tkType: result = parseTypeDescKAux(p, nkTypeOfExpr) of tkTuple: result = parseTuple(p) of tkProc: result = parseProcExpr(p, true) - of tkIf: result = parseIfExpr(p) + of tkIf: result = parseIfExpr(p, nkIfExpr) + of tkWhen: result = parseIfExpr(p, nkWhenExpr) else: result = lowestExpr(p) proc parseTypeDesc(p: var TParser): PNode = @@ -718,7 +729,7 @@ proc isExprStart(p: TParser): bool = case p.tok.tokType of tkSymbol, tkAccent, tkOpr, tkNot, tkNil, tkCast, tkIf, tkProc, tkBind, tkParLe, tkBracketLe, tkCurlyLe, tkIntLit..tkCharLit, tkVar, tkRef, tkPtr, - tkTuple, tkType: + tkTuple, tkType, tkWhen: result = true else: result = false diff --git a/compiler/renderer.nim b/compiler/renderer.nim index 0be578a1a..6545b2e72 100755 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -349,7 +349,8 @@ proc lsub(n: PNode): int = of nkBind: result = lsons(n) + len("bind_") of nkBindStmt: result = lcomma(n) + len("bind_") of nkCheckedFieldExpr: result = lsub(n.sons[0]) - of nkLambda, nkDo: result = lsons(n) + len("lambda__=_") # XXX: render nkDo + of nkLambda: result = lsons(n) + len("proc__=_") + of nkDo: result = lsons(n) + len("do__:_") of nkConstDef, nkIdentDefs: result = lcomma(n, 0, - 3) var L = sonsLen(n) @@ -673,7 +674,17 @@ proc gident(g: var TSrcGen, n: PNode) = t = tkOpr put(g, t, s) if n.kind == nkSym and renderIds in g.flags: put(g, tkIntLit, $n.sym.id) + +proc doParamsAux(g: var TSrcGen, params: PNode) = + if params.len > 1: + put(g, tkParLe, "(") + gcomma(g, params, 1) + put(g, tkParRi, ")") + if params.sons[0].kind != nkEmpty: + putWithSpace(g, tkOpr, "->") + gsub(g, params.sons[0]) + proc gsub(g: var TSrcGen, n: PNode, c: TContext) = if isNil(n): return var @@ -800,14 +811,19 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = gsub(g, n.sons[0]) of nkCheckedFieldExpr, nkHiddenAddr, nkHiddenDeref: gsub(g, n.sons[0]) - of nkLambda, nkDo: # XXX: nkDo is rendered as regular lambda - assert(n.sons[genericParamsPos].kind == nkEmpty) - putWithSpace(g, tkLambda, "lambda") + of nkLambda: + putWithSpace(g, tkLambda, "proc") gsub(g, n.sons[paramsPos]) gsub(g, n.sons[pragmasPos]) put(g, tkSpaces, Space) putWithSpace(g, tkEquals, "=") gsub(g, n.sons[bodyPos]) + of nkDo: + putWithSpace(g, tkDo, "do") + doParamsAux(g, n.sons[paramsPos]) + gsub(g, n.sons[pragmasPos]) + put(g, tkColon, ":") + gsub(g, n.sons[bodyPos]) of nkConstDef, nkIdentDefs: gcomma(g, n, 0, - 3) var L = sonsLen(n) @@ -956,7 +972,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = of nkIfStmt: putWithSpace(g, tkIf, "if") gif(g, n) - of nkWhenStmt, nkRecWhen: + of nkWhen, nkRecWhen: putWithSpace(g, tkWhen, "when") gif(g, n) of nkWhileStmt: gwhile(g, n) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 2475492cc..8ab4c5f63 100755 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1356,6 +1356,9 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result = semIndirectOp(c, n, flags) of nkMacroStmt: result = semMacroStmt(c, n) + of nkWhenExpr: + result = semWhen(c, n, false) + result = semExpr(c, result) of nkBracketExpr: checkMinSonsLen(n, 1) var s = qualifiedLookup(c, n.sons[0], {checkUndeclared}) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 2de496b9a..0449c5644 100755 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -25,13 +25,13 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode = for i in countup(0, sonsLen(n) - 1): var it = n.sons[i] case it.kind - of nkElifBranch: + of nkElifBranch, nkElifExpr: checkSonsLen(it, 2) var e = semAndEvalConstExpr(c, it.sons[0]) if e.kind != nkIntLit: InternalError(n.info, "semWhen") if e.intVal != 0 and result == nil: setResult(it.sons[1]) - of nkElse: + of nkElse, nkElseExpr: checkSonsLen(it, 1) if result == nil: setResult(it.sons[0]) diff --git a/web/news.txt b/web/news.txt index fd2a50606..dd1d55a18 100755 --- a/web/news.txt +++ b/web/news.txt @@ -58,7 +58,8 @@ Language Additions - Added explicit ``static`` sections for enforced compile time evaluation. - ``addr`` is now treated like a prefix operator syntactically. - Added ``global`` pragma that can be used to introduce new global variables - from within procs. + from within procs. +- when expressions are now allowed just like if expressions 2012-02-09 Version 0.8.14 released |