diff options
-rw-r--r-- | src/ast.rs | 2 | ||||
-rw-r--r-- | src/eval/builtins.rs | 24 | ||||
-rw-r--r-- | src/eval/mod.rs | 33 | ||||
-rw-r--r-- | src/parser.rs | 67 |
4 files changed, 54 insertions, 72 deletions
@@ -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! { | |||
48 | fn print(ctx: &mut Context, args: &[ast::Expr]) -> Result { | 48 | fn 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 | ||
158 | fn member(ctx: &mut Context, args: &[ast::Expr]) -> Result { | 155 | fn 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::{ | |||
13 | use crate::ast::*; | 13 | use crate::ast::*; |
14 | use crate::string::parse_string; | 14 | use crate::string::parse_string; |
15 | 15 | ||
16 | fn ws<'a, F: 'a, O, E>(inner: F) -> impl FnMut(&'a str) -> IResult<&'a str, O, E> | 16 | fn ws<'a, F, O, E>(inner: F) -> impl FnMut(&'a str) -> IResult<&'a str, O, E> |
17 | where | 17 | where |
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 |
25 | fn _parse_comment<'a>(i: &'a str) -> IResult<&'a str, ()> { | 26 | fn _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 | ||
29 | fn parse_unit<'a>(i: &'a str) -> IResult<&'a str, ()> { | 30 | fn 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 | ||
42 | fn parse_int<'a>(i: &'a str) -> IResult<&'a str, i128> { | 43 | fn 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 | ||
60 | fn parse_lit<'a>(i: &'a str) -> IResult<&'a str, Literal> { | 61 | fn 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 | ||
121 | fn parse_assign<'a>(i: &'a str) -> IResult<&'a str, Expr> { | 122 | fn 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 | ||
128 | fn parse_union<'a>(i: &'a str) -> IResult<&'a str, Expr> { | 129 | fn 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 | ||
135 | fn parse_intersection<'a>(i: &'a str) -> IResult<&'a str, Expr> { | 136 | fn 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 | ||
142 | fn parse_negated<'a>(i: &'a str) -> IResult<&'a str, Expr> { | 143 | fn 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 | ||
151 | fn parse_rel<'a>(i: &'a str) -> IResult<&'a str, Expr> { | 152 | fn 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 | ||
158 | fn parse_sum<'a>(i: &'a str) -> IResult<&'a str, Expr> { | 159 | fn 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 | ||
167 | fn parse_mul<'a>(i: &'a str) -> IResult<&'a str, Expr> { | 168 | fn 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 | ||
177 | fn parse_field_or_index<'a>(i: &'a str) -> IResult<&'a str, Expr> { | 178 | fn 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 | ||
203 | fn parse_list<'a>(i: &'a str) -> IResult<&'a str, List> { | 204 | fn 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 | ||
210 | fn parse_atom<'a>(i: &'a str) -> IResult<&'a str, Expr> { | 211 | fn 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 | ||
224 | fn parse_call<'a>(i: &'a str) -> IResult<&'a str, Call> { | 225 | fn 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 | ||
239 | fn parse_block<'a>(i: &'a str) -> IResult<&'a str, Block> { | 240 | fn 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 | ||
246 | fn parse_if<'a>(i: &'a str) -> IResult<&'a str, IfExpr> { | 247 | fn 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 | ||
268 | fn parse_expr<'a>(i: &'a str) -> IResult<&'a str, Expr> { | 269 | fn parse_expr(i: &str) -> IResult<&str, Expr> { |
269 | parse_assign.parse(i) | 270 | parse_assign.parse(i) |
270 | } | 271 | } |
271 | 272 | ||
272 | fn parse_bare<'a>(i: &'a str) -> IResult<&'a str, Expr> { | 273 | fn parse_bare(i: &str) -> IResult<&str, Expr> { |
273 | parse_expr(i) | 274 | parse_expr(i) |
274 | } | 275 | } |
275 | 276 | ||
276 | fn parse_type<'a>(i: &'a str) -> IResult<&'a str, Type> { | 277 | fn 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 | ||
284 | fn parse_declaration<'a>(i: &'a str) -> IResult<&'a str, Declaration> { | 285 | fn 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 | ||
295 | fn parse_statement<'a>(i: &'a str) -> IResult<&'a str, Statement> { | 296 | fn 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 | ||
367 | fn parse_modifier<'a>(i: &str) -> IResult<&str, Modifier> { | 368 | fn 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 | ||
373 | fn parse_pattern<'a>(i: &str) -> IResult<&str, Pattern> { | 374 | fn 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> { | 380 | fn 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 | |||
387 | fn 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 | ||
394 | fn parse_tree_atom<'a>(i: &str) -> IResult<&str, TreePattern> { | 387 | fn 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 | ||
398 | fn parse_tree_list<'a>(i: &str) -> IResult<&str, TreePattern> { | 391 | fn 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 | ||
407 | pub fn parse_stanza<'a>(i: &str) -> IResult<&str, Stanza> { | 400 | pub 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 { |