diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2023-10-05 14:26:22 +0200 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2023-10-05 14:26:22 +0200 |
commit | de09fda5dcef16bf50663f7ffb56074e6ad20b5a (patch) | |
tree | 3651f3e12d621e6f0196e7ffbaee885e56a676e9 | |
parent | abae806efdf6ac5f919c93057dd8df1faff1058c (diff) |
Filter: Fix scope handling in for loops
Changes in scope implementation broke scope handling in for loops.
The term in for loops is supposed to be parsed in the parent scope.
-rw-r--r-- | filter/config.Y | 5 | ||||
-rw-r--r-- | filter/test.conf | 57 |
2 files changed, 61 insertions, 1 deletions
diff --git a/filter/config.Y b/filter/config.Y index 3cd8e3e4..f3ed2dc5 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; @@ -993,7 +994,9 @@ cmd: new_config->current_scope->slots += 2; } for_var IN /* Parse term in the parent scope */ - { new_config->current_scope->active = 0; } term { new_config->current_scope->active = 1; } + { 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 22b4984a..f9289189 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -1939,6 +1939,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 * ---------------------------------------- */ |