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), ExprStatement(Position, Expression), } impl Statement { pub fn parse(parser: &mut Parser) -> Result { 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), FunctionCall(Position, Ident, Vec), ValueRef(Position, Pattern), } impl Expression { pub fn parse(parser: &mut Parser) -> Result { 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 { 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), }