mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2025-12-07 04:06:48 +01:00
This commit is contained in:
parent
c8827b43c3
commit
b500eb63fc
14 changed files with 657 additions and 742 deletions
|
|
@ -1,91 +1,65 @@
|
|||
use crate::*;
|
||||
use Value::*;
|
||||
use DslValue::*;
|
||||
|
||||
impl<S, A> Dsl<S> for When<A> where S: Eval<Ast, bool> + Eval<Ast, A> {
|
||||
fn try_provide (state: &S, source: impl DslValue) -> Perhaps<Self> {
|
||||
if let Exp(_, mut exp) = source.value()
|
||||
&& let Some(Ast(Key(id))) = exp.peek() && *id == *"when" {
|
||||
let _ = exp.next();
|
||||
return Ok(Some(Self(
|
||||
state.eval(exp.next().unwrap(), ||"when: expected condition")?,
|
||||
state.eval(exp.next().unwrap(), ||"when: expected content")?,
|
||||
)))
|
||||
}
|
||||
fn exp_match <S: DslValue, E: DslIter, T> (source: S, namespace: &str, cb: impl Fn(&str, E)) -> Perhaps<T> {
|
||||
if let Some(exp) = source.exp()
|
||||
&& let Some(Key(key)) = exp.next()
|
||||
&& key.starts_with(namespace) {
|
||||
cb(key.split_at(namespace.len()).1, exp)
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
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, source: impl DslValue) -> Perhaps<Self> {
|
||||
if let Exp(_, mut exp) = source.value()
|
||||
&& let Some(Ast(Key(id))) = exp.peek() && *id == *"either" {
|
||||
let _ = exp.next();
|
||||
return Ok(Some(Self(
|
||||
state.eval(exp.next().unwrap(), ||"either: expected condition")?,
|
||||
state.eval(exp.next().unwrap(), ||"either: expected content 1")?,
|
||||
state.eval(exp.next().unwrap(), ||"either: expected content 2")?,
|
||||
)))
|
||||
}
|
||||
Ok(None)
|
||||
impl<S, A> FromDsl<S> for When<A> where S: Eval<Ast, bool> + Eval<Ast, A> {
|
||||
fn try_provide (state: &S, source: DslValue<impl DslStr, impl DslExp>) -> Perhaps<Self> {
|
||||
exp_match::<S, Self>(source, "when", |_, tail|Ok(Some(Self(
|
||||
tail.eval(0, ||"no condition")?,
|
||||
tail.eval(1, ||"no content")?,
|
||||
))))
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, A> Dsl<S> for Align<A> where S: Eval<Option<Ast>, A> {
|
||||
fn try_provide (state: &S, source: impl DslValue) -> Perhaps<Self> {
|
||||
if let Exp(_, source) = source.value() {
|
||||
let mut rest = source.clone();
|
||||
return Ok(Some(match rest.next().as_ref().and_then(|x|x.key()) {
|
||||
Some("align/c") => Self::c(state.eval(rest.next(), ||"align/c: expected content")?),
|
||||
Some("align/x") => Self::x(state.eval(rest.next(), ||"align/x: expected content")?),
|
||||
Some("align/y") => Self::y(state.eval(rest.next(), ||"align/y: expected content")?),
|
||||
Some("align/n") => Self::n(state.eval(rest.next(), ||"align/n: expected content")?),
|
||||
Some("align/s") => Self::s(state.eval(rest.next(), ||"align/s: expected content")?),
|
||||
Some("align/e") => Self::e(state.eval(rest.next(), ||"align/e: expected content")?),
|
||||
Some("align/w") => Self::w(state.eval(rest.next(), ||"align/w: expected content")?),
|
||||
Some("align/nw") => Self::nw(state.eval(rest.next(), ||"align/nw: expected content")?),
|
||||
Some("align/ne") => Self::ne(state.eval(rest.next(), ||"align/ne: expected content")?),
|
||||
Some("align/sw") => Self::sw(state.eval(rest.next(), ||"align/sw: expected content")?),
|
||||
Some("align/se") => Self::se(state.eval(rest.next(), ||"align/se: expected content")?),
|
||||
_ => return Ok(None),
|
||||
}))
|
||||
}
|
||||
Ok(None)
|
||||
impl<S, A, B> FromDsl<S> for Either<A, B> where S: Eval<Ast, bool> + Eval<Ast, A> + Eval<Ast, B> {
|
||||
fn try_provide (state: &S, source: DslValue<impl DslStr, impl DslExp>) -> Perhaps<Self> {
|
||||
exp_match::<S, Self>(source, "either", |_, tail|Ok(Some(Self(
|
||||
tail.eval(0, ||"no condition")?,
|
||||
tail.eval(1, ||"no content 1")?,
|
||||
tail.eval(2, ||"no content 2")?,
|
||||
))))
|
||||
}
|
||||
}
|
||||
|
||||
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 DslValue) -> Perhaps<Self> {
|
||||
if let Exp(_, exp) = source.value() {
|
||||
let mut rest = exp.clone();
|
||||
return Ok(Some(match rest.next().as_ref().and_then(|x|x.key()) {
|
||||
Some("bsp/n") => Self::n(
|
||||
state.eval(rest.next(), ||"bsp/n: expected content 1")?,
|
||||
state.eval(rest.next(), ||"bsp/n: expected content 2")?,
|
||||
),
|
||||
Some("bsp/s") => Self::s(
|
||||
state.eval(rest.next(), ||"bsp/s: expected content 1")?,
|
||||
state.eval(rest.next(), ||"bsp/s: expected content 2")?,
|
||||
),
|
||||
Some("bsp/e") => Self::e(
|
||||
state.eval(rest.next(), ||"bsp/e: expected content 1")?,
|
||||
state.eval(rest.next(), ||"bsp/e: expected content 2")?,
|
||||
),
|
||||
Some("bsp/w") => Self::w(
|
||||
state.eval(rest.next(), ||"bsp/w: expected content 1")?,
|
||||
state.eval(rest.next(), ||"bsp/w: expected content 2")?,
|
||||
),
|
||||
Some("bsp/a") => Self::a(
|
||||
state.eval(rest.next(), ||"bsp/a: expected content 1")?,
|
||||
state.eval(rest.next(), ||"bsp/a: expected content 2")?,
|
||||
),
|
||||
Some("bsp/b") => Self::b(
|
||||
state.eval(rest.next(), ||"bsp/b: expected content 1")?,
|
||||
state.eval(rest.next(), ||"bsp/b: expected content 2")?,
|
||||
),
|
||||
_ => return Ok(None),
|
||||
}))
|
||||
}
|
||||
Ok(None)
|
||||
impl<S, A> FromDsl<S> for Align<A> where S: Eval<Option<Ast>, A> {
|
||||
fn try_provide (state: &S, source: DslValue<impl DslStr, impl DslExp>) -> Perhaps<Self> {
|
||||
exp_match::<S, Self>(source, "align/", |head, tail|Ok(Some(match head {
|
||||
"c" => Self::c(tail.eval(0, ||"no content")?),
|
||||
"x" => Self::x(tail.eval(0, ||"no content")?),
|
||||
"y" => Self::y(tail.eval(0, ||"no content")?),
|
||||
"n" => Self::n(tail.eval(0, ||"no content")?),
|
||||
"s" => Self::s(tail.eval(0, ||"no content")?),
|
||||
"e" => Self::e(tail.eval(0, ||"no content")?),
|
||||
"w" => Self::w(tail.eval(0, ||"no content")?),
|
||||
"nw" => Self::nw(tail.eval(0, ||"no content")?),
|
||||
"ne" => Self::ne(tail.eval(0, ||"no content")?),
|
||||
"sw" => Self::sw(tail.eval(0, ||"no content")?),
|
||||
"se" => Self::se(tail.eval(0, ||"no content")?),
|
||||
_ => return Err("invalid align variant")
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, A, B> FromDsl<S> for Bsp<A, B> where S: Eval<Option<Ast>, A> + Eval<Option<Ast>, B> {
|
||||
fn try_provide (state: &S, source: DslValue<impl DslStr, impl DslExp>) -> Perhaps<Self> {
|
||||
exp_match::<S, Self>(source, "bsp/", |head, tail|Ok(Some(match head {
|
||||
"n" => Self::n(tail.eval(0, ||"no content 1"), tail.eval(1, ||"no content 2")),
|
||||
"s" => Self::s(tail.eval(0, ||"no content 1"), tail.eval(1, ||"no content 2")),
|
||||
"e" => Self::e(tail.eval(0, ||"no content 1"), tail.eval(1, ||"no content 2")),
|
||||
"w" => Self::w(tail.eval(0, ||"no content 1"), tail.eval(1, ||"no content 2")),
|
||||
"a" => Self::a(tail.eval(0, ||"no content 1"), tail.eval(1, ||"no content 2")),
|
||||
"b" => Self::b(tail.eval(0, ||"no content 1"), tail.eval(1, ||"no content 2")),
|
||||
_ => return Ok(None),
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -124,3 +98,77 @@ impl<S, A, B> Dsl<S> for Bsp<A, B> where S: Eval<Option<Ast>, A> + Eval<Option<A
|
|||
//} else {
|
||||
//None
|
||||
//}));
|
||||
//if let Exp(_, exp) = source.value() {
|
||||
//let mut rest = exp.clone();
|
||||
//return Ok(Some(match rest.next().as_ref().and_then(|x|x.key()) {
|
||||
//Some("bsp/n") => Self::n(
|
||||
//state.eval(rest.next(), ||"bsp/n: no content 1")?,
|
||||
//state.eval(rest.next(), ||"bsp/n: no content 2")?,
|
||||
//),
|
||||
//Some("bsp/s") => Self::s(
|
||||
//state.eval(rest.next(), ||"bsp/s: no content 1")?,
|
||||
//state.eval(rest.next(), ||"bsp/s: no content 2")?,
|
||||
//),
|
||||
//Some("bsp/e") => Self::e(
|
||||
//state.eval(rest.next(), ||"bsp/e: no content 1")?,
|
||||
//state.eval(rest.next(), ||"bsp/e: no content 2")?,
|
||||
//),
|
||||
//Some("bsp/w") => Self::w(
|
||||
//state.eval(rest.next(), ||"bsp/w: no content 1")?,
|
||||
//state.eval(rest.next(), ||"bsp/w: no content 2")?,
|
||||
//),
|
||||
//Some("bsp/a") => Self::a(
|
||||
//state.eval(rest.next(), ||"bsp/a: no content 1")?,
|
||||
//state.eval(rest.next(), ||"bsp/a: no content 2")?,
|
||||
//),
|
||||
//Some("bsp/b") => Self::b(
|
||||
//state.eval(rest.next(), ||"bsp/b: no content 1")?,
|
||||
//state.eval(rest.next(), ||"bsp/b: no content 2")?,
|
||||
//),
|
||||
//_ => return Ok(None),
|
||||
//}))
|
||||
//}
|
||||
//Ok(None)
|
||||
//if let Exp(_, source) = source.value() {
|
||||
//let mut rest = source.clone();
|
||||
//return Ok(Some(match rest.next().as_ref().and_then(|x|x.key()) {
|
||||
//Some("align/c") => Self::c(state.eval(rest.next(), ||"align/c: no content")?),
|
||||
//Some("align/x") => Self::x(state.eval(rest.next(), ||"align/x: no content")?),
|
||||
//Some("align/y") => Self::y(state.eval(rest.next(), ||"align/y: no content")?),
|
||||
//Some("align/n") => Self::n(state.eval(rest.next(), ||"align/n: no content")?),
|
||||
//Some("align/s") => Self::s(state.eval(rest.next(), ||"align/s: no content")?),
|
||||
//Some("align/e") => Self::e(state.eval(rest.next(), ||"align/e: no content")?),
|
||||
//Some("align/w") => Self::w(state.eval(rest.next(), ||"align/w: no content")?),
|
||||
//Some("align/nw") => Self::nw(state.eval(rest.next(), ||"align/nw: no content")?),
|
||||
//Some("align/ne") => Self::ne(state.eval(rest.next(), ||"align/ne: no content")?),
|
||||
//Some("align/sw") => Self::sw(state.eval(rest.next(), ||"align/sw: no content")?),
|
||||
//Some("align/se") => Self::se(state.eval(rest.next(), ||"align/se: no content")?),
|
||||
//_ => return Ok(None),
|
||||
//}))
|
||||
//}
|
||||
//Ok(None)
|
||||
//Ok(match source.exp_head().and_then(|e|e.key()) {
|
||||
//Some("either") => Some(Self(
|
||||
//source.exp_tail().and_then(|t|t.get(0)).map(|x|state.eval(x, ||"when: no condition"))?,
|
||||
//source.exp_tail().and_then(|t|t.get(1)).map(|x|state.eval(x, ||"when: no content 1"))?,
|
||||
//source.exp_tail().and_then(|t|t.get(2)).map(|x|state.eval(x, ||"when: no content 2"))?,
|
||||
//)),
|
||||
//_ => None
|
||||
//})
|
||||
//if let Exp(_, mut exp) = source.value()
|
||||
//&& let Some(Ast(Key(id))) = exp.peek() && *id == *"either" {
|
||||
//let _ = exp.next();
|
||||
//return Ok(Some(Self(
|
||||
//state.eval(exp.next().unwrap(), ||"either: no condition")?,
|
||||
//state.eval(exp.next().unwrap(), ||"either: no content 1")?,
|
||||
//state.eval(exp.next().unwrap(), ||"either: no content 2")?,
|
||||
//)))
|
||||
//}
|
||||
//Ok(None)
|
||||
//Ok(match source.exp_head().and_then(|e|e.key()) {
|
||||
//Some("when") => Some(Self(
|
||||
//source.exp_tail().and_then(|t|t.get(0)).map(|x|state.eval(x, ||"when: no condition"))?,
|
||||
//source.exp_tail().and_then(|t|t.get(1)).map(|x|state.eval(x, ||"when: no content"))?,
|
||||
//)),
|
||||
//_ => None
|
||||
//})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue