|
|
|
@ -16,6 +16,7 @@ enum Scope {
|
|
|
|
|
DepList,
|
|
|
|
|
SourceList,
|
|
|
|
|
Function,
|
|
|
|
|
Loop,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct Parser {
|
|
|
|
@ -79,19 +80,33 @@ impl Parser {
|
|
|
|
|
fn parse_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
|
let token = self.lexer.peek_or_err()?;
|
|
|
|
|
match token.kind {
|
|
|
|
|
token::Kind::BreakKeyword => self.parse_break_stmt(),
|
|
|
|
|
token::Kind::DependKeyword => self.parse_depend_stmt(),
|
|
|
|
|
token::Kind::FnKeyword => self.parse_fn(false),
|
|
|
|
|
token::Kind::ForKeyword => self.parse_for_stmt(),
|
|
|
|
|
token::Kind::IfKeyword => self.parse_if_stmt(),
|
|
|
|
|
token::Kind::ReturnKeyword => self.parse_return_stmt(),
|
|
|
|
|
token::Kind::SetKeyword => self.parse_set_stmt(),
|
|
|
|
|
token::Kind::SourceKeyword => self.parse_source_stmt(),
|
|
|
|
|
token::Kind::TargetKeyword => self.parse_target_stmt(),
|
|
|
|
|
token::Kind::TypeKeyword => self.parse_type_stmt(),
|
|
|
|
|
token::Kind::WhileKeyword => self.parse_while_stmt(),
|
|
|
|
|
k if k.is_start_of_expr() => self.parse_expr_stmt(),
|
|
|
|
|
_ => self.syntax_error(format!("Unexpected token {}", token), &token),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// ```notrust
|
|
|
|
|
/// BreakStatement
|
|
|
|
|
/// : "break" ";"
|
|
|
|
|
/// ```
|
|
|
|
|
fn parse_break_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
|
self.lexer.expect_kind(token::Kind::BreakKeyword)?;
|
|
|
|
|
self.assert_scope(Scope::Loop)?;
|
|
|
|
|
self.lexer.expect_kind(token::Kind::Semi)?;
|
|
|
|
|
Ok(tree::Node::Break)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// ```notrust
|
|
|
|
|
/// BlockStatement
|
|
|
|
|
/// : "{" [ StatementList ] "}"
|
|
|
|
@ -182,6 +197,50 @@ impl Parser {
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// ```notrust
|
|
|
|
|
/// WhileStatement
|
|
|
|
|
/// : "while" "(" Expression ")" BlockStatement
|
|
|
|
|
/// ```
|
|
|
|
|
fn parse_while_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
|
self.lexer.expect_kind(token::Kind::WhileKeyword)?;
|
|
|
|
|
self.scope.push(Scope::Loop);
|
|
|
|
|
self.lexer.expect_kind(token::Kind::OParen)?;
|
|
|
|
|
let condition = self.parse_expr(&[token::Kind::CParen])?;
|
|
|
|
|
let block = self.parse_block_stmt()?;
|
|
|
|
|
self.scope.pop();
|
|
|
|
|
Ok(tree::Node::WhileStmt {
|
|
|
|
|
condition: Box::new(condition),
|
|
|
|
|
block: Box::new(block),
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// ```notrust
|
|
|
|
|
/// ForStatement
|
|
|
|
|
/// : "for" "(" [ Expression ] ";" [ Expression ] ";" [ Expression ] ")" BlockStatement
|
|
|
|
|
/// ```
|
|
|
|
|
fn parse_for_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
|
self.lexer.expect_kind(token::Kind::ForKeyword)?;
|
|
|
|
|
self.scope.push(Scope::Loop);
|
|
|
|
|
self.lexer.expect_kind(token::Kind::OParen)?;
|
|
|
|
|
let terminators = [token::Kind::Semi, token::Kind::Semi, token::Kind::CParen];
|
|
|
|
|
let mut exprs = Vec::new();
|
|
|
|
|
for i in 0..3 {
|
|
|
|
|
exprs.push(if self.lexer.next_if(terminators[i]) {
|
|
|
|
|
None
|
|
|
|
|
} else {
|
|
|
|
|
Some(Box::new(self.parse_expr(&terminators[i..=i])?))
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
let body = self.parse_block_stmt()?;
|
|
|
|
|
self.scope.pop();
|
|
|
|
|
Ok(tree::Node::ForStmt {
|
|
|
|
|
exec: exprs.pop().unwrap(),
|
|
|
|
|
condition: exprs.pop().unwrap(),
|
|
|
|
|
setup: exprs.pop().unwrap(),
|
|
|
|
|
body: Box::new(body),
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// ```notrust
|
|
|
|
|
/// SetStatement
|
|
|
|
|
/// : "set" AssignmentExpression ";"
|
|
|
|
@ -213,8 +272,8 @@ impl Parser {
|
|
|
|
|
/// : "type" Expression ";"
|
|
|
|
|
/// ```
|
|
|
|
|
fn parse_type_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
|
self.assert_scope(Scope::Target)?;
|
|
|
|
|
self.lexer.expect_kind(token::Kind::TypeKeyword)?;
|
|
|
|
|
self.assert_scope(Scope::Target)?;
|
|
|
|
|
let expr = self.parse_expr(&[token::Kind::Semi])?;
|
|
|
|
|
Ok(tree::Node::TypeExpr(Box::new(expr)))
|
|
|
|
|
}
|
|
|
|
@ -224,8 +283,8 @@ impl Parser {
|
|
|
|
|
/// : "source" Expression ";"
|
|
|
|
|
/// ```
|
|
|
|
|
fn parse_source_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
|
self.assert_scope(Scope::Target)?;
|
|
|
|
|
self.lexer.expect_kind(token::Kind::SourceKeyword)?;
|
|
|
|
|
self.assert_scope(Scope::Target)?;
|
|
|
|
|
self.scope.push(Scope::SourceList);
|
|
|
|
|
let source = self.parse_expr(&[token::Kind::Semi])?;
|
|
|
|
|
self.scope.pop();
|
|
|
|
|