Fixed syntax error location

pull/2/head
Mark 2023-03-25 20:10:31 -07:00
parent 934aeea082
commit c167196809
Signed by: Mark
GPG Key ID: AD62BB059C2AAEE4
2 changed files with 77 additions and 39 deletions

View File

@ -83,8 +83,25 @@ impl Token {
Token::Number(_l, _) | Token::Number(_l, _) |
Token::Constant(_l, _, _) Token::Constant(_l, _, _)
=> panic!(), => panic!(),
_ => panic!()
}
}
#[inline(always)]
pub fn get_mut_line_location(&mut self) -> &mut LineLocation {
match self {
Token::PreNumber(l, _) |
Token::PreWord(l, _) |
Token::PreOperator(l, _) |
Token::PreGroupStart(l) |
Token::PreGroupEnd(l) |
Token::PreGroup(l, _)
=> l,
// These have a line location, but we shouldn't ever need to get it.
Token::Number(_l, _) |
Token::Constant(_l, _, _)
=> panic!(),
_ => panic!() _ => panic!()
} }
} }
@ -261,6 +278,7 @@ pub enum ParserError {
pub fn evaluate(s: &String) -> Result<Token, (LineLocation, ParserError)> { pub fn evaluate(s: &String) -> Result<Token, (LineLocation, ParserError)> {
let tokens = p_tokenize(s); let tokens = p_tokenize(s);
let (_, tokens) = p_find_subs(tokens);
let mut g = p_groupify(tokens)?; let mut g = p_groupify(tokens)?;
g = p_treeify(g)?; g = p_treeify(g)?;
g = p_evaluate(g)?; g = p_evaluate(g)?;
@ -274,7 +292,7 @@ pub fn substitute(s: &String) -> String{
let mut new_s = s.clone(); let mut new_s = s.clone();
let tokens = p_tokenize(s); let tokens = p_tokenize(s);
let subs = p_find_subs(tokens); let (subs, _) = p_find_subs(tokens);
for r in subs.iter() { for r in subs.iter() {
new_s.replace_range( new_s.replace_range(

View File

@ -7,60 +7,80 @@ use crate::parser::LineLocation;
pub fn p_find_subs( pub fn p_find_subs(
mut g: VecDeque<Token>, mut g: VecDeque<Token>,
) -> Vec<(LineLocation, String)> { ) -> (
Vec<(LineLocation, String)>,
VecDeque<Token>
) {
// Array of replacements
let mut r: Vec<(LineLocation, String)> = Vec::with_capacity(8); let mut r: Vec<(LineLocation, String)> = Vec::with_capacity(8);
// New token array, with updated locations
let mut n: VecDeque<Token> = VecDeque::with_capacity(g.len());
let mut offset: usize = 0;
while g.len() > 0 { while g.len() > 0 {
// Read in reverse. Very important! // Read in reverse. Very important!
let t = g.pop_back().unwrap(); let mut t = g.pop_back().unwrap();
match &t { let target: Option<&str> = match &mut t {
Token::PreOperator(_, o) => {
Token::PreOperator(l, o) => {
match o { match o {
Operator::Multiply => { r.push((l.clone(), String::from("×"))); }, Operator::Multiply => {Some("×")},
Operator::Divide => { r.push((l.clone(), String::from("÷"))); }, Operator::Divide => {Some("÷")},
_ => {} _ => {None}
} }
}, },
Token::PreWord(l, s) => { Token::PreWord(_, s) => {
match &s[..] { match &s[..] {
// Greek letters // Greek letters
"alpha" => { r.push((l.clone(), String::from("α"))); }, "alpha" => {Some("α")},
"beta" => { r.push((l.clone(), String::from("β"))); }, "beta" => {Some("β")},
"gamma" => { r.push((l.clone(), String::from("γ"))); }, "gamma" => {Some("γ")},
"delta" => { r.push((l.clone(), String::from("δ"))); }, "delta" => {Some("δ")},
"epsilon" => { r.push((l.clone(), String::from("ε"))); }, "epsilon" => {Some("ε")},
"zeta" => { r.push((l.clone(), String::from("ζ"))); }, "zeta" => {Some("ζ")},
"eta" => { r.push((l.clone(), String::from("η"))); }, "eta" => {Some("η")},
"theta" => { r.push((l.clone(), String::from("θ"))); }, "theta" => {Some("θ")},
"iota" => { r.push((l.clone(), String::from("ι"))); }, "iota" => {Some("ι")},
//"kappa" => { r.push((l.clone(), String::from("κ"))); }, "kappa" => {Some("κ")},
"lambda" => { r.push((l.clone(), String::from("λ"))); }, "lambda" => {Some("λ")},
"mu" => { r.push((l.clone(), String::from("μ"))); }, "mu" => {Some("μ")},
"nu" => { r.push((l.clone(), String::from("ν"))); }, "nu" => {Some("ν")},
"xi" => { r.push((l.clone(), String::from("ξ"))); }, "xi" => {Some("ξ")},
//"omicron" => { r.push((l.clone(), String::from("ο"))); }, "omicron" => {Some("ο")},
"pi" => { r.push((l.clone(), String::from("π"))); }, "pi" => {Some("π")},
"rho" => { r.push((l.clone(), String::from("ρ"))); }, "rho" => {Some("ρ")},
"sigma" => { r.push((l.clone(), String::from("σ"))); }, "sigma" => {Some("σ")},
"tau" => { r.push((l.clone(), String::from("τ"))); }, "tau" => {Some("τ")},
//"upsilon" => { r.push((l.clone(), String::from("υ"))); }, "upsilon" => {Some("υ")},
"phi" => { r.push((l.clone(), String::from("φ"))); }, "phi" => {Some("φ")},
"chi" => { r.push((l.clone(), String::from("χ"))); }, "chi" => {Some("χ")},
"psi" => { r.push((l.clone(), String::from("ψ"))); }, "psi" => {Some("ψ")},
"omega" => { r.push((l.clone(), String::from("ω"))); } "omega" => {Some("ω")}
_ => {} _ => {None}
} }
},
} _ => {None}
_ => {} };
if target.is_none() {
// Even if nothing changed, we need to update token location
let l = t.get_mut_line_location();
*l = LineLocation{pos: l.pos - offset, len: l.len};
} else {
let target = target.unwrap();
let l = t.get_mut_line_location();
r.push((l.clone(), String::from(target)));
*l = LineLocation{ pos: l.pos - offset, len: target.chars().count()};
offset += l.len - target.chars().count();
} }
n.push_front(t);
} }
return r; return (r, n);
} }