Skip to content

Commit

Permalink
Allow for arbitrary-precision floats in filters.
Browse files Browse the repository at this point in the history
  • Loading branch information
01mf02 committed Apr 18, 2024
1 parent 050f530 commit 103a935
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 15 deletions.
8 changes: 4 additions & 4 deletions jaq-interpret/src/filter.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::box_iter::{box_once, flat_map_with, map_with, BoxIter};
use crate::results::{fold, recurse, then, Fold, Results};
use crate::val::{Val, ValR, ValRs};
use crate::val::{Val, ValR, ValRs, ValT};
use crate::{rc_lazy_list, Bind, Ctx, Error};
use alloc::{boxed::Box, string::String, vec::Vec};
use core::ops::ControlFlow;
Expand Down Expand Up @@ -59,7 +59,7 @@ pub(crate) enum Ast {
ToString,

Int(isize),
Float(f64),
Num(String),
Str(String),
Array(Id),
ObjEmpty,
Expand Down Expand Up @@ -217,7 +217,7 @@ impl<'a> FilterT<'a> for Ref<'a> {
Ast::Id => box_once(Ok(cv.1)),
Ast::ToString => Box::new(once_with(move || Ok(Val::str(cv.1.to_string_or_clone())))),
Ast::Int(n) => box_once(Ok(Val::Int(*n))),
Ast::Float(x) => box_once(Ok(Val::Float(*x))),
Ast::Num(x) => box_once(Val::from_num(x.clone())),
Ast::Str(s) => Box::new(once_with(move || Ok(Val::str(s.clone())))),
Ast::Array(f) => Box::new(once_with(move || w(f).run(cv).collect::<Result<_, _>>())),
Ast::ObjEmpty => box_once(Ok(Val::obj(Default::default()))),
Expand Down Expand Up @@ -339,7 +339,7 @@ impl<'a> FilterT<'a> for Ref<'a> {
let w = move |id: &Id| Ref(*id, self.1);
match &self.1[self.0 .0] {
Ast::ToString => err,
Ast::Int(_) | Ast::Float(_) | Ast::Str(_) => err,
Ast::Int(_) | Ast::Num(_) | Ast::Str(_) => err,
Ast::Array(_) | Ast::ObjEmpty | Ast::ObjSingle(..) => err,
Ast::Neg(_) | Ast::Logic(..) | Ast::Math(..) | Ast::Ord(..) => err,
Ast::Update(..) | Ast::UpdateMath(..) | Ast::Assign(..) => err,
Expand Down
19 changes: 9 additions & 10 deletions jaq-interpret/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,34 +27,33 @@ pub enum Call {
Native(crate::filter::Native),
}

#[derive(Debug, Copy, Clone)]
#[derive(Debug, Clone)]
pub enum Num {
Float(f64),
Num(String),
Int(isize),
}

impl Num {
fn parse(n: &str) -> Result<Self, Self> {
fn parse(n: String) -> Result<Self, String> {
if n.contains(['.', 'e', 'E']) {
n.parse().map(Num::Float).map_err(|_| Self::Float(0.))
Ok(Self::Num(n))
} else {
n.parse().map(Num::Int).map_err(|_| Self::Int(0))
n.parse().map(Num::Int).map_err(|_| n)
}
}
}

pub enum Error {
Undefined(Arg),
Num(Num),
Num(String),
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Undefined(Bind::Var(_)) => "undefined variable",
Self::Undefined(Bind::Fun(_)) => "undefined filter",
Self::Num(Num::Float(_)) => "cannot interpret as floating-point number",
Self::Num(Num::Int(_)) => "cannot interpret as machine-size integer",
Self::Num(_) => "cannot interpret as machine-size integer",
}
.fmt(f)
}
Expand Down Expand Up @@ -176,9 +175,9 @@ impl Ctx {
Expr::Fold(typ, Fold { xs, x, init, f })
}
Expr::Id => Expr::Id,
Expr::Num(n) => Expr::Num(Num::parse(&n).unwrap_or_else(|n| {
Expr::Num(n) => Expr::Num(Num::parse(n).unwrap_or_else(|n| {
self.errs.push((Error::Num(n), f.1.clone()));
n
Num::Int(0)
})),
Expr::Str(s) => Expr::Str(Box::new((*s).map(|f| self.expr(f)))),
Expr::Array(a) => Expr::Array(a.map(|a| get(self, *a))),
Expand Down
2 changes: 1 addition & 1 deletion jaq-interpret/src/lir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ impl Ctx {
}

Expr::Id => Filter::Id,
Expr::Num(hir::Num::Float(f)) => Filter::Float(f),
Expr::Num(hir::Num::Num(n)) => Filter::Num(n),
Expr::Num(hir::Num::Int(i)) => Filter::Int(i),
Expr::Str(s) => self.of_str(*s),
Expr::Array(a) => Filter::Array(a.map_or(EMPTY, |a| self.get(*a))),
Expand Down
5 changes: 5 additions & 0 deletions jaq-interpret/src/val.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ pub type ValR2<V> = Result<V, Error<V>>;
pub trait ValT:
Clone + fmt::Display + From<bool> + From<isize> + From<String> + FromIterator<Self>
{
fn from_num(n: String) -> ValR2<Self>;
fn from_map<I: IntoIterator<Item = (Self, Self)>>(iter: I) -> ValR2<Self>;

/// If `Ok(k)` is in `v.keys()`, then
Expand Down Expand Up @@ -92,6 +93,10 @@ pub trait ValT:
type Range<V> = core::ops::Range<Option<V>>;

impl ValT for Val {
fn from_num(n: String) -> ValR2<Self> {
Ok(Val::Num(Rc::new(n)))
}

fn from_map<I: IntoIterator<Item = (Self, Self)>>(iter: I) -> ValR2<Self> {
let iter = iter.into_iter().map(|(k, v)| Ok((k.to_str()?, v)));
Ok(Self::obj(iter.collect::<Result<_, _>>()?))
Expand Down

0 comments on commit 103a935

Please sign in to comment.