Update parse orders a bit
This commit is contained in:
		
							parent
							
								
									c9dffa7713
								
							
						
					
					
						commit
						3414aaee9b
					
				| @ -18,22 +18,38 @@ impl From<io::Error> for GenericError { | ||||
| pub enum CompilerError { | ||||
|     Fatal, | ||||
|     ExpectedToken(Position, char), | ||||
|     ExpectedExpression(Position, Box<CompilerError>), | ||||
|     ExpectedExpression(Position, Option<Box<CompilerError>>), | ||||
|     ExpectedIdent(Position), | ||||
|     ExpectedStatement(Position), | ||||
|     ExpectedStatement(Position, Option<Box<CompilerError>>), | ||||
|     ExpectedPattern(Position), | ||||
| } | ||||
| 
 | ||||
| impl CompilerError { | ||||
|     fn from_opt(from: &Option<Box<CompilerError>>) -> 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) | ||||
|  | ||||
| @ -13,4 +13,5 @@ fn main() { | ||||
|         eprintln!("Syntax error: {}", error); | ||||
|         std::process::exit(1); | ||||
|     } | ||||
|     dbg!(reid); | ||||
| } | ||||
|  | ||||
| @ -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<ParsedReid, CompilerError> { | ||||
|         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, | ||||
|             ))) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -4,47 +4,11 @@ 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), | ||||
|     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<Statement>), | ||||
|     ValueRef(Position, Pattern), | ||||
| } | ||||
| 
 | ||||
| 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 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)) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user