use const_format::concatcp;
pub use self::arbitrary::Arbitrary;
_____!();
use rand::make_rng;
use rand::rngs::SmallRng;
use crate::bug;
use crate::cfg::CfgMod;
use crate::cfg::extend_func;
use crate::semantics::cfg::Cfg;
use crate::semantics::core::PREFIX_CELL;
use crate::semantics::func::CtxConstInputFreeFunc;
use crate::semantics::func::CtxFreeInputAwareFunc;
use crate::semantics::val::BIT;
use crate::semantics::val::BYTE;
use crate::semantics::val::CALL;
use crate::semantics::val::CELL;
use crate::semantics::val::CFG;
use crate::semantics::val::DECIMAL;
use crate::semantics::val::FUNC;
use crate::semantics::val::FuncVal;
use crate::semantics::val::INT;
use crate::semantics::val::KEY;
use crate::semantics::val::LINK;
use crate::semantics::val::LIST;
use crate::semantics::val::LinkVal;
use crate::semantics::val::MAP;
use crate::semantics::val::PAIR;
use crate::semantics::val::PrimFuncVal;
use crate::semantics::val::QUOTE;
use crate::semantics::val::TEXT;
use crate::semantics::val::UNIT;
use crate::semantics::val::Val;
use crate::type_::Bit;
use crate::type_::Byte;
use crate::type_::Call;
use crate::type_::Cell;
use crate::type_::Decimal;
use crate::type_::Int;
use crate::type_::Key;
use crate::type_::List;
use crate::type_::Map;
use crate::type_::Pair;
use crate::type_::Quote;
use crate::type_::Text;
use crate::type_::Unit;
#[derive(Clone)]
pub struct ValueLib {
pub any: PrimFuncVal,
pub get_type: PrimFuncVal,
pub equal: PrimFuncVal,
}
const VALUE: &str = "value";
pub const ANY: &str = concatcp!(PREFIX_CELL, VALUE, ".any");
pub const GET_TYPE: &str = concatcp!(PREFIX_CELL, VALUE, ".get_type");
pub const EQUAL: &str = concatcp!(PREFIX_CELL, VALUE, ".equal");
impl Default for ValueLib {
fn default() -> Self {
ValueLib {
any: CtxFreeInputAwareFunc { fn_: any }.build(),
get_type: CtxConstInputFreeFunc { fn_: get_type }.build(),
equal: CtxFreeInputAwareFunc { fn_: equal }.build(),
}
}
}
impl CfgMod for ValueLib {
fn extend(self, cfg: &mut Cfg) {
extend_func(cfg, ANY, self.any);
extend_func(cfg, GET_TYPE, self.get_type);
extend_func(cfg, EQUAL, self.equal);
}
}
const TYPE_UNIT: &str = concatcp!(PREFIX_CELL, UNIT);
const TYPE_BIT: &str = concatcp!(PREFIX_CELL, BIT);
const TYPE_KEY: &str = concatcp!(PREFIX_CELL, KEY);
const TYPE_TEXT: &str = concatcp!(PREFIX_CELL, TEXT);
const TYPE_INT: &str = concatcp!(PREFIX_CELL, INT);
const TYPE_DECIMAL: &str = concatcp!(PREFIX_CELL, DECIMAL);
const TYPE_BYTE: &str = concatcp!(PREFIX_CELL, BYTE);
const TYPE_CELL: &str = concatcp!(PREFIX_CELL, CELL);
const TYPE_PAIR: &str = concatcp!(PREFIX_CELL, PAIR);
const TYPE_LIST: &str = concatcp!(PREFIX_CELL, LIST);
const TYPE_MAP: &str = concatcp!(PREFIX_CELL, MAP);
const TYPE_QUOTE: &str = concatcp!(PREFIX_CELL, QUOTE);
const TYPE_CALL: &str = concatcp!(PREFIX_CELL, CALL);
const TYPE_LINK: &str = concatcp!(PREFIX_CELL, LINK);
const TYPE_CFG: &str = concatcp!(PREFIX_CELL, CFG);
const TYPE_FUNC: &str = concatcp!(PREFIX_CELL, FUNC);
pub fn any(cfg: &mut Cfg, input: Val) -> Val {
const DEPTH: usize = 0;
let mut rng: SmallRng = make_rng();
let rng = &mut rng;
match input {
Val::Unit(_) => Val::any(rng, DEPTH),
Val::Key(s) => match &*s {
TYPE_UNIT => Val::Unit(Unit::any(rng, DEPTH)),
TYPE_BIT => Val::Bit(Bit::any(rng, DEPTH)),
TYPE_KEY => Val::Key(Key::any(rng, DEPTH)),
TYPE_TEXT => Val::Text(Text::any(rng, DEPTH).into()),
TYPE_INT => Val::Int(Int::any(rng, DEPTH).into()),
TYPE_DECIMAL => Val::Decimal(Decimal::any(rng, DEPTH).into()),
TYPE_BYTE => Val::Byte(Byte::any(rng, DEPTH).into()),
TYPE_CELL => Val::Cell(Cell::<Val>::any(rng, DEPTH).into()),
TYPE_PAIR => Val::Pair(Pair::<Val, Val>::any(rng, DEPTH).into()),
TYPE_LIST => Val::List(List::<Val>::any(rng, DEPTH).into()),
TYPE_MAP => Val::Map(Map::<Key, Val>::any(rng, DEPTH).into()),
TYPE_QUOTE => Val::Quote(Quote::<Val>::any(rng, DEPTH).into()),
TYPE_CALL => Val::Call(Call::<Val, Val>::any(rng, DEPTH).into()),
TYPE_LINK => Val::Link(LinkVal::any(rng, DEPTH)),
TYPE_CFG => Val::Cfg(Cfg::any(rng, DEPTH).into()),
TYPE_FUNC => Val::Func(FuncVal::any(rng, DEPTH)),
s => bug!(cfg, "{ANY}: unknown type {s}"),
},
v => bug!(cfg, "{ANY}: expected input to be a key or a unit, but got {v}"),
}
}
pub fn get_type(_cfg: &mut Cfg, ctx: &Val) -> Val {
let s = match ctx {
Val::Unit(_) => TYPE_UNIT,
Val::Bit(_) => TYPE_BIT,
Val::Key(_) => TYPE_KEY,
Val::Text(_) => TYPE_TEXT,
Val::Int(_) => TYPE_INT,
Val::Decimal(_) => TYPE_DECIMAL,
Val::Byte(_) => TYPE_BYTE,
Val::Cell(_) => TYPE_CELL,
Val::Pair(_) => TYPE_PAIR,
Val::List(_) => TYPE_LIST,
Val::Map(_) => TYPE_MAP,
Val::Quote(_) => TYPE_QUOTE,
Val::Call(_) => TYPE_CALL,
Val::Link(_) => TYPE_LINK,
Val::Cfg(_) => TYPE_CFG,
Val::Func(_) => TYPE_FUNC,
Val::Dyn(val) => return Val::Key(val.type_name()),
};
Val::Key(Key::from_str_unchecked(s))
}
pub fn equal(cfg: &mut Cfg, input: Val) -> Val {
let Val::Pair(pair) = input else {
return bug!(cfg, "{EQUAL}: expected input to be a pair, but got {input}");
};
Val::Bit(Bit::from(pair.left == pair.right))
}
mod arbitrary;