Groupify refactor

pull/2/head
Mark 2023-04-01 18:28:31 -07:00
parent f07ba9ed38
commit 52a508cd98
Signed by: Mark
GPG Key ID: AD62BB059C2AAEE4
1 changed files with 103 additions and 51 deletions

View File

@ -6,18 +6,18 @@ use crate::parser::ParserError;
use crate::tokens::Operator; use crate::tokens::Operator;
// Inserts implicit operators
fn lookback( // Turn `-` into `neg`,
// put `neg`s inside numbers.
fn lookback_negatives(
g: &mut VecDeque<PreToken> g: &mut VecDeque<PreToken>
) -> Result<(), (LineLocation, ParserError)> { ) -> Result<(), (LineLocation, ParserError)> {
for i in 0..g.len() { // Convert `-` operators to `neg` operators
let mut i: usize = 0;
println!("{i} {:?}", g); while i < g.len() {
if i == 0 {
if i < 1 {
let a: PreToken = g.remove(i).unwrap(); let a: PreToken = g.remove(i).unwrap();
match &a { match &a {
PreToken::PreOperator(l,o) PreToken::PreOperator(l,o)
=> { => {
@ -27,11 +27,92 @@ fn lookback(
}, },
_ => { g.insert(i, a); } _ => { g.insert(i, a); }
}; };
} else { } else {
let a: PreToken = g.remove(i-1).unwrap(); let a: PreToken = g.remove(i-1).unwrap();
let b: PreToken = g.remove(i-1).unwrap(); let b: PreToken = g.remove(i-1).unwrap();
match (&a, &b) {
(PreToken::PreOperator(_, sa), PreToken::PreOperator(l,sb))
=> {
if sb == "-" && {
let o = Operator::from_string(sa);
o.is_some() &&
(
o.as_ref().unwrap().is_binary() ||
!o.as_ref().unwrap().is_left_associative()
)
} {
g.insert(i-1, PreToken::PreOperator(*l, String::from("neg")));
g.insert(i-1, a);
} else { g.insert(i-1, b); g.insert(i-1, a); }
},
_ => { g.insert(i-1, b); g.insert(i-1, a); }
}
}
i += 1;
}
// Make negative numbers negative numbers.
// We don't need `neg` operators in this case.
// Note that we read the token array right-to-left, since `neg` is right-associative.
let mut i: usize = g.len();
loop {
if i > 1 { i -= 1; } else { break; }
let a: PreToken = g.remove(i-1).unwrap();
let b: PreToken = g.remove(i-1).unwrap();
match (&a, &b) {
(PreToken::PreOperator(la,sa), PreToken::PreNumber(lb,sb))
=> {
if sa == "neg" {
let first = &sb[0..1];
if first == "-" {
// Already negative. Remove the old one.
g.insert(i-1,
PreToken::PreNumber(
LineLocation { pos: la.pos, len: lb.pos - la.pos + lb.len },
format!("{}", &sb[1..])
)
);
} else {
// Not negative yet. Add one.
g.insert(i-1,
PreToken::PreNumber(
LineLocation { pos: la.pos, len: lb.pos - la.pos + lb.len },
format!("-{sb}")
)
);
}
} else { g.insert(i-1, b); g.insert(i-1, a); }
},
_ => { g.insert(i-1, b); g.insert(i-1, a); }
}
}
return Ok(());
}
// Inserts implicit operators
fn lookback(
g: &mut VecDeque<PreToken>
) -> Result<(), (LineLocation, ParserError)> {
lookback_negatives(g)?;
let mut i: usize = 0;
while i < g.len() {
if i >= 1 {
let a: PreToken = g.remove(i-1).unwrap();
let b: PreToken = g.remove(i-1).unwrap();
match (&a, &b) { match (&a, &b) {
// Insert ImplicitMultiply // Insert ImplicitMultiply
(PreToken::PreGroup(_,_), PreToken::PreGroup(l ,_)) (PreToken::PreGroup(_,_), PreToken::PreGroup(l ,_))
@ -53,31 +134,6 @@ fn lookback(
g.insert(i-1, a); g.insert(i-1, a);
}, },
// The following are syntax errors
(PreToken::PreNumber(la,_), PreToken::PreNumber(lb,_))
=> {
return Err((
LineLocation{pos: la.pos, len: lb.pos - la.pos + lb.len},
ParserError::Syntax
));
}
(PreToken::PreOperator(_, sa), PreToken::PreOperator(l,sb))
=> {
if sb == "-" && {
let o = Operator::from_string(sa);
o.is_some() &&
(
o.as_ref().unwrap().is_binary() ||
!o.as_ref().unwrap().is_left_associative()
)
} {
g.insert(i-1, PreToken::PreOperator(*l, String::from("neg")));
g.insert(i-1, a);
} else { g.insert(i-1, b); g.insert(i-1, a); }
}
// Insert implicit multiplications for right-unary operators // Insert implicit multiplications for right-unary operators
(PreToken::PreNumber(_,_), PreToken::PreOperator(l,s)) (PreToken::PreNumber(_,_), PreToken::PreOperator(l,s))
| (PreToken::PreGroup(_,_), PreToken::PreOperator(l,s)) | (PreToken::PreGroup(_,_), PreToken::PreOperator(l,s))
@ -94,11 +150,6 @@ fn lookback(
loc, loc,
String::from("i*") String::from("i*")
)); ));
} else if (!o.is_binary()) && o.is_left_associative() {
g.insert(i-1, PreToken::PreOperator(
loc,
String::from("i*")
));
} }
} }
g.insert(i-1, a); g.insert(i-1, a);
@ -124,21 +175,22 @@ fn lookback(
} }
g.insert(i-1, a); g.insert(i-1, a);
}, },
// This shouldn't ever happen. // The following are syntax errors
(PreToken::PreGroupStart(_), _) (PreToken::PreNumber(la,_), PreToken::PreNumber(lb,_))
| (_, PreToken::PreGroupStart(_)) => {
| (PreToken::PreGroupEnd(_), _) return Err((
| (_, PreToken::PreGroupEnd(_)) LineLocation{pos: la.pos, len: lb.pos - la.pos + lb.len},
| (PreToken::Container(_), _) ParserError::Syntax
| (_, PreToken::Container(_)) ));
=> panic!() },
_ => {g.insert(i-1, b); g.insert(i-1, a);}
} }
}; }
i += 1;
} }
println!("{:?}", g);
return Ok(()); return Ok(());
} }