use std::{time::SystemTime, str::FromStr, iter::FromIterator};
use kul::{
common::inmem::{
parse_str, parse_str_with,
Text, OperatorBindings, DatumAllocator,
},
Combiner, Datum, datum::{BoxDatum, DatumBox}, Error, Text as _,
};
fn no_extension() {
dbg!(parse_str("λ"));
dbg!(parse_str(r"es\{c\}ap\\es"));
dbg!(parse_str("{}"));
dbg!(parse_str("{▷}"));
dbg!(parse_str("Surrounding {{▷} λ {}} text."));
}
fn with_extensions()
{
#[derive(Hash, Eq, PartialEq, Debug)]
enum MyDatumVariants {
Time(SystemTime),
Integer(i128),
}
#[derive(Debug)]
enum MyCombinerError<'input> {
Oops,
Darnit(MyDatum<'input>),
}
type MyDatum<'input> = BoxDatum<Text<'input>, MyDatumVariants>;
type MyOperatorBindings<'input> =
OperatorBindings<'input, MyDatumVariants, MyCombinerError<'input>>;
type MyDatumAllocator<'input> = DatumAllocator<'input, MyDatumVariants>;
type AllocArg<'a> = &'a mut MyDatumAllocator<'static>;
let comment = |_operator, _operands, _: AllocArg<'_>| {
Ok(None)
};
let pass_thru = |_operator, operands, _: AllocArg<'_>| {
Ok(Some(operands))
};
let current_time = |_operator, operands, _: AllocArg<'_>| {
if let Datum::EmptyList = operands {
Ok(Some(Datum::Extra(MyDatumVariants::Time(SystemTime::now()))))
} else {
Err(Error::FailedCombiner(MyCombinerError::Darnit(operands)))
}
};
let int = |_operator, operands: Text<'_>, _: AllocArg<'_>| {
let i = i128::from_str(&String::from_iter(operands.chars()))
.map_err(|_| Error::FailedCombiner(MyCombinerError::Oops))?;
Ok(Some(Datum::Extra(MyDatumVariants::Integer(i))))
};
let mut bindings = MyOperatorBindings::default();
bindings.hashmap.insert(Datum::Text(Text::from_str("#")),
Combiner::Operative(Box::new(comment)));
bindings.hashmap.insert(Datum::Text(Text::from_str("current-time")),
Combiner::Applicative(Box::new(current_time)));
bindings.hashmap.insert(Datum::Text(Text::from_str("int")),
Combiner::Operative(Box::new(int)));
let compound_operator_form =
Datum::Combination {
operator: DatumBox::new(Datum::Text(Text::from_str("compound"))),
operands: DatumBox::new(Datum::EmptyList),
};
bindings.hashmap.insert(compound_operator_form,
Combiner::Applicative(Box::new(pass_thru)));
dbg!(parse_str_with(
"{{compound} {current-time} {# removed} {unbound form} {int -42}}",
bindings)
);
}
fn main() {
no_extension();
with_extensions();
}