mirror of
https://github.com/rm-dr/daisy
synced 2025-07-06 18:54:31 -07:00
Reorganized code, added basic error handling
This commit is contained in:
@ -1,5 +1,10 @@
|
||||
use std::collections::VecDeque;
|
||||
use crate::parser::tokenize::Token;
|
||||
|
||||
use crate::parser::Token;
|
||||
use crate::parser::LineLocation;
|
||||
use crate::parser::ParserError;
|
||||
|
||||
|
||||
|
||||
enum OperatorType {
|
||||
Binary, // A binary operator, like a + b
|
||||
@ -12,7 +17,7 @@ fn fold_operators_once(
|
||||
op_type: &OperatorType,
|
||||
check: fn(&str) -> bool,
|
||||
new_token: fn(&str, VecDeque<Token>) -> Token,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), (LineLocation, ParserError)> {
|
||||
|
||||
// Groups to process
|
||||
let mut t_vec: VecDeque<&mut Token> = VecDeque::with_capacity(32);
|
||||
@ -122,7 +127,7 @@ fn fold_operators_once(
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
pub fn fold_operators(exp: &mut Token) -> Result<(), ()> {
|
||||
pub fn fold_operators(exp: &mut Token) -> Result<(), (LineLocation, ParserError)> {
|
||||
fold_operators_once(
|
||||
exp, &OperatorType::UnaryLeft,
|
||||
|s| s=="!",
|
||||
|
@ -1,6 +1,9 @@
|
||||
use crate::parser::tokenize::Token;
|
||||
use crate::parser::Token;
|
||||
use crate::parser::LineLocation;
|
||||
use crate::parser::ParserError;
|
||||
|
||||
pub fn replace_pre(g: &mut Token) -> Result<(), ()> {
|
||||
|
||||
pub fn replace_pre(g: &mut Token) -> Result<(), (LineLocation, ParserError)> {
|
||||
|
||||
match g {
|
||||
Token::PreGroup(_, ref mut vec) => {
|
||||
@ -8,10 +11,10 @@ pub fn replace_pre(g: &mut Token) -> Result<(), ()> {
|
||||
replace_pre(i)?;
|
||||
}
|
||||
},
|
||||
Token::PreNumber(_, s) => {
|
||||
Token::PreNumber(l, s) => {
|
||||
let n = match s.parse() {
|
||||
Ok(n) => n,
|
||||
Err(_) => panic!()
|
||||
Err(_) => return Err((*l, ParserError::BadNumber))
|
||||
};
|
||||
*g = Token::Number(n);
|
||||
}
|
||||
@ -19,8 +22,7 @@ pub fn replace_pre(g: &mut Token) -> Result<(), ()> {
|
||||
if s == "mod" {
|
||||
*g = Token::PreOperator(*l, String::from("mod"));
|
||||
} else {
|
||||
return Err(());
|
||||
//new.push_back(t);
|
||||
return Err((*l, ParserError::Syntax));
|
||||
}
|
||||
},
|
||||
Token::PreOperator(_, _) => {},
|
||||
|
@ -1,44 +1,8 @@
|
||||
use std::collections::VecDeque;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct LineLocation {
|
||||
pos: usize,
|
||||
len: usize
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Token {
|
||||
|
||||
// Only used after tokenizing
|
||||
PreGroup(LineLocation, VecDeque<Token>),
|
||||
PreOperator(LineLocation, String),
|
||||
PreNumber(LineLocation, String),
|
||||
PreWord(LineLocation, String),
|
||||
|
||||
// All PreGroups should vanish after operator folding
|
||||
// All PreOperators should become Operators
|
||||
// All PreNumbers should become Numbers
|
||||
// All PreWords should become TODO.
|
||||
|
||||
// Only used in tree
|
||||
|
||||
Number(f64),
|
||||
|
||||
// Functions
|
||||
|
||||
// Operators
|
||||
Multiply(VecDeque<Token>),
|
||||
Divide(VecDeque<Token>),
|
||||
Add(VecDeque<Token>),
|
||||
Subtract(VecDeque<Token>),
|
||||
Factorial(VecDeque<Token>),
|
||||
Negative(VecDeque<Token>),
|
||||
Power(VecDeque<Token>),
|
||||
Modulo(VecDeque<Token>),
|
||||
|
||||
//Function(String, VecDeque<Token>),
|
||||
}
|
||||
use crate::parser::Token;
|
||||
use crate::parser::LineLocation;
|
||||
use crate::parser::ParserError;
|
||||
|
||||
#[inline(always)]
|
||||
fn update_line_location(mut t: Token, stop_i: usize) -> Token {
|
||||
@ -60,16 +24,8 @@ fn update_line_location(mut t: Token, stop_i: usize) -> Token {
|
||||
}
|
||||
|
||||
|
||||
/// Turn a string into a set of tokens.
|
||||
/// Does not check syntax. Fails if `input` contains an invalid character.
|
||||
//
|
||||
// # Arguments:
|
||||
// `input`: A string like `(-3*2.2)/3`
|
||||
//
|
||||
// # Returns:
|
||||
// * `Ok(Vec<token>)` if we were successful.
|
||||
// * `Err(())` if we couldn't tokenize this string.
|
||||
pub fn tokenize(input: &String) -> Result<Token, ()> {
|
||||
|
||||
pub fn tokenize(input: &String) -> Result<Token, (LineLocation, ParserError)> {
|
||||
let mut t: Option<Token> = None; // The current token we're reading
|
||||
let mut g: Vec<Token> = Vec::with_capacity(8); // Vector of "grouping levels"
|
||||
g.push(Token::PreGroup(LineLocation{pos: 0, len: 0}, VecDeque::with_capacity(8)));
|
||||
@ -190,7 +146,7 @@ pub fn tokenize(input: &String) -> Result<Token, ()> {
|
||||
_ => panic!()
|
||||
};
|
||||
|
||||
g_now.push_back(update_line_location(new_group, i));
|
||||
g_now.push_back(update_line_location(new_group, i+1));
|
||||
},
|
||||
|
||||
// Space. Basic seperator.
|
||||
@ -199,7 +155,7 @@ pub fn tokenize(input: &String) -> Result<Token, ()> {
|
||||
}
|
||||
|
||||
// Invalid token
|
||||
_ => { return Err(()); }
|
||||
_ => { return Err((LineLocation{pos: i, len: 1}, ParserError::InvalidChar)); }
|
||||
};
|
||||
}
|
||||
|
||||
@ -210,5 +166,21 @@ pub fn tokenize(input: &String) -> Result<Token, ()> {
|
||||
};
|
||||
if t.is_some() { g_now.push_back(update_line_location(t.unwrap(), input.len())); }
|
||||
|
||||
if g.len() != 1 {
|
||||
let q: LineLocation = match g.last_mut().unwrap() {
|
||||
Token::PreGroup(l, _) => *l,
|
||||
_ => panic!()
|
||||
};
|
||||
|
||||
let LineLocation{pos:p, ..} = q;
|
||||
return Err((
|
||||
LineLocation{
|
||||
pos: p,
|
||||
len: input.len() - p
|
||||
},
|
||||
ParserError::MissingCloseParen
|
||||
))
|
||||
}
|
||||
|
||||
return Ok(g.pop().unwrap());
|
||||
}
|
@ -1,12 +1,14 @@
|
||||
use crate::parser::tokenize::Token;
|
||||
use crate::parser::Token;
|
||||
use crate::parser::ParserError;
|
||||
use crate::parser::LineLocation;
|
||||
|
||||
pub fn unwrap_groups(g: &mut Token) -> Result<(), ()> {
|
||||
pub fn unwrap_groups(g: &mut Token) -> Result<(), (LineLocation, ParserError)> {
|
||||
|
||||
match g {
|
||||
// If g is a PreGroup, unwrap it
|
||||
Token::PreGroup(_, ref mut vec) => {
|
||||
Token::PreGroup(l, ref mut vec) => {
|
||||
if vec.len() != 1 {
|
||||
panic!();
|
||||
return Err((*l, ParserError::Syntax));
|
||||
}
|
||||
|
||||
let mut i = vec.pop_front().unwrap();
|
||||
|
Reference in New Issue
Block a user