45 lines
1.5 KiB
Nim
45 lines
1.5 KiB
Nim
import ../types
|
|
import utils
|
|
|
|
# below are the expressions that can contain statements in some way
|
|
# the only expressions that can contain a statement are:
|
|
# the block expression
|
|
proc statement*(par: Parser)
|
|
|
|
proc parseBlock(par: Parser): Node =
|
|
## Despite the name, can be used for statements if the arg statement is true
|
|
## Also can be used for function bodies
|
|
result = Node(kind: nkBlockExpr)
|
|
while par.current.tokenType != tkRightBrace and par.current.tokenType != tkEof:
|
|
result.children.add(par.statement())
|
|
|
|
par.consume(tkRightBrace, "Expect '}' after block.")
|
|
|
|
# statements
|
|
|
|
proc breakStatement(par: Parser): Node =
|
|
if not par.match(tkLabel):
|
|
par.error("Label expected after break.")
|
|
|
|
let label = comp.previous.text[1..^1]
|
|
result = Node(kind: nkBreak, label: label)
|
|
|
|
par.consume(tkSemicolon, "Semicolon expected after break statement.")
|
|
if par.current.tokenType != tkRightBrace:
|
|
par.error("Break statement must be the last element inside the innermost block it is in.")
|
|
|
|
proc statement*(par: Parser): Node =
|
|
if par.match(tkVar):
|
|
result = par.varStatement()
|
|
par.consume(tkSemicolon, "Semicolon expected after expression statement.")
|
|
elif par.match(tkDef):
|
|
result = par.procStatement()
|
|
par.consume(tkSemicolon, "Semicolon expected after procedure declaration.")
|
|
elif par.match(tkBreak):
|
|
result = par.breakStatement()
|
|
else:
|
|
result = Node(kind: nkExprStmt, expression: par.expression())
|
|
par.consume(tkSemicolon, "Semicolon expected after expression statement.")
|
|
|
|
if par.panicMode:
|
|
par.synchronize() |