when expressions, proper rendering for nkDo and nkLambda and parser support for x.type and x.addr

This commit is contained in:
Zahary Karadjov
2012-04-05 22:43:37 +03:00
parent 6d80583d5a
commit 98b7bdaa50
6 changed files with 55 additions and 19 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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})

View File

@@ -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])

View File

@@ -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