|
|
@ -5,7 +5,7 @@ use crate::lex::token;
|
|
|
|
use crate::lex::token::Token;
|
|
|
|
use crate::lex::token::Token;
|
|
|
|
use crate::lex::Lexer;
|
|
|
|
use crate::lex::Lexer;
|
|
|
|
|
|
|
|
|
|
|
|
use crate::ast::tree::Operator;
|
|
|
|
use crate::ast::tree::{File, Operator};
|
|
|
|
use std::fs;
|
|
|
|
use std::fs;
|
|
|
|
use std::io;
|
|
|
|
use std::io;
|
|
|
|
|
|
|
|
|
|
|
@ -62,10 +62,10 @@ impl Parser {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
self.scope.pop();
|
|
|
|
self.scope.pop();
|
|
|
|
Ok(tree::Node::File {
|
|
|
|
Ok(tree::Node::File(
|
|
|
|
name: self.filename.clone(),
|
|
|
|
token::Position { file: self.filename.clone(), line: 0, col: 0 },
|
|
|
|
content: nodes,
|
|
|
|
File { name: self.filename.clone(), content: nodes }
|
|
|
|
})
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// ```notrust
|
|
|
|
/// ```notrust
|
|
|
@ -101,10 +101,10 @@ impl Parser {
|
|
|
|
/// : "break" ";"
|
|
|
|
/// : "break" ";"
|
|
|
|
/// ```
|
|
|
|
/// ```
|
|
|
|
fn parse_break_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
fn parse_break_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
self.lexer.expect_kind(token::Kind::BreakKeyword)?;
|
|
|
|
let break_keyword = self.lexer.expect_kind(token::Kind::BreakKeyword)?;
|
|
|
|
self.assert_scope(Scope::Loop)?;
|
|
|
|
self.assert_scope(Scope::Loop)?;
|
|
|
|
self.lexer.expect_kind(token::Kind::Semi)?;
|
|
|
|
self.lexer.expect_kind(token::Kind::Semi)?;
|
|
|
|
Ok(tree::Node::Break)
|
|
|
|
Ok(tree::Node::Break(break_keyword.pos))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// ```notrust
|
|
|
|
/// ```notrust
|
|
|
@ -116,7 +116,7 @@ impl Parser {
|
|
|
|
/// ```
|
|
|
|
/// ```
|
|
|
|
fn parse_block_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
fn parse_block_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
let mut nodes = Vec::new();
|
|
|
|
let mut nodes = Vec::new();
|
|
|
|
self.lexer.expect_kind(token::Kind::OBrace)?;
|
|
|
|
let obrace = self.lexer.expect_kind(token::Kind::OBrace)?;
|
|
|
|
while let Some(result) = self.lexer.peek() {
|
|
|
|
while let Some(result) = self.lexer.peek() {
|
|
|
|
match result?.kind {
|
|
|
|
match result?.kind {
|
|
|
|
token::Kind::CBrace => {
|
|
|
|
token::Kind::CBrace => {
|
|
|
@ -126,7 +126,7 @@ impl Parser {
|
|
|
|
_ => nodes.push(self.parse_stmt()?),
|
|
|
|
_ => nodes.push(self.parse_stmt()?),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(tree::Node::Block(nodes))
|
|
|
|
Ok(tree::Node::Block(obrace.pos, nodes))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// ```notrust
|
|
|
|
/// ```notrust
|
|
|
@ -135,9 +135,9 @@ impl Parser {
|
|
|
|
/// ```
|
|
|
|
/// ```
|
|
|
|
fn parse_return_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
fn parse_return_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
self.assert_scope(Scope::Function)?;
|
|
|
|
self.assert_scope(Scope::Function)?;
|
|
|
|
self.lexer.expect_kind(token::Kind::ReturnKeyword)?;
|
|
|
|
let return_keyword = self.lexer.expect_kind(token::Kind::ReturnKeyword)?;
|
|
|
|
let expr = self.parse_expr(&[token::Kind::Semi])?;
|
|
|
|
let expr = self.parse_expr(&[token::Kind::Semi])?;
|
|
|
|
Ok(tree::Node::ReturnStmt(Box::new(expr)))
|
|
|
|
Ok(tree::Node::ReturnStmt(return_keyword.pos, Box::new(expr)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// ```notrust
|
|
|
|
/// ```notrust
|
|
|
@ -149,16 +149,14 @@ impl Parser {
|
|
|
|
self.assert_scope_not(Scope::Target)?;
|
|
|
|
self.assert_scope_not(Scope::Target)?;
|
|
|
|
self.scope.push(Scope::Target);
|
|
|
|
self.scope.push(Scope::Target);
|
|
|
|
|
|
|
|
|
|
|
|
self.lexer.expect_kind(token::Kind::TargetKeyword)?;
|
|
|
|
let target_keyword = self.lexer.expect_kind(token::Kind::TargetKeyword)?;
|
|
|
|
let name_token = self.lexer.expect_kind(token::Kind::Ident)?;
|
|
|
|
let name_token = self.lexer.expect_kind(token::Kind::Ident)?;
|
|
|
|
|
|
|
|
let name = tree::Node::Ident(name_token.pos, name_token.raw);
|
|
|
|
|
|
|
|
|
|
|
|
let children = self.parse_block_stmt()?;
|
|
|
|
let children = self.parse_block_stmt()?;
|
|
|
|
|
|
|
|
|
|
|
|
self.scope.pop();
|
|
|
|
self.scope.pop();
|
|
|
|
Ok(tree::Node::Target {
|
|
|
|
Ok(tree::Node::make_target_stmt(target_keyword.pos, name, children))
|
|
|
|
name: Box::new(tree::Node::Ident(name_token.raw)),
|
|
|
|
|
|
|
|
content: Box::new(children),
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// ```notrust
|
|
|
|
/// ```notrust
|
|
|
@ -168,10 +166,10 @@ impl Parser {
|
|
|
|
fn parse_depend_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
fn parse_depend_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
self.assert_scope(Scope::Target)?;
|
|
|
|
self.assert_scope(Scope::Target)?;
|
|
|
|
self.scope.push(Scope::DepList);
|
|
|
|
self.scope.push(Scope::DepList);
|
|
|
|
self.lexer.expect_kind(token::Kind::DependKeyword)?;
|
|
|
|
let depend_keyword = self.lexer.expect_kind(token::Kind::DependKeyword)?;
|
|
|
|
let rvalue = self.parse_expr(&[token::Kind::Semi])?;
|
|
|
|
let rvalue = self.parse_expr(&[token::Kind::Semi])?;
|
|
|
|
self.scope.pop();
|
|
|
|
self.scope.pop();
|
|
|
|
Ok(tree::Node::DepList(Box::new(rvalue)))
|
|
|
|
Ok(tree::Node::DepList(depend_keyword.pos, Box::new(rvalue)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// ```notrust
|
|
|
|
/// ```notrust
|
|
|
@ -179,22 +177,16 @@ impl Parser {
|
|
|
|
/// : "if" "(" Expression ")" BlockStatement [ "else" BlockStatement ]
|
|
|
|
/// : "if" "(" Expression ")" BlockStatement [ "else" BlockStatement ]
|
|
|
|
/// ```
|
|
|
|
/// ```
|
|
|
|
fn parse_if_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
fn parse_if_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
self.lexer.expect_kind(token::Kind::IfKeyword)?;
|
|
|
|
let if_keyword = self.lexer.expect_kind(token::Kind::IfKeyword)?;
|
|
|
|
self.lexer.expect_kind(token::Kind::OParen)?;
|
|
|
|
self.lexer.expect_kind(token::Kind::OParen)?;
|
|
|
|
let condition = self.parse_expr(&[token::Kind::CParen])?;
|
|
|
|
let condition = self.parse_expr(&[token::Kind::CParen])?;
|
|
|
|
let then_block = self.parse_block_stmt()?;
|
|
|
|
let then_block = self.parse_block_stmt()?;
|
|
|
|
let mut else_block = None;
|
|
|
|
let else_block = if self.lexer.next_if(token::Kind::ElseKeyword).is_some() {
|
|
|
|
if let Some(Ok(token)) = self.lexer.peek() {
|
|
|
|
Some(self.parse_block_stmt()?)
|
|
|
|
if token.kind == token::Kind::ElseKeyword {
|
|
|
|
} else {
|
|
|
|
self.lexer.next();
|
|
|
|
None
|
|
|
|
else_block = Some(Box::new(self.parse_block_stmt()?));
|
|
|
|
};
|
|
|
|
}
|
|
|
|
Ok(tree::Node::make_if_stmt(if_keyword.pos, condition, then_block, else_block))
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(tree::Node::IfStmt {
|
|
|
|
|
|
|
|
condition: Box::new(condition),
|
|
|
|
|
|
|
|
then_block: Box::new(then_block),
|
|
|
|
|
|
|
|
else_block,
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// ```notrust
|
|
|
|
/// ```notrust
|
|
|
@ -202,16 +194,13 @@ impl Parser {
|
|
|
|
/// : "while" "(" Expression ")" BlockStatement
|
|
|
|
/// : "while" "(" Expression ")" BlockStatement
|
|
|
|
/// ```
|
|
|
|
/// ```
|
|
|
|
fn parse_while_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
fn parse_while_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
self.lexer.expect_kind(token::Kind::WhileKeyword)?;
|
|
|
|
let while_keyword = self.lexer.expect_kind(token::Kind::WhileKeyword)?;
|
|
|
|
self.scope.push(Scope::Loop);
|
|
|
|
self.scope.push(Scope::Loop);
|
|
|
|
self.lexer.expect_kind(token::Kind::OParen)?;
|
|
|
|
self.lexer.expect_kind(token::Kind::OParen)?;
|
|
|
|
let condition = self.parse_expr(&[token::Kind::CParen])?;
|
|
|
|
let condition = self.parse_expr(&[token::Kind::CParen])?;
|
|
|
|
let block = self.parse_block_stmt()?;
|
|
|
|
let body = self.parse_block_stmt()?;
|
|
|
|
self.scope.pop();
|
|
|
|
self.scope.pop();
|
|
|
|
Ok(tree::Node::WhileStmt {
|
|
|
|
Ok(tree::Node::make_while_stmt(while_keyword.pos, condition, body))
|
|
|
|
condition: Box::new(condition),
|
|
|
|
|
|
|
|
block: Box::new(block),
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// ```notrust
|
|
|
|
/// ```notrust
|
|
|
@ -219,26 +208,24 @@ impl Parser {
|
|
|
|
/// : "for" "(" [ Expression ] ";" [ Expression ] ";" [ Expression ] ")" BlockStatement
|
|
|
|
/// : "for" "(" [ Expression ] ";" [ Expression ] ";" [ Expression ] ")" BlockStatement
|
|
|
|
/// ```
|
|
|
|
/// ```
|
|
|
|
fn parse_for_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
fn parse_for_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
self.lexer.expect_kind(token::Kind::ForKeyword)?;
|
|
|
|
let for_keyword = self.lexer.expect_kind(token::Kind::ForKeyword)?;
|
|
|
|
self.scope.push(Scope::Loop);
|
|
|
|
self.scope.push(Scope::Loop);
|
|
|
|
self.lexer.expect_kind(token::Kind::OParen)?;
|
|
|
|
self.lexer.expect_kind(token::Kind::OParen)?;
|
|
|
|
let terminators = [token::Kind::Semi, token::Kind::Semi, token::Kind::CParen];
|
|
|
|
let terminators = [token::Kind::Semi, token::Kind::Semi, token::Kind::CParen];
|
|
|
|
let mut exprs = Vec::new();
|
|
|
|
let mut exprs = Vec::new();
|
|
|
|
for i in 0..3 {
|
|
|
|
for i in 0..3 {
|
|
|
|
exprs.push(if self.lexer.next_if(terminators[i]) {
|
|
|
|
exprs.push(if self.lexer.next_if(terminators[i]).is_some() {
|
|
|
|
None
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
Some(Box::new(self.parse_expr(&terminators[i..=i])?))
|
|
|
|
Some(self.parse_expr(&terminators[i..=i])?)
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let body = self.parse_block_stmt()?;
|
|
|
|
let body = self.parse_block_stmt()?;
|
|
|
|
self.scope.pop();
|
|
|
|
self.scope.pop();
|
|
|
|
Ok(tree::Node::ForStmt {
|
|
|
|
let exec = exprs.pop().unwrap();
|
|
|
|
exec: exprs.pop().unwrap(),
|
|
|
|
let condition = exprs.pop().unwrap();
|
|
|
|
condition: exprs.pop().unwrap(),
|
|
|
|
let setup = exprs.pop().unwrap();
|
|
|
|
setup: exprs.pop().unwrap(),
|
|
|
|
Ok(tree::Node::make_for_stmt(for_keyword.pos, setup, condition, exec, body))
|
|
|
|
body: Box::new(body),
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// ```notrust
|
|
|
|
/// ```notrust
|
|
|
@ -247,15 +234,12 @@ impl Parser {
|
|
|
|
/// ```
|
|
|
|
/// ```
|
|
|
|
fn parse_set_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
fn parse_set_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
self.assert_scope(Scope::File)?;
|
|
|
|
self.assert_scope(Scope::File)?;
|
|
|
|
self.lexer.expect_kind(token::Kind::SetKeyword)?;
|
|
|
|
let set_keyword = self.lexer.expect_kind(token::Kind::SetKeyword)?;
|
|
|
|
let expr = self.parse_expr(&[token::Kind::Semi])?;
|
|
|
|
let expr = self.parse_expr(&[token::Kind::Semi])?;
|
|
|
|
match expr {
|
|
|
|
match expr {
|
|
|
|
tree::Node::BinaryExpr { op, lhs, rhs } => {
|
|
|
|
tree::Node::BinaryExpr(_, expr) => {
|
|
|
|
if op == Operator::Eq {
|
|
|
|
if expr.op == Operator::Eq {
|
|
|
|
Ok(tree::Node::SetExpr {
|
|
|
|
Ok(tree::Node::make_set_stmt(set_keyword.pos, *expr.lhs, *expr.rhs))
|
|
|
|
name: lhs,
|
|
|
|
|
|
|
|
val: rhs,
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
self.syntax_error(format!("Invalid operator"), self.lexer.current().unwrap())
|
|
|
|
self.syntax_error(format!("Invalid operator"), self.lexer.current().unwrap())
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -272,10 +256,10 @@ impl Parser {
|
|
|
|
/// : "type" Expression ";"
|
|
|
|
/// : "type" Expression ";"
|
|
|
|
/// ```
|
|
|
|
/// ```
|
|
|
|
fn parse_type_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
fn parse_type_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
self.lexer.expect_kind(token::Kind::TypeKeyword)?;
|
|
|
|
let type_keyword = self.lexer.expect_kind(token::Kind::TypeKeyword)?;
|
|
|
|
self.assert_scope(Scope::Target)?;
|
|
|
|
self.assert_scope(Scope::Target)?;
|
|
|
|
let expr = self.parse_expr(&[token::Kind::Semi])?;
|
|
|
|
let expr = self.parse_expr(&[token::Kind::Semi])?;
|
|
|
|
Ok(tree::Node::TypeExpr(Box::new(expr)))
|
|
|
|
Ok(tree::Node::TypeStmt(type_keyword.pos, Box::new(expr)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// ```notrust
|
|
|
|
/// ```notrust
|
|
|
@ -283,12 +267,12 @@ impl Parser {
|
|
|
|
/// : "source" Expression ";"
|
|
|
|
/// : "source" Expression ";"
|
|
|
|
/// ```
|
|
|
|
/// ```
|
|
|
|
fn parse_source_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
fn parse_source_stmt(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
self.lexer.expect_kind(token::Kind::SourceKeyword)?;
|
|
|
|
let source_keyword = self.lexer.expect_kind(token::Kind::SourceKeyword)?;
|
|
|
|
self.assert_scope(Scope::Target)?;
|
|
|
|
self.assert_scope(Scope::Target)?;
|
|
|
|
self.scope.push(Scope::SourceList);
|
|
|
|
self.scope.push(Scope::SourceList);
|
|
|
|
let source = self.parse_expr(&[token::Kind::Semi])?;
|
|
|
|
let source = self.parse_expr(&[token::Kind::Semi])?;
|
|
|
|
self.scope.pop();
|
|
|
|
self.scope.pop();
|
|
|
|
Ok(tree::Node::SourceList(Box::new(source)))
|
|
|
|
Ok(tree::Node::SourceList(source_keyword.pos, Box::new(source)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// ```notrust
|
|
|
|
/// ```notrust
|
|
|
@ -354,11 +338,7 @@ impl Parser {
|
|
|
|
let op_token = self.lexer.require_next()?;
|
|
|
|
let op_token = self.lexer.require_next()?;
|
|
|
|
let op = Operator::from_token(&op_token)?;
|
|
|
|
let op = Operator::from_token(&op_token)?;
|
|
|
|
let rhs = self.parse_binary_expr_or_higher(terminators)?;
|
|
|
|
let rhs = self.parse_binary_expr_or_higher(terminators)?;
|
|
|
|
return Ok(tree::Node::BinaryExpr {
|
|
|
|
return Ok(tree::Node::make_binary_expr(op_token.pos, lhs, op, rhs));
|
|
|
|
op,
|
|
|
|
|
|
|
|
lhs: Box::new(lhs),
|
|
|
|
|
|
|
|
rhs: Box::new(rhs),
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
} else if token.kind.binary_op_precedence().is_some() {
|
|
|
|
} else if token.kind.binary_op_precedence().is_some() {
|
|
|
|
// shoot, this wasn't an assignment, all of our work was useless
|
|
|
|
// shoot, this wasn't an assignment, all of our work was useless
|
|
|
|
self.lexer.restore(bookmark);
|
|
|
|
self.lexer.restore(bookmark);
|
|
|
@ -387,7 +367,7 @@ impl Parser {
|
|
|
|
&mut self,
|
|
|
|
&mut self,
|
|
|
|
terminators: &[token::Kind],
|
|
|
|
terminators: &[token::Kind],
|
|
|
|
) -> Result<tree::Node, Error> {
|
|
|
|
) -> Result<tree::Node, Error> {
|
|
|
|
let mut expr = self.parse_unary_expr_or_higher()?;
|
|
|
|
let mut lhs = self.parse_unary_expr_or_higher()?;
|
|
|
|
|
|
|
|
|
|
|
|
while let Some(Ok(token)) = self.lexer.peek() {
|
|
|
|
while let Some(Ok(token)) = self.lexer.peek() {
|
|
|
|
if terminators.contains(&token.kind) {
|
|
|
|
if terminators.contains(&token.kind) {
|
|
|
@ -398,14 +378,10 @@ impl Parser {
|
|
|
|
let op = Operator::from_token(&token)?;
|
|
|
|
let op = Operator::from_token(&token)?;
|
|
|
|
self.lexer.next();
|
|
|
|
self.lexer.next();
|
|
|
|
let precedence = token.kind.binary_op_precedence().unwrap();
|
|
|
|
let precedence = token.kind.binary_op_precedence().unwrap();
|
|
|
|
expr = tree::Node::BinaryExpr {
|
|
|
|
lhs = tree::Node::make_binary_expr(token.pos, lhs, op, self.parse_binary_rhs(precedence, terminators)?);
|
|
|
|
op,
|
|
|
|
|
|
|
|
lhs: Box::new(expr),
|
|
|
|
|
|
|
|
rhs: Box::new(self.parse_binary_rhs(precedence, terminators)?),
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Ok(expr)
|
|
|
|
Ok(lhs)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// This is for parsing the right-hand side of a binary expression.
|
|
|
|
/// This is for parsing the right-hand side of a binary expression.
|
|
|
@ -440,11 +416,7 @@ impl Parser {
|
|
|
|
if new_precedence > precedence {
|
|
|
|
if new_precedence > precedence {
|
|
|
|
let op = Operator::from_token(&token)?;
|
|
|
|
let op = Operator::from_token(&token)?;
|
|
|
|
self.lexer.next();
|
|
|
|
self.lexer.next();
|
|
|
|
lhs = tree::Node::BinaryExpr {
|
|
|
|
lhs = tree::Node::make_binary_expr(token.pos, lhs, op, self.parse_binary_rhs(new_precedence, terminators)?);
|
|
|
|
op,
|
|
|
|
|
|
|
|
lhs: Box::new(lhs),
|
|
|
|
|
|
|
|
rhs: Box::new(self.parse_binary_rhs(new_precedence, terminators)?),
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -470,10 +442,7 @@ impl Parser {
|
|
|
|
self.lexer.next(); // consume unary operator token
|
|
|
|
self.lexer.next(); // consume unary operator token
|
|
|
|
let op = Operator::from_token(&token)?;
|
|
|
|
let op = Operator::from_token(&token)?;
|
|
|
|
let expr = self.parse_primary_expr()?;
|
|
|
|
let expr = self.parse_primary_expr()?;
|
|
|
|
return Ok(tree::Node::UnaryExpr {
|
|
|
|
return Ok(tree::Node::make_unary_expr(token.pos, op, expr));
|
|
|
|
op,
|
|
|
|
|
|
|
|
node: Box::new(expr),
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.parse_primary_expr()
|
|
|
|
self.parse_primary_expr()
|
|
|
@ -484,6 +453,7 @@ impl Parser {
|
|
|
|
/// : "(" Expression ")"
|
|
|
|
/// : "(" Expression ")"
|
|
|
|
/// | ArrayExpression
|
|
|
|
/// | ArrayExpression
|
|
|
|
/// | CallExpression
|
|
|
|
/// | CallExpression
|
|
|
|
|
|
|
|
/// | MemberExpression
|
|
|
|
/// | Identifier
|
|
|
|
/// | Identifier
|
|
|
|
/// | StringLiteral
|
|
|
|
/// | StringLiteral
|
|
|
|
/// | IntLiteral
|
|
|
|
/// | IntLiteral
|
|
|
@ -499,6 +469,9 @@ impl Parser {
|
|
|
|
/// ParameterList
|
|
|
|
/// ParameterList
|
|
|
|
/// : Expression [ "," ]
|
|
|
|
/// : Expression [ "," ]
|
|
|
|
/// | Expression "," ParameterList
|
|
|
|
/// | Expression "," ParameterList
|
|
|
|
|
|
|
|
///
|
|
|
|
|
|
|
|
/// MemberExpression
|
|
|
|
|
|
|
|
/// : PrimaryExpression "." PrimaryExpression
|
|
|
|
/// ```
|
|
|
|
/// ```
|
|
|
|
fn parse_primary_expr(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
fn parse_primary_expr(&mut self) -> Result<tree::Node, Error> {
|
|
|
|
let token = self.lexer.require_next()?;
|
|
|
|
let token = self.lexer.require_next()?;
|
|
|
@ -508,7 +481,7 @@ impl Parser {
|
|
|
|
self.parse_primary_expr_rest(expr)
|
|
|
|
self.parse_primary_expr_rest(expr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
token::Kind::Ident => {
|
|
|
|
token::Kind::Ident => {
|
|
|
|
let ident = tree::Node::Ident(String::from(token.raw));
|
|
|
|
let ident = tree::Node::Ident(token.pos, String::from(token.raw));
|
|
|
|
self.parse_primary_expr_rest(ident)
|
|
|
|
self.parse_primary_expr_rest(ident)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
token::Kind::IntLiteral => {
|
|
|
|
token::Kind::IntLiteral => {
|
|
|
@ -520,11 +493,11 @@ impl Parser {
|
|
|
|
_ => raw.parse(),
|
|
|
|
_ => raw.parse(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.unwrap();
|
|
|
|
.unwrap();
|
|
|
|
Ok(tree::Node::Int(num))
|
|
|
|
Ok(tree::Node::Int(token.pos, num))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
token::Kind::StringLiteral => Ok(tree::Node::String(token.raw)),
|
|
|
|
token::Kind::StringLiteral => Ok(tree::Node::String(token.pos, token.raw)),
|
|
|
|
token::Kind::TrueKeyword => Ok(tree::Node::Bool(true)),
|
|
|
|
token::Kind::TrueKeyword => Ok(tree::Node::Bool(token.pos, true)),
|
|
|
|
token::Kind::FalseKeyword => Ok(tree::Node::Bool(false)),
|
|
|
|
token::Kind::FalseKeyword => Ok(tree::Node::Bool(token.pos, false)),
|
|
|
|
token::Kind::FnKeyword => {
|
|
|
|
token::Kind::FnKeyword => {
|
|
|
|
self.lexer.prev(); // parse_fn() expects to consume the keyword
|
|
|
|
self.lexer.prev(); // parse_fn() expects to consume the keyword
|
|
|
|
self.parse_fn(true)
|
|
|
|
self.parse_fn(true)
|
|
|
@ -532,7 +505,7 @@ impl Parser {
|
|
|
|
token::Kind::OBracket => {
|
|
|
|
token::Kind::OBracket => {
|
|
|
|
let elements =
|
|
|
|
let elements =
|
|
|
|
self.parse_delimited_list(token::Kind::Comma, token::Kind::CBracket, true)?;
|
|
|
|
self.parse_delimited_list(token::Kind::Comma, token::Kind::CBracket, true)?;
|
|
|
|
Ok(tree::Node::Array(elements))
|
|
|
|
Ok(tree::Node::Array(token.pos, elements))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => self.syntax_error(format!("Unexpected token {}", token.kind), &token),
|
|
|
|
_ => self.syntax_error(format!("Unexpected token {}", token.kind), &token),
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -556,29 +529,19 @@ impl Parser {
|
|
|
|
self.lexer.next();
|
|
|
|
self.lexer.next();
|
|
|
|
let params =
|
|
|
|
let params =
|
|
|
|
self.parse_delimited_list(token::Kind::Comma, token::Kind::CParen, false)?;
|
|
|
|
self.parse_delimited_list(token::Kind::Comma, token::Kind::CParen, false)?;
|
|
|
|
self.parse_primary_expr_rest(tree::Node::CallExpr {
|
|
|
|
self.parse_primary_expr_rest(tree::Node::make_call_expr(token.pos, start, params))
|
|
|
|
func: Box::new(start),
|
|
|
|
|
|
|
|
params,
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
token::Kind::OBracket => {
|
|
|
|
token::Kind::OBracket => {
|
|
|
|
// array index
|
|
|
|
// array index
|
|
|
|
self.lexer.next();
|
|
|
|
self.lexer.next();
|
|
|
|
let index = self.parse_expr(&[token::Kind::CBracket])?;
|
|
|
|
let index = self.parse_expr(&[token::Kind::CBracket])?;
|
|
|
|
self.parse_primary_expr_rest(tree::Node::ArrayExpr {
|
|
|
|
self.parse_primary_expr_rest(tree::Node::make_array_expr(token.pos, start, index))
|
|
|
|
array: Box::new(start),
|
|
|
|
|
|
|
|
index: Box::new(index),
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
token::Kind::Dot => {
|
|
|
|
token::Kind::Dot => {
|
|
|
|
// member access
|
|
|
|
// member access
|
|
|
|
self.lexer.next();
|
|
|
|
self.lexer.next();
|
|
|
|
let member = self.lexer.expect_kind(token::Kind::Ident)?;
|
|
|
|
let member = self.lexer.expect_kind(token::Kind::Ident)?;
|
|
|
|
self.parse_primary_expr_rest(tree::Node::BinaryExpr {
|
|
|
|
self.parse_primary_expr_rest(tree::Node::make_binary_expr(token.pos, start, Operator::Dot, tree::Node::Ident(member.pos, member.raw)))
|
|
|
|
op: Operator::Dot,
|
|
|
|
|
|
|
|
lhs: Box::new(start),
|
|
|
|
|
|
|
|
rhs: Box::new(tree::Node::Ident(member.raw)),
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => Ok(start),
|
|
|
|
_ => Ok(start),
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -596,13 +559,13 @@ impl Parser {
|
|
|
|
/// ```
|
|
|
|
/// ```
|
|
|
|
fn parse_fn(&mut self, allow_anonymous: bool) -> Result<tree::Node, Error> {
|
|
|
|
fn parse_fn(&mut self, allow_anonymous: bool) -> Result<tree::Node, Error> {
|
|
|
|
self.scope.push(Scope::Function);
|
|
|
|
self.scope.push(Scope::Function);
|
|
|
|
self.lexer.expect_kind(token::Kind::FnKeyword)?;
|
|
|
|
let fn_keyword = self.lexer.expect_kind(token::Kind::FnKeyword)?;
|
|
|
|
|
|
|
|
|
|
|
|
// function name is optional (there are inline anonymous functions)
|
|
|
|
// function name is optional (there are inline anonymous functions)
|
|
|
|
let name = if let Some(Ok(token)) = self.lexer.peek() {
|
|
|
|
let name = if let Some(Ok(token)) = self.lexer.peek() {
|
|
|
|
if token.kind == token::Kind::Ident {
|
|
|
|
if token.kind == token::Kind::Ident {
|
|
|
|
self.lexer.next();
|
|
|
|
self.lexer.next();
|
|
|
|
Some(Box::new(tree::Node::Ident(token.raw)))
|
|
|
|
Some(tree::Node::Ident(token.pos, token.raw))
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -619,7 +582,7 @@ impl Parser {
|
|
|
|
let params = self.parse_delimited_list(token::Kind::Comma, token::Kind::CParen, false)?;
|
|
|
|
let params = self.parse_delimited_list(token::Kind::Comma, token::Kind::CParen, false)?;
|
|
|
|
for p in ¶ms {
|
|
|
|
for p in ¶ms {
|
|
|
|
match p {
|
|
|
|
match p {
|
|
|
|
tree::Node::Ident(_) => continue,
|
|
|
|
tree::Node::Ident(_, _) => continue,
|
|
|
|
_ => {
|
|
|
|
_ => {
|
|
|
|
return self
|
|
|
|
return self
|
|
|
|
.syntax_error(format!("Not an identifier"), &self.lexer.current().unwrap())
|
|
|
|
.syntax_error(format!("Not an identifier"), &self.lexer.current().unwrap())
|
|
|
@ -630,11 +593,7 @@ impl Parser {
|
|
|
|
let body = self.parse_block_stmt()?;
|
|
|
|
let body = self.parse_block_stmt()?;
|
|
|
|
|
|
|
|
|
|
|
|
self.scope.pop();
|
|
|
|
self.scope.pop();
|
|
|
|
Ok(tree::Node::Fn {
|
|
|
|
Ok(tree::Node::make_fn(fn_keyword.pos, name, params, body))
|
|
|
|
name,
|
|
|
|
|
|
|
|
params,
|
|
|
|
|
|
|
|
body: Box::new(body),
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Parse a terminated, delimited list of expressions. This is used for
|
|
|
|
/// Parse a terminated, delimited list of expressions. This is used for
|
|
|
|