From 57c4e39dcb8eb6013e22cfe82597111c5c6a55af Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 26 Feb 2018 09:53:46 +0200 Subject: Regularize directory target/scope-specific variable assignment syntax --- build/export.build | 2 +- build2/dump.cxx | 3 +- build2/parser.cxx | 321 +++++++++++++-------- build2/parser.hxx | 5 +- old-tests/amalgam/libtest/build/export.build | 2 +- old-tests/attribute/buildfile | 4 +- old-tests/cli/lib/libtest/build/export.build | 2 +- old-tests/cli/lib/libtest/test/buildfile | 2 +- old-tests/install/lib/libtest/build/export.build | 2 +- old-tests/install/lib/libtest/build/root.build | 2 +- old-tests/postponed/buildfile | 2 +- .../scope/amalgamation/l1/build/bootstrap.build | 2 +- old-tests/scope/amalgamation/l1/buildfile | 8 +- old-tests/semantics/include/includer | 5 +- old-tests/semantics/source/sourcer | 4 +- old-tests/test.sh | 1 - old-tests/variable/override/buildfile | 2 +- old-tests/variable/override/p/buildfile | 2 +- old-tests/variable/qualified/buildfile | 27 -- old-tests/variable/qualified/test.out | 12 - old-tests/variable/qualified/test.sh | 3 - old-tests/variable/type-pattern-append/buildfile | 4 +- old-tests/variable/type/buildfile | 4 +- tests/eval/qual.test | 2 +- tests/search/dir/testscript | 4 +- tests/variable/override/testscript | 6 +- tests/variable/scope-specific/buildfile | 5 + tests/variable/scope-specific/testscript | 54 ++++ tests/variable/target-specific/buildfile | 5 + tests/variable/target-specific/testscript | 61 ++++ 30 files changed, 366 insertions(+), 192 deletions(-) delete mode 100644 old-tests/variable/qualified/buildfile delete mode 100644 old-tests/variable/qualified/test.out delete mode 100755 old-tests/variable/qualified/test.sh create mode 100644 tests/variable/scope-specific/buildfile create mode 100644 tests/variable/scope-specific/testscript create mode 100644 tests/variable/target-specific/buildfile create mode 100644 tests/variable/target-specific/testscript diff --git a/build/export.build b/build/export.build index dc3401a..dc77dee 100644 --- a/build/export.build +++ b/build/export.build @@ -2,7 +2,7 @@ # copyright : Copyright (c) 2014-2017 Code Synthesis Ltd # license : MIT; see accompanying LICENSE file -$out_root/: +$out_root/ { include build2/ } diff --git a/build2/dump.cxx b/build2/dump.cxx index 263f1b5..07ca17c 100644 --- a/build2/dump.cxx +++ b/build2/dump.cxx @@ -340,7 +340,8 @@ namespace build2 os << ind << (rd.empty () ? dir_path (".") : rd); } - os << ":" << endl << ind << '{'; + os << endl + << ind << '{'; const dir_path* orb (relative_base); relative_base = &d; diff --git a/build2/parser.cxx b/build2/parser.cxx index bb7123c..071703a 100644 --- a/build2/parser.cxx +++ b/build2/parser.cxx @@ -68,6 +68,8 @@ namespace build2 } } + explicit operator bool () const {return p_ != nullptr;} + // Note: move-assignable to empty only. // enter_scope (enter_scope&& x) {*this = move (x);} @@ -439,9 +441,24 @@ namespace build2 } } - const location nloc (get_location (t)); + location nloc (get_location (t)); names ns (parse_names (t, tt, pattern_mode::ignore)); + // Allow things like function calls that don't result in anything. + // + if (tt == type::newline && ns.empty ()) + { + if (at.first) + fail (at.second) << "standalone attributes"; + else + attributes_pop (); + + next (t, tt); + continue; + } + + // If we have a colon, then this is target-related. + // if (tt == type::colon) { // While '{}:' means empty name, '{$x}:' where x is empty list @@ -454,7 +471,7 @@ namespace build2 if (tt == type::newline) { - // See if this is a directory/target scope. + // See if this is a target scope. // if (peek () == type::lcbrace) { @@ -465,50 +482,15 @@ namespace build2 if (next (t, tt) != type::newline) fail (t) << "expected newline after {"; - // See if this is a directory or target scope. Different - // things can appear inside depending on which one it is. - // - bool dir (false); - for (const auto& n: ns) - { - if (n.directory ()) - { - if (ns.size () != 1) - { - // @@ TODO: point to name (and above). - // - fail (nloc) << "multiple names in directory scope"; - } - - dir = true; - } - } - - next (t, tt); - - if (dir) - { - // Directory scope. - // - if (at.first) - fail (at.second) << "attributes before directory scope"; - else - attributes_pop (); - - // Can contain anything that a top level can. - // - enter_scope sg (*this, move (ns[0].dir)); - parse_clause (t, tt); - } + if (at.first) + fail (at.second) << "attributes before target scope"; else - { - if (at.first) - fail (at.second) << "attributes before target scope"; - else - attributes_pop (); + attributes_pop (); - // @@ TODO: target scope (also prerequisite scope below). - } + // @@ TODO: target scope (also prerequisite scope below). + // + fail (nloc) << "target scopes are not yet supported" << + info << "if migrating, remove ':'"; if (tt != type::rcbrace) fail (t) << "expected } instead of " << t; @@ -525,15 +507,14 @@ namespace build2 // If this is not a scope, then it is a target without any // prerequisites. Fall through. - // } // Dependency declaration (including prerequisite-specific variable - // assignment) or scope/target-specific variable assignment. + // assignment) or target-specific variable assignment. // if (at.first) - fail (at.second) << "attributes before target/scope"; + fail (at.second) << "attributes before target"; else attributes_pop (); @@ -546,32 +527,28 @@ namespace build2 tt == type::newline || tt == type::eos) { - // @@ PAT: currently we pattern-expand scope/target-specific vars. + // @@ PAT: currently we pattern-expand target-specific vars. // const location ploc (get_location (t)); names pns (tt != type::newline && tt != type::eos ? parse_names (t, tt, pattern_mode::expand) : names ()); - // Scope/target-specific variable assignment. + // Target-specific variable assignment. // if (tt == type::assign || tt == type::prepend || tt == type::append) { token at (t); type att (tt); - const variable& var ( - var_pool.rw (*scope_).insert ( - parse_variable_name (move (pns), ploc), - true /* overridable */)); - + const variable& var (parse_variable_name (move (pns), ploc)); apply_variable_attributes (var); - // If we have multiple targets/scopes, then we save the value - // tokens when parsing the first one and then replay them for - // the subsequent. We have to do it this way because the value - // may contain variable expansions that would be sensitive to - // the target/scope context in which they are evaluated. + // If we have multiple targets, then we save the value tokens when + // parsing the first one and then replay them for the subsequent. + // We have to do it this way because the value may contain + // variable expansions that would be sensitive to the target/scope + // context in which they are evaluated. // // Note: watch out for an out-qualified single target (two names). // @@ -583,12 +560,18 @@ namespace build2 name& n (*i); if (n.qualified ()) - fail (nloc) << "project name in scope/target " << n; + fail (nloc) << "project name in target " << n; if (n.directory () && !n.pair) // Not out-qualified. { // Scope variable. // + + // @@ TODO: break for now before changing to target. + // + fail (nloc) << "change of semantics: will be target, not scope" << + info << "remove ':' for scope semantics"; + if (var.visibility == variable_visibility::target) fail (ploc) << "variable " << var << " has target " << "visibility but assigned in a scope" << @@ -840,11 +823,7 @@ namespace build2 type at (tt); - const variable& var ( - var_pool.rw (*scope_).insert ( - parse_variable_name (move (vns), vloc), - true /* overridable */)); - + const variable& var (parse_variable_name (move (vns), vloc)); apply_variable_attributes (var); // We handle multiple targets and/or prerequisites by replaying @@ -889,40 +868,124 @@ namespace build2 // Variable assignment. // - if (tt == type::assign || tt == type::prepend || tt == type::append) + // This can take any of the following forms: + // + // x = y + // foo/ x = y (ns will have two elements) + // foo/ [attrs] x = y (tt will be '[') + // + // In the future we may also want to support: + // + // foo/ bar/ x = y + // + if (tt == type::assign || tt == type::prepend || tt == type::append || + tt == type::lsbrace) { - const variable& var ( - var_pool.rw (*scope_).insert ( - parse_variable_name (move (ns), nloc), - true /* overridable */)); + // Detect and handle the directory scope. If things look off, then we + // let parse_variable_name() complain. + // + dir_path d; - apply_variable_attributes (var); + if ((ns.size () == 2 && ns[0].directory ()) || + (ns.size () == 1 && ns[0].directory () && tt == type::lsbrace)) + { + if (at.first) + fail (at.second) << "attributes before scope directory"; - if (var.visibility == variable_visibility::target) - fail (nloc) << "variable " << var << " has target visibility but " - << "assigned in a scope" << - info << "consider changing to '*: " << var << "'"; + if (tt == type::lsbrace) + { + attributes_pop (); + attributes_push (t, tt); - parse_variable (t, tt, var, tt); + d = move (ns[0].dir); + nloc = get_location (t); + ns = parse_names (t, tt, pattern_mode::ignore); - if (tt == type::newline) - next (t, tt); - else if (tt != type::eos) - fail (t) << "expected newline instead of " << t; + // It got to be a variable assignment. + // + if (tt != type::assign && + tt != type::prepend && + tt != type::append) + fail (t) << "variable assignment expected instead of " << t; + } + else + { + d = move (ns[0].dir); + ns.erase (ns.begin ()); + } + } - continue; + if (tt != type::lsbrace) + { + const variable& var (parse_variable_name (move (ns), nloc)); + apply_variable_attributes (var); + + if (var.visibility == variable_visibility::target) + fail (nloc) << "variable " << var << " has target visibility but " + << "assigned in a scope" << + info << "consider changing to '*: " << var << "'"; + + { + enter_scope sg (d.empty () + ? enter_scope () + : enter_scope (*this, move (d))); + parse_variable (t, tt, var, tt); + } + + if (tt == type::newline) + next (t, tt); + else if (tt != type::eos) + fail (t) << "expected newline instead of " << t; + + continue; + } + + // Not "our" attribute, see if anyone else likes it. } - // Allow things like function calls that don't result in anything. + // See if this is a directory scope. // - if (tt == type::newline && ns.empty ()) + if (tt == type::newline && peek () == type::lcbrace) { + if (ns.size () != 1) + fail (nloc) << "multiple scope directories"; + + name& n (ns[0]); + + if (!n.directory ()) + fail (nloc) << "scope directory expected"; + + next (t, tt); + + // Should be on its own line. + // + if (next (t, tt) != type::newline) + fail (t) << "expected newline after {"; + + next (t, tt); + if (at.first) - fail (at.second) << "standalone attributes"; + fail (at.second) << "attributes before scope directory"; else attributes_pop (); - next (t, tt); + // Can contain anything that a top level can. + // + { + enter_scope sg (*this, move (n.dir)); + parse_clause (t, tt); + } + + if (tt != type::rcbrace) + fail (t) << "expected } instead of " << t; + + // Should be on its own line. + // + if (next (t, tt) == type::newline) + next (t, tt); + else if (tt != type::eos) + fail (t) << "expected newline after }"; + continue; } @@ -1726,11 +1789,7 @@ namespace build2 if (tt != type::colon) fail (t) << "expected ':' instead of " << t << " after variable name"; - const variable& var ( - var_pool.rw (*scope_).insert ( - parse_variable_name (move (vns), vloc), - true /* overridable */)); - + const variable& var (parse_variable_name (move (vns), vloc)); apply_variable_attributes (var); if (var.visibility == variable_visibility::target) @@ -2020,7 +2079,7 @@ namespace build2 next (t, tt); // Swallow newline. } - string parser:: + const variable& parser:: parse_variable_name (names&& ns, const location& l) { // The list should contain a single, simple name. @@ -2030,11 +2089,15 @@ namespace build2 string& n (ns[0].value); + //@@ OLD if (n.front () == '.') // Fully qualified name. - return string (n, 1, string::npos); + n.erase (0, 1); else + { //@@ TODO: append namespace if any. - return move (n); + } + + return var_pool.rw (*scope_).insert (move (n), true /* overridable */); } void parser:: @@ -2601,12 +2664,12 @@ namespace build2 } // If this is the first expression then handle the eval-qual special case - // (scope/target qualified name represented as a special ':'-style pair). + // (target-qualified name represented as a special ':'-style pair). // if (first && tt == type::colon) { if (at.first) - fail (at.second) << "attributes before qualified variable name"; + fail (at.second) << "attributes before target-qualified variable name"; attributes_pop (); @@ -2621,7 +2684,7 @@ namespace build2 return v; // Empty. if (v.type != nullptr || !v || v.as ().size () != 1) - fail (l) << "expected scope/target before ':'"; + fail (l) << "expected target before ':'"; if (n.type != nullptr || !n || n.as ().size () != 1) fail (nl) << "expected variable name after ':'"; @@ -3897,24 +3960,32 @@ namespace build2 vector_view ns (reverse (v, storage)); // Movable. size_t n (ns.size ()); - // Make sure the result of evaluation is a potentially-qualified - // simple name. + // We cannot handle scope-qualification in the eval context as + // we do for target-qualification (see eval-qual) since then we + // would be treating all paths as qualified variables. So we + // have to do it here. // - if (n > 2 || - (n == 2 && ns[0].pair != ':') || - !ns[n - 1].simple ()) - fail (loc) << "expected variable/function name instead of '" - << ns << "'"; - - if (n == 2) + if (n == 2 && ns[0].pair == ':') // $(foo: x) { qual = move (ns[0]); if (qual.empty ()) fail (loc) << "empty variable/function qualification"; - - qual.pair = '\0'; // We broke up the pair. } + else if (n == 2 && ns[0].directory ()) // $(foo/ x) + { + qual = move (ns[0]); + qual.pair = '/'; + } + else if (n > 1) + fail (loc) << "expected variable/function name instead of '" + << ns << "'"; + + // Note: checked for empty below. + // + if (!ns[n - 1].simple ()) + fail (loc) << "expected variable/function name instead of '" + << ns[n - 1] << "'"; name = move (ns[n - 1].value); } @@ -3941,7 +4012,7 @@ namespace build2 next (t, tt); // Get '('. // @@ Should we use (target/scope) qualification (of name) as the - // context in which to call the function? + // context in which to call the function? Hm, interesting... // values args (parse_eval (t, tt, pmode)); tt = peek (); @@ -4601,13 +4672,13 @@ namespace build2 { tracer trace ("parser::lookup_variable", &path_); - // Process variable name. + // Process variable name. @@ OLD // if (name.front () == '.') // Fully namespace-qualified name. name.erase (0, 1); else { - //@@ TODO: append namespace if any. + //@@ TODO : append namespace if any. } // If we are qualified, it can be a scope or a target. @@ -4615,13 +4686,29 @@ namespace build2 enter_scope sg; enter_target tg; - if (qual.directory ()) //@@ OUT - sg = enter_scope (*this, move (qual.dir)); - else if (!qual.empty ()) - // @@ OUT TODO - // - tg = enter_target ( - *this, move (qual), build2::name (), true, loc, trace); + if (!qual.empty ()) + { + switch (qual.pair) + { + case '/': + { + assert (qual.directory ()); + sg = enter_scope (*this, move (qual.dir)); + break; + } + case ':': + { + qual.pair = '\0'; + + // @@ OUT TODO + // + tg = enter_target ( + *this, move (qual), build2::name (), true, loc, trace); + break; + } + default: assert (false); + } + } // Lookup. // diff --git a/build2/parser.hxx b/build2/parser.hxx index 1b39491..acf507e 100644 --- a/build2/parser.hxx +++ b/build2/parser.hxx @@ -117,7 +117,7 @@ namespace build2 void parse_variable (token&, token_type&, const variable&, token_type); - string + const variable& parse_variable_name (names&&, const location&); // Note: calls attributes_push() that the caller must pop. @@ -368,6 +368,9 @@ namespace build2 // Customization hooks. // protected: + // If qual is not empty, then its pair member should indicate the kind + // of qualification: ':' -- target, '/' -- scope. + // virtual lookup lookup_variable (name&& qual, string&& name, const location&); diff --git a/old-tests/amalgam/libtest/build/export.build b/old-tests/amalgam/libtest/build/export.build index b95e409..c1c6a8b 100644 --- a/old-tests/amalgam/libtest/build/export.build +++ b/old-tests/amalgam/libtest/build/export.build @@ -1,4 +1,4 @@ -$out_root/: +$out_root/ { include buildfile } diff --git a/old-tests/attribute/buildfile b/old-tests/attribute/buildfile index 6675894..7338641 100644 --- a/old-tests/attribute/buildfile +++ b/old-tests/attribute/buildfile @@ -6,10 +6,10 @@ #[foo=dir/file{bar}] # error: invalid attribute key #[foo] print hello # error: attributes before print -#[foo]./: # error: attributes before directory scope +#[foo]./ # error: attributes before directory scope #{ #} -#[foo]./: # error: attributes before target/scope +#[foo]./: # error: attributes before target scope #./: [foo] buildfile # error: attributes before prerequisites #import [foo] libz # error: attributes without variable diff --git a/old-tests/cli/lib/libtest/build/export.build b/old-tests/cli/lib/libtest/build/export.build index e8b12b3..f5e50c7 100644 --- a/old-tests/cli/lib/libtest/build/export.build +++ b/old-tests/cli/lib/libtest/build/export.build @@ -1,4 +1,4 @@ -$out_root/: +$out_root/ { include test/ } diff --git a/old-tests/cli/lib/libtest/test/buildfile b/old-tests/cli/lib/libtest/test/buildfile index a7667e6..4cf5ebe 100644 --- a/old-tests/cli/lib/libtest/test/buildfile +++ b/old-tests/cli/lib/libtest/test/buildfile @@ -6,7 +6,7 @@ cli.cxx{base}: cli{base} cli.options += -I $src_root --include-with-brackets -extra/: +extra/ { cxx{test} hxx{test}: cli{test} cli.options += --include-prefix test/extra --guard-prefix TEST_EXTRA \ diff --git a/old-tests/install/lib/libtest/build/export.build b/old-tests/install/lib/libtest/build/export.build index e8b12b3..f5e50c7 100644 --- a/old-tests/install/lib/libtest/build/export.build +++ b/old-tests/install/lib/libtest/build/export.build @@ -1,4 +1,4 @@ -$out_root/: +$out_root/ { include test/ } diff --git a/old-tests/install/lib/libtest/build/root.build b/old-tests/install/lib/libtest/build/root.build index 20536a2..9cf16a1 100644 --- a/old-tests/install/lib/libtest/build/root.build +++ b/old-tests/install/lib/libtest/build/root.build @@ -4,7 +4,7 @@ hxx{*}: extension = hxx ixx{*}: extension = ixx cxx{*}: extension = cxx -tests/: +tests/ { exe{*}: test = true install = false diff --git a/old-tests/postponed/buildfile b/old-tests/postponed/buildfile index 53873aa..437d85f 100644 --- a/old-tests/postponed/buildfile +++ b/old-tests/postponed/buildfile @@ -2,4 +2,4 @@ using cxx exe{driver}: cxx{driver} fsdir{$out_root/out} -./: exe{driver} +./: exe{driver} diff --git a/old-tests/scope/amalgamation/l1/build/bootstrap.build b/old-tests/scope/amalgamation/l1/build/bootstrap.build index 6bde838..81499d4 100644 --- a/old-tests/scope/amalgamation/l1/build/bootstrap.build +++ b/old-tests/scope/amalgamation/l1/build/bootstrap.build @@ -8,7 +8,7 @@ using config # If they are the same, then this scope will simply # be "upgraded". # -$src_root/../: +$src_root/../ { print 0: $project print 0: $src_base diff --git a/old-tests/scope/amalgamation/l1/buildfile b/old-tests/scope/amalgamation/l1/buildfile index 55d8c64..c6d3506 100644 --- a/old-tests/scope/amalgamation/l1/buildfile +++ b/old-tests/scope/amalgamation/l1/buildfile @@ -1,6 +1,6 @@ # Out of amalgamation. # -../../: +../../ { print -1: $project print -1: $src_base @@ -9,7 +9,7 @@ # In amalgamation. # -../s/: +../s/ { print 0: $project print 0: $src_base @@ -18,7 +18,7 @@ # In project. # -s/: +s/ { print 1: $project print 1: $src_base @@ -27,7 +27,7 @@ s/: # In sub-project. # -l2/s/: +l2/s/ { print 2: $project print 2: $src_base diff --git a/old-tests/semantics/include/includer b/old-tests/semantics/include/includer index 70527a5..700076e 100644 --- a/old-tests/semantics/include/includer +++ b/old-tests/semantics/include/includer @@ -2,9 +2,10 @@ include include includee1 include includee1 ../include/includee2 # includee1 is skipped include nested/includee3 -nested/: +nested/ { include includee5 include ../includee2 # skipped } -: + +./: diff --git a/old-tests/semantics/source/sourcer b/old-tests/semantics/source/sourcer index eb1310e..030e9bc 100644 --- a/old-tests/semantics/source/sourcer +++ b/old-tests/semantics/source/sourcer @@ -1,9 +1,9 @@ source source sourcee1 source sourcee1 ../source/sourcee2 -nested/: +nested/ { source sourcee3 source ../sourcee1 } -: +./: diff --git a/old-tests/test.sh b/old-tests/test.sh index f02291a..96a7ed3 100755 --- a/old-tests/test.sh +++ b/old-tests/test.sh @@ -24,6 +24,5 @@ test "variable/expansion" test "variable/null" test "variable/override" test "variable/prepend" -test "variable/qualified" test "variable/type" test "variable/type-pattern-append" diff --git a/old-tests/variable/override/buildfile b/old-tests/variable/override/buildfile index c090e81..2889f69 100644 --- a/old-tests/variable/override/buildfile +++ b/old-tests/variable/override/buildfile @@ -20,7 +20,7 @@ elif ($a == pr) print ". :" $v -d/: +d/ { if ($d_a == as) { diff --git a/old-tests/variable/override/p/buildfile b/old-tests/variable/override/p/buildfile index 527b9ae..5b84925 100644 --- a/old-tests/variable/override/p/buildfile +++ b/old-tests/variable/override/p/buildfile @@ -13,7 +13,7 @@ elif ($p_a == pr) print "p :" $v -d/: +d/ { if ($p_d_a == as) { diff --git a/old-tests/variable/qualified/buildfile b/old-tests/variable/qualified/buildfile deleted file mode 100644 index 870b808..0000000 --- a/old-tests/variable/qualified/buildfile +++ /dev/null @@ -1,27 +0,0 @@ -#v = (foo:) # error: variable name expected before ':' -#v = (:bar) # error: scope/target expected after ':' - -print (foo:bar) -print (foo :bar) -print (foo: bar) -print (foo : bar) -print (foo/: bar) -print (foo/file{fox}: bar) - -bar=bar -sub/: -{ - bar=Bar - fsdir{./}: bar=BAR - file{x}: bar=BBAARR -} - -print $(./:bar) -print $(sub/:bar) -print $(fsdir{sub/}:bar) -print $(sub/file{x}:bar) - -print $(sub/file{y}:bar) -print $(sup/:bar) - -./: diff --git a/old-tests/variable/qualified/test.out b/old-tests/variable/qualified/test.out deleted file mode 100644 index 5bf062e..0000000 --- a/old-tests/variable/qualified/test.out +++ /dev/null @@ -1,12 +0,0 @@ -foo:bar -foo:bar -foo:bar -foo:bar -foo/:bar -foo/file{fox}:bar -bar -Bar -BAR -BBAARR -Bar -bar diff --git a/old-tests/variable/qualified/test.sh b/old-tests/variable/qualified/test.sh deleted file mode 100755 index c745b76..0000000 --- a/old-tests/variable/qualified/test.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -b -q | diff --strip-trailing-cr -u test.out - diff --git a/old-tests/variable/type-pattern-append/buildfile b/old-tests/variable/type-pattern-append/buildfile index a91b340..348f70f 100644 --- a/old-tests/variable/type-pattern-append/buildfile +++ b/old-tests/variable/type-pattern-append/buildfile @@ -41,7 +41,7 @@ x = $(dir{./}:x5) print $(dir{./}:x5) x6 = [string] a -sub/: +sub/ { dir{*}: x6 += b dir{*}: x6 += [null] @@ -50,7 +50,7 @@ sub/: x7 = [string] b dir{*}: x7 =+ a -sub/: +sub/ { dir{*}: x7 += c print $(dir{./}:x7) diff --git a/old-tests/variable/type/buildfile b/old-tests/variable/type/buildfile index a22cddd..ef56f19 100644 --- a/old-tests/variable/type/buildfile +++ b/old-tests/variable/type/buildfile @@ -54,14 +54,14 @@ v4b =+ [uint64] 01 print $v4b # 2 v5a = 01 -sub/: +sub/ { v5a += [uint64] 01 print $v5a # 2 } v5b = 01 -sub/: +sub/ { v5b =+ [uint64] 01 print $v5b # 2 diff --git a/tests/eval/qual.test b/tests/eval/qual.test index f6e6592..341b315 100644 --- a/tests/eval/qual.test +++ b/tests/eval/qual.test @@ -12,7 +12,7 @@ $* <'print (foo/dir{}: bar)' >'dir{foo/}:bar' : scope : attribute : $* <'([string] foo:bar)' 2>>EOE != 0 -:1:2: error: attributes before qualified variable name +:1:2: error: attributes before target-qualified variable name EOE : leader diff --git a/tests/search/dir/testscript b/tests/search/dir/testscript index 4cd368b..e9ffa6a 100644 --- a/tests/search/dir/testscript +++ b/tests/search/dir/testscript @@ -30,14 +30,14 @@ $* <'./: bar/' >'bar' : existing-scope : $* <'bar' -bar/: x = y +bar/ x = y ./: bar/ EOI : existing-target-implied : $* <'bar' -dir{bar/}: x = y +dir{bar/}: x = y # @@ TMP ./: bar/ EOI diff --git a/tests/variable/override/testscript b/tests/variable/override/testscript index 9b8efdf..3529574 100644 --- a/tests/variable/override/testscript +++ b/tests/variable/override/testscript @@ -34,15 +34,15 @@ x = [string] 0 print $x - dir/: + dir/ { print $x } - dir/: x = [uint64] 1 + dir/ x = [uint64] 1 print $x - dir/: + dir/ { print $x } diff --git a/tests/variable/scope-specific/buildfile b/tests/variable/scope-specific/buildfile new file mode 100644 index 0000000..2f3de77 --- /dev/null +++ b/tests/variable/scope-specific/buildfile @@ -0,0 +1,5 @@ +# file : tests/variable/scope-specific/buildfile +# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +# license : MIT; see accompanying LICENSE file + +./: test{testscript} $b diff --git a/tests/variable/scope-specific/testscript b/tests/variable/scope-specific/testscript new file mode 100644 index 0000000..1f5f5fb --- /dev/null +++ b/tests/variable/scope-specific/testscript @@ -0,0 +1,54 @@ +# file : tests/variable/scope-specific/testscript +# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +# license : MIT; see accompanying LICENSE file + +.include ../../common.test + +: basic-line +: +$* <>EOO +x = x +foo/ x = X +foo/ [uint64] y=00 +print $x +print $(foo/ x) +print $(foo/ y) +EOI +x +X +0 +EOO + +: basic-block +: +$* <>EOO +x = x +foo/ +{ + x = X + [uint64] y = 00 + print $x +} +print $x +print $(foo/ y) +EOI +X +x +0 +EOO + +: expect-assignment +: +$* <>EOE != 0 +foo/ [uint64] y +EOI +:1:16: error: variable assignment expected instead of +EOE + +: unexpected-attribute +: +$* <>EOE != 0 +[uint64] foo/ y = 0 +EOI +:1:1: error: attributes before scope directory +EOE diff --git a/tests/variable/target-specific/buildfile b/tests/variable/target-specific/buildfile new file mode 100644 index 0000000..5a8178b --- /dev/null +++ b/tests/variable/target-specific/buildfile @@ -0,0 +1,5 @@ +# file : tests/variable/target-specific/buildfile +# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +# license : MIT; see accompanying LICENSE file + +./: test{testscript} $b diff --git a/tests/variable/target-specific/testscript b/tests/variable/target-specific/testscript new file mode 100644 index 0000000..e8cc9c2 --- /dev/null +++ b/tests/variable/target-specific/testscript @@ -0,0 +1,61 @@ +# file : tests/variable/scope-specific/testscript +# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +# license : MIT; see accompanying LICENSE file + +.include ../../common.test + +: basic-line +: +$* <>EOO +x = x +#./: x = X @@ TMP +dir{./}: x = X +file{foo}: [uint64] y=00 +sub/ +{ + file{foo}: z = Z +} +print $x +print $(./: x) +print $(file{foo}: y) +print $(sub/file{foo}: z) +EOI +x +X +0 +Z +EOO + +: eval-qual +: +$* <>EOO +print (foo:bar) +print (foo :bar) +print (foo: bar) +print (foo : bar) +print (foo/: bar) +print (foo/file{fox}: bar) +EOI +foo:bar +foo:bar +foo:bar +foo:bar +foo/:bar +foo/file{fox}:bar +EOO + +: eval-qual-name-expected +: +$* <>EOE != 0 +print (foo:) +EOI +:1:12: error: expected name instead of ')' +EOE + +: eval-qual-target-expected +: +$* <>EOE != 0 +print (:foo) +EOI +:1:8: error: expected target before ':' +EOE -- cgit v1.1