diff --git a/filter/config.Y b/filter/config.Y index 66446783..45444eb2 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -20,6 +20,7 @@ static inline u32 pair_a(u32 p) { return p >> 16; } static inline u32 pair_b(u32 p) { return p & 0xFFFF; } static struct symbol *this_function; +static struct sym_scope *this_for_scope; static struct f_method_scope { struct f_inst *object; @@ -28,8 +29,6 @@ static struct f_method_scope { } f_method_scope_stack[32]; static int f_method_scope_pos = -1; -static struct sym_scope *f_for_stored_scope; - #define FM (f_method_scope_stack[f_method_scope_pos]) static inline void f_method_call_start(struct f_inst *object) @@ -1015,15 +1014,9 @@ cmd: new_config->current_scope->slots += 2; } for_var IN /* Parse term in the parent scope */ - { - ASSERT_DIE(f_for_stored_scope == NULL); - f_for_stored_scope = new_config->current_scope; - new_config->current_scope = new_config->current_scope->next; - } term { - ASSERT_DIE(f_for_stored_scope); - new_config->current_scope = f_for_stored_scope; - f_for_stored_scope = NULL; - } + { this_for_scope = new_config->current_scope; new_config->current_scope = this_for_scope->next; } + term + { new_config->current_scope = this_for_scope; this_for_scope = NULL; } DO cmd { cf_pop_block_scope(new_config); $$ = f_for_cycle($3, $6, $9); diff --git a/filter/test.conf b/filter/test.conf index 3d55495c..2e93fc0f 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -2049,6 +2049,63 @@ bt_test_suite(t_if_else, "Testing if-else statement"); +/* + * Test for-in statement + * --------------------- + */ + +function t_for_in() +{ + bgppath p = +empty+.prepend(5).prepend(4).prepend(3).prepend(2).prepend(1); + bgppath q = +empty+.prepend(30).prepend(20).prepend(10); + int a; + + # basic for loop + a = 0; + for int i in p do { + a = 2 * a + i; + } + bt_assert(a = 57); + + # basic for loop, no braces + a = 0; + for int i in p do a = 2 * a + i; + bt_assert(a = 57); + + # for loop with empty body + a = 0; + for int i in p do { } + bt_assert(a = 0); + + # for loop over empty path + a = 0; + for int i in +empty+ do a = 1; + bt_assert(a = 0); + + # for loop with var name shadowing + a = 0; + for int p in p do { + a = 2 * a + p; + } + bt_assert(a = 57); + + # nested for loops + a = 0; + int n = 1; + for int i in p do { + for int j in q do { + a = a + i * j * n; + n = n + 1; + } + } + bt_assert(a = 9300); +} + +bt_test_suite(t_for_in, "Testing for-in statement"); + + + + /* * Unused functions -- testing only parsing * ----------------------------------------