104 lines
3.1 KiB
Rust
104 lines
3.1 KiB
Rust
use super::{CompilerError, Parser, Position};
|
|
|
|
type Ident = String;
|
|
|
|
#[derive(Debug)]
|
|
pub struct ParsedReid(pub Expression);
|
|
|
|
#[derive(Debug)]
|
|
pub enum Expression {
|
|
BlockExpr(Position, Vec<Expression>),
|
|
StatementExpr(Position, Statement),
|
|
}
|
|
|
|
impl Expression {
|
|
pub fn parse(parser: &mut Parser) -> Result<Expression, CompilerError> {
|
|
let begin_pos = parser.pos();
|
|
|
|
let expect = parser.expect("{");
|
|
if let Some(_) = expect.get() {
|
|
let mut exp_list = Vec::new();
|
|
while {
|
|
match Expression::parse(parser) {
|
|
Ok(exp) => {
|
|
exp_list.push(exp);
|
|
true
|
|
}
|
|
Err(_) => false,
|
|
}
|
|
} {}
|
|
if let Some(_) = parser.expect("}").get() {
|
|
Ok(Expression::BlockExpr(begin_pos, exp_list))
|
|
} else {
|
|
Err(CompilerError::ExpectedToken(parser.pos(), '}'))
|
|
}
|
|
} else {
|
|
match Statement::parse(parser) {
|
|
Ok(statement) => Ok(Expression::StatementExpr(begin_pos, statement)),
|
|
Err(err) => Err(CompilerError::ExpectedExpression(begin_pos, Box::new(err))),
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum Statement {
|
|
LetStatement(Position, Ident, Box<Expression>),
|
|
ValueRef(Position, Pattern),
|
|
}
|
|
|
|
impl Statement {
|
|
pub fn parse(parser: &mut Parser) -> Result<Statement, CompilerError> {
|
|
let pos = parser.pos();
|
|
|
|
if let Some(_) = parser.expect("let").get() {
|
|
let ident = parser
|
|
.expect_ident()
|
|
.get_or(CompilerError::ExpectedIdent(pos))?;
|
|
parser
|
|
.expect("=")
|
|
.get_or(CompilerError::ExpectedToken(pos, '='))?;
|
|
match Expression::parse(parser) {
|
|
Ok(expr) => {
|
|
parser
|
|
.expect(";")
|
|
.get_or(CompilerError::ExpectedToken(pos, ';'))?;
|
|
Ok(Statement::LetStatement(pos, ident, Box::new(expr)))
|
|
}
|
|
Err(err) => Err(CompilerError::ExpectedExpression(pos, Box::new(err))),
|
|
}
|
|
} else if let Ok(pattern) = Pattern::parse(parser) {
|
|
Ok(Statement::ValueRef(pos, pattern))
|
|
} else {
|
|
Err(CompilerError::ExpectedStatement(pos))
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum Pattern {
|
|
IdentPattern(Position, Ident),
|
|
LiteralPattern(Position, LiteralPattern),
|
|
}
|
|
|
|
impl Pattern {
|
|
fn parse(parser: &mut Parser) -> Result<Pattern, CompilerError> {
|
|
let pos = parser.pos();
|
|
if let Some(string) = parser.expect_string_lit().get() {
|
|
Ok(Pattern::LiteralPattern(
|
|
pos,
|
|
LiteralPattern::StringLit(string),
|
|
))
|
|
} else if let Some(ident) = parser.expect_ident().get() {
|
|
Ok(Pattern::IdentPattern(pos, ident))
|
|
} else {
|
|
Err(CompilerError::ExpectedPattern(pos))
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum LiteralPattern {
|
|
StringLit(String),
|
|
}
|