66 lines
2.0 KiB
Nim
66 lines
2.0 KiB
Nim
{.used.}
|
|
|
|
import ../scanner
|
|
import ../chunk
|
|
|
|
import types
|
|
import utils
|
|
import precedence
|
|
import scope
|
|
import variables
|
|
|
|
# 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*(comp: Compiler)
|
|
|
|
proc parseBlock(comp: Compiler) =
|
|
## Despite the name, can be used for statements if the arg statement is true
|
|
## Also can be used for function bodies
|
|
comp.beginScope()
|
|
while comp.current.tokenType != tkRightBrace and comp.current.tokenType != tkEof:
|
|
comp.statement()
|
|
discard comp.endScope()
|
|
|
|
comp.consume(tkRightBrace, "Expect '}' after block.")
|
|
|
|
tkLeftBrace.genRule(parseBlock, nop, pcNone)
|
|
|
|
# statements
|
|
|
|
proc breakStatement(comp: Compiler) =
|
|
if not comp.match(tkLabel):
|
|
comp.error("Label expected after break.")
|
|
|
|
let label = comp.previous.text[1..^1]
|
|
for i in countdown(comp.scopes.high, 0):
|
|
let scope = comp.scopes[i]
|
|
if scope.labels.contains(label):
|
|
comp.jumpToEnd(scope)
|
|
break
|
|
|
|
comp.consume(tkSemicolon, "Semicolon expected after break statement.")
|
|
if comp.current.tokenType != tkRightBrace:
|
|
comp.error("Break statement must be the last element inside the innermost block it is in.")
|
|
|
|
proc statement*(comp: Compiler) =
|
|
if comp.match(tkVar):
|
|
comp.varStatement()
|
|
comp.consume(tkSemicolon, "Semicolon expected after expression statement.")
|
|
# elif comp.match(tkDef):
|
|
# comp.procStatement()
|
|
# comp.consume(tkSemicolon, "Semicolon expected after procedure declaration.")
|
|
elif comp.match(tkBreak):
|
|
comp.breakStatement()
|
|
else:
|
|
comp.expression()
|
|
if comp.current.tokenType == tkRightBrace:
|
|
# last expression in the block expression -> semicolon optional
|
|
comp.writeChunk(0, opSetLocal)
|
|
comp.writeChunk(0, comp.scopeRetIndex().toDU8())
|
|
else:
|
|
comp.consume(tkSemicolon, "Semicolon expected after expression statement.")
|
|
comp.writeChunk(-1, opPop)
|
|
|
|
if comp.panicMode:
|
|
comp.synchronize() |