diff options
-rw-r--r-- | libbuild2/build/script/parser.cxx | 2 | ||||
-rw-r--r-- | libbuild2/parser.cxx | 32 | ||||
-rw-r--r-- | tests/loop/for.testscript | 14 |
3 files changed, 39 insertions, 9 deletions
diff --git a/libbuild2/build/script/parser.cxx b/libbuild2/build/script/parser.cxx index 77bd21b..77fdfee 100644 --- a/libbuild2/build/script/parser.cxx +++ b/libbuild2/build/script/parser.cxx @@ -1562,7 +1562,7 @@ namespace build2 { value& lhs (environment_->assign (var)); - attributes_.push_back (move (val_attrs)); + attributes_.push_back (val_attrs); apply_value_attributes (&var, lhs, move (val), type::assign); }; diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx index d167200..b1f6eb2 100644 --- a/libbuild2/parser.cxx +++ b/libbuild2/parser.cxx @@ -4393,13 +4393,12 @@ namespace build2 next_with_attributes (t, tt); attributes_push (t, tt); - // @@ PAT: currently we pattern-expand for var. + // Enable list element attributes. // - const location vloc (get_location (t)); - names vns (parse_names (t, tt, pattern_mode::expand)); + enable_attributes (); - if (tt != type::colon) - fail (t) << "expected ':' instead of " << t << " after variable name"; + const location vloc (get_location (t)); + names vns (parse_names (t, tt, pattern_mode::preserve)); const variable& var (parse_variable_name (move (vns), vloc)); apply_variable_attributes (var); @@ -4410,6 +4409,17 @@ namespace build2 << " visibility but is assigned in for-loop"; } + // Parse the list element attributes, if present. + // + attributes_push (t, tt); + + if (tt != type::colon) + fail (t) << "expected ':' instead of " << t << " after variable name"; + + // Save element attributes so that we can inject them on each iteration. + // + attributes val_attrs (attributes_pop ()); + // Now the value (list of names) to iterate over. Parse it similar to a // value on the RHS of an assignment (expansion, attributes). // @@ -4474,7 +4484,7 @@ namespace build2 // Iterate. // - value& v (scope_->assign (var)); // Assign even if no iterations. + value& lhs (scope_->assign (var)); // Assign even if no iterations. if (!val) return; @@ -4494,11 +4504,17 @@ namespace build2 names n; n.push_back (move (*i)); if (pair) n.push_back (move (*++i)); - v = value (move (n)); + value v (move (n)); if (etype != nullptr) typify (v, *etype, &var); + // Inject element attributes. + // + attributes_.push_back (val_attrs); + + apply_value_attributes (&var, lhs, move (v), type::assign); + lexer l (is, *path_, line); lexer* ol (lexer_); lexer_ = &l; @@ -7479,7 +7495,7 @@ namespace build2 // Handle value subscript. // - if (tt == type::lsbrace) + if (tt == type::lsbrace && mode () == lexer_mode::eval) { location bl (get_location (t)); next (t, tt); // `[` diff --git a/tests/loop/for.testscript b/tests/loop/for.testscript index 5376029..e043ec0 100644 --- a/tests/loop/for.testscript +++ b/tests/loop/for.testscript @@ -116,3 +116,17 @@ a@1 b@2 c@3 EOO + +: elem-attribute +: +$* <<EOI >>EOO +for i [uint64]: 0 1 2 +{ + i += 1 + print $i +} +EOI +1 +2 +3 +EOO |