1use std;
17use std::borrow::Borrow;
18use std::str::FromStr;
19
20use abortable_parser;
21use abortable_parser::combinators::eoi;
22use abortable_parser::iter::SliceIter;
23use abortable_parser::{Error, Peekable, Result};
24
25use self::precedence::op_expression;
26use crate::ast::*;
27use crate::error::BuildError;
28use crate::iter::OffsetStrIter;
29use crate::tokenizer::*;
30
31pub use crate::tokenizer::{CommentGroup, CommentMap};
32
33type ParseResult<'a, O> = Result<SliceIter<'a, Token>, O>;
34
35#[cfg(feature = "tracing")]
36const ENABLE_TRACE: bool = true;
37#[cfg(not(feature = "tracing"))]
38const ENABLE_TRACE: bool = false;
39
40type ConvertResult<'a, O> = std::result::Result<O, abortable_parser::Error<SliceIter<'a, Token>>>;
41
42macro_rules! trace_parse {
43 ($i:expr, $rule:ident!( $($args:tt)* )) => {
44 {
45 use crate::parse::ENABLE_TRACE;
46 if ENABLE_TRACE {
47 eprintln!("Entering Rule: {:?} {:?}", stringify!($rule), $i);
48 }
49 let result = $rule!($i, $($args)* );
50 if ENABLE_TRACE {
51 eprintln!("Exiting Rule: {:?} with {:?}", stringify!($rule), result);
52 }
53 result
54 }
55 };
56
57 ($i:expr, $rule:ident) => {
58 {
59 use crate::parse::ENABLE_TRACE;
60 if ENABLE_TRACE {
61 eprintln!("Entering Rule: {:?} {:?}", stringify!($rule), $i);
62 }
63 let result = run!($i, $rule);
64 if ENABLE_TRACE {
65 eprintln!("Exiting Rule: {:?} with {:?}", stringify!($rule), result);
66 }
67 result
68 }
69 };
70}
71
72fn symbol_to_value<'a>(s: &Token) -> ConvertResult<'a, Value> {
73 Ok(Value::Symbol(value_node!(
74 s.fragment.clone(),
75 s.pos.clone()
76 )))
77}
78
79make_fn!(
81 symbol<SliceIter<Token>, Value>,
82 match_type!(BAREWORD => symbol_to_value)
83);
84
85fn str_to_value<'a>(s: &Token) -> ConvertResult<'a, Value> {
86 Ok(Value::Str(value_node!(s.fragment.clone(), s.pos.clone())))
87}
88
89make_fn!(
91 quoted_value<SliceIter<Token>, Value>,
92 match_type!(STR => str_to_value)
93);
94
95fn triple_to_number<'a>(
97 input: SliceIter<'a, Token>,
98 v: (Option<Token>, Option<Token>, Option<Token>),
99) -> ConvertResult<'a, Value> {
100 let (pref, mut pref_pos) = match v.0 {
101 None => ("", Position::new(0, 0, 0)),
102 Some(ref bs) => (bs.fragment.borrow(), bs.pos.clone()),
103 };
104
105 let has_dot = v.1.is_some();
106
107 if v.0.is_some() && !has_dot && v.2.is_none() {
108 let i = match FromStr::from_str(pref) {
109 Ok(i) => i,
110 Err(_) => {
111 return Err(Error::new(
112 format!("Not an integer! {}", pref),
113 Box::new(input.clone()),
114 ));
115 }
116 };
117 return Ok(Value::Int(value_node!(i, pref_pos)));
118 }
119
120 if v.0.is_none() && has_dot {
121 pref_pos = v.1.unwrap().pos;
122 }
123
124 let suf = match v.2 {
125 None => "".into(),
126 Some(bs) => bs.fragment,
127 };
128
129 let to_parse = pref.to_string() + "." + &suf;
130 let f = match FromStr::from_str(&to_parse) {
131 Ok(f) => f,
132 Err(_) => {
133 return Err(Error::new(
134 format!("Not a float! {}", to_parse),
135 Box::new(input.clone()),
136 ));
137 }
138 };
139 return Ok(Value::Float(value_node!(f, pref_pos)));
140}
141
142fn number(input: SliceIter<Token>) -> Result<SliceIter<Token>, Value> {
155 let parsed = do_each!(input,
156 num => either!(
157 complete!(
158 "Not a float",
159 do_each!( prefix => match_type!(DIGIT),
161 has_dot => punct!("."),
162 suffix => match_type!(DIGIT),
163 (Some(prefix.clone()), Some(has_dot.clone()), Some(suffix.clone()))
164 )),
165 complete!(
166 "Not a float",
167 do_each!( prefix => match_type!(DIGIT),
169 has_dot => punct!("."),
170 (Some(prefix.clone()), Some(has_dot.clone()), None)
171 )),
172 complete!(
173 "Not a float",
174 do_each!( has_dot => punct!("."),
176 suffix => match_type!(DIGIT),
177 (None, Some(has_dot.clone()), Some(suffix.clone()))
178 )),
179 do_each!( prefix => match_type!(DIGIT),
181 (Some(prefix.clone()), None, None)
182 )),
183 (num)
184 );
185 match parsed {
186 Result::Abort(e) => Result::Abort(e),
187 Result::Fail(e) => Result::Fail(e),
188 Result::Incomplete(offset) => Result::Incomplete(offset),
189 Result::Complete(rest, triple) => {
190 let num = triple_to_number(rest.clone(), triple);
191 match num {
192 Ok(val) => Result::Complete(rest, val),
193 Err(e) => Result::Fail(e),
194 }
195 }
196 }
197}
198make_fn!(
201 boolean_value<SliceIter<Token>, Value>,
202 do_each!(
203 b => match_type!(BOOLEAN),
204 (Value::Boolean(PositionedItem{
205 val: b.fragment.as_ref() == "true",
206 pos: b.pos,
207 }))
208 )
209);
210
211make_fn!(
212 field_value<SliceIter<Token>, (Token, Option<Expression>, Expression)>,
213 do_each!(
214 field => wrap_err!(either!(match_type!(BOOLEAN), match_type!(BAREWORD), match_type!(STR)),
215 "Field names must be a bareword or a string."),
216 constraint => optional!(shape_suffix),
217 _ => must!(punct!("=")),
218 value => must!(expression),
219 (field, constraint, value)
220 )
221);
222
223fn vec_to_tuple(pos: Position, fields: Option<FieldList>) -> Value {
225 Value::Tuple(value_node!(fields.unwrap_or(Vec::new()), pos))
226}
227
228make_fn!(
229 field_list<SliceIter<Token>, FieldList>,
230 separated!(punct!(","), field_value)
231);
232
233make_fn!(
234 tuple<SliceIter<Token>, Value>,
235 do_each!(
236 pos => pos,
237 _ => punct!("{"),
238 v => optional!(field_list),
239 _ => optional!(punct!(",")),
240 _ => must!(punct!("}")),
241 (vec_to_tuple(pos, v))
242 )
243);
244
245fn tuple_to_list<Sp: Into<Position>>(pos: Sp, elems: Option<Vec<Expression>>) -> Value {
246 Value::List(ListDef {
247 elems: elems.unwrap_or_else(|| Vec::new()),
248 pos: pos.into(),
249 })
250}
251
252make_fn!(
253 list_value<SliceIter<Token>, Value>,
254 do_each!(
255 start => punct!("["),
256 elements => optional!(separated!(punct!(","), expression)),
257 _ => optional!(punct!(",")),
258 _ => must!(punct!("]")),
259 (tuple_to_list(start.pos, elements))
260 )
261);
262
263make_fn!(
264 empty_value<SliceIter<Token>, Value>,
265 do_each!(
266 pos => pos,
267 _ => match_type!(EMPTY),
268 (Value::Empty(pos.into()))
269 )
270);
271
272make_fn!(
273 compound_value<SliceIter<Token>, Value>,
274 either!(trace_parse!(list_value), trace_parse!(tuple))
275);
276
277make_fn!(
278 value<SliceIter<Token>, Value>,
279 either!(
280 trace_parse!(symbol),
281 trace_parse!(compound_value),
282 trace_parse!(boolean_value),
283 trace_parse!(empty_value),
284 trace_parse!(number),
285 trace_parse!(quoted_value)
286 )
287);
288
289make_fn!(
290 shape_suffix<SliceIter<Token>, Expression>,
291 do_each!(
292 _ => punct!("::"),
293 shape => non_op_expression,
294 (shape)
295 )
296);
297
298fn value_to_expression(v: Value) -> Expression {
299 Expression::Simple(v)
300}
301
302make_fn!(
303 simple_expression<SliceIter<Token>, Expression>,
304 do_each!(
305 val => trace_parse!(value),
306 _ => not!(either!(punct!("{"), punct!("["), punct!("("))),
307 (value_to_expression(val))
308 )
309);
310
311fn expression_to_grouped_expression(e: Expression, pos: Position) -> Expression {
312 Expression::Grouped(Box::new(e), pos)
313}
314
315make_fn!(
316 grouped_expression<SliceIter<Token>, Expression>,
317 do_each!(
318 pos => pos,
319 _ => punct!("("),
320 expr => do_each!(
321 expr => trace_parse!(expression),
322 _ => must!(punct!(")")),
323 (expr)
324 ),
325 (expression_to_grouped_expression(expr, pos))
326 )
327);
328
329fn tuple_to_copy(sym: Value, fields: Option<FieldList>) -> Expression {
330 let pos = sym.pos().clone();
331 let fields = match fields {
332 Some(fields) => fields,
333 None => Vec::new(),
334 };
335 Expression::Copy(CopyDef {
336 selector: sym,
337 fields: fields,
338 pos: pos,
339 })
340}
341
342make_fn!(
343 copy_expression<SliceIter<Token>, Expression>,
344 do_each!(
345 sym => trace_parse!(symbol),
346 _ => punct!("{"),
347 fields => optional!(trace_parse!(field_list)),
348 _ => optional!(punct!(",")),
349 _ => must!(punct!("}")),
350 (tuple_to_copy(sym, fields))
351 )
352);
353
354fn tuple_to_func<'a>(
355 pos: Position,
356 vals: Option<Vec<(Value, Option<Expression>)>>,
357 val: Expression,
358) -> ConvertResult<'a, Expression> {
359 let mut default_args = match vals {
360 None => Vec::new(),
361 Some(vals) => vals,
362 };
363 let arglist = default_args
364 .drain(0..)
365 .map(|(s, constraint)| {
366 (
367 PositionedItem {
368 pos: s.pos().clone(),
369 val: s.to_string().into(),
370 },
371 constraint,
372 )
373 })
374 .collect();
375 Ok(Expression::Func(FuncDef {
376 scope: None,
377 argdefs: arglist,
378 fields: Box::new(val),
379 pos: pos,
380 }))
381}
382
383make_fn!(
384 arglist<SliceIter<Token>, Vec<(Value, Option<Expression>)>>,
385 separated!(
386 punct!(","),
387 do_each!(
388 sym => symbol,
389 constraint => optional!(shape_suffix),
390 (sym, constraint)
391 )
392 )
393);
394
395fn module_expression(input: SliceIter<Token>) -> Result<SliceIter<Token>, Expression> {
396 let parsed = do_each!(input,
397 pos => pos,
398 _ => word!("module"),
399 _ => must!(punct!("{")),
400 arglist => trace_parse!(optional!(field_list)),
401 _ => optional!(punct!(",")),
402 _ => must!(punct!("}")),
403 _ => must!(punct!("=>")),
404 out_expr_and_constraint => optional!(
405 do_each!(
406 _ => punct!("("),
407 expr => must!(expression),
408 constraint => optional!(shape_suffix),
409 _ => must!(punct!(")")),
410 (expr, constraint)
411 )
412 ),
413 _ => must!(punct!("{")),
414 stmt_list => trace_parse!(repeat!(statement)),
415 _ => must!(punct!("}")),
416 (pos, arglist, out_expr_and_constraint, stmt_list)
417 );
418 match parsed {
419 Result::Abort(e) => Result::Abort(e),
420 Result::Fail(e) => Result::Fail(e),
421 Result::Incomplete(offset) => Result::Incomplete(offset),
422 Result::Complete(rest, (pos, arglist, out_expr_and_constraint, stmt_list)) => {
423 let mut def = ModuleDef::new(arglist.unwrap_or_else(|| Vec::new()), stmt_list, pos);
424 if let Some((expr, constraint)) = out_expr_and_constraint {
425 def.set_out_expr(expr);
426 def.out_constraint = constraint.map(Box::new);
427 }
428 Result::Complete(rest, Expression::Module(def))
429 }
430 }
431}
432
433fn func_expression(input: SliceIter<Token>) -> Result<SliceIter<Token>, Expression> {
434 let parsed = do_each!(input,
435 pos => pos,
436 _ => word!("func"),
437 _ => must!(punct!("(")),
438 arglist => trace_parse!(optional!(arglist)),
439 _ => must!(punct!(")")),
440 _ => must!(punct!("=>")),
441 map => trace_parse!(expression),
442 (pos, arglist, map)
443 );
444 match parsed {
445 Result::Abort(e) => Result::Abort(e),
446 Result::Fail(e) => Result::Fail(e),
447 Result::Incomplete(offset) => Result::Incomplete(offset),
448 Result::Complete(rest, (pos, arglist, map)) => match tuple_to_func(pos, arglist, map) {
449 Ok(expr) => Result::Complete(rest, expr),
450 Err(e) => Result::Fail(Error::caused_by(
451 "Invalid func syntax",
452 Box::new(e),
453 Box::new(rest.clone()),
454 )),
455 },
456 }
457}
458
459make_fn!(
460 alt_select_expression<SliceIter<Token>, Expression>,
461 do_each!(
462 pos => pos,
463 _ => word!("select"),
464 _ => must!(punct!("(")),
465 val => must!(expression),
466 default => optional!(
467 do_each!(
468 _ => punct!(","),
469 def => must!(expression),
470 (def)
471 )
472 ),
473 _ => optional!(punct!(",")),
474 _ => must!(punct!(")")),
475 _ => must!(punct!("=>")),
476 _ => must!(punct!("{")),
477 tpl => must!(field_list),
478 _ => optional!(punct!(",")),
479 _ => must!(punct!("}")),
480 (Expression::Select(SelectDef {
481 val: Box::new(val),
482 default: default.map(|e| Box::new(e)),
483 tuple: tpl,
484 pos: pos,
485 }))
486 )
487);
488
489make_fn!(
490 simple_format_args<SliceIter<Token>, FormatArgs>,
491 do_each!(
492 _ => punct!("("),
493 args => separated!(punct!(","), trace_parse!(expression)),
494 _ => must!(punct!(")")),
495 (FormatArgs::List(args))
496 )
497);
498
499make_fn!(
500 expression_format_args<SliceIter<Token>, FormatArgs>,
501 do_each!(
502 expr => must!(expression),
503 (FormatArgs::Single(Box::new(expr)))
504 )
505);
506
507make_fn!(
508 format_expression<SliceIter<Token>, Expression>,
509 do_each!(
510 tmpl => match_type!(STR),
511 _ => punct!("%"),
512 args => wrap_err!(must!(either!(simple_format_args, expression_format_args)),
513 "Expected format arguments"),
514 (Expression::Format(FormatDef {
515 template: tmpl.fragment.to_string(),
516 args: args,
517 pos: tmpl.pos,
518 }))
519 )
520);
521
522make_fn!(
523 include_expression<SliceIter<Token>, Expression>,
524 do_each!(
525 pos => pos,
526 _ => word!("include"),
527 typ => must!(match_type!(BAREWORD)),
528 path => must!(match_type!(STR)),
529 (Expression::Include(IncludeDef{
530 pos: pos,
531 typ: typ,
532 path: path,
533 }))
534 )
535);
536
537fn tuple_to_call<'a>(
538 input: SliceIter<'a, Token>,
539 val: Value,
540 exprs: Option<Vec<Expression>>,
541) -> ConvertResult<'a, Expression> {
542 if let Value::Symbol(_) = val {
543 Ok(Expression::Call(CallDef {
544 funcref: val,
545 arglist: exprs.unwrap_or_else(|| Vec::new()),
546 pos: (&input).into(),
547 }))
548 } else {
549 Err(Error::new(
550 format!("Expected Selector Got {:?}", val),
551 Box::new(input.clone()),
552 ))
553 }
554}
555
556make_fn!(
557 cast_expression<SliceIter<Token>, Expression>,
558 do_each!(
559 typ => either!(
560 word!("int"),
561 word!("float"),
562 word!("str"),
563 word!("bool")
564 ),
565 _ => punct!("("),
566 expr => expression,
567 _ => punct!(")"),
568 (Expression::Cast(CastDef{
569 cast_type: match typ.fragment.as_ref() {
570 "int" => CastType::Int,
571 "float" => CastType::Float,
572 "str" => CastType::Str,
573 "bool" => CastType::Bool,
574 _ => unreachable!(),
575 },
576 target: Box::new(expr),
577 pos: typ.pos,
578 }))
579 )
580);
581
582fn call_expression(input: SliceIter<Token>) -> Result<SliceIter<Token>, Expression> {
583 let parsed = do_each!(input.clone(),
584 callee_name => trace_parse!(symbol),
585 _ => punct!("("),
586 args => optional!(separated!(punct!(","), trace_parse!(expression))),
587 _ => optional!(punct!(",")),
588 _ => must!(punct!(")")),
589 (callee_name, args)
590 );
591 match parsed {
592 Result::Abort(e) => Result::Abort(e),
593 Result::Fail(e) => Result::Fail(e),
594 Result::Incomplete(offset) => Result::Incomplete(offset),
595 Result::Complete(rest, (name, args)) => match tuple_to_call(input.clone(), name, args) {
596 Ok(expr) => Result::Complete(rest, expr),
597 Err(e) => Result::Fail(Error::caused_by(
598 "Invalid Call Syntax",
599 Box::new(e),
600 Box::new(rest),
601 )),
602 },
603 }
604}
605
606make_fn!(
607 reduce_expression<SliceIter<Token>, Expression>,
608 do_each!(
609 pos => pos,
610 _ => word!("reduce"),
611 _ => must!(punct!("(")),
612 func => must!(expression),
613 _ => must!(punct!(",")),
614 acc => must!(trace_parse!(expression)),
615 _ => must!(punct!(",")),
616 tgt => must!(trace_parse!(expression)),
617 _ => optional!(punct!(",")),
618 _ => must!(punct!(")")),
619 (Expression::FuncOp(FuncOpDef::Reduce(ReduceOpDef{
620 func: Box::new(func),
621 acc: Box::new(acc),
622 target: Box::new(tgt),
623 pos: pos,
624 })))
625 )
626);
627
628make_fn!(
629 map_expression<SliceIter<Token>, Expression>,
630 do_each!(
631 pos => pos,
632 _ => word!("map"),
633 _ => must!(punct!("(")),
634 func => must!(expression),
635 _ => must!(punct!(",")),
636 list => must!(trace_parse!(expression)),
637 _ => optional!(punct!(",")),
638 _ => must!(punct!(")")),
639 (Expression::FuncOp(FuncOpDef::Map(MapFilterOpDef{
640 func: Box::new(func),
641 target: Box::new(list),
642 pos: pos,
643 })))
644 )
645);
646
647make_fn!(
648 filter_expression<SliceIter<Token>, Expression>,
649 do_each!(
650 pos => pos,
651 _ => word!("filter"),
652 _ => must!(punct!("(")),
653 func => must!(expression),
654 _ => must!(punct!(",")),
655 list => must!(trace_parse!(expression)),
656 _ => optional!(punct!(",")),
657 _ => must!(punct!(")")),
658 (Expression::FuncOp(FuncOpDef::Filter(MapFilterOpDef{
659 func: Box::new(func),
660 target: Box::new(list),
661 pos: pos,
662 })))
663 )
664);
665
666make_fn!(
667 func_op_expression<SliceIter<Token>, Expression>,
668 either!(reduce_expression, map_expression, filter_expression)
669);
670
671make_fn!(
672 range_expression<SliceIter<Token>, Expression>,
673 do_each!(
674 pos => pos,
675 start => either!(simple_expression, grouped_expression),
676 _ => punct!(":"),
677 maybe_step => optional!(
678 do_each!(
679 step => either!(simple_expression, grouped_expression),
680 _ => punct!(":"),
681 (Box::new(step))
682 )
683 ),
684 end => must!(wrap_err!(either!(simple_expression, grouped_expression), "Expected simple or grouped expression")),
685 (Expression::Range(RangeDef{
686 pos: pos,
687 start: Box::new(start),
688 step: maybe_step,
689 end: Box::new(end),
690 }))
691 )
692);
693
694make_fn!(
695 import_expression<SliceIter<Token>, Expression>,
696 do_each!(
697 pos => pos,
698 _ => word!("import"),
699 path => must!(wrap_err!(match_type!(STR), "Expected import path")),
700 (Expression::Import(ImportDef{
701 pos: pos,
702 path: path,
703 }))
704 )
705);
706
707make_fn!(
708 string_expression<SliceIter<Token>, Expression>,
709 do_each!(
710 val => trace_parse!(quoted_value),
711 (value_to_expression(val))
712 )
713);
714
715make_fn!(
716 fail_expression<SliceIter<Token>, Expression>,
717 do_each!(
718 pos => pos,
719 _ => word!("fail"),
720 msg => must!(wrap_err!(expression, "Expected failure message")),
721 (Expression::Fail(FailDef{
722 pos: pos,
723 message: Box::new(msg),
724 }))
725 )
726);
727
728make_fn!(
729 trace_expression<SliceIter<Token>, Expression>,
730 do_each!(
731 pos => pos,
732 _ => word!("TRACE"),
733 expr => must!(wrap_err!(expression, "Expected failure message")),
734 (Expression::Debug(DebugDef{
735 pos: pos,
736 expr: Box::new(expr),
737 }))
738 )
739);
740
741make_fn!(
742 not_expression<SliceIter<Token>, Expression>,
743 do_each!(
744 pos => pos,
745 _ => word!("not"),
746 expr => must!(wrap_err!(expression, "Expected failure message")),
747 (Expression::Not(NotDef{
748 pos: pos,
749 expr: Box::new(expr),
750 }))
751 )
752);
753
754fn unprefixed_expression(input: SliceIter<Token>) -> ParseResult<Expression> {
755 let _input = input.clone();
756 either!(
757 input,
758 trace_parse!(format_expression),
759 trace_parse!(range_expression),
760 trace_parse!(simple_expression),
761 trace_parse!(cast_expression),
763 trace_parse!(call_expression),
764 trace_parse!(copy_expression)
765 )
766}
767
768make_fn!(
769 non_op_expression<SliceIter<Token>, Expression>,
770 either!(
771 trace_parse!(func_op_expression),
772 trace_parse!(func_expression),
773 trace_parse!(import_expression),
774 trace_parse!(trace_expression),
775 trace_parse!(not_expression),
776 trace_parse!(fail_expression),
777 trace_parse!(module_expression),
778 trace_parse!(alt_select_expression),
779 trace_parse!(grouped_expression),
780 trace_parse!(include_expression),
781 trace_parse!(unprefixed_expression)
782 )
783);
784
785pub fn expression(input: SliceIter<Token>) -> ParseResult<Expression> {
786 let _input = input.clone();
787 match trace_parse!(_input, op_expression) {
788 Result::Incomplete(i) => Result::Incomplete(i),
789 Result::Fail(_) => trace_parse!(input, non_op_expression),
790 Result::Abort(e) => Result::Abort(e),
791 Result::Complete(rest, expr) => Result::Complete(rest, expr),
792 }
793}
794
795make_fn!(
796 expression_statement<SliceIter<Token>, Statement>,
797 do_each!(
798 e => do_each!(
799 expr => trace_parse!(expression),
800 _ => must!(punct!(";")),
801 (expr)
802 ),
803 (Statement::Expression(e))
804 )
805);
806
807macro_rules! match_binding_name {
809 ($i:expr,) => {{
810 use abortable_parser::{Error, Result};
811 let mut _i = $i.clone();
812 match match_type!(_i, BAREWORD) {
813 Result::Complete(i, t) => {
814 if t.fragment.as_ref() == "env" {
815 return Result::Abort(Error::new(
816 format!("Cannot use binding {}. It is a reserved word.", t.fragment),
817 Box::new($i.clone()),
818 ));
819 }
820 Result::Complete(i, t)
821 }
822 Result::Incomplete(i) => Result::Incomplete(i),
823 Result::Fail(e) => Result::Fail(e),
824 Result::Abort(e) => Result::Abort(e),
825 }
826 }};
827}
828
829make_fn!(
830 let_stmt_body<SliceIter<Token>, Statement>,
831 do_each!(
832 pos => pos,
833 name => wrap_err!(match_binding_name!(), "Expected name for binding"),
834 constraint => optional!(trace_parse!(shape_suffix)),
835 _ => punct!("="),
836 val => trace_parse!(wrap_err!(expression, "Expected Expression to bind")),
837 _ => punct!(";"),
838 (Statement::Let(LetDef {
839 pos: pos,
840 name: name,
841 constraint: constraint,
842 value: val,
843 }))
844 )
845);
846
847make_fn!(
848 let_statement<SliceIter<Token>, Statement>,
849 do_each!(
850 _ => word!("let"),
851 stmt => trace_parse!(must!(let_stmt_body)),
852 (stmt)
853 )
854);
855
856make_fn!(
857 assert_statement<SliceIter<Token>, Statement>,
858 do_each!(
859 pos => pos,
860 _ => word!("assert"),
861 expr => wrap_err!(must!(expression), "Expected Tuple {ok=<bool>, desc=<str>}"),
862 _ => must!(punct!(";")),
863 (Statement::Assert(pos, expr))
864 )
865);
866
867make_fn!(
868 out_statement<SliceIter<Token>, Statement>,
869 do_each!(
870 pos => pos,
871 _ => word!("out"),
872 typ => wrap_err!(must!(match_type!(BAREWORD)), "Expected converter name"),
873 expr => wrap_err!(must!(expression), "Expected Expression to export"),
874 _ => must!(punct!(";")),
875 (Statement::Output(pos, typ.clone(), expr.clone()))
876 )
877);
878
879make_fn!(
880 print_statement<SliceIter<Token>, Statement>,
881 do_each!(
882 pos => pos,
883 _ => word!("convert"),
884 typ => wrap_err!(must!(match_type!(BAREWORD)), "Expected converter name"),
885 expr => wrap_err!(must!(expression), "Expected Expression to print"),
886 _ => must!(punct!(";")),
887 (Statement::Print(pos, typ.clone(), expr.clone()))
888 )
889);
890
891fn statement(i: SliceIter<Token>) -> Result<SliceIter<Token>, Statement> {
893 return either!(
894 i,
895 trace_parse!(assert_statement),
896 trace_parse!(let_statement),
897 trace_parse!(out_statement),
898 trace_parse!(print_statement),
899 trace_parse!(expression_statement)
900 );
901}
902pub fn parse<'a>(
906 input: OffsetStrIter<'a>,
907 comment_map: Option<&mut CommentMap>,
908) -> std::result::Result<Vec<Statement>, BuildError> {
909 match tokenize(input.clone(), comment_map) {
910 Ok(tokenized) => {
911 let mut out = Vec::new();
912 let mut i_ = SliceIter::new(&tokenized);
913 loop {
914 let i = i_.clone();
915 if let Some(tok) = i.peek_next() {
916 if tok.typ == TokenType::END {
917 break;
918 }
919 }
920 match statement(i.clone()) {
921 Result::Abort(e) => {
922 return Err(BuildError::from(e));
923 }
924 Result::Fail(e) => {
925 return Err(BuildError::from(e));
926 }
927 Result::Incomplete(_ei) => {
928 let err = abortable_parser::Error::new(
929 "Unexpected end of parse input",
930 Box::new(i.clone()),
931 );
932 return Err(BuildError::from(err));
933 }
934 Result::Complete(rest, stmt) => {
935 out.push(stmt);
936 i_ = rest;
937 if eoi(i).is_complete() {
938 break;
939 }
940 }
941 }
942 }
943 return Ok(out);
944 }
945 Err(e) => {
946 return Err(e);
947 }
948 }
949}
950
951pub mod precedence;