mirror of https://github.com/rm-dr/daisy
Cleaned up code
parent
fc4995847f
commit
6db5137b56
|
@ -10,7 +10,6 @@ This is nowhere near complete. Stay tuned.
|
||||||
|
|
||||||
|
|
||||||
## Before For 1.0 release
|
## Before For 1.0 release
|
||||||
- Cleanup parser
|
|
||||||
- Non-recursive treeify
|
- Non-recursive treeify
|
||||||
|
|
||||||
- Replace strings with &str?
|
- Replace strings with &str?
|
||||||
|
|
|
@ -14,8 +14,6 @@ use crate::parser::find_subs::find_subs;
|
||||||
|
|
||||||
use crate::tokens::LineLocation;
|
use crate::tokens::LineLocation;
|
||||||
use crate::tokens::Token;
|
use crate::tokens::Token;
|
||||||
use crate::tokens::Operator;
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum PreToken {
|
enum PreToken {
|
||||||
|
|
|
@ -39,8 +39,11 @@ impl PromptBuffer {
|
||||||
|
|
||||||
|
|
||||||
pub fn write_prompt(&mut self, stdout: &mut RawTerminal<std::io::Stdout>) -> Result<(), std::io::Error> {
|
pub fn write_prompt(&mut self, stdout: &mut RawTerminal<std::io::Stdout>) -> Result<(), std::io::Error> {
|
||||||
|
let i = self.buffer.chars().count();
|
||||||
|
let i = if i == 0 {0} else {i - self.cursor};
|
||||||
|
|
||||||
// Draw prettyprinted expression
|
// Draw prettyprinted expression
|
||||||
let s = substitute(&self.get_contents(), self.get_cursor_idx());
|
let s = substitute(&self.get_contents(), i);
|
||||||
write!(
|
write!(
|
||||||
stdout, "\r{}{}==>{}{} {}",
|
stdout, "\r{}{}==>{}{} {}",
|
||||||
style::Bold,
|
style::Bold,
|
||||||
|
@ -142,12 +145,6 @@ impl PromptBuffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_cursor(&self) -> usize { self.cursor }
|
|
||||||
pub fn get_cursor_idx(&self) -> usize {
|
|
||||||
let l = self.buffer.chars().count();
|
|
||||||
if l == 0 {0} else {l - self.cursor}
|
|
||||||
}
|
|
||||||
|
|
||||||
// History manipulation
|
// History manipulation
|
||||||
pub fn hist_up(&mut self) {
|
pub fn hist_up(&mut self) {
|
||||||
if self.buffer_changed && self.buffer.len() != 0 { return; }
|
if self.buffer_changed && self.buffer.len() != 0 { return; }
|
||||||
|
|
328
src/tokens.rs
328
src/tokens.rs
|
@ -30,8 +30,7 @@ impl Token {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn get_args(&mut self) -> Option<&mut VecDeque<Token>> {
|
pub fn get_args(&mut self) -> Option<&mut VecDeque<Token>> {
|
||||||
match self {
|
match self {
|
||||||
Token::Operator(_, _, ref mut a)
|
Token::Operator(_, _, ref mut a) => Some(a),
|
||||||
=> Some(a),
|
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,129 +46,24 @@ impl Token {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn as_number(&self) -> Token {
|
|
||||||
match self {
|
|
||||||
Token::Number(l,v) => {
|
|
||||||
Token::Number(*l, *v)
|
|
||||||
},
|
|
||||||
Token::Constant(l,v,_) => {
|
|
||||||
Token::Number(*l, *v)
|
|
||||||
},
|
|
||||||
_ => panic!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn eval(&self) -> Token {
|
pub fn eval(&self) -> Token {
|
||||||
let (o, v) = match self {
|
match self {
|
||||||
Token::Operator(_, o, v) => (o, v),
|
Token::Number(l,v) => { Token::Number(*l, *v) },
|
||||||
Token::Number(l, v) => { return Token::Number(*l, *v); },
|
Token::Constant(l,v,_) => { Token::Number(*l, *v) },
|
||||||
|
Token::Operator(_,o,v) => { o.apply(v) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Temporary solution
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn as_number(&self) -> Token {
|
||||||
|
match self {
|
||||||
|
Token::Number(l,v) => { Token::Number(*l, *v) },
|
||||||
|
Token::Constant(l,v,_) => { Token::Number(*l, *v) },
|
||||||
_ => panic!()
|
_ => panic!()
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
match o {
|
|
||||||
Operator::Negative => {
|
|
||||||
if v.len() != 1 {panic!()};
|
|
||||||
let v = v[0].as_number();
|
|
||||||
|
|
||||||
if let Token::Number(l, v) = v {
|
|
||||||
Token::Number(l, -v)
|
|
||||||
} else { panic!(); }
|
|
||||||
},
|
|
||||||
|
|
||||||
Operator::Add => {
|
|
||||||
let mut sum: f64 = 0f64;
|
|
||||||
let mut new_pos: usize = 0;
|
|
||||||
let mut new_len: usize = 0;
|
|
||||||
for i in v.iter() {
|
|
||||||
let j = i.as_number();
|
|
||||||
if let Token::Number(l, v) = j {
|
|
||||||
if new_pos == 0 {new_pos = l.pos};
|
|
||||||
new_len = new_len + l.len;
|
|
||||||
sum += v;
|
|
||||||
} else {
|
|
||||||
panic!();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Token::Number(
|
|
||||||
LineLocation { pos: new_pos, len: new_len },
|
|
||||||
sum
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
Operator::ImplicitMultiply |
|
|
||||||
Operator::Multiply => {
|
|
||||||
let mut prod: f64 = 1f64;
|
|
||||||
let mut new_pos: usize = 0;
|
|
||||||
let mut new_len: usize = 0;
|
|
||||||
for i in v.iter() {
|
|
||||||
let j = i.as_number();
|
|
||||||
if let Token::Number(l, v) = j {
|
|
||||||
if new_pos == 0 {new_pos = l.pos};
|
|
||||||
new_len = new_len + l.len;
|
|
||||||
prod *= v;
|
|
||||||
} else {
|
|
||||||
panic!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Token::Number(
|
|
||||||
LineLocation { pos: new_pos, len: new_len },
|
|
||||||
prod
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
Operator::Divide => {
|
|
||||||
if v.len() != 2 {panic!()};
|
|
||||||
let a = v[0].as_number();
|
|
||||||
let b = v[1].as_number();
|
|
||||||
|
|
||||||
if let Token::Number(la, va) = a {
|
|
||||||
if let Token::Number(lb, vb) = b {
|
|
||||||
Token::Number(
|
|
||||||
LineLocation { pos: la.pos, len: lb.pos - la.pos + lb.len },
|
|
||||||
va/vb
|
|
||||||
)
|
|
||||||
} else { panic!(); }
|
|
||||||
} else { panic!(); }
|
|
||||||
},
|
|
||||||
|
|
||||||
Operator::ModuloLong |
|
|
||||||
Operator::Modulo => {
|
|
||||||
if v.len() != 2 {panic!()};
|
|
||||||
let a = v[0].as_number();
|
|
||||||
let b = v[1].as_number();
|
|
||||||
|
|
||||||
if let Token::Number(la, va) = a {
|
|
||||||
if let Token::Number(lb, vb) = b {
|
|
||||||
Token::Number(
|
|
||||||
LineLocation { pos: la.pos, len: lb.pos - la.pos + lb.len },
|
|
||||||
va%vb
|
|
||||||
)
|
|
||||||
} else { panic!(); }
|
|
||||||
} else { panic!(); }
|
|
||||||
},
|
|
||||||
|
|
||||||
Operator::Power => {
|
|
||||||
if v.len() != 2 {panic!()};
|
|
||||||
let a = v[0].as_number();
|
|
||||||
let b = v[1].as_number();
|
|
||||||
|
|
||||||
if let Token::Number(la, va) = a {
|
|
||||||
if let Token::Number(lb, vb) = b {
|
|
||||||
Token::Number(
|
|
||||||
LineLocation { pos: la.pos, len: lb.pos - la.pos + lb.len },
|
|
||||||
va.powf(vb)
|
|
||||||
)
|
|
||||||
} else { panic!(); }
|
|
||||||
} else { panic!(); }
|
|
||||||
},
|
|
||||||
|
|
||||||
Operator::Factorial => { todo!() },
|
|
||||||
Operator::Subtract => { panic!() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Operator types, in order of increasing priority.
|
/// Operator types, in order of increasing priority.
|
||||||
|
@ -184,53 +78,14 @@ pub enum Operator {
|
||||||
ImplicitMultiply,
|
ImplicitMultiply,
|
||||||
Modulo, // Mod invoked with %
|
Modulo, // Mod invoked with %
|
||||||
Negative,
|
Negative,
|
||||||
|
|
||||||
|
|
||||||
Power,
|
Power,
|
||||||
|
|
||||||
Factorial,
|
Factorial,
|
||||||
|
|
||||||
|
// Not accessible from prompt
|
||||||
|
Flip,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Operator {
|
impl Operator {
|
||||||
#[inline(always)]
|
|
||||||
pub fn into_token(self, l: LineLocation, mut args: VecDeque<Token>) -> Token {
|
|
||||||
match self {
|
|
||||||
Operator::Subtract => {
|
|
||||||
if args.len() != 2 { panic!() }
|
|
||||||
let a = args.pop_front().unwrap();
|
|
||||||
let b = args.pop_front().unwrap();
|
|
||||||
let b = Token::Operator(l, Operator::Negative, VecDeque::from(vec!(b)));
|
|
||||||
|
|
||||||
Token::Operator(
|
|
||||||
l, Operator::Add,
|
|
||||||
VecDeque::from(vec!(a,b))
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
Operator::Factorial
|
|
||||||
| Operator::Negative
|
|
||||||
=> {
|
|
||||||
if args.len() != 1 { panic!() }
|
|
||||||
Token::Operator(l, self, args)
|
|
||||||
},
|
|
||||||
|
|
||||||
Operator::Modulo
|
|
||||||
| Operator::ModuloLong
|
|
||||||
| Operator::Divide
|
|
||||||
| Operator::Power
|
|
||||||
=> {
|
|
||||||
if args.len() != 2 { panic!() }
|
|
||||||
Token::Operator(l, self, args)
|
|
||||||
},
|
|
||||||
|
|
||||||
Operator::Add
|
|
||||||
| Operator::Multiply
|
|
||||||
| Operator::ImplicitMultiply
|
|
||||||
=> Token::Operator(l, self, args)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn from_string(s: &str) -> Option<Operator> {
|
pub fn from_string(s: &str) -> Option<Operator> {
|
||||||
match s {
|
match s {
|
||||||
|
@ -266,4 +121,153 @@ impl Operator {
|
||||||
_ => true
|
_ => true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn into_token(self, l: LineLocation, mut args: VecDeque<Token>) -> Token {
|
||||||
|
match self {
|
||||||
|
Operator::Subtract => {
|
||||||
|
if args.len() != 2 { panic!() }
|
||||||
|
let a = args.pop_front().unwrap();
|
||||||
|
let b = args.pop_front().unwrap();
|
||||||
|
let b = Token::Operator(l, Operator::Negative, VecDeque::from(vec!(b)));
|
||||||
|
|
||||||
|
Token::Operator(
|
||||||
|
l, Operator::Add,
|
||||||
|
VecDeque::from(vec!(a,b))
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
Operator::Divide => {
|
||||||
|
if args.len() != 2 { panic!() }
|
||||||
|
let a = args.pop_front().unwrap();
|
||||||
|
let b = args.pop_front().unwrap();
|
||||||
|
let b = Token::Operator(l, Operator::Flip, VecDeque::from(vec!(b)));
|
||||||
|
|
||||||
|
Token::Operator(
|
||||||
|
l, Operator::Multiply,
|
||||||
|
VecDeque::from(vec!(a,b))
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
Operator::ImplicitMultiply
|
||||||
|
=> { Token::Operator(l, Operator::Multiply, args) },
|
||||||
|
|
||||||
|
Operator::ModuloLong
|
||||||
|
=> { Token::Operator(l, Operator::Modulo, args) },
|
||||||
|
|
||||||
|
Operator::Factorial
|
||||||
|
| Operator::Negative
|
||||||
|
| Operator::Flip
|
||||||
|
| Operator::Add
|
||||||
|
| Operator::Multiply
|
||||||
|
| Operator::Modulo
|
||||||
|
| Operator::Power
|
||||||
|
=> { Token::Operator(l, self, args) },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Operator{
|
||||||
|
pub fn apply(&self, args: &VecDeque<Token>) -> Token {
|
||||||
|
match self {
|
||||||
|
Operator::ImplicitMultiply |
|
||||||
|
Operator::ModuloLong |
|
||||||
|
Operator::Divide |
|
||||||
|
Operator::Subtract => { panic!() }
|
||||||
|
|
||||||
|
Operator::Negative => {
|
||||||
|
if args.len() != 1 {panic!()};
|
||||||
|
let args = args[0].as_number();
|
||||||
|
|
||||||
|
if let Token::Number(l, v) = args {
|
||||||
|
Token::Number(l, -v)
|
||||||
|
} else { panic!(); }
|
||||||
|
},
|
||||||
|
|
||||||
|
Operator::Flip => {
|
||||||
|
if args.len() != 1 {panic!()};
|
||||||
|
let args = args[0].as_number();
|
||||||
|
|
||||||
|
if let Token::Number(l, v) = args {
|
||||||
|
Token::Number(l, 1f64/v)
|
||||||
|
} else { panic!(); }
|
||||||
|
},
|
||||||
|
|
||||||
|
Operator::Add => {
|
||||||
|
let mut sum: f64 = 0f64;
|
||||||
|
let mut new_pos: usize = 0;
|
||||||
|
let mut new_len: usize = 0;
|
||||||
|
for i in args.iter() {
|
||||||
|
let j = i.as_number();
|
||||||
|
if let Token::Number(l, v) = j {
|
||||||
|
if new_pos == 0 {new_pos = l.pos};
|
||||||
|
new_len = new_len + l.len;
|
||||||
|
sum += v;
|
||||||
|
} else {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Token::Number(
|
||||||
|
LineLocation { pos: new_pos, len: new_len },
|
||||||
|
sum
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
Operator::Multiply => {
|
||||||
|
let mut prod: f64 = 1f64;
|
||||||
|
let mut new_pos: usize = 0;
|
||||||
|
let mut new_len: usize = 0;
|
||||||
|
for i in args.iter() {
|
||||||
|
let j = i.as_number();
|
||||||
|
if let Token::Number(l, v) = j {
|
||||||
|
if new_pos == 0 {new_pos = l.pos};
|
||||||
|
new_len = new_len + l.len;
|
||||||
|
prod *= v;
|
||||||
|
} else {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Token::Number(
|
||||||
|
LineLocation { pos: new_pos, len: new_len },
|
||||||
|
prod
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
Operator::Modulo => {
|
||||||
|
if args.len() != 2 {panic!()};
|
||||||
|
let a = args[0].as_number();
|
||||||
|
let b = args[1].as_number();
|
||||||
|
|
||||||
|
if let Token::Number(la, va) = a {
|
||||||
|
if let Token::Number(lb, vb) = b {
|
||||||
|
Token::Number(
|
||||||
|
LineLocation { pos: la.pos, len: lb.pos - la.pos + lb.len },
|
||||||
|
va%vb
|
||||||
|
)
|
||||||
|
} else { panic!(); }
|
||||||
|
} else { panic!(); }
|
||||||
|
},
|
||||||
|
|
||||||
|
Operator::Power => {
|
||||||
|
if args.len() != 2 {panic!()};
|
||||||
|
let a = args[0].as_number();
|
||||||
|
let b = args[1].as_number();
|
||||||
|
|
||||||
|
if let Token::Number(la, va) = a {
|
||||||
|
if let Token::Number(lb, vb) = b {
|
||||||
|
Token::Number(
|
||||||
|
LineLocation { pos: la.pos, len: lb.pos - la.pos + lb.len },
|
||||||
|
va.powf(vb)
|
||||||
|
)
|
||||||
|
} else { panic!(); }
|
||||||
|
} else { panic!(); }
|
||||||
|
},
|
||||||
|
|
||||||
|
Operator::Factorial => { todo!() },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue