some cleanup

This commit is contained in:
elkowar 2021-07-03 19:05:45 +02:00
parent 1ec5a1d6bc
commit af19291bf9
No known key found for this signature in database
GPG key ID: E321AD71B1D1F27F
21 changed files with 135 additions and 293 deletions

View file

@ -10,6 +10,8 @@ use std::{
str::FromStr,
};
// https://michael-f-bryan.github.io/static-analyser-in-rust/book/codemap.html
type VarName = String;
type AttrValue = String;
type AttrName = String;
@ -24,48 +26,6 @@ impl FromExpr for Expr {
}
}
#[derive(Debug, Eq, PartialEq)]
pub enum DefType {
Widget,
}
impl FromStr for DefType {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"defwidget" => Ok(DefType::Widget),
_ => Err(()),
}
}
}
#[derive(Debug, Eq, PartialEq)]
pub struct Definitional<C, A> {
def_type: DefType,
name: String,
attrs: HashMap<AttrName, A>,
children: Vec<C>,
span: Span,
}
impl<C: FromExpr, A: FromExpr> FromExpr for Definitional<C, A> {
fn from_expr(e: Expr) -> AstResult<Self> {
let span = e.span();
spanned!(e.span(), {
let list = e.as_list()?;
let mut iter = ExprIterator::new(list.into_iter());
let (span, def_type) = iter.next_symbol()?;
let def_type = def_type.parse().map_err(|_| AstError::InvalidDefinition(Some(span)))?;
let (_, name) = iter.next_symbol()?;
let attrs = iter.key_values()?;
let children = iter.map(|x| C::from_expr(x)).collect::<AstResult<Vec<_>>>()?;
Definitional { span, def_type, name, attrs, children }
})
}
}
#[derive(Debug, Eq, PartialEq)]
pub struct Element<C, A> {
name: String,
@ -80,8 +40,8 @@ impl<C: FromExpr, A: FromExpr> FromExpr for Element<C, A> {
spanned!(e.span(), {
let list = e.as_list()?;
let mut iter = ExprIterator::new(list.into_iter());
let (_, name) = iter.next_symbol()?;
let attrs = iter.key_values()?;
let (_, name) = iter.expect_symbol()?;
let attrs = iter.expect_key_values()?;
let children = iter.map(C::from_expr).collect::<AstResult<Vec<_>>>()?;
Element { span, name, attrs, children }
})
@ -101,9 +61,6 @@ mod test {
insta::assert_debug_snapshot!(
Element::<Expr, Expr>::from_expr(parser.parse("(box :bar 12 :baz \"hi\" foo (bar))").unwrap()).unwrap()
);
insta::assert_debug_snapshot!(
Definitional::<Expr, Expr>::from_expr(parser.parse("(defwidget box (child) (child2))").unwrap()).unwrap()
);
});
}
}

View file

@ -15,7 +15,7 @@ impl std::fmt::Display for Span {
impl std::fmt::Debug for Span {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self)
write!(f, "{}..{}", self.0, self.1)
}
}
@ -36,7 +36,7 @@ impl Display for ExprType {
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
#[derive(PartialEq, Eq, Clone)]
pub enum Expr {
List(Span, Vec<Expr>),
Table(Span, Vec<(Expr, Expr)>),
@ -48,22 +48,29 @@ pub enum Expr {
}
macro_rules! as_func {
($exprtype:expr, $name:ident < $t:ty > = $p:pat => $value:expr) => {
($exprtype:expr, $name:ident $nameref:ident < $t:ty > = $p:pat => $value:expr) => {
pub fn $name(self) -> Result<$t, AstError> {
match self {
$p => Ok($value),
x => Err(AstError::WrongExprType(Some(x.span()), $exprtype, x.expr_type())),
}
}
pub fn $nameref(&self) -> Result<&$t, AstError> {
match self {
$p => Ok($value),
x => Err(AstError::WrongExprType(Some(x.span()), $exprtype, x.expr_type())),
}
}
};
}
impl Expr {
as_func!(ExprType::Str, as_str<String> = Expr::Str(_, x) => x);
as_func!(ExprType::Str, as_str as_str_ref<String> = Expr::Str(_, x) => x);
as_func!(ExprType::Symbol, as_symbol<String> = Expr::Symbol(_, x) => x);
as_func!(ExprType::Symbol, as_symbol as_symbol_ref<String> = Expr::Symbol(_, x) => x);
as_func!(ExprType::List, as_list<Vec<Expr>> = Expr::List(_, x) => x);
as_func!(ExprType::List, as_list as_list_ref<Vec<Expr>> = Expr::List(_, x) => x);
pub fn expr_type(&self) -> ExprType {
match self {
@ -88,6 +95,13 @@ impl Expr {
Expr::Comment(span) => *span,
}
}
pub fn first_list_elem(&self) -> Option<&Expr> {
match self {
Expr::List(_, list) => list.first(),
_ => None,
}
}
}
impl std::fmt::Display for Expr {
@ -104,6 +118,20 @@ impl std::fmt::Display for Expr {
}
}
}
impl std::fmt::Debug for Expr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use Expr::*;
match self {
Number(span, x) => write!(f, "Number<{}>({})", span, x),
List(span, x) => f.debug_tuple(&format!("List<{}>", span)).field(x).finish(),
Table(span, x) => f.debug_tuple(&format!("Table<{}>", span)).field(x).finish(),
Keyword(span, x) => write!(f, "Number<{}>({})", span, x),
Symbol(span, x) => write!(f, "Symbol<{}>({})", span, x),
Str(span, x) => write!(f, "Str<{}>({})", span, x),
Comment(span) => write!(f, "Comment<{}>", span),
}
}
}
pub struct ExprIterator<I: Iterator<Item = Expr>> {
iter: itertools::PutBack<I>,
@ -128,15 +156,19 @@ macro_rules! return_or_put_back {
}
impl<I: Iterator<Item = Expr>> ExprIterator<I> {
return_or_put_back!(next_symbol, ExprType::Symbol, (Span, String) = Expr::Symbol(span, x) => (span, x));
return_or_put_back!(expect_symbol, ExprType::Symbol, (Span, String) = Expr::Symbol(span, x) => (span, x));
return_or_put_back!(next_string, ExprType::Str, (Span, String) = Expr::Str(span, x) => (span, x));
return_or_put_back!(expect_string, ExprType::Str, (Span, String) = Expr::Str(span, x) => (span, x));
return_or_put_back!(expect_number, ExprType::Number, (Span, i32) = Expr::Number(span, x) => (span, x));
return_or_put_back!(expect_list, ExprType::List, (Span, Vec<Expr>) = Expr::List(span, x) => (span, x));
pub fn new(iter: I) -> Self {
ExprIterator { iter: itertools::put_back(iter) }
}
pub fn key_values<T: FromExpr>(&mut self) -> AstResult<HashMap<String, T>> {
pub fn expect_key_values<T: FromExpr>(&mut self) -> AstResult<HashMap<String, T>> {
parse_key_values(&mut self.iter)
}
}

View file

@ -41,6 +41,7 @@ fn test() {
r#"{:key value 12 "hi" (test) (1 2 3)}"#,
r#"; test"#,
r#"(f arg ; test
arg2)"#
arg2)"#,
"\"h\\\"i\""
);
}

View file

@ -8,22 +8,14 @@ Definitional {
name: "box",
attrs: {},
children: [
List(
15..22,
List<15..22>(
[
Symbol(
16..21,
"child",
),
Symbol<16..21>(child),
],
),
List(
23..31,
List<23..31>(
[
Symbol(
24..30,
"child2",
),
Symbol<24..30>(child2),
],
),
],

View file

@ -6,27 +6,14 @@ expression: "Element::<Expr,\n Expr>::from_expr(parser.parse(\"(box :ba
Element {
name: "box",
attrs: {
":bar": Number(
10..12,
12,
),
":baz": Str(
18..22,
"hi",
),
":baz": Str<18..22>(hi),
":bar": Number<10..12>(12),
},
children: [
Symbol(
23..26,
"foo",
),
List(
27..32,
Symbol<23..26>(foo),
List<27..32>(
[
Symbol(
28..31,
"bar",
),
Symbol<28..31>(bar),
],
),
],

View file

@ -1,20 +1,13 @@
---
source: src/main.rs
source: src/lib.rs
expression: "p.parse(r#\"(test \"h\\\"i\")\"#)"
---
Ok(
List(
0..13,
List<0..13>(
[
Symbol(
1..5,
"test",
),
Str(
6..12,
"h\\\"i",
),
Symbol<1..5>(test),
Str<6..12>(h\"i),
],
),
)

View file

@ -1,20 +1,13 @@
---
source: src/main.rs
source: src/lib.rs
expression: "p.parse(r#\"(test \" hi \")\"#)"
---
Ok(
List(
0..13,
List<0..13>(
[
Symbol(
1..5,
"test",
),
Str(
6..12,
" hi ",
),
Symbol<1..5>(test),
Str<6..12>( hi ),
],
),
)

View file

@ -1,42 +1,21 @@
---
source: src/main.rs
source: src/lib.rs
expression: "p.parse(\"(+ (1 2 (* 2 5)))\")"
---
Ok(
List(
0..17,
List<0..17>(
[
Symbol(
1..2,
"+",
),
List(
3..16,
Symbol<1..2>(+),
List<3..16>(
[
Number(
4..5,
1,
),
Number(
6..7,
2,
),
List(
8..15,
Number<4..5>(1),
Number<6..7>(2),
List<8..15>(
[
Symbol(
9..10,
"*",
),
Number(
11..12,
2,
),
Number(
13..14,
5,
),
Symbol<9..10>(*),
Number<11..12>(2),
Number<13..14>(5),
],
),
],

View file

@ -1,57 +1,30 @@
---
source: src/main.rs
source: src/lib.rs
expression: "p.parse(r#\"{:key value 12 \"hi\" (test) (1 2 3)}\"#)"
---
Ok(
Table(
0..35,
Table<0..35>(
[
(
Keyword(
1..5,
":key",
),
Symbol(
6..11,
"value",
),
Number<1..5>(:key),
Symbol<6..11>(value),
),
(
Number(
12..14,
12,
),
Str(
15..19,
"hi",
),
Number<12..14>(12),
Str<15..19>(hi),
),
(
List(
20..26,
List<20..26>(
[
Symbol(
21..25,
"test",
),
Symbol<21..25>(test),
],
),
List(
27..34,
List<27..34>(
[
Number(
28..29,
1,
),
Number(
30..31,
2,
),
Number(
32..33,
3,
),
Number<28..29>(1),
Number<30..31>(2),
Number<32..33>(3),
],
),
),

View file

@ -1,10 +1,8 @@
---
source: src/main.rs
source: src/lib.rs
expression: "p.parse(r#\"; test\"#)"
---
Ok(
Comment(
0..6,
),
Comment<0..6>,
)

View file

@ -4,24 +4,12 @@ expression: "p.parse(r#\"(f arg ; test\n arg2)\"#)"
---
Ok(
List(
0..27,
List<0..27>(
[
Symbol(
1..2,
"f",
),
Symbol(
3..6,
"arg",
),
Comment(
7..13,
),
Symbol(
22..26,
"arg2",
),
Symbol<1..2>(f),
Symbol<3..6>(arg),
Comment<7..13>,
Symbol<22..26>(arg2),
],
),
)

View file

@ -0,0 +1,8 @@
---
source: src/lib.rs
expression: "p.parse(\"\\\"h\\\\\\\"i\\\"\")"
---
Ok(
Str<0..6>(h\"i),
)

View file

@ -1,16 +1,12 @@
---
source: src/main.rs
source: src/lib.rs
expression: "p.parse(\"(12)\")"
---
Ok(
List(
0..4,
List<0..4>(
[
Number(
1..3,
12,
),
Number<1..3>(12),
],
),
)

View file

@ -1,20 +1,13 @@
---
source: src/main.rs
source: src/lib.rs
expression: "p.parse(\"(1 2)\")"
---
Ok(
List(
0..5,
List<0..5>(
[
Number(
1..2,
1,
),
Number(
3..4,
2,
),
Number<1..2>(1),
Number<3..4>(2),
],
),
)

View file

@ -1,24 +1,14 @@
---
source: src/main.rs
source: src/lib.rs
expression: "p.parse(\"(1 :foo 1)\")"
---
Ok(
List(
0..10,
List<0..10>(
[
Number(
1..2,
1,
),
Keyword(
3..7,
":foo",
),
Number(
8..9,
1,
),
Number<1..2>(1),
Number<3..7>(:foo),
Number<8..9>(1),
],
),
)

View file

@ -1,20 +1,13 @@
---
source: src/main.rs
source: src/lib.rs
expression: "p.parse(\"(:foo 1)\")"
---
Ok(
List(
0..8,
List<0..8>(
[
Keyword(
1..5,
":foo",
),
Number(
6..7,
1,
),
Number<1..5>(:foo),
Number<6..7>(1),
],
),
)

View file

@ -1,20 +1,13 @@
---
source: src/main.rs
source: src/lib.rs
expression: "p.parse(\"(:foo->: 1)\")"
---
Ok(
List(
0..11,
List<0..11>(
[
Keyword(
1..8,
":foo->:",
),
Number(
9..10,
1,
),
Number<1..8>(:foo->:),
Number<9..10>(1),
],
),
)

View file

@ -1,20 +1,13 @@
---
source: src/main.rs
source: src/lib.rs
expression: "p.parse(\"(foo 1)\")"
---
Ok(
List(
0..7,
List<0..7>(
[
Symbol(
1..4,
"foo",
),
Number(
5..6,
1,
),
Symbol<1..4>(foo),
Number<5..6>(1),
],
),
)

View file

@ -1,20 +1,13 @@
---
source: src/main.rs
source: src/lib.rs
expression: "p.parse(\"(lol😄 1)\")"
---
Ok(
List(
0..11,
List<0..11>(
[
Symbol(
1..8,
"lol😄",
),
Number(
9..10,
1,
),
Symbol<1..8>(lol😄),
Number<9..10>(1),
],
),
)

View file

@ -1,20 +1,13 @@
---
source: src/main.rs
source: src/lib.rs
expression: "p.parse(r#\"(test \"hi\")\"#)"
---
Ok(
List(
0..11,
List<0..11>(
[
Symbol(
1..5,
"test",
),
Str(
6..10,
"hi",
),
Symbol<1..5>(test),
Str<6..10>(hi),
],
),
)

View file

@ -1,11 +1,8 @@
---
source: src/main.rs
source: src/lib.rs
expression: "p.parse(\"1\")"
---
Ok(
Number(
0..1,
1,
),
Number<0..1>(1),
)