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 {
|
pub enum CompilerError {
|
||||||
Fatal,
|
Fatal,
|
||||||
ExpectedToken(Position, char),
|
ExpectedToken(Position, char),
|
||||||
ExpectedExpression(Position, Box<CompilerError>),
|
ExpectedExpression(Position, Option<Box<CompilerError>>),
|
||||||
ExpectedIdent(Position),
|
ExpectedIdent(Position),
|
||||||
ExpectedStatement(Position),
|
ExpectedStatement(Position, Option<Box<CompilerError>>),
|
||||||
ExpectedPattern(Position),
|
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 {
|
impl Display for CompilerError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let text = match self {
|
let text = match self {
|
||||||
CompilerError::Fatal => "Fatal error".to_string(),
|
CompilerError::Fatal => "Fatal error".to_string(),
|
||||||
CompilerError::ExpectedToken(pos, c) => format!("Expected token '{}' at {}", c, pos),
|
CompilerError::ExpectedToken(pos, c) => format!("Expected token '{}' at {}", c, pos),
|
||||||
CompilerError::ExpectedExpression(pos, err) => {
|
CompilerError::ExpectedExpression(pos, err) => format!(
|
||||||
format!("Expected expression at {}.\n {}", pos, err)
|
"Expected expression at {}{}",
|
||||||
}
|
pos,
|
||||||
|
CompilerError::from_opt(err)
|
||||||
|
),
|
||||||
CompilerError::ExpectedIdent(pos) => format!("Expected ident at {}", pos),
|
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),
|
CompilerError::ExpectedPattern(pos) => format!("Expected pattern at {}", pos),
|
||||||
};
|
};
|
||||||
write!(f, "{}", text)
|
write!(f, "{}", text)
|
||||||
|
@ -13,4 +13,5 @@ fn main() {
|
|||||||
eprintln!("Syntax error: {}", error);
|
eprintln!("Syntax error: {}", error);
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
dbg!(reid);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
mod parsed_reid;
|
mod parsed_reid;
|
||||||
|
|
||||||
use super::errors::CompilerError;
|
use super::errors::CompilerError;
|
||||||
use parsed_reid::{Expression, ParsedReid};
|
use parsed_reid::{Expression, ParsedReid, Statement};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
@ -32,16 +32,16 @@ impl Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(mut self) -> Result<ParsedReid, CompilerError> {
|
pub fn parse(mut self) -> Result<ParsedReid, CompilerError> {
|
||||||
let mut exp_list = Vec::new();
|
let mut statement_list = Vec::new();
|
||||||
|
|
||||||
let mut error = None;
|
let mut error = None;
|
||||||
|
|
||||||
while {
|
while {
|
||||||
self.skip_whitespace();
|
self.skip_whitespace();
|
||||||
if self.remaining() > 0 {
|
if self.remaining() > 0 {
|
||||||
match Expression::parse(&mut self) {
|
match Statement::parse(&mut self) {
|
||||||
Ok(exp) => {
|
Ok(exp) => {
|
||||||
exp_list.push(exp);
|
statement_list.push(exp);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@ -57,7 +57,10 @@ impl Parser {
|
|||||||
if let Some(error) = error {
|
if let Some(error) = error {
|
||||||
Err(error)
|
Err(error)
|
||||||
} else {
|
} 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)]
|
#[derive(Debug)]
|
||||||
pub struct ParsedReid(pub Expression);
|
pub struct ParsedReid(pub Expression);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[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 {
|
pub enum Statement {
|
||||||
LetStatement(Position, Ident, Box<Expression>),
|
LetStatement(Position, Ident, Box<Expression>),
|
||||||
ValueRef(Position, Pattern),
|
ExprStatement(Position, Expression),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Statement {
|
impl Statement {
|
||||||
@ -65,12 +29,54 @@ impl Statement {
|
|||||||
.get_or(CompilerError::ExpectedToken(pos, ';'))?;
|
.get_or(CompilerError::ExpectedToken(pos, ';'))?;
|
||||||
Ok(Statement::LetStatement(pos, ident, Box::new(expr)))
|
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) {
|
} else if let Ok(pattern) = Pattern::parse(parser) {
|
||||||
Ok(Statement::ValueRef(pos, pattern))
|
Ok(Expression::ValueRef(begin_pos, pattern))
|
||||||
} else {
|
} else {
|
||||||
Err(CompilerError::ExpectedStatement(pos))
|
Err(CompilerError::ExpectedExpression(begin_pos, None))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user