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
commit 98b7bdaa50
6 changed files with 55 additions and 19 deletions

View file

@ -143,7 +143,7 @@ type
nkPragma, # a pragma statement nkPragma, # a pragma statement
nkPragmaBlock, # a pragma with a block nkPragmaBlock, # a pragma with a block
nkIfStmt, # an if statement nkIfStmt, # an if statement
nkWhenStmt, # a when statement nkWhenStmt, # a when expression or statement
nkForStmt, # a for statement nkForStmt, # a for statement
nkWhileStmt, # a while statement nkWhileStmt, # a while statement
nkCaseStmt, # a case statement nkCaseStmt, # a case statement
@ -246,6 +246,11 @@ const
sfImmediate* = sfDeadCodeElim # macro or template is immediately expanded sfImmediate* = sfDeadCodeElim # macro or template is immediately expanded
# without considering any possible overloads # without considering any possible overloads
const
# getting ready for the future expr/stmt merge
nkWhen* = nkWhenStmt
nkWhenExpr* = nkWhenStmt
type type
TTypeKind* = enum # order is important! TTypeKind* = enum # order is important!
# Don't forget to change hti.nim if you make a change here # 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) optInd(p, a)
eat(p, endTok) eat(p, endTok)
proc newDotExpr(p: var TParser, a: PNode): PNode = proc dotExpr(p: var TParser, a: PNode): PNode =
getTok(p) getTok(p)
optInd(p, a) optInd(p, a)
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) result = newNodeI(nkDotExpr, a.info)
addSon(result, a) addSon(result, a)
addSon(result, parseSymbol(p)) addSon(result, parseSymbol(p))
proc qualifiedIdent(p: var TParser): PNode = proc qualifiedIdent(p: var TParser): PNode =
result = parseSymbol(p) #optInd(p, result); 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) = proc qualifiedIdentListAux(p: var TParser, endTok: TTokType, result: PNode) =
getTok(p) getTok(p)
@ -477,7 +487,7 @@ proc primary(p: var TParser): PNode =
exprColonEqExprListAux(p, nkExprEqExpr, tkParRi, tkEquals, result) exprColonEqExprListAux(p, nkExprEqExpr, tkParRi, tkEquals, result)
parseDoBlocks(p, result) parseDoBlocks(p, result)
of tkDot: of tkDot:
result = newDotExpr(p, result) result = dotExpr(p, result)
result = parseGStrLit(p, result) result = parseGStrLit(p, result)
of tkBracketLe: of tkBracketLe:
result = indexExprList(p, result, nkBracketExpr, tkBracketRi) result = indexExprList(p, result, nkBracketExpr, tkBracketRi)
@ -506,8 +516,8 @@ proc lowestExprAux(p: var TParser, limit: int): PNode =
proc lowestExpr(p: var TParser): PNode = proc lowestExpr(p: var TParser): PNode =
result = lowestExprAux(p, -1) result = lowestExprAux(p, -1)
proc parseIfExpr(p: var TParser): PNode = proc parseIfExpr(p: var TParser, kind: TNodeKind): PNode =
result = newNodeP(nkIfExpr, p) result = newNodeP(kind, p)
while true: while true:
getTok(p) # skip `if`, `elif` getTok(p) # skip `if`, `elif`
var branch = newNodeP(nkElifExpr, p) var branch = newNodeP(nkElifExpr, p)
@ -707,7 +717,8 @@ proc parseExpr(p: var TParser): PNode =
of tkType: result = parseTypeDescKAux(p, nkTypeOfExpr) of tkType: result = parseTypeDescKAux(p, nkTypeOfExpr)
of tkTuple: result = parseTuple(p) of tkTuple: result = parseTuple(p)
of tkProc: result = parseProcExpr(p, true) 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) else: result = lowestExpr(p)
proc parseTypeDesc(p: var TParser): PNode = proc parseTypeDesc(p: var TParser): PNode =
@ -718,7 +729,7 @@ proc isExprStart(p: TParser): bool =
case p.tok.tokType case p.tok.tokType
of tkSymbol, tkAccent, tkOpr, tkNot, tkNil, tkCast, tkIf, tkProc, tkBind, of tkSymbol, tkAccent, tkOpr, tkNot, tkNil, tkCast, tkIf, tkProc, tkBind,
tkParLe, tkBracketLe, tkCurlyLe, tkIntLit..tkCharLit, tkVar, tkRef, tkPtr, tkParLe, tkBracketLe, tkCurlyLe, tkIntLit..tkCharLit, tkVar, tkRef, tkPtr,
tkTuple, tkType: tkTuple, tkType, tkWhen:
result = true result = true
else: result = false else: result = false

View file

@ -349,7 +349,8 @@ proc lsub(n: PNode): int =
of nkBind: result = lsons(n) + len("bind_") of nkBind: result = lsons(n) + len("bind_")
of nkBindStmt: result = lcomma(n) + len("bind_") of nkBindStmt: result = lcomma(n) + len("bind_")
of nkCheckedFieldExpr: result = lsub(n.sons[0]) 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: of nkConstDef, nkIdentDefs:
result = lcomma(n, 0, - 3) result = lcomma(n, 0, - 3)
var L = sonsLen(n) var L = sonsLen(n)
@ -674,6 +675,16 @@ proc gident(g: var TSrcGen, n: PNode) =
put(g, t, s) put(g, t, s)
if n.kind == nkSym and renderIds in g.flags: put(g, tkIntLit, $n.sym.id) 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) = proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
if isNil(n): return if isNil(n): return
var var
@ -800,14 +811,19 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
gsub(g, n.sons[0]) gsub(g, n.sons[0])
of nkCheckedFieldExpr, nkHiddenAddr, nkHiddenDeref: of nkCheckedFieldExpr, nkHiddenAddr, nkHiddenDeref:
gsub(g, n.sons[0]) gsub(g, n.sons[0])
of nkLambda, nkDo: # XXX: nkDo is rendered as regular lambda of nkLambda:
assert(n.sons[genericParamsPos].kind == nkEmpty) putWithSpace(g, tkLambda, "proc")
putWithSpace(g, tkLambda, "lambda")
gsub(g, n.sons[paramsPos]) gsub(g, n.sons[paramsPos])
gsub(g, n.sons[pragmasPos]) gsub(g, n.sons[pragmasPos])
put(g, tkSpaces, Space) put(g, tkSpaces, Space)
putWithSpace(g, tkEquals, "=") putWithSpace(g, tkEquals, "=")
gsub(g, n.sons[bodyPos]) 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: of nkConstDef, nkIdentDefs:
gcomma(g, n, 0, - 3) gcomma(g, n, 0, - 3)
var L = sonsLen(n) var L = sonsLen(n)
@ -956,7 +972,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
of nkIfStmt: of nkIfStmt:
putWithSpace(g, tkIf, "if") putWithSpace(g, tkIf, "if")
gif(g, n) gif(g, n)
of nkWhenStmt, nkRecWhen: of nkWhen, nkRecWhen:
putWithSpace(g, tkWhen, "when") putWithSpace(g, tkWhen, "when")
gif(g, n) gif(g, n)
of nkWhileStmt: gwhile(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) result = semIndirectOp(c, n, flags)
of nkMacroStmt: of nkMacroStmt:
result = semMacroStmt(c, n) result = semMacroStmt(c, n)
of nkWhenExpr:
result = semWhen(c, n, false)
result = semExpr(c, result)
of nkBracketExpr: of nkBracketExpr:
checkMinSonsLen(n, 1) checkMinSonsLen(n, 1)
var s = qualifiedLookup(c, n.sons[0], {checkUndeclared}) 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): for i in countup(0, sonsLen(n) - 1):
var it = n.sons[i] var it = n.sons[i]
case it.kind case it.kind
of nkElifBranch: of nkElifBranch, nkElifExpr:
checkSonsLen(it, 2) checkSonsLen(it, 2)
var e = semAndEvalConstExpr(c, it.sons[0]) var e = semAndEvalConstExpr(c, it.sons[0])
if e.kind != nkIntLit: InternalError(n.info, "semWhen") if e.kind != nkIntLit: InternalError(n.info, "semWhen")
if e.intVal != 0 and result == nil: if e.intVal != 0 and result == nil:
setResult(it.sons[1]) setResult(it.sons[1])
of nkElse: of nkElse, nkElseExpr:
checkSonsLen(it, 1) checkSonsLen(it, 1)
if result == nil: if result == nil:
setResult(it.sons[0]) setResult(it.sons[0])

View file

@ -59,6 +59,7 @@ Language Additions
- ``addr`` is now treated like a prefix operator syntactically. - ``addr`` is now treated like a prefix operator syntactically.
- Added ``global`` pragma that can be used to introduce new global variables - 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 2012-02-09 Version 0.8.14 released