Reid/src/parser/parsed_reid.rs

139 lines
4.5 KiB
Rust

use super::{Expectable, Parser, Position, SyntaxError};
type Ident = String;
#[derive(Debug, Clone)]
pub struct ParsedReid(pub Expression);
#[derive(Debug, Clone)]
pub enum Statement {
LetStatement(Position, Ident, Box<Expression>),
ExprStatement(Position, Expression),
}
impl Statement {
pub fn parse(parser: &mut Parser) -> Result<Statement, SyntaxError> {
let pos = parser.pos();
if parser.expect_static("let").get().is_some() {
let ident = parser
.expect_ident()
.get_or(SyntaxError::ExpectedIdent(pos))?;
parser
.expect_static("=")
.get_or(SyntaxError::ExpectedToken(pos, '='))?;
match Expression::parse(parser) {
Ok(expr) => {
parser
.expect_static(";")
.get_or(SyntaxError::ExpectedToken(pos, ';'))?;
Ok(Statement::LetStatement(pos, ident, Box::new(expr)))
}
Err(err) => Err(SyntaxError::ExpectedExpression(pos, Some(Box::new(err)))),
}
} else {
match Expression::parse(parser) {
Ok(expr) => {
let statement = Statement::ExprStatement(pos, expr);
parser
.expect_static(";")
.get_or(SyntaxError::ExpectedToken(pos, ';'))?;
Ok(statement)
}
Err(err) => Err(SyntaxError::ExpectedStatement(pos, Some(Box::new(err)))),
}
}
}
}
#[derive(Debug, Clone)]
pub enum Expression {
BlockExpr(Position, Vec<Statement>),
FunctionCall(Position, Ident, Vec<Expression>),
ValueRef(Position, Pattern),
}
impl Expression {
pub fn parse(parser: &mut Parser) -> Result<Expression, SyntaxError> {
let begin_pos = parser.pos();
if parser.expect_static("{").get().is_some() {
let mut statement_list = Vec::new();
while {
match Statement::parse(parser) {
Ok(exp) => {
statement_list.push(exp);
true
}
Err(_) => false,
}
} {}
if parser.expect_static("}").get().is_some() {
Ok(Expression::BlockExpr(begin_pos, statement_list))
} else {
Err(SyntaxError::ExpectedToken(parser.pos(), '}'))
}
} else if let Some(texts) = parser.expect_ident().and(Expectable::Static("(")).get() {
let pos = parser.pos();
let name = texts.get(0).unwrap();
let mut arg_list = Vec::new();
while {
match Expression::parse(parser) {
Ok(exp) => {
arg_list.push(exp);
parser.expect_static(",").get().is_some()
}
Err(err) => {
if arg_list.is_empty() {
false
} else {
return Err(err);
}
}
}
} {}
parser
.expect_static(")")
.get_or(SyntaxError::ExpectedToken(pos, ')'))?;
Ok(Expression::FunctionCall(pos, name.clone(), arg_list))
} else if let Ok(pattern) = Pattern::parse(parser) {
Ok(Expression::ValueRef(begin_pos, pattern))
} else {
Err(SyntaxError::ExpectedExpression(begin_pos, None))
}
}
}
#[derive(Debug, Clone)]
pub enum Pattern {
IdentPattern(Position, Ident),
LiteralPattern(Position, LiteralPattern),
}
impl Pattern {
fn parse(parser: &mut Parser) -> Result<Pattern, SyntaxError> {
let pos = parser.pos();
if let Some(string) = parser.expect_string_lit().get() {
Ok(Pattern::LiteralPattern(
pos,
LiteralPattern::StringLit(string),
))
} else if let Some(int) = parser.expect_numeral_lit().get() {
Ok(Pattern::LiteralPattern(
pos,
LiteralPattern::Integer32Lit(int),
))
} else if let Some(ident) = parser.expect_ident().get() {
Ok(Pattern::IdentPattern(pos, ident))
} else {
Err(SyntaxError::ExpectedPattern(pos))
}
}
}
#[derive(Debug, Clone)]
pub enum LiteralPattern {
StringLit(String),
Integer32Lit(String),
}