Added formattedtext and better error class

This commit is contained in:
2023-08-03 22:13:38 -07:00
parent 8076990a41
commit e67a5c4696
14 changed files with 522 additions and 532 deletions

View File

@ -1,14 +1,10 @@
mod stage;
mod token;
mod parsererror;
mod expression;
mod linelocation;
use self::{
token::Token,
parsererror::ParserError,
};
use self::token::Token;
pub use self::{
expression::Expression,
@ -19,11 +15,11 @@ pub use self::{
};
use crate::context::Context;
use crate::errors::DaisyError;
pub fn parse(
s: &String, context: &Context
) -> Result<Expression, (LineLocation, ParserError)> {
) -> Result<Expression, (LineLocation, DaisyError)> {
let expressions = stage::tokenize(s);
let (_, expressions) = stage::find_subs(expressions);
@ -33,7 +29,7 @@ pub fn parse(
return Ok(g);
}
pub fn parse_no_context(s: &String) -> Result<Expression, (LineLocation, ParserError)> {
pub fn parse_no_context(s: &String) -> Result<Expression, (LineLocation, DaisyError)> {
parse(s, &Context::new())
}

View File

@ -1,32 +0,0 @@
/// Types of parser errors.
/// If we cannot parse a string, one of these is returned.
#[derive(Debug)]
pub enum ParserError {
//MissingCloseParen,
ExtraCloseParen,
EmptyGroup,
Syntax,
BadNumber
}
impl ToString for ParserError {
fn to_string(&self) -> String {
match self {
//ParserError::MissingCloseParen => {
// String::from("This group is never closed")
//},
ParserError::ExtraCloseParen => {
String::from("Extra close parenthesis")
},
ParserError::EmptyGroup => {
String::from("Groups can't be empty")
},
ParserError::Syntax => {
String::from("Syntax")
},
ParserError::BadNumber => {
String::from("Invalid number")
}
}
}
}

View File

@ -3,14 +3,15 @@ use std::collections::VecDeque;
use super::super::{
Token,
LineLocation,
ParserError,
Operator
};
use crate::errors::DaisyError;
fn lookback_signs(
g: &mut VecDeque<Token>
) -> Result<(), (LineLocation, ParserError)> {
) -> Result<(), (LineLocation, DaisyError)> {
// Convert `-` operators to `neg` operators
// Delete `+`s that mean "positive" instead of "add"
@ -99,7 +100,7 @@ fn lookback_signs(
// Inserts implicit operators
fn lookback(
g: &mut VecDeque<Token>
) -> Result<(), (LineLocation, ParserError)> {
) -> Result<(), (LineLocation, DaisyError)> {
lookback_signs(g)?;
@ -178,7 +179,7 @@ fn lookback(
// The following are syntax errors
(Token::Quantity(la,_), Token::Quantity(lb,_))
=> {
return Err((*la + *lb, ParserError::Syntax));
return Err((*la + *lb, DaisyError::Syntax));
},
_ => {g.insert(i-1, b); g.insert(i-1, a);}
}
@ -195,7 +196,7 @@ pub fn groupify(
mut g: VecDeque<Token>
) -> Result<
Token,
(LineLocation, ParserError)
(LineLocation, DaisyError)
> {
let last_linelocation: LineLocation = *g.back().unwrap().get_line_location();
@ -220,8 +221,8 @@ pub fn groupify(
Token::GroupEnd(l) => {
let l = *l_now + l;
if i_level == 0 { return Err((l, ParserError::ExtraCloseParen)) }
if v_now.len() == 0 { return Err((l, ParserError::EmptyGroup)) }
if i_level == 0 { return Err((l, DaisyError::ExtraCloseParen)) }
if v_now.len() == 0 { return Err((l, DaisyError::EmptyGroup)) }
i_level -= 1;
@ -243,7 +244,7 @@ pub fn groupify(
// Error on missing parenthesis
if levels.len() != 1 {
let (l, _) = levels.pop().unwrap();
return Err((l, ParserError::MissingCloseParen))
return Err((l, DaisyError::MissingCloseParen))
}
*/
@ -252,7 +253,7 @@ pub fn groupify(
let (l, mut v) = levels.pop().unwrap();
let (_, v_now) = levels.last_mut().unwrap();
if v.len() == 0 { return Err((l, ParserError::EmptyGroup)) }
if v.len() == 0 { return Err((l, DaisyError::EmptyGroup)) }
lookback(&mut v)?;
v_now.push_back(Token::Group(l, v));

View File

@ -1,9 +1,9 @@
use std::collections::VecDeque;
use crate::context::Context;
use crate::errors::DaisyError;
use super::super::{
Token,
ParserError,
LineLocation,
Expression,
Operator
@ -13,7 +13,7 @@ fn treeify_binary(
i: usize,
g_inner: &mut VecDeque<Token>,
context: &Context
) -> Result<bool, (LineLocation, ParserError)> {
) -> Result<bool, (LineLocation, DaisyError)> {
let this: &Token = &g_inner[i];
@ -23,7 +23,7 @@ fn treeify_binary(
Token::Operator(l, _) => l,
_ => panic!()
};
return Err((*l, ParserError::Syntax)); // left argument is empty
return Err((*l, DaisyError::Syntax)); // left argument is empty
}
@ -35,7 +35,7 @@ fn treeify_binary(
Token::Operator(l, _) => l,
_ => panic!()
};
return Err((*l, ParserError::Syntax)); // Left argument is empty
return Err((*l, DaisyError::Syntax)); // Left argument is empty
}
};
@ -47,7 +47,7 @@ fn treeify_binary(
Token::Operator(l, _) => l,
_ => panic!()
};
return Err((*l, ParserError::Syntax)); // right argument is empty
return Err((*l, DaisyError::Syntax)); // right argument is empty
}
};
@ -57,7 +57,7 @@ fn treeify_binary(
if let Token::Operator(l, s) = left {
let o = Operator::from_string(s);
if o.is_none() { return Err((*l, ParserError::Syntax)); } // Bad string
if o.is_none() { return Err((*l, DaisyError::Syntax)); } // Bad string
let o = o.unwrap();
if {
@ -67,13 +67,13 @@ fn treeify_binary(
return Ok(false);
} else {
let tl = *this.get_line_location() + *l;
return Err((tl, ParserError::Syntax)); // left argument isn't valid
return Err((tl, DaisyError::Syntax)); // left argument isn't valid
}
}
if let Token::Operator(l, s) = right {
let o = Operator::from_string(s);
if o.is_none() { return Err((*l, ParserError::Syntax)); } // Bad string
if o.is_none() { return Err((*l, DaisyError::Syntax)); } // Bad string
let o = o.unwrap();
if {
@ -83,7 +83,7 @@ fn treeify_binary(
return Ok(false);
} else {
let tl = *this.get_line_location() + *l;
return Err((tl, ParserError::Syntax)); // right argument isn't valid (two operators next to each other)
return Err((tl, DaisyError::Syntax)); // right argument isn't valid (two operators next to each other)
}
}
@ -92,7 +92,7 @@ fn treeify_binary(
let this_op = {
let Token::Operator(l, s) = this else {panic!()};
let o = Operator::from_string(s);
if o.is_none() { return Err((*l, ParserError::Syntax)); } // bad operator string
if o.is_none() { return Err((*l, DaisyError::Syntax)); } // bad operator string
o.unwrap()
};
@ -100,14 +100,14 @@ fn treeify_binary(
let left_op = if i > 1 {
let Token::Operator(l, s) = &g_inner[i-2] else {panic!()};
let o = Operator::from_string(s);
if o.is_none() { return Err((*l, ParserError::Syntax)); } // Bad operator string
if o.is_none() { return Err((*l, DaisyError::Syntax)); } // Bad operator string
Some(o.unwrap())
} else { None };
let right_op = if i < g_inner.len()-2 {
let Token::Operator(l, s) = &g_inner[i+2] else {panic!()};
let o = Operator::from_string(s);
if o.is_none() { return Err((*l, ParserError::Syntax)); } // Bad operator string
if o.is_none() { return Err((*l, DaisyError::Syntax)); } // Bad operator string
Some(o.unwrap())
} else { None };
@ -159,7 +159,7 @@ fn treeify_unary(
g_inner: &mut VecDeque<Token>,
left_associative: bool,
context: &Context
) -> Result<bool, (LineLocation, ParserError)> {
) -> Result<bool, (LineLocation, DaisyError)> {
let this: &Token = &g_inner[i];
let next: &Token;
@ -172,7 +172,7 @@ fn treeify_unary(
Token::Operator(l, _) => l,
_ => panic!()
};
return Err((*l, ParserError::Syntax)); // argument is missing
return Err((*l, DaisyError::Syntax)); // argument is missing
}
};
} else {
@ -184,7 +184,7 @@ fn treeify_unary(
Token::Operator(l, _) => l,
_ => panic!()
};
return Err((*l, ParserError::Syntax)); // argument is missing
return Err((*l, DaisyError::Syntax)); // argument is missing
}
};
}
@ -204,7 +204,7 @@ fn treeify_unary(
// Previous operator is invalid
return Err((
*this.get_line_location(),
ParserError::Syntax
DaisyError::Syntax
));
}
}
@ -212,14 +212,14 @@ fn treeify_unary(
if let Token::Operator(l, _) = next {
let tl = *this.get_line_location() + *l;
// Argument is invalid
return Err((tl, ParserError::Syntax));
return Err((tl, DaisyError::Syntax));
} else {
// This operator
let this_op = {
let Token::Operator(l, s) = this else {panic!()};
let o = Operator::from_string(s);
if o.is_none() { return Err((*l, ParserError::Syntax)); } // Bad string
if o.is_none() { return Err((*l, DaisyError::Syntax)); } // Bad string
o.unwrap()
};
@ -228,14 +228,14 @@ fn treeify_unary(
if i > 1 {
let Token::Operator(l, s) = &g_inner[i-2] else {panic!()};
let o = Operator::from_string(s);
if o.is_none() { return Err((*l, ParserError::Syntax)); } // Bad string
if o.is_none() { return Err((*l, DaisyError::Syntax)); } // Bad string
Some(o.unwrap())
} else { None }
} else {
if i < g_inner.len()-2 {
let Token::Operator(l, s) = &g_inner[i+2] else {panic!()};
let o = Operator::from_string(s);
if o.is_none() { return Err((*l, ParserError::Syntax)); } // Bad string
if o.is_none() { return Err((*l, DaisyError::Syntax)); } // Bad string
Some(o.unwrap())
} else { None }
};
@ -285,7 +285,7 @@ fn treeify_unary(
pub fn treeify(
mut g: Token,
context: &Context
) -> Result<Expression, (LineLocation, ParserError)> {
) -> Result<Expression, (LineLocation, DaisyError)> {
let (l, g_inner): (LineLocation, &mut VecDeque<Token>) = match g {
Token::Group(l, ref mut x) => (l, x),
_ => panic!()
@ -293,7 +293,7 @@ pub fn treeify(
if g_inner.len() == 0 {
// This shouldn't ever happen.
return Err((l, ParserError::EmptyGroup));
return Err((l, DaisyError::EmptyGroup));
}
let mut left_associative = true;
@ -315,7 +315,7 @@ pub fn treeify(
let this_op = match &g_inner[i] {
Token::Operator(l, s) => {
let o = Operator::from_string(&s);
if o.is_none() { return Err((*l, ParserError::Syntax)); }
if o.is_none() { return Err((*l, DaisyError::Syntax)); }
o.unwrap()
},
_ => {
@ -356,7 +356,7 @@ pub fn treeify(
return match g {
// Catch edge cases
Token::Operator(l, _) => {
Err((l, ParserError::Syntax))
Err((l, DaisyError::Syntax))
},
Token::Group(_,_) => {
treeify(g, context)

View File

@ -2,10 +2,10 @@ use std::collections::VecDeque;
use crate::quantity::Unit;
use crate::quantity::Quantity;
use crate::context::Context;
use crate::errors::DaisyError;
use super::{
LineLocation,
ParserError,
Expression,
Constant
};
@ -57,7 +57,7 @@ impl Token {
}
#[inline(always)]
pub fn to_expression(self, context: &Context) -> Result<Expression, (LineLocation, ParserError)>{
pub fn to_expression(self, context: &Context) -> Result<Expression, (LineLocation, DaisyError)>{
match self {
Token::Quantity(l, mut s) => {
@ -71,7 +71,7 @@ impl Token {
let r = Quantity::new_rational_from_string(&s);
if r.is_none() {
return Err((l, ParserError::BadNumber))
return Err((l, DaisyError::BadNumber))
}
return Ok(Expression::Quantity(l, r.unwrap()));