@@ -14,9 +14,9 @@ void print_parser(auto const& context, regex_parser const&, auto& ostream,
14
14
} // namespace detail
15
15
} // namespace boost::parser
16
16
17
- #include < boost/parser/parser.hpp>
18
17
#include < cctype>
19
18
#include < climits>
19
+ #include < ctrl_statements.hpp>
20
20
#include < debug.hpp>
21
21
#include < fstream>
22
22
#include < iostream>
@@ -26,6 +26,9 @@ void print_parser(auto const& context, regex_parser const&, auto& ostream,
26
26
#include < regex>
27
27
#include < vector>
28
28
29
+ // this is last
30
+ #include < boost/parser/parser.hpp>
31
+
29
32
namespace bp = ::boost::parser;
30
33
using namespace bp ::literals;
31
34
@@ -219,9 +222,16 @@ bp::rule<class list_r, list> const list_r = "list";
219
222
bp::rule<class time , time_parts> const time = " time" ;
220
223
bp::rule<class duration , time_parts> const duration = " duration" ;
221
224
222
- bp::rule<class if_elif , if_elif_statement > const if_elif =
225
+ bp::rule<class if_elif , statement::ptr > const if_elif =
223
226
" if/then[/elif/else]/endif statement" ;
224
227
228
+ bp::rule<class loop_instruction , instruction> const loop_instruction =
229
+ " loop body instruction" ;
230
+ bp::rule<class while_loop , statement::ptr> const while_loop =
231
+ " while/do/done statement" ;
232
+ bp::rule<class for_loop , statement::ptr> const for_loop =
233
+ " for/in/do/done statement" ;
234
+
225
235
bp::rule<class program_r , program> const program_r = " program" ;
226
236
bp::rule<class user_input , program> const user_input = " user input" ;
227
237
@@ -401,16 +411,18 @@ auto const parse_if_cond = [](auto& ctx) {
401
411
auto & attr = _attr (ctx);
402
412
auto & val = _val (ctx);
403
413
// print_ctx_types(parse_if_cond);
404
- val.branches .emplace_back (
405
- std::make_tuple (true , simple_program{attr}, program{}));
414
+ auto ifstmt = std::make_shared<if_elif_statement>();
415
+ ifstmt->set_cond (attr);
416
+ val = ifstmt;
406
417
};
407
418
408
419
auto const parse_if_body = [](auto & ctx) {
409
420
// parse_if_body: attr = vector<instruction>, val = if_elif_statement
410
421
auto & attr = _attr (ctx);
411
422
auto & val = _val (ctx);
423
+ auto ifstmt = std::dynamic_pointer_cast<if_elif_statement>(val);
412
424
// print_ctx_types(parse_if_body);
413
- std::get<program>(val. branches . back ()). body = attr;
425
+ ifstmt-> set_body ( attr) ;
414
426
};
415
427
416
428
auto const parse_else = [](auto & ctx) {
@@ -419,9 +431,53 @@ auto const parse_else = [](auto& ctx) {
419
431
auto & val = _val (ctx);
420
432
// print_ctx_types(parse_else);
421
433
// new branch with an empty condition
422
- val.branches .emplace_back (
423
- std::make_tuple (true , simple_program{}, program{}));
424
- std::get<program>(val.branches .back ()).body = attr;
434
+ auto ifstmt = std::dynamic_pointer_cast<if_elif_statement>(val);
435
+ ifstmt->set_else (attr);
436
+ };
437
+
438
+ auto const parse_while_cond = [](auto & ctx) {
439
+ const auto & attr = _attr (ctx);
440
+ auto & val = _val (ctx);
441
+ // print_ctx_types(parse_while_cond);
442
+ auto whl = std::make_shared<while_statement>();
443
+ whl->cond = attr;
444
+ val = whl;
445
+ };
446
+
447
+ auto const parse_loop_body = [](auto & ctx) {
448
+ const auto & attr = _attr (ctx);
449
+ auto & val = _val (ctx);
450
+ // print_ctx_types(parse_loop_body);
451
+ if (auto whl = std::dynamic_pointer_cast<while_statement>(val); whl)
452
+ {
453
+ whl->set_body (attr);
454
+ val = whl;
455
+ }
456
+ else if (auto fl = std::dynamic_pointer_cast<for_statement>(val); fl)
457
+ {
458
+ fl->set_body (attr);
459
+ val = fl;
460
+ }
461
+ };
462
+
463
+ auto const parse_for_var = [](auto & ctx) {
464
+ const auto & attr = _attr (ctx);
465
+ auto & val = _val (ctx);
466
+ // print_ctx_types(parse_for_var);
467
+ auto fl = std::make_shared<for_statement>();
468
+ // fl->var_name = std::get<std::string>((*attr).left);
469
+ fl->set_var (attr);
470
+ val = fl;
471
+ };
472
+
473
+ auto const parse_for_cond = [](auto & ctx) {
474
+ const auto & attr = _attr (ctx);
475
+ auto & val = _val (ctx);
476
+ // print_ctx_types(parse_for_cond);
477
+ // parse_for_cond: attr = vector<simple_instruction>, val = for_statement
478
+ auto fl = std::dynamic_pointer_cast<for_statement>(val);
479
+ fl->set_setup (attr);
480
+ val = fl;
425
481
};
426
482
427
483
auto const parse_real = [](auto & ctx) {
@@ -654,6 +710,21 @@ auto const save_time_suffix = [](auto& ctx) {
654
710
val.suffix = attr;
655
711
};
656
712
713
+ auto const parse_keyword = [](auto & ctx) {
714
+ const auto & attr = _attr (ctx);
715
+ auto & val = _val (ctx);
716
+ print_ctx_types (parse_keyword);
717
+ keyword k{attr};
718
+ val = simple_instruction{k};
719
+ };
720
+
721
+ auto const passthru = [](auto & ctx) {
722
+ const auto & attr = _attr (ctx);
723
+ auto & val = _val (ctx);
724
+ print_ctx_types (passthru);
725
+ val = attr;
726
+ };
727
+
657
728
auto const set_binary = [](auto & ctx) {
658
729
auto & val = _val (ctx);
659
730
print_ctx_val_type (set_binary);
@@ -773,10 +844,10 @@ auto re_fn_def = bp::regex()[parse_regulars];
773
844
774
845
auto const simple_instruction_r_def =
775
846
(boolean | re_fn | function | time | duration | number_r | matrix_r |
776
- list_r | program_r | operators)[parse_simple_instruction];
847
+ list_r | symbolic_r | program_r | operators)[parse_simple_instruction];
777
848
778
849
auto const instruction_r_def =
779
- (if_elif | simple_instruction_r | symbolic_r )[parse_instruction];
850
+ (if_elif | while_loop | for_loop | simple_instruction_r )[parse_instruction];
780
851
781
852
auto const if_elif_def =
782
853
" if" _l > (+simple_instruction_r)[parse_if_cond] > " then" _l >
@@ -785,6 +856,19 @@ auto const if_elif_def =
785
856
" then" _l > (+(instruction_r - if_sub_words))[parse_if_body]) >
786
857
-(" else" _l > (+(instruction_r - if_sub_words))[parse_else]) > " endif" _l;
787
858
859
+ auto const loop_instruction_def =
860
+ (bp::string(" break" ) | bp::string(" continue" ))[parse_keyword] |
861
+ instruction_r[passthru];
862
+
863
+ auto const while_loop_def = " while" _l >
864
+ (+simple_instruction_r)[parse_while_cond] > " do" _l >
865
+ (+loop_instruction)[parse_loop_body] > " done" _l;
866
+
867
+ auto const for_loop_def = " for" _l > bp::lexeme[variable[parse_for_var]] >
868
+ " in" _l > (+simple_instruction_r)[parse_for_cond] >
869
+ " do" _l > (+loop_instruction)[parse_loop_body] >
870
+ " done" _l;
871
+
788
872
auto const program_r_def = " $(" _l > (*instruction_r)[parse_standalone_program] >
789
873
" )" _l;
790
874
@@ -1068,9 +1152,11 @@ auto const symbolic_r_def = "'"_l[set_no_commas] >
1068
1152
1069
1153
BOOST_PARSER_DEFINE_RULES (uinteger, integer, ufloating, floating, rati0nal,
1070
1154
c0mplex, number_r, hex_int, oct_int, bin_int,
1071
- matrix_r, list_r, time, duration, if_elif,
1072
- simple_instruction_r, instruction_r, program_r, re_fn,
1073
- function, operators, user_input);
1155
+ matrix_r, list_r, time, duration, if_elif, while_loop,
1156
+ for_loop, loop_instruction, simple_instruction_r,
1157
+ instruction_r, program_r, re_fn, function, operators,
1158
+ user_input);
1159
+
1074
1160
BOOST_PARSER_DEFINE_RULES (variable, paren_expr, paren_fn, paren_fn_call,
1075
1161
expr_atomic, factorial, expon, negation, multdiv,
1076
1162
addsub, equation, symbolic_r);
0 commit comments