mirror of https://github.com/rm-dr/daisy
Improved history storage
parent
e571d2bebf
commit
5ffad0cc4e
|
@ -0,0 +1,31 @@
|
|||
use crate::parser::Token;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Context {
|
||||
history: Vec<Token>,
|
||||
variables: HashMap<String, Token>
|
||||
}
|
||||
|
||||
impl Context {
|
||||
pub fn new() -> Context {
|
||||
Context{ history: Vec::new(), variables: HashMap::new() }
|
||||
}
|
||||
|
||||
pub fn push_hist(&mut self, t: Token) { self.history.push(t); }
|
||||
pub fn push_var(&mut self, s: String, t: Token) { self.variables.insert(s, t); }
|
||||
pub fn del_var(&mut self, s: &String) { self.variables.remove(s); }
|
||||
|
||||
pub fn get_variable(&self, s: String) -> Option<Token> {
|
||||
|
||||
let v: Option<&Token>;
|
||||
|
||||
if s == "ans" {
|
||||
v = self.history.last();
|
||||
} else {
|
||||
v = self.variables.get(&s);
|
||||
}
|
||||
|
||||
if v.is_some() { Some(v.unwrap().clone()) } else { None }
|
||||
}
|
||||
}
|
|
@ -13,20 +13,18 @@ use termion::{
|
|||
};
|
||||
|
||||
use super::promptbuffer::PromptBuffer;
|
||||
//use crate::tokens::EvalError;
|
||||
use crate::parser;
|
||||
use crate::command;
|
||||
use crate::evaluate::evaluate;
|
||||
use crate::evaluate::EvalError;
|
||||
|
||||
|
||||
use crate::context::Context;
|
||||
|
||||
|
||||
#[inline(always)]
|
||||
fn do_expression(
|
||||
stdout: &mut RawTerminal<std::io::Stdout>,
|
||||
s: &String,
|
||||
history: &Vec<parser::Token>
|
||||
context: &Context
|
||||
) -> Result<parser::Token, ()> {
|
||||
#[cfg(debug_assertions)]
|
||||
RawTerminal::suspend_raw_mode(&stdout).unwrap();
|
||||
|
@ -62,7 +60,7 @@ fn do_expression(
|
|||
// Evaluate expression
|
||||
#[cfg(debug_assertions)]
|
||||
RawTerminal::suspend_raw_mode(&stdout).unwrap();
|
||||
let g = evaluate(&g, history);
|
||||
let g = evaluate(&g, context);
|
||||
#[cfg(debug_assertions)]
|
||||
RawTerminal::activate_raw_mode(&stdout).unwrap();
|
||||
|
||||
|
@ -158,7 +156,7 @@ pub fn main() -> Result<(), std::io::Error> {
|
|||
//write!(stdout, "{:?}", size).unwrap();
|
||||
|
||||
let mut pb: PromptBuffer = PromptBuffer::new(64);
|
||||
let mut history: Vec<parser::Token> = Vec::new();
|
||||
let mut context: Context = Context::new();
|
||||
|
||||
|
||||
'outer: loop {
|
||||
|
@ -179,8 +177,8 @@ pub fn main() -> Result<(), std::io::Error> {
|
|||
} else if command::is_command(&in_str) {
|
||||
command::do_command(&mut stdout, &in_str)?;
|
||||
} else {
|
||||
let r = do_expression(&mut stdout, &in_str, &history);
|
||||
if let Ok(t) = r { history.push(t); }
|
||||
let r = do_expression(&mut stdout, &in_str, &context);
|
||||
if let Ok(t) = r { context.push_hist(t); }
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use crate::parser::Token;
|
||||
use crate::parser::Operator;
|
||||
use crate::context::Context;
|
||||
|
||||
|
||||
use super::operator::eval_operator;
|
||||
use super::function::eval_function;
|
||||
use super::EvalError;
|
||||
|
||||
|
||||
pub fn evaluate(t: &Token, history: &Vec<Token>) -> Result<Token, EvalError> {
|
||||
pub fn evaluate(t: &Token, context: &Context) -> Result<Token, EvalError> {
|
||||
let mut g = t.clone();
|
||||
let mut coords: Vec<usize> = Vec::with_capacity(16);
|
||||
coords.push(0);
|
||||
|
@ -31,17 +32,13 @@ pub fn evaluate(t: &Token, history: &Vec<Token>) -> Result<Token, EvalError> {
|
|||
loop {
|
||||
e = match e {
|
||||
Token::Quantity(_) => { break; },
|
||||
Token::Constant(c) => { evaluate(&c.value(), history).unwrap() },
|
||||
Token::Constant(c) => { evaluate(&c.value(), context).unwrap() },
|
||||
Token::Operator(Operator::Function(f), v) => { eval_function(&f, &v)? },
|
||||
Token::Operator(o, v) => { eval_operator(&o, &v)? },
|
||||
Token::Variable(s) => {
|
||||
if s == "ans" {
|
||||
if history.len() == 0 {
|
||||
return Err(EvalError::NoHistory);
|
||||
} else {
|
||||
history.last().unwrap().clone()
|
||||
}
|
||||
} else { panic!(); }
|
||||
if let Some(t) = context.get_variable(s) { t } else {
|
||||
return Err(EvalError::NoHistory);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ pub mod parser;
|
|||
pub mod command;
|
||||
pub mod quantity;
|
||||
pub mod evaluate;
|
||||
|
||||
pub mod context;
|
||||
|
||||
mod entry;
|
||||
use crate::entry::main_e;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Many of these have been borrowed from insect.
|
||||
use crate::parser;
|
||||
use crate::evaluate::evaluate;
|
||||
use crate::context::Context;
|
||||
|
||||
fn eval_to_str(s: &str) -> Result<String, ()> {
|
||||
let g = match parser::parse(&String::from(s)) {
|
||||
|
@ -9,7 +10,7 @@ fn eval_to_str(s: &str) -> Result<String, ()> {
|
|||
};
|
||||
//let out_str = g.print();
|
||||
|
||||
return match evaluate(&g, &Vec::new()) {
|
||||
return match evaluate(&g, &Context::new()) {
|
||||
Ok(x) => Ok(x.to_string_outer()),
|
||||
Err(_) => Err(())
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue