forked from Orchid/orchid
Cut down on macro nonsense
- InertAtomic replaced atomic_inert! for improved tooling support - atomic_defaults! is easier to type out than to explain in a docstring - Changed rustfmt config to better support tiny functions such as as_any
This commit is contained in:
@@ -4,16 +4,18 @@ use std::sync::Arc;
|
||||
use itertools::Itertools;
|
||||
|
||||
use super::Boolean;
|
||||
use crate::systems::cast_exprinst::with_uint;
|
||||
use crate::foreign::InertAtomic;
|
||||
use crate::systems::codegen::{orchid_opt, tuple};
|
||||
use crate::systems::RuntimeError;
|
||||
use crate::utils::{iter_find, unwrap_or};
|
||||
use crate::{atomic_inert, define_fn, ConstTree, Interner, Literal};
|
||||
use crate::{define_fn, ConstTree, Interner, Literal};
|
||||
|
||||
/// A block of binary data
|
||||
#[derive(Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Binary(pub Arc<Vec<u8>>);
|
||||
atomic_inert!(Binary, typestr = "a binary blob");
|
||||
impl InertAtomic for Binary {
|
||||
fn type_str() -> &'static str { "a binary blob" }
|
||||
}
|
||||
|
||||
impl Debug for Binary {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
@@ -96,11 +98,7 @@ define_fn! {expr=x in
|
||||
|
||||
define_fn! {expr=x in
|
||||
/// Extract a subsection of the binary data
|
||||
pub Slice {
|
||||
s: Binary,
|
||||
i: u64 as with_uint(x, Ok),
|
||||
len: u64 as with_uint(x, Ok)
|
||||
} => {
|
||||
pub Slice { s: Binary, i: u64, len: u64 } => {
|
||||
if i + len < s.0.len() as u64 {
|
||||
RuntimeError::fail(
|
||||
"Byte index out of bounds".to_string(),
|
||||
@@ -123,10 +121,7 @@ define_fn! {expr=x in
|
||||
|
||||
define_fn! {expr=x in
|
||||
/// Split binary data block into two smaller blocks
|
||||
pub Split {
|
||||
bin: Binary,
|
||||
i: u64 as with_uint(x, Ok)
|
||||
} => {
|
||||
pub Split { bin: Binary, i: u64 } => {
|
||||
if bin.0.len() < *i as usize {
|
||||
RuntimeError::fail(
|
||||
"Byte index out of bounds".to_string(),
|
||||
@@ -144,7 +139,7 @@ define_fn! {expr=x in
|
||||
define_fn! {
|
||||
/// Detect the number of bytes in the binary data block
|
||||
pub Size = |x| {
|
||||
Ok(Literal::Uint(Binary::try_from(x)?.0.len() as u64).into())
|
||||
Ok(Literal::Uint(x.downcast::<Binary>()?.0.len() as u64).into())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::foreign::InertAtomic;
|
||||
use crate::interner::Interner;
|
||||
use crate::representations::interpreted::Clause;
|
||||
use crate::systems::AssertionError;
|
||||
use crate::{atomic_inert, define_fn, ConstTree, Literal, PathSet};
|
||||
use crate::{define_fn, ConstTree, Literal, PathSet};
|
||||
|
||||
/// Booleans exposed to Orchid
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct Boolean(pub bool);
|
||||
atomic_inert!(Boolean, typestr = "a boolean");
|
||||
impl InertAtomic for Boolean {
|
||||
fn type_str() -> &'static str { "a boolean" }
|
||||
}
|
||||
|
||||
impl From<bool> for Boolean {
|
||||
fn from(value: bool) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
fn from(value: bool) -> Self { Self(value) }
|
||||
}
|
||||
|
||||
define_fn! {expr=x in
|
||||
@@ -36,7 +37,7 @@ define_fn! {expr=x in
|
||||
define_fn! {
|
||||
/// Takes a boolean and two branches, runs the first if the bool is true, the
|
||||
/// second if it's false.
|
||||
IfThenElse = |x| x.try_into()
|
||||
IfThenElse = |x| x.downcast()
|
||||
.map_err(|_| AssertionError::ext(x.clone(), "a boolean"))
|
||||
.map(|b: Boolean| if b.0 {Clause::Lambda {
|
||||
args: Some(PathSet { steps: Rc::new(vec![]), next: None }),
|
||||
|
||||
@@ -3,7 +3,8 @@ use std::fmt::Debug;
|
||||
use crate::foreign::{Atomic, AtomicReturn};
|
||||
use crate::interpreter::Context;
|
||||
use crate::representations::interpreted::ExprInst;
|
||||
use crate::{atomic_defaults, write_fn_step, ConstTree, Interner};
|
||||
use crate::utils::ddispatch::Responder;
|
||||
use crate::{write_fn_step, ConstTree, Interner};
|
||||
|
||||
write_fn_step! {
|
||||
/// Print and return whatever expression is in the argument without
|
||||
@@ -15,8 +16,9 @@ write_fn_step! {
|
||||
struct Inspect1 {
|
||||
expr_inst: ExprInst,
|
||||
}
|
||||
impl Responder for Inspect1 {}
|
||||
impl Atomic for Inspect1 {
|
||||
atomic_defaults!();
|
||||
fn as_any(&self) -> &dyn std::any::Any { self }
|
||||
fn run(&self, ctx: Context) -> crate::foreign::AtomicResult {
|
||||
println!("{}", self.expr_inst);
|
||||
Ok(AtomicReturn {
|
||||
|
||||
@@ -4,6 +4,7 @@ use ordered_float::NotNan;
|
||||
|
||||
use super::ArithmeticError;
|
||||
use crate::foreign::ExternError;
|
||||
use crate::interpreted::TryFromExprInst;
|
||||
use crate::representations::interpreted::{Clause, ExprInst};
|
||||
use crate::representations::{Literal, Primitive};
|
||||
use crate::systems::cast_exprinst::with_lit;
|
||||
@@ -40,14 +41,12 @@ impl Numeric {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&ExprInst> for Numeric {
|
||||
type Error = Rc<dyn ExternError>;
|
||||
fn try_from(value: &ExprInst) -> Result<Self, Self::Error> {
|
||||
with_lit(value, |l| match l {
|
||||
impl TryFromExprInst for Numeric {
|
||||
fn from_exi(exi: &ExprInst) -> Result<Self, Rc<dyn ExternError>> {
|
||||
with_lit(exi, |l| match l {
|
||||
Literal::Uint(i) => Ok(Numeric::Uint(*i)),
|
||||
Literal::Num(n) => Ok(Numeric::Num(*n)),
|
||||
_ => AssertionError::fail(value.clone(), "an integer or number")?,
|
||||
_ => AssertionError::fail(exi.clone(), "an integer or number")?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,17 @@ use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::foreign::cps_box::{const_cps, init_cps, CPSBox};
|
||||
use crate::foreign::Atomic;
|
||||
use crate::foreign::{Atomic, InertAtomic};
|
||||
use crate::interpreted::ExprInst;
|
||||
use crate::interpreter::HandlerTable;
|
||||
use crate::systems::codegen::call;
|
||||
use crate::{atomic_inert, define_fn, ConstTree, Interner};
|
||||
use crate::{define_fn, ConstTree, Interner};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct State(Rc<RefCell<ExprInst>>);
|
||||
atomic_inert!(State, typestr = "a state");
|
||||
impl InertAtomic for State {
|
||||
fn type_str() -> &'static str { "a stateful container" }
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct NewStateCmd;
|
||||
@@ -21,8 +23,8 @@ struct SetStateCmd(State);
|
||||
#[derive(Debug, Clone)]
|
||||
struct GetStateCmd(State);
|
||||
|
||||
define_fn! { SetState = |x| Ok(init_cps(2, SetStateCmd(x.try_into()?))) }
|
||||
define_fn! { GetState = |x| Ok(init_cps(2, GetStateCmd(x.try_into()?))) }
|
||||
define_fn! { SetState = |x| Ok(init_cps(2, SetStateCmd(x.downcast()?))) }
|
||||
define_fn! { GetState = |x| Ok(init_cps(2, GetStateCmd(x.downcast()?))) }
|
||||
|
||||
fn new_state_handler<E>(cmd: &CPSBox<NewStateCmd>) -> Result<ExprInst, E> {
|
||||
let (_, default, handler) = cmd.unpack2();
|
||||
|
||||
Reference in New Issue
Block a user