Skip to content

Commit

Permalink
rework Context api - fixes #12
Browse files Browse the repository at this point in the history
  • Loading branch information
vic1707 committed Oct 31, 2023
1 parent 4d068b2 commit 1613689
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 15 deletions.
62 changes: 58 additions & 4 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,63 @@ use crate::{
};

#[derive(Debug, Default, PartialEq)]
#[non_exhaustive]
pub struct Context<'a> {
pub vars: HashMap<&'a str, f64>,
pub funcs: HashMap<&'a str, Function<'a>>,
pub expected_vars: Option<HashSet<&'a str>>,
vars: HashMap<&'a str, f64>,
funcs: HashMap<&'a str, Function<'a>>,
expected_vars: Option<HashSet<&'a str>>,
}

impl<'a> Context<'a> {
#[inline]
#[must_use]
pub fn new() -> Self {
Self {
vars: HashMap::new(),
funcs: HashMap::new(),
expected_vars: None,
}
}

#[inline]
#[must_use]
pub fn with_expected_vars(
mut self,
expected_vars: HashSet<&'a str>,
) -> Self {
self.expected_vars = Some(expected_vars);
self
}

#[inline]
pub fn add_var<T: Into<f64>>(&mut self, name: &'a str, value: T) {
self.vars.insert(name, value.into());
}

#[inline]
pub fn add_func(&mut self, name: &'a str, func: Function<'a>) {
self.funcs.insert(name, func);
}

#[inline]
pub fn set_expected_vars(&mut self, expected_vars: HashSet<&'a str>) {
self.expected_vars = Some(expected_vars);
}

#[inline]
#[must_use]
pub fn get_var(&self, name: &'a str) -> Option<&f64> {
self.vars.get(name)
}

#[inline]
#[must_use]
pub fn get_func(&self, name: &'a str) -> Option<&Function<'a>> {
self.funcs.get(name)
}

#[inline]
#[must_use]
pub const fn get_expected_vars(&self) -> Option<&HashSet<&'a str>> {
self.expected_vars.as_ref()
}
}
8 changes: 3 additions & 5 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ impl<'a> Parser<'a> {
// Check if no unknown variable was found
if let Some(unknown_var) = self
.ctx
.expected_vars
.as_ref()
.get_expected_vars()
.and_then(|expected| xprs.vars.difference(expected).next())
{
yeet!(ParseError::new_variable_not_declared(
Expand Down Expand Up @@ -171,10 +170,9 @@ impl<'a> ParserImpl<'a> {
// else defaults to variable
let ident = self
.ctx
.vars
.get(name)
.get_var(name)
.map(|&value| Identifier::Constant(value))
.or_else(|| self.ctx.funcs.get(name).map(Identifier::Function))
.or_else(|| self.ctx.get_func(name).map(Identifier::Function))
.unwrap_or_else(|| name.into());

let el = match ident {
Expand Down
12 changes: 6 additions & 6 deletions src/tests/parser/ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ const MEAN: Function = xprs_fn!("MEAN", mean);
fn get_parser_with_ctx<'a>() -> Parser<'a> {
let mut ctx = Context::default();

ctx.vars.insert("x", 2.0_f64);
ctx.vars.insert("phi", 1.618_033_988_749_895_f64);
ctx.add_var("x", 2.0_f64);
ctx.add_var("phi", 1.618_033_988_749_895_f64);

ctx.funcs.insert("double", DOUBLE);
ctx.funcs.insert("add", ADD);
ctx.add_func("double", DOUBLE);
ctx.add_func("add", ADD);

let mut parser = Parser::new_with_ctx(ctx);

parser.ctx_mut().vars.insert("y", 1.0_f64);
parser.ctx_mut().funcs.insert("mean", MEAN);
parser.ctx_mut().add_var("y", 1.0_f64);
parser.ctx_mut().add_func("mean", MEAN);

parser
}
Expand Down

0 comments on commit 1613689

Please sign in to comment.