From 3414aaee9b7acf75d692edfbfd3593b799623bf9 Mon Sep 17 00:00:00 2001 From: Teascade Date: Mon, 22 Jun 2020 16:58:42 +0300 Subject: [PATCH] Update parse orders a bit --- src/errors.rs | 28 ++++++++++--- src/main.rs | 1 + src/parser/mod.rs | 13 +++--- src/parser/parsed_reid.rs | 86 +++++++++++++++++++++------------------ 4 files changed, 77 insertions(+), 51 deletions(-) diff --git a/src/errors.rs b/src/errors.rs index 2200479..dc1e60d 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -18,22 +18,38 @@ impl From for GenericError { pub enum CompilerError { Fatal, ExpectedToken(Position, char), - ExpectedExpression(Position, Box), + ExpectedExpression(Position, Option>), ExpectedIdent(Position), - ExpectedStatement(Position), + ExpectedStatement(Position, Option>), ExpectedPattern(Position), } +impl CompilerError { + fn from_opt(from: &Option>) -> String { + if let Some(err) = from { + format!("\n {}", err) + } else { + String::new() + } + } +} + impl Display for CompilerError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let text = match self { CompilerError::Fatal => "Fatal error".to_string(), CompilerError::ExpectedToken(pos, c) => format!("Expected token '{}' at {}", c, pos), - CompilerError::ExpectedExpression(pos, err) => { - format!("Expected expression at {}.\n {}", pos, err) - } + CompilerError::ExpectedExpression(pos, err) => format!( + "Expected expression at {}{}", + pos, + CompilerError::from_opt(err) + ), CompilerError::ExpectedIdent(pos) => format!("Expected ident at {}", pos), - CompilerError::ExpectedStatement(pos) => format!("Expected statement at {}", pos), + CompilerError::ExpectedStatement(pos, err) => format!( + "Expected statement at {}{}", + pos, + CompilerError::from_opt(err) + ), CompilerError::ExpectedPattern(pos) => format!("Expected pattern at {}", pos), }; write!(f, "{}", text) diff --git a/src/main.rs b/src/main.rs index 2c0f5e9..7b1478e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,4 +13,5 @@ fn main() { eprintln!("Syntax error: {}", error); std::process::exit(1); } + dbg!(reid); } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 404f5aa..2c55f3a 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -1,7 +1,7 @@ mod parsed_reid; use super::errors::CompilerError; -use parsed_reid::{Expression, ParsedReid}; +use parsed_reid::{Expression, ParsedReid, Statement}; use std::fmt; use std::fmt::Display; @@ -32,16 +32,16 @@ impl Parser { } pub fn parse(mut self) -> Result { - let mut exp_list = Vec::new(); + let mut statement_list = Vec::new(); let mut error = None; while { self.skip_whitespace(); if self.remaining() > 0 { - match Expression::parse(&mut self) { + match Statement::parse(&mut self) { Ok(exp) => { - exp_list.push(exp); + statement_list.push(exp); true } Err(err) => { @@ -57,7 +57,10 @@ impl Parser { if let Some(error) = error { Err(error) } else { - Ok(ParsedReid(Expression::BlockExpr(Position(0, 0), exp_list))) + Ok(ParsedReid(Expression::BlockExpr( + Position(0, 0), + statement_list, + ))) } } diff --git a/src/parser/parsed_reid.rs b/src/parser/parsed_reid.rs index 53a2a8e..5c6fc02 100644 --- a/src/parser/parsed_reid.rs +++ b/src/parser/parsed_reid.rs @@ -4,47 +4,11 @@ type Ident = String; #[derive(Debug)] pub struct ParsedReid(pub Expression); - #[derive(Debug)] -pub enum Expression { - BlockExpr(Position, Vec), - StatementExpr(Position, Statement), -} -impl Expression { - pub fn parse(parser: &mut Parser) -> Result { - 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), - ValueRef(Position, Pattern), + ExprStatement(Position, Expression), } impl Statement { @@ -65,12 +29,54 @@ impl Statement { .get_or(CompilerError::ExpectedToken(pos, ';'))?; Ok(Statement::LetStatement(pos, ident, Box::new(expr))) } - Err(err) => Err(CompilerError::ExpectedExpression(pos, Box::new(err))), + Err(err) => Err(CompilerError::ExpectedExpression(pos, Some(Box::new(err)))), + } + } else { + match Expression::parse(parser) { + Ok(expr) => { + let statement = Statement::ExprStatement(pos, expr); + parser + .expect(";") + .get_or(CompilerError::ExpectedToken(pos, ';'))?; + Ok(statement) + } + Err(err) => Err(CompilerError::ExpectedStatement(pos, Some(Box::new(err)))), + } + } + } +} + +#[derive(Debug)] +pub enum Expression { + BlockExpr(Position, Vec), + ValueRef(Position, Pattern), +} + +impl Expression { + pub fn parse(parser: &mut Parser) -> Result { + let begin_pos = parser.pos(); + + let expect = parser.expect("{"); + if let Some(_) = expect.get() { + let mut statement_list = Vec::new(); + while { + match Statement::parse(parser) { + Ok(exp) => { + statement_list.push(exp); + true + } + Err(_) => false, + } + } {} + if let Some(_) = parser.expect("}").get() { + Ok(Expression::BlockExpr(begin_pos, statement_list)) + } else { + Err(CompilerError::ExpectedToken(parser.pos(), '}')) } } else if let Ok(pattern) = Pattern::parse(parser) { - Ok(Statement::ValueRef(pos, pattern)) + Ok(Expression::ValueRef(begin_pos, pattern)) } else { - Err(CompilerError::ExpectedStatement(pos)) + Err(CompilerError::ExpectedExpression(begin_pos, None)) } } }