mirror of
https://github.com/rm-dr/daisy
synced 2025-04-19 03:15:59 -07:00
98 lines
2.2 KiB
Rust
98 lines
2.2 KiB
Rust
mod stage;
|
|
|
|
mod token;
|
|
mod expression;
|
|
mod linelocation;
|
|
|
|
use self::token::Token;
|
|
|
|
pub use self::{
|
|
expression::Expression,
|
|
expression::Constant,
|
|
expression::Operator,
|
|
expression::Function,
|
|
linelocation::LineLocation,
|
|
};
|
|
|
|
use crate::context::Context;
|
|
use crate::errors::DaisyError;
|
|
|
|
pub fn parse(
|
|
context: &Context, s: &String
|
|
) -> Result<Expression, (LineLocation, DaisyError)> {
|
|
|
|
let mut expressions = stage::tokenize(context, s);
|
|
if context.config.enable_substituion {
|
|
(_, expressions) = stage::find_subs(expressions);
|
|
}
|
|
let g = stage::groupify(context, expressions)?;
|
|
let g = stage::treeify(context, g)?;
|
|
|
|
return Ok(g);
|
|
}
|
|
|
|
pub fn parse_no_context(s: &String) -> Result<Expression, (LineLocation, DaisyError)> {
|
|
parse(&Context::new(), s)
|
|
}
|
|
|
|
pub fn substitute(context: &Context, s: &String) -> String {
|
|
if !context.config.enable_substituion { return s.clone(); }
|
|
let (_, s) = substitute_cursor(context, s, s.chars().count());
|
|
return s;
|
|
}
|
|
|
|
pub fn substitute_cursor(
|
|
context: &Context,
|
|
s: &String, // The string to substitute
|
|
c: usize // Location of the cursor right now
|
|
) -> (
|
|
usize, // New cursor
|
|
String // String with substitutions
|
|
) {
|
|
|
|
if !context.config.enable_substituion { return (c, s.clone()); }
|
|
if s == "" { return (c, s.clone()) }
|
|
|
|
|
|
let mut new_s = s.clone();
|
|
|
|
let expressions = stage::tokenize(context, s);
|
|
let (mut subs, _) = stage::find_subs(expressions);
|
|
let mut new_c = c.clone();
|
|
|
|
while subs.len() > 0 {
|
|
// Apply substitutions in reverse order
|
|
// r is the current substitution: (linelocation, string)
|
|
let r = subs.pop_back().unwrap();
|
|
|
|
if { // Don't substitute if our cursor is inside the substitution
|
|
c >= r.0.pos &&
|
|
c < r.0.pos+r.0.len
|
|
} { continue; }
|
|
|
|
// If this substitution is before our cursor,
|
|
// we need to adjust our cursor's position.
|
|
if c > r.0.pos {
|
|
let c_o = r.0.len; // Old length
|
|
let c_n = r.1.chars().count(); // New length
|
|
|
|
if c_n > c_o {
|
|
// Move cursor right by difference
|
|
new_c += c_n - c_o;
|
|
|
|
} else if c_n < c_o {
|
|
// Move cursor left by difference
|
|
if new_c >= c_o - c_n {
|
|
new_c -= c_o - c_n;
|
|
} else { new_c = 0; }
|
|
}
|
|
}
|
|
|
|
new_s.replace_range(
|
|
r.0.pos..r.0.pos+r.0.len,
|
|
&r.1[..]
|
|
)
|
|
}
|
|
|
|
return (new_c, new_s);
|
|
} |