dsl gets the gordian treatment

This commit is contained in:
🪞👃🪞 2025-05-26 22:49:55 +03:00
parent 93b1cf1a5c
commit d6e8be6ce5
9 changed files with 540 additions and 456 deletions

View file

@ -1,12 +1,13 @@
use crate::*;
impl<S, A> Dsl<S> for When<A> where S: Eval<Ast, bool> + Eval<Ast, A> {
fn try_provide (state: S, source: Ast) -> Perhaps<Self> {
if let Ast::Exp(source) = source {
if let Some(Ast::Key(id)) = source.next() && *id == *"when" {
fn try_provide (state: S, source: impl Ast) -> Perhaps<Self> {
if let Ast::Exp(exp) = source {
let mut iter = source.clone();
if let Some(Ast::Key(id)) = iter.next() && *id == *"when" {
return Ok(Some(Self(
state.eval(source.next().unwrap(), ||"when: expected condition")?,
state.eval(source.next().unwrap(), ||"when: expected content")?,
state.eval(iter.next().unwrap(), ||"when: expected condition")?,
state.eval(iter.next().unwrap(), ||"when: expected content")?,
)))
}
}
@ -15,13 +16,14 @@ impl<S, A> Dsl<S> for When<A> where S: Eval<Ast, bool> + Eval<Ast, A> {
}
impl<S, A, B> Dsl<S> for Either<A, B> where S: Eval<Ast, bool> + Eval<Ast, A> + Eval<Ast, B> {
fn try_provide (state: S, mut source: Ast) -> Perhaps<Self> {
if let Ast::Exp(mut source) = source {
if let Some(Ast::Key(id)) = source.next() && *id == *"either" {
fn try_provide (state: S, source: impl Ast) -> Perhaps<Self> {
if let Ast::Exp(source) = source {
let mut iter = source.clone();
if let Some(Ast::Key(id)) = iter.next() && *id == *"either" {
return Ok(Some(Self(
state.eval(source.next().unwrap(), ||"either: expected condition")?,
state.eval(source.next().unwrap(), ||"either: expected content 1")?,
state.eval(source.next().unwrap(), ||"either: expected content 2")?,
state.eval(iter.next().unwrap(), ||"either: expected condition")?,
state.eval(iter.next().unwrap(), ||"either: expected content 1")?,
state.eval(iter.next().unwrap(), ||"either: expected content 2")?,
)))
}
}
@ -29,41 +31,35 @@ impl<S, A, B> Dsl<S> for Either<A, B> where S: Eval<Ast, bool> + Eval<Ast, A> +
}
}
impl<S, A, B> Dsl<S> for Bsp<A, B>
where S: Eval<Option<Ast>, A> + Eval<Option<Ast>, B> {
fn try_provide (state: S, source: Ast) -> Perhaps<Self> {
impl<S, A, B> Dsl<S> for Bsp<A, B> where S: Eval<Option<Ast>, A> + Eval<Option<Ast>, B> {
fn try_provide (state: S, source: impl Ast) -> Perhaps<Self> {
Ok(Some(if let Ast::Exp(source) = source {
match source.next() {
Some(Value::Key("bsp/n")) => {
let a: A = state.eval(source.next(), ||"bsp/n: expected content 1")?;
let b: B = state.eval(source.next(), ||"bsp/n: expected content 2")?;
Self::n(a, b)
},
Some(Value::Key("bsp/s")) => {
let a: A = state.eval(source.next(), ||"bsp/s: expected content 1")?;
let b: B = state.eval(source.next(), ||"bsp/s: expected content 2")?;
Self::s(a, b)
},
Some(Value::Key("bsp/e")) => {
let a: A = state.eval(source.next(), ||"bsp/e: expected content 1")?;
let b: B = state.eval(source.next(), ||"bsp/e: expected content 2")?;
Self::e(a, b)
},
Some(Value::Key("bsp/w")) => {
let a: A = state.eval(source.next(), ||"bsp/w: expected content 1")?;
let b: B = state.eval(source.next(), ||"bsp/w: expected content 2")?;
Self::w(a, b)
},
Some(Value::Key("bsp/a")) => {
let a: A = state.eval(source.next(), ||"bsp/a: expected content 1")?;
let b: B = state.eval(source.next(), ||"bsp/a: expected content 2")?;
Self::a(a, b)
},
Some(Value::Key("bsp/b")) => {
let a: A = state.eval(source.next(), ||"bsp/b: expected content 1")?;
let b: B = state.eval(source.next(), ||"bsp/b: expected content 2")?;
Self::b(a, b)
},
let mut iter = source.clone();
match iter.next() {
Some(Value::Key("bsp/n")) => Self::n(
state.eval(iter.next(), ||"bsp/n: expected content 1")?,
state.eval(iter.next(), ||"bsp/n: expected content 2")?,
),
Some(Value::Key("bsp/s")) => Self::s(
state.eval(iter.next(), ||"bsp/s: expected content 1")?,
state.eval(iter.next(), ||"bsp/s: expected content 2")?,
),
Some(Value::Key("bsp/e")) => Self::e(
state.eval(iter.next(), ||"bsp/e: expected content 1")?,
state.eval(iter.next(), ||"bsp/e: expected content 2")?,
),
Some(Value::Key("bsp/w")) => Self::w(
state.eval(iter.next(), ||"bsp/w: expected content 1")?,
state.eval(iter.next(), ||"bsp/w: expected content 2")?,
),
Some(Value::Key("bsp/a")) => Self::a(
state.eval(iter.next(), ||"bsp/a: expected content 1")?,
state.eval(iter.next(), ||"bsp/a: expected content 2")?,
),
Some(Value::Key("bsp/b")) => Self::b(
state.eval(iter.next(), ||"bsp/b: expected content 1")?,
state.eval(iter.next(), ||"bsp/b: expected content 2")?,
),
_ => return Ok(None),
}
} else {
@ -73,53 +69,32 @@ where S: Eval<Option<Ast>, A> + Eval<Option<Ast>, B> {
}
impl<S, A> Dsl<S> for Align<A> where S: Eval<Option<Ast>, A> {
fn try_provide (state: S, source: Ast) -> Perhaps<Self> {
fn try_provide (state: S, source: impl Ast) -> Perhaps<Self> {
Ok(Some(if let Ast::Exp(source) = source {
match source.next() {
Some(Value::Key("align/c")) => {
let content: A = state.eval(source.next(), ||"align/c: expected content")?;
Self::c(content)
},
Some(Value::Key("align/x")) => {
let content: A = state.eval(source.next(), ||"align/x: expected content")?;
Self::x(content)
},
Some(Value::Key("align/y")) => {
let content: A = state.eval(source.next(), ||"align/y: expected content")?;
Self::y(content)
},
Some(Value::Key("align/n")) => {
let content: A = state.eval(source.next(), ||"align/n: expected content")?;
Self::n(content)
},
Some(Value::Key("align/s")) => {
let content: A = state.eval(source.next(), ||"align/s: expected content")?;
Self::s(content)
},
Some(Value::Key("align/e")) => {
let content: A = state.eval(source.next(), ||"align/e: expected content")?;
Self::e(content)
},
Some(Value::Key("align/w")) => {
let content: A = state.eval(source.next(), ||"align/w: expected content")?;
Self::w(content)
},
Some(Value::Key("align/nw")) => {
let content: A = state.eval(source.next(), ||"align/nw: expected content")?;
Self::nw(content)
},
Some(Value::Key("align/ne")) => {
let content: A = state.eval(source.next(), ||"align/ne: expected content")?;
Self::ne(content)
},
Some(Value::Key("align/sw")) => {
let content: A = state.eval(source.next(), ||"align/sw: expected content")?;
Self::sw(content)
},
Some(Value::Key("align/se")) => {
let content: A = state.eval(source.next(), ||"align/se: expected content")?;
Self::se(content)
},
let mut iter = source.clone();
match iter.next() {
Some(Value::Key("align/c")) =>
Self::c(state.eval(iter.next(), ||"align/c: expected content")?),
Some(Value::Key("align/x")) =>
Self::x(state.eval(iter.next(), ||"align/x: expected content")?),
Some(Value::Key("align/y")) =>
Self::y(state.eval(iter.next(), ||"align/y: expected content")?),
Some(Value::Key("align/n")) =>
Self::n(state.eval(iter.next(), ||"align/n: expected content")?),
Some(Value::Key("align/s")) =>
Self::s(state.eval(iter.next(), ||"align/s: expected content")?),
Some(Value::Key("align/e")) =>
Self::e(state.eval(iter.next(), ||"align/e: expected content")?),
Some(Value::Key("align/w")) =>
Self::w(state.eval(iter.next(), ||"align/w: expected content")?),
Some(Value::Key("align/nw")) =>
Self::nw(state.eval(iter.next(), ||"align/nw: expected content")?),
Some(Value::Key("align/ne")) =>
Self::ne(state.eval(iter.next(), ||"align/ne: expected content")?),
Some(Value::Key("align/sw")) =>
Self::sw(state.eval(iter.next(), ||"align/sw: expected content")?),
Some(Value::Key("align/se")) =>
Self::se(state.eval(iter.next(), ||"align/se: expected content")?),
_ => return Ok(None),
}
} else {