2023-06-11 13:53:45 -07:00
|
|
|
mod stage;
|
2023-03-27 21:22:29 -07:00
|
|
|
|
2023-06-11 13:53:45 -07:00
|
|
|
mod pretoken;
|
|
|
|
mod parsererror;
|
|
|
|
mod token;
|
2023-03-27 21:22:29 -07:00
|
|
|
|
2023-06-11 13:53:45 -07:00
|
|
|
use self::{
|
|
|
|
pretoken::PreToken,
|
|
|
|
parsererror::ParserError,
|
|
|
|
parsererror::LineLocation
|
|
|
|
};
|
2023-03-27 09:47:02 -07:00
|
|
|
|
2023-06-11 13:53:45 -07:00
|
|
|
pub use self::{
|
|
|
|
token::Token,
|
|
|
|
token::Constant,
|
|
|
|
token::Operator,
|
|
|
|
token::Function,
|
|
|
|
};
|
2023-03-27 09:47:02 -07:00
|
|
|
|
|
|
|
|
|
|
|
pub fn parse(
|
|
|
|
s: &String
|
|
|
|
) -> Result<
|
2023-03-27 21:22:29 -07:00
|
|
|
Token,
|
|
|
|
(LineLocation, ParserError)
|
2023-03-27 09:47:02 -07:00
|
|
|
> {
|
|
|
|
|
2023-06-11 13:53:45 -07:00
|
|
|
let tokens = stage::tokenize(s);
|
|
|
|
let (_, tokens) = stage::find_subs(tokens);
|
|
|
|
let g = stage::groupify(tokens)?;
|
|
|
|
let g = stage::treeify(g)?;
|
2023-03-27 09:47:02 -07:00
|
|
|
|
2023-03-29 10:39:15 -07:00
|
|
|
return Ok(g);
|
2023-03-27 09:47:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-03-27 22:13:14 -07:00
|
|
|
pub fn substitute(
|
2023-04-04 10:22:32 -07:00
|
|
|
s: &String, // The string to substitute
|
2023-03-27 22:13:14 -07:00
|
|
|
c: usize // Location of the cursor right now
|
2023-04-04 10:22:32 -07:00
|
|
|
) -> (
|
|
|
|
usize, // Location of cursor in substituted string
|
|
|
|
String // String with substitutions
|
|
|
|
) {
|
|
|
|
if s == "" { return (c, s.clone()) }
|
2023-03-27 09:47:02 -07:00
|
|
|
let mut new_s = s.clone();
|
|
|
|
|
2023-04-04 10:22:32 -07:00
|
|
|
let l = s.chars().count();
|
2023-06-11 13:53:45 -07:00
|
|
|
let tokens = stage::tokenize(s);
|
|
|
|
let (subs, _) = stage::find_subs(tokens);
|
2023-04-04 10:22:32 -07:00
|
|
|
let mut new_c = l - c;
|
2023-03-27 09:47:02 -07:00
|
|
|
|
|
|
|
for r in subs.iter() {
|
2023-04-04 10:22:32 -07:00
|
|
|
// find_subs gives substitutions in reverse order.
|
|
|
|
|
|
|
|
if { // Don't substitute if our cursor is inside the substitution
|
2023-03-27 22:13:14 -07:00
|
|
|
c >= r.0.pos &&
|
|
|
|
c < r.0.pos+r.0.len
|
|
|
|
} { continue; }
|
|
|
|
|
2023-04-04 10:22:32 -07:00
|
|
|
if c < r.0.pos {
|
|
|
|
let ct = r.1.chars().count();
|
|
|
|
if ct >= r.0.len {
|
|
|
|
if new_c >= ct - r.0.len {
|
|
|
|
new_c += ct - r.0.len
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
new_c -= r.0.len - ct
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-27 09:47:02 -07:00
|
|
|
new_s.replace_range(
|
|
|
|
r.0.pos..r.0.pos+r.0.len,
|
|
|
|
&r.1[..]
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2023-04-04 10:22:32 -07:00
|
|
|
return (new_c, new_s);
|
2023-03-27 09:47:02 -07:00
|
|
|
}
|