|
|
|
@ -63,8 +63,15 @@ impl Parser {
|
|
|
|
|
|
|
|
|
|
self.scope.pop();
|
|
|
|
|
Ok(tree::Node::File(
|
|
|
|
|
token::Position { file: self.filename.clone(), line: 0, col: 0 },
|
|
|
|
|
File { name: self.filename.clone(), content: nodes }
|
|
|
|
|
token::Position {
|
|
|
|
|
file: self.filename.clone(),
|
|
|
|
|
line: 0,
|
|
|
|
|
col: 0,
|
|
|
|
|
},
|
|
|
|
|
File {
|
|
|
|
|
name: self.filename.clone(),
|
|
|
|
|
content: nodes,
|
|
|
|
|
},
|
|
|
|
|
))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -156,7 +163,11 @@ impl Parser {
|
|
|
|
|
let children = self.parse_block_stmt()?;
|
|
|
|
|
|
|
|
|
|
self.scope.pop();
|
|
|
|
|
Ok(tree::Node::make_target_stmt(target_keyword.pos, name, children))
|
|
|
|
|
Ok(tree::Node::make_target_stmt(
|
|
|
|
|
target_keyword.pos,
|
|
|
|
|
name,
|
|
|
|
|
children,
|
|
|
|
|
))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// ```notrust
|
|
|
|
@ -186,7 +197,12 @@ impl Parser {
|
|
|
|
|
} else {
|
|
|
|
|
None
|
|
|
|
|
};
|
|
|
|
|
Ok(tree::Node::make_if_stmt(if_keyword.pos, condition, then_block, else_block))
|
|
|
|
|
Ok(tree::Node::make_if_stmt(
|
|
|
|
|
if_keyword.pos,
|
|
|
|
|
condition,
|
|
|
|
|
then_block,
|
|
|
|
|
else_block,
|
|
|
|
|
))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// ```notrust
|
|
|
|
@ -200,7 +216,11 @@ impl Parser {
|
|
|
|
|
let condition = self.parse_expr(&[token::Kind::CParen])?;
|
|
|
|
|
let body = self.parse_block_stmt()?;
|
|
|
|
|
self.scope.pop();
|
|
|
|
|
Ok(tree::Node::make_while_stmt(while_keyword.pos, condition, body))
|
|
|
|
|
Ok(tree::Node::make_while_stmt(
|
|
|
|
|
while_keyword.pos,
|
|
|
|
|
condition,
|
|
|
|
|
body,
|
|
|
|
|
))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// ```notrust
|
|
|
|
@ -225,7 +245,13 @@ impl Parser {
|
|
|
|
|
let exec = exprs.pop().unwrap();
|
|
|
|
|
let condition = exprs.pop().unwrap();
|
|
|
|
|
let setup = exprs.pop().unwrap();
|
|
|
|
|
Ok(tree::Node::make_for_stmt(for_keyword.pos, setup, condition, exec, body))
|
|
|
|
|
Ok(tree::Node::make_for_stmt(
|
|
|
|
|
for_keyword.pos,
|
|
|
|
|
setup,
|
|
|
|
|
condition,
|
|
|
|
|
exec,
|
|
|
|
|
body,
|
|
|
|
|
))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// ```notrust
|
|
|
|
@ -239,7 +265,11 @@ impl Parser {
|
|
|
|
|
match expr {
|
|
|
|
|
tree::Node::BinaryExpr(_, expr) => {
|
|
|
|
|
if expr.op == Operator::Eq {
|
|
|
|
|
Ok(tree::Node::make_set_stmt(set_keyword.pos, *expr.lhs, *expr.rhs))
|
|
|
|
|
Ok(tree::Node::make_set_stmt(
|
|
|
|
|
set_keyword.pos,
|
|
|
|
|
*expr.lhs,
|
|
|
|
|
*expr.rhs,
|
|
|
|
|
))
|
|
|
|
|
} else {
|
|
|
|
|
self.syntax_error(format!("Invalid operator"), self.lexer.current().unwrap())
|
|
|
|
|
}
|
|
|
|
@ -378,7 +408,12 @@ impl Parser {
|
|
|
|
|
let op = Operator::from_token(&token)?;
|
|
|
|
|
self.lexer.next();
|
|
|
|
|
let precedence = token.kind.binary_op_precedence().unwrap();
|
|
|
|
|
lhs = tree::Node::make_binary_expr(token.pos, lhs, op, self.parse_binary_rhs(precedence, terminators)?);
|
|
|
|
|
lhs = tree::Node::make_binary_expr(
|
|
|
|
|
token.pos,
|
|
|
|
|
lhs,
|
|
|
|
|
op,
|
|
|
|
|
self.parse_binary_rhs(precedence, terminators)?,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(lhs)
|
|
|
|
@ -416,7 +451,12 @@ impl Parser {
|
|
|
|
|
if new_precedence > precedence {
|
|
|
|
|
let op = Operator::from_token(&token)?;
|
|
|
|
|
self.lexer.next();
|
|
|
|
|
lhs = tree::Node::make_binary_expr(token.pos, lhs, op, self.parse_binary_rhs(new_precedence, terminators)?);
|
|
|
|
|
lhs = tree::Node::make_binary_expr(
|
|
|
|
|
token.pos,
|
|
|
|
|
lhs,
|
|
|
|
|
op,
|
|
|
|
|
self.parse_binary_rhs(new_precedence, terminators)?,
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
@ -529,19 +569,28 @@ impl Parser {
|
|
|
|
|
self.lexer.next();
|
|
|
|
|
let params =
|
|
|
|
|
self.parse_delimited_list(token::Kind::Comma, token::Kind::CParen, false)?;
|
|
|
|
|
self.parse_primary_expr_rest(tree::Node::make_call_expr(token.pos, start, params))
|
|
|
|
|
self.parse_primary_expr_rest(tree::Node::make_call_expr(
|
|
|
|
|
token.pos, start, params,
|
|
|
|
|
))
|
|
|
|
|
}
|
|
|
|
|
token::Kind::OBracket => {
|
|
|
|
|
// array index
|
|
|
|
|
self.lexer.next();
|
|
|
|
|
let index = self.parse_expr(&[token::Kind::CBracket])?;
|
|
|
|
|
self.parse_primary_expr_rest(tree::Node::make_array_expr(token.pos, start, index))
|
|
|
|
|
self.parse_primary_expr_rest(tree::Node::make_array_expr(
|
|
|
|
|
token.pos, start, index,
|
|
|
|
|
))
|
|
|
|
|
}
|
|
|
|
|
token::Kind::Dot => {
|
|
|
|
|
// member access
|
|
|
|
|
self.lexer.next();
|
|
|
|
|
let member = self.lexer.expect_kind(token::Kind::Ident)?;
|
|
|
|
|
self.parse_primary_expr_rest(tree::Node::make_binary_expr(token.pos, start, Operator::Dot, tree::Node::Ident(member.pos, member.raw)))
|
|
|
|
|
self.parse_primary_expr_rest(tree::Node::make_binary_expr(
|
|
|
|
|
token.pos,
|
|
|
|
|
start,
|
|
|
|
|
Operator::Dot,
|
|
|
|
|
tree::Node::Ident(member.pos, member.raw),
|
|
|
|
|
))
|
|
|
|
|
}
|
|
|
|
|
_ => Ok(start),
|
|
|
|
|
}
|
|
|
|
|