aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ast.rs2
-rw-r--r--src/eval/builtins.rs24
-rw-r--r--src/eval/mod.rs33
-rw-r--r--src/parser.rs67
4 files changed, 54 insertions, 72 deletions
diff --git a/src/ast.rs b/src/ast.rs
index 7e83b3d..ec5f953 100644
--- a/src/ast.rs
+++ b/src/ast.rs
@@ -10,7 +10,7 @@ impl Program {
10 } 10 }
11 } 11 }
12 12
13 pub fn from_str(mut self, i: &str) -> Result<Self, nom::error::Error<&str>> { 13 pub fn with_file(mut self, i: &str) -> Result<Self, nom::error::Error<&str>> {
14 use nom::Finish; 14 use nom::Finish;
15 let (remaining_input, stanzas) = crate::parser::parse_file(i).finish()?; 15 let (remaining_input, stanzas) = crate::parser::parse_file(i).finish()?;
16 assert!(remaining_input.trim().is_empty(), "{remaining_input}"); 16 assert!(remaining_input.trim().is_empty(), "{remaining_input}");
diff --git a/src/eval/builtins.rs b/src/eval/builtins.rs
index 7820a8e..7d10a86 100644
--- a/src/eval/builtins.rs
+++ b/src/eval/builtins.rs
@@ -48,11 +48,8 @@ builtins! {
48fn print(ctx: &mut Context, args: &[ast::Expr]) -> Result { 48fn print(ctx: &mut Context, args: &[ast::Expr]) -> Result {
49 for arg in args { 49 for arg in args {
50 let val = ctx.eval_expr(arg)?; 50 let val = ctx.eval_expr(arg)?;
51 let mut default_stream =Box::new(std::io::stdout()) as Box<dyn std::io::Write> ; 51 let mut default_stream = Box::new(std::io::stdout()) as Box<dyn std::io::Write>;
52 let stream = ctx 52 let stream = ctx.output_stream.as_mut().unwrap_or(&mut default_stream);
53 .output_stream
54 .as_mut()
55 .unwrap_or(&mut default_stream);
56 write!(stream, "{val}").unwrap(); 53 write!(stream, "{val}").unwrap();
57 } 54 }
58 Ok(Value::Unit) 55 Ok(Value::Unit)
@@ -157,9 +154,9 @@ fn kind(ctx: &mut Context, args: &[ast::Expr]) -> Result {
157 154
158fn member(ctx: &mut Context, args: &[ast::Expr]) -> Result { 155fn member(ctx: &mut Context, args: &[ast::Expr]) -> Result {
159 let [list_expr, element_expr] = get_args::<2>(args)?; 156 let [list_expr, element_expr] = get_args::<2>(args)?;
160 let list = ctx.eval_expr(&list_expr)?; 157 let list = ctx.eval_expr(list_expr)?;
161 let v = list.as_list()?; 158 let v = list.as_list()?;
162 let element = ctx.eval_expr(&element_expr)?; 159 let element = ctx.eval_expr(element_expr)?;
163 v.iter() 160 v.iter()
164 .any(|item| item == &element) 161 .any(|item| item == &element)
165 .wrap(Value::Boolean) 162 .wrap(Value::Boolean)
@@ -174,7 +171,7 @@ fn push(ctx: &mut Context, args: &[ast::Expr]) -> Result {
174 lhs 171 lhs
175 ))); 172 )));
176 }; 173 };
177 let element = ctx.eval_expr(&rhs)?; 174 let element = ctx.eval_expr(rhs)?;
178 let variable = ctx.lookup_mut(ident)?; 175 let variable = ctx.lookup_mut(ident)?;
179 variable.mutate(|v| match &mut v.value { 176 variable.mutate(|v| match &mut v.value {
180 Value::List(l) => { 177 Value::List(l) => {
@@ -195,9 +192,7 @@ fn pop(ctx: &mut Context, args: &[ast::Expr]) -> Result {
195 }; 192 };
196 let variable = ctx.lookup_mut(ident)?; 193 let variable = ctx.lookup_mut(ident)?;
197 variable.mutate(|v| match &mut v.value { 194 variable.mutate(|v| match &mut v.value {
198 Value::List(l) => l 195 Value::List(l) => l.pop().ok_or(Error::ArrayOutOfBounds { idx: 0, len: 0 }),
199 .pop()
200 .ok_or_else(|| Error::ArrayOutOfBounds { idx: 0, len: 0 }),
201 _ => Err(v.ty().expected([ast::Type::List])), 196 _ => Err(v.ty().expected([ast::Type::List])),
202 }) 197 })
203} 198}
@@ -211,12 +206,7 @@ fn isempty(ctx: &mut Context, args: &[ast::Expr]) -> Result {
211 .is_empty() 206 .is_empty()
212 .wrap(Value::Boolean) 207 .wrap(Value::Boolean)
213 .wrap(Ok), 208 .wrap(Ok),
214 ast::Type::String => v 209 ast::Type::String => v.as_str().unwrap().is_empty().wrap(Value::Boolean).wrap(Ok),
215 .as_str()
216 .unwrap()
217 .is_empty()
218 .wrap(Value::Boolean)
219 .wrap(Ok),
220 _ => Err(v.ty().expected([ast::Type::List])), 210 _ => Err(v.ty().expected([ast::Type::List])),
221 } 211 }
222} 212}
diff --git a/src/eval/mod.rs b/src/eval/mod.rs
index c4460c0..9455704 100644
--- a/src/eval/mod.rs
+++ b/src/eval/mod.rs
@@ -474,11 +474,11 @@ impl<'s> Context<'s> {
474 ast::Expr::Unit => Ok(Value::Unit), 474 ast::Expr::Unit => Ok(Value::Unit),
475 ast::Expr::Lit(lit) => self.eval_lit(lit), 475 ast::Expr::Lit(lit) => self.eval_lit(lit),
476 ast::Expr::Ident(ident) => self.lookup(ident).map(Variable::value).cloned(), 476 ast::Expr::Ident(ident) => self.lookup(ident).map(Variable::value).cloned(),
477 ast::Expr::Bin(lhs, op, rhs) => self.eval_bin(&*lhs, *op, &*rhs), 477 ast::Expr::Bin(lhs, op, rhs) => self.eval_bin(lhs, *op, rhs),
478 ast::Expr::Unary(expr, op) => self.eval_unary(&*expr, *op), 478 ast::Expr::Unary(expr, op) => self.eval_unary(expr, *op),
479 ast::Expr::Call(call) => self.eval_call(&*call), 479 ast::Expr::Call(call) => self.eval_call(call),
480 ast::Expr::List(list) => self.eval_list(&*list), 480 ast::Expr::List(list) => self.eval_list(list),
481 ast::Expr::Index(target, idx) => self.eval_index(&*target, &*idx), 481 ast::Expr::Index(target, idx) => self.eval_index(target, idx),
482 ast::Expr::If(if_expr) => self.eval_if(if_expr), 482 ast::Expr::If(if_expr) => self.eval_if(if_expr),
483 ast::Expr::Block(block) => self.eval_block(block), 483 ast::Expr::Block(block) => self.eval_block(block),
484 ast::Expr::Node => self.eval_node(), 484 ast::Expr::Node => self.eval_node(),
@@ -609,7 +609,7 @@ impl<'s> Context<'s> {
609 match op { 609 match op {
610 ast::LogicOp::Or => { 610 ast::LogicOp::Or => {
611 if l_value { 611 if l_value {
612 return Ok(l); 612 Ok(l)
613 } else { 613 } else {
614 let r = self.eval_expr(rhs)?; 614 let r = self.eval_expr(rhs)?;
615 l.or(&r) 615 l.or(&r)
@@ -617,7 +617,7 @@ impl<'s> Context<'s> {
617 } 617 }
618 ast::LogicOp::And => { 618 ast::LogicOp::And => {
619 if !l_value { 619 if !l_value {
620 return Ok(l); 620 Ok(l)
621 } else { 621 } else {
622 let r = self.eval_expr(rhs)?; 622 let r = self.eval_expr(rhs)?;
623 l.and(&r) 623 l.and(&r)
@@ -644,7 +644,7 @@ impl<'s> Context<'s> {
644 } 644 }
645 645
646 fn eval_call(&mut self, call: &ast::Call) -> Result { 646 fn eval_call(&mut self, call: &ast::Call) -> Result {
647 ((&*builtins::BUILTINS) 647 ((*builtins::BUILTINS)
648 .get(call.function.as_str()) 648 .get(call.function.as_str())
649 .ok_or_else(|| Error::FailedLookup(call.function.to_owned()))?)( 649 .ok_or_else(|| Error::FailedLookup(call.function.to_owned()))?)(
650 self, 650 self,
@@ -675,7 +675,7 @@ impl<'s> Context<'s> {
675 675
676 fn eval_declaration(&mut self, decl: &ast::Declaration) -> Result { 676 fn eval_declaration(&mut self, decl: &ast::Declaration) -> Result {
677 let initial_value = match decl.init.as_ref() { 677 let initial_value = match decl.init.as_ref() {
678 Some(init) => Some(self.eval_expr(&*init)?), 678 Some(init) => Some(self.eval_expr(init)?),
679 None => None, 679 None => None,
680 }; 680 };
681 let variable = self.bind(&decl.name, decl.ty)?; 681 let variable = self.bind(&decl.name, decl.ty)?;
@@ -775,7 +775,7 @@ pub fn evaluate(file: &str, program: &str, language: tree_sitter::Language) -> R
775 775
776 let tree = parser.parse(file, None).unwrap(); 776 let tree = parser.parse(file, None).unwrap();
777 777
778 let program = ast::Program::new().from_str(program).unwrap(); 778 let program = ast::Program::new().with_file(program).unwrap();
779 let mut ctx = Context::new(language) 779 let mut ctx = Context::new(language)
780 .with_input(file.to_owned()) 780 .with_input(file.to_owned())
781 .with_tree(tree) 781 .with_tree(tree)
@@ -796,7 +796,7 @@ mod test {
796 let mut parser = tree_sitter::Parser::new(); 796 let mut parser = tree_sitter::Parser::new();
797 let _ = parser.set_language(&language); 797 let _ = parser.set_language(&language);
798 let tree = parser.parse(file, None).unwrap(); 798 let tree = parser.parse(file, None).unwrap();
799 let program = ast::Program::new().from_str(program).unwrap(); 799 let program = ast::Program::new().with_file(program).unwrap();
800 800
801 let mut output = Vec::new(); 801 let mut output = Vec::new();
802 let mut ctx = Context::new(language) 802 let mut ctx = Context::new(language)
@@ -983,7 +983,7 @@ mod test {
983 print(a); 983 print(a);
984 } 984 }
985 ", 985 ",
986 expect!["[5]"] 986 expect!["[5]"],
987 ); 987 );
988 988
989 gen_test( 989 gen_test(
@@ -993,7 +993,7 @@ mod test {
993 print(length(a)); 993 print(length(a));
994 } 994 }
995 ", 995 ",
996 expect!["3"] 996 expect!["3"],
997 ); 997 );
998 998
999 gen_test( 999 gen_test(
@@ -1005,7 +1005,7 @@ mod test {
1005 print(member(a, 6)); 1005 print(member(a, 6));
1006 } 1006 }
1007 "#, 1007 "#,
1008 expect!["true, false"] 1008 expect!["true, false"],
1009 ); 1009 );
1010 1010
1011 gen_test( 1011 gen_test(
@@ -1029,7 +1029,7 @@ mod test {
1029 [5, 4, 3] 1029 [5, 4, 3]
1030 [5, 4] 1030 [5, 4]
1031 [5] 1031 [5]
1032 "#]] 1032 "#]],
1033 ); 1033 );
1034 1034
1035 gen_test( 1035 gen_test(
@@ -1044,8 +1044,7 @@ mod test {
1044 expect![[r#" 1044 expect![[r#"
1045 false 1045 false
1046 true 1046 true
1047 "#]] 1047 "#]],
1048 ); 1048 );
1049
1050 } 1049 }
1051} 1050}
diff --git a/src/parser.rs b/src/parser.rs
index 8b04307..0719f93 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -13,20 +13,21 @@ use nom::{
13use crate::ast::*; 13use crate::ast::*;
14use crate::string::parse_string; 14use crate::string::parse_string;
15 15
16fn ws<'a, F: 'a, O, E>(inner: F) -> impl FnMut(&'a str) -> IResult<&'a str, O, E> 16fn ws<'a, F, O, E>(inner: F) -> impl FnMut(&'a str) -> IResult<&'a str, O, E>
17where 17where
18 F: FnMut(&'a str) -> IResult<&'a str, O, E>, 18 F: FnMut(&'a str) -> IResult<&'a str, O, E>,
19 F: 'a,
19 E: ParseError<&'a str>, 20 E: ParseError<&'a str>,
20{ 21{
21 delimited(multispace0, inner, multispace0) 22 delimited(multispace0, inner, multispace0)
22} 23}
23 24
24// TODO use this 25// TODO use this
25fn _parse_comment<'a>(i: &'a str) -> IResult<&'a str, ()> { 26fn _parse_comment(i: &str) -> IResult<&str, ()> {
26 value((), pair(tag("//"), is_not("\n\r")))(i) 27 value((), pair(tag("//"), is_not("\n\r")))(i)
27} 28}
28 29
29fn parse_unit<'a>(i: &'a str) -> IResult<&'a str, ()> { 30fn parse_unit(i: &str) -> IResult<&str, ()> {
30 let open = char('('); 31 let open = char('(');
31 let close = char(')'); 32 let close = char(')');
32 let unit = tuple((open, close)); 33 let unit = tuple((open, close));
@@ -39,7 +40,7 @@ fn parse_bool(i: &str) -> IResult<&str, bool> {
39 alt((t, f)).parse(i) 40 alt((t, f)).parse(i)
40} 41}
41 42
42fn parse_int<'a>(i: &'a str) -> IResult<&'a str, i128> { 43fn parse_int(i: &str) -> IResult<&str, i128> {
43 map(recognize(many1(one_of("0123456789"))), |s: &str| { 44 map(recognize(many1(one_of("0123456789"))), |s: &str| {
44 s.parse::<i128>().unwrap() 45 s.parse::<i128>().unwrap()
45 })(i) 46 })(i)
@@ -57,7 +58,7 @@ fn parse_ident(i: &str) -> IResult<&str, Identifier> {
57 map(parse_name, str::to_owned)(i) 58 map(parse_name, str::to_owned)(i)
58} 59}
59 60
60fn parse_lit<'a>(i: &'a str) -> IResult<&'a str, Literal> { 61fn parse_lit(i: &str) -> IResult<&str, Literal> {
61 alt(( 62 alt((
62 map(parse_string, Literal::Str), 63 map(parse_string, Literal::Str),
63 map(parse_int, Literal::Int), 64 map(parse_int, Literal::Int),
@@ -118,28 +119,28 @@ where
118 }) 119 })
119} 120}
120 121
121fn parse_assign<'a>(i: &'a str) -> IResult<&'a str, Expr> { 122fn parse_assign(i: &str) -> IResult<&str, Expr> {
122 let op = map(parse_assign_op, BinOp::Assign); 123 let op = map(parse_assign_op, BinOp::Assign);
123 let recursive = parse_binary(parse_atom, op, parse_assign); 124 let recursive = parse_binary(parse_atom, op, parse_assign);
124 let base = parse_union; 125 let base = parse_union;
125 alt((recursive, base)).parse(i) 126 alt((recursive, base)).parse(i)
126} 127}
127 128
128fn parse_union<'a>(i: &'a str) -> IResult<&'a str, Expr> { 129fn parse_union(i: &str) -> IResult<&str, Expr> {
129 let op = parse_op("||", BinOp::Logic(LogicOp::Or)); 130 let op = parse_op("||", BinOp::Logic(LogicOp::Or));
130 let recursive = parse_binary(parse_intersection, op, parse_union); 131 let recursive = parse_binary(parse_intersection, op, parse_union);
131 let base = parse_intersection; 132 let base = parse_intersection;
132 alt((recursive, base)).parse(i) 133 alt((recursive, base)).parse(i)
133} 134}
134 135
135fn parse_intersection<'a>(i: &'a str) -> IResult<&'a str, Expr> { 136fn parse_intersection(i: &str) -> IResult<&str, Expr> {
136 let op = parse_op("&&", BinOp::Logic(LogicOp::And)); 137 let op = parse_op("&&", BinOp::Logic(LogicOp::And));
137 let recursive = parse_binary(parse_negated, op, parse_intersection); 138 let recursive = parse_binary(parse_negated, op, parse_intersection);
138 let base = parse_negated; 139 let base = parse_negated;
139 alt((recursive, base)).parse(i) 140 alt((recursive, base)).parse(i)
140} 141}
141 142
142fn parse_negated<'a>(i: &'a str) -> IResult<&'a str, Expr> { 143fn parse_negated(i: &str) -> IResult<&str, Expr> {
143 let op = parse_op("!", UnaryOp::Not); 144 let op = parse_op("!", UnaryOp::Not);
144 let recursive = map(tuple((op, parse_rel)), |(op, expr)| { 145 let recursive = map(tuple((op, parse_rel)), |(op, expr)| {
145 Expr::Unary(expr.boxed(), op) 146 Expr::Unary(expr.boxed(), op)
@@ -148,14 +149,14 @@ fn parse_negated<'a>(i: &'a str) -> IResult<&'a str, Expr> {
148 alt((recursive, base)).parse(i) 149 alt((recursive, base)).parse(i)
149} 150}
150 151
151fn parse_rel<'a>(i: &'a str) -> IResult<&'a str, Expr> { 152fn parse_rel(i: &str) -> IResult<&str, Expr> {
152 let op = map(parse_cmp_op, BinOp::Cmp); 153 let op = map(parse_cmp_op, BinOp::Cmp);
153 let recursive = parse_binary(parse_sum, op, parse_rel); 154 let recursive = parse_binary(parse_sum, op, parse_rel);
154 let base = parse_sum; 155 let base = parse_sum;
155 alt((recursive, base)).parse(i) 156 alt((recursive, base)).parse(i)
156} 157}
157 158
158fn parse_sum<'a>(i: &'a str) -> IResult<&'a str, Expr> { 159fn parse_sum(i: &str) -> IResult<&str, Expr> {
159 let add = parse_op("+", BinOp::Arith(ArithOp::Add)); 160 let add = parse_op("+", BinOp::Arith(ArithOp::Add));
160 let sub = parse_op("-", BinOp::Arith(ArithOp::Sub)); 161 let sub = parse_op("-", BinOp::Arith(ArithOp::Sub));
161 let op = alt((add, sub)); 162 let op = alt((add, sub));
@@ -164,7 +165,7 @@ fn parse_sum<'a>(i: &'a str) -> IResult<&'a str, Expr> {
164 alt((recursive, base)).parse(i) 165 alt((recursive, base)).parse(i)
165} 166}
166 167
167fn parse_mul<'a>(i: &'a str) -> IResult<&'a str, Expr> { 168fn parse_mul(i: &str) -> IResult<&str, Expr> {
168 let mul = parse_op("*", BinOp::Arith(ArithOp::Mul)); 169 let mul = parse_op("*", BinOp::Arith(ArithOp::Mul));
169 let div = parse_op("/", BinOp::Arith(ArithOp::Div)); 170 let div = parse_op("/", BinOp::Arith(ArithOp::Div));
170 let mod_ = parse_op("%", BinOp::Arith(ArithOp::Mod)); 171 let mod_ = parse_op("%", BinOp::Arith(ArithOp::Mod));
@@ -174,7 +175,7 @@ fn parse_mul<'a>(i: &'a str) -> IResult<&'a str, Expr> {
174 alt((recursive, base)).parse(i) 175 alt((recursive, base)).parse(i)
175} 176}
176 177
177fn parse_field_or_index<'a>(i: &'a str) -> IResult<&'a str, Expr> { 178fn parse_field_or_index(i: &str) -> IResult<&str, Expr> {
178 enum FieldOrIndex { 179 enum FieldOrIndex {
179 Field(String), 180 Field(String),
180 Index(Expr), 181 Index(Expr),
@@ -200,14 +201,14 @@ fn parse_field_or_index<'a>(i: &'a str) -> IResult<&'a str, Expr> {
200 )(i) 201 )(i)
201} 202}
202 203
203fn parse_list<'a>(i: &'a str) -> IResult<&'a str, List> { 204fn parse_list(i: &str) -> IResult<&str, List> {
204 let open = ws(char('[')); 205 let open = ws(char('['));
205 let items = separated_list0(char(','), parse_expr); 206 let items = separated_list0(char(','), parse_expr);
206 let close = ws(char(']')); 207 let close = ws(char(']'));
207 map(tuple((open, items, close)), |(_, items, _)| List { items }).parse(i) 208 map(tuple((open, items, close)), |(_, items, _)| List { items }).parse(i)
208} 209}
209 210
210fn parse_atom<'a>(i: &'a str) -> IResult<&'a str, Expr> { 211fn parse_atom(i: &str) -> IResult<&str, Expr> {
211 let inner = alt(( 212 let inner = alt((
212 map(tag("node"), |_| Expr::Node), 213 map(tag("node"), |_| Expr::Node),
213 map(parse_block, Expr::Block), 214 map(parse_block, Expr::Block),
@@ -221,7 +222,7 @@ fn parse_atom<'a>(i: &'a str) -> IResult<&'a str, Expr> {
221 ws(inner).parse(i) 222 ws(inner).parse(i)
222} 223}
223 224
224fn parse_call<'a>(i: &'a str) -> IResult<&'a str, Call> { 225fn parse_call(i: &str) -> IResult<&str, Call> {
225 let ident = parse_ident; 226 let ident = parse_ident;
226 let open = ws(char('(')); 227 let open = ws(char('('));
227 let args = separated_list0(char(','), parse_expr); 228 let args = separated_list0(char(','), parse_expr);
@@ -236,14 +237,14 @@ fn parse_call<'a>(i: &'a str) -> IResult<&'a str, Call> {
236 .parse(i) 237 .parse(i)
237} 238}
238 239
239fn parse_block<'a>(i: &'a str) -> IResult<&'a str, Block> { 240fn parse_block(i: &str) -> IResult<&str, Block> {
240 let open = ws(char('{')); 241 let open = ws(char('{'));
241 let statements = map(many0(parse_statement), |body| Block { body }); 242 let statements = map(many0(parse_statement), |body| Block { body });
242 let close = ws(char('}')); 243 let close = ws(char('}'));
243 delimited(open, statements, close).parse(i) 244 delimited(open, statements, close).parse(i)
244} 245}
245 246
246fn parse_if<'a>(i: &'a str) -> IResult<&'a str, IfExpr> { 247fn parse_if(i: &str) -> IResult<&str, IfExpr> {
247 let if_ = delimited(multispace0, tag("if"), multispace1); 248 let if_ = delimited(multispace0, tag("if"), multispace1);
248 249
249 let open = char('('); 250 let open = char('(');
@@ -265,15 +266,15 @@ fn parse_if<'a>(i: &'a str) -> IResult<&'a str, IfExpr> {
265 )(i) 266 )(i)
266} 267}
267 268
268fn parse_expr<'a>(i: &'a str) -> IResult<&'a str, Expr> { 269fn parse_expr(i: &str) -> IResult<&str, Expr> {
269 parse_assign.parse(i) 270 parse_assign.parse(i)
270} 271}
271 272
272fn parse_bare<'a>(i: &'a str) -> IResult<&'a str, Expr> { 273fn parse_bare(i: &str) -> IResult<&str, Expr> {
273 parse_expr(i) 274 parse_expr(i)
274} 275}
275 276
276fn parse_type<'a>(i: &'a str) -> IResult<&'a str, Type> { 277fn parse_type(i: &str) -> IResult<&str, Type> {
277 let int = value(Type::Integer, tag("int")); 278 let int = value(Type::Integer, tag("int"));
278 let string = value(Type::String, tag("string")); 279 let string = value(Type::String, tag("string"));
279 let bool_ = value(Type::Boolean, tag("bool")); 280 let bool_ = value(Type::Boolean, tag("bool"));
@@ -281,7 +282,7 @@ fn parse_type<'a>(i: &'a str) -> IResult<&'a str, Type> {
281 alt((int, string, bool_, list)).parse(i) 282 alt((int, string, bool_, list)).parse(i)
282} 283}
283 284
284fn parse_declaration<'a>(i: &'a str) -> IResult<&'a str, Declaration> { 285fn parse_declaration(i: &str) -> IResult<&str, Declaration> {
285 let ty = parse_type; 286 let ty = parse_type;
286 let name = parse_ident; 287 let name = parse_ident;
287 let op = ws(char('=')); 288 let op = ws(char('='));
@@ -292,7 +293,7 @@ fn parse_declaration<'a>(i: &'a str) -> IResult<&'a str, Declaration> {
292 )(i) 293 )(i)
293} 294}
294 295
295fn parse_statement<'a>(i: &'a str) -> IResult<&'a str, Statement> { 296fn parse_statement(i: &str) -> IResult<&str, Statement> {
296 let semicolon = ws(char(';')); 297 let semicolon = ws(char(';'));
297 let inner = alt(( 298 let inner = alt((
298 map(parse_declaration, Statement::Declaration), 299 map(parse_declaration, Statement::Declaration),
@@ -364,38 +365,30 @@ fn parse_statement<'a>(i: &'a str) -> IResult<&'a str, Statement> {
364// }; 365// };
365// } 366// }
366 367
367fn parse_modifier<'a>(i: &str) -> IResult<&str, Modifier> { 368fn parse_modifier(i: &str) -> IResult<&str, Modifier> {
368 let pre = value(Modifier::Enter, tag("enter")); 369 let pre = value(Modifier::Enter, tag("enter"));
369 let post = value(Modifier::Leave, tag("leave")); 370 let post = value(Modifier::Leave, tag("leave"));
370 map(opt(alt((pre, post))), Option::unwrap_or_default)(i) 371 map(opt(alt((pre, post))), Option::unwrap_or_default)(i)
371} 372}
372 373
373fn parse_pattern<'a>(i: &str) -> IResult<&str, Pattern> { 374fn parse_pattern(i: &str) -> IResult<&str, Pattern> {
374 let begin = value(Pattern::Begin, ws(tag("BEGIN"))); 375 let begin = value(Pattern::Begin, ws(tag("BEGIN")));
375 let end = value(Pattern::End, ws(tag("END"))); 376 let end = value(Pattern::End, ws(tag("END")));
376 ws(alt((begin, end, parse_tree_pattern))).parse(i) 377 ws(alt((begin, end, parse_tree_pattern))).parse(i)
377} 378}
378 379
379// fn parse_node_pattern<'a>(i: &str) -> IResult<&str, Pattern> { 380fn parse_tree_pattern(i: &str) -> IResult<&str, Pattern> {
380// map(
381// tuple((parse_modifier, multispace0, parse_ident)),
382// |(modifier, _, kind)| Pattern::Node(NodePattern { modifier, kind }),
383// )
384// .parse(i)
385// }
386
387fn parse_tree_pattern<'a>(i: &str) -> IResult<&str, Pattern> {
388 let parse_matcher = alt((parse_tree_atom, parse_tree_list)); 381 let parse_matcher = alt((parse_tree_atom, parse_tree_list));
389 tuple((parse_modifier, multispace0, parse_matcher)) 382 tuple((parse_modifier, multispace0, parse_matcher))
390 .map(|(modifier, _, matcher)| Pattern::Tree { modifier, matcher }) 383 .map(|(modifier, _, matcher)| Pattern::Tree { modifier, matcher })
391 .parse(i) 384 .parse(i)
392} 385}
393 386
394fn parse_tree_atom<'a>(i: &str) -> IResult<&str, TreePattern> { 387fn parse_tree_atom(i: &str) -> IResult<&str, TreePattern> {
395 parse_ident.map(TreePattern::Atom).parse(i) 388 parse_ident.map(TreePattern::Atom).parse(i)
396} 389}
397 390
398fn parse_tree_list<'a>(i: &str) -> IResult<&str, TreePattern> { 391fn parse_tree_list(i: &str) -> IResult<&str, TreePattern> {
399 let open = terminated(char('('), multispace0); 392 let open = terminated(char('('), multispace0);
400 let close = preceded(multispace0, char(')')); 393 let close = preceded(multispace0, char(')'));
401 let list = separated_list1(multispace1, alt((parse_tree_atom, parse_tree_list))); 394 let list = separated_list1(multispace1, alt((parse_tree_atom, parse_tree_list)));
@@ -404,7 +397,7 @@ fn parse_tree_list<'a>(i: &str) -> IResult<&str, TreePattern> {
404 .parse(i) 397 .parse(i)
405} 398}
406 399
407pub fn parse_stanza<'a>(i: &str) -> IResult<&str, Stanza> { 400pub fn parse_stanza(i: &str) -> IResult<&str, Stanza> {
408 map( 401 map(
409 tuple((parse_pattern, parse_block)), 402 tuple((parse_pattern, parse_block)),
410 |(pattern, statements)| Stanza { 403 |(pattern, statements)| Stanza {