mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-25 12:25:08 +00:00
when expressions, proper rendering for nkDo and nkLambda and parser support for x.type and x.addr
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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})
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user