From 6b7075adc71104c5f6ad652b99fb753565eb67d8 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 18 Nov 2016 17:28:46 +0200 Subject: Add function machinery, implement path.normalize() Note that multi-argument functions are not yet "callable" since there is no support for value packs. --- unit-tests/function/buildfile | 14 +++++ unit-tests/function/call.test | 131 ++++++++++++++++++++++++++++++++++++++++ unit-tests/function/driver.cxx | 110 +++++++++++++++++++++++++++++++++ unit-tests/function/syntax.test | 29 +++++++++ 4 files changed, 284 insertions(+) create mode 100644 unit-tests/function/buildfile create mode 100644 unit-tests/function/call.test create mode 100644 unit-tests/function/driver.cxx create mode 100644 unit-tests/function/syntax.test (limited to 'unit-tests/function') diff --git a/unit-tests/function/buildfile b/unit-tests/function/buildfile new file mode 100644 index 0000000..6c1d346 --- /dev/null +++ b/unit-tests/function/buildfile @@ -0,0 +1,14 @@ +# file : unit-tests/function/buildfile +# copyright : Copyright (c) 2014-2016 Code Synthesis Ltd +# license : MIT; see accompanying LICENSE file + +#@@ Temporary until we get utility library support. +# +import libs = libbutl%lib{butl} +src = token lexer diagnostics utility variable name b-options types-parsers \ +context scope parser target operation rule prerequisite file module function \ +functions-path algorithm search dump filesystem config/{utility init operation} + +exe{driver}: cxx{driver} ../../build2/cxx{$src} $libs test{call syntax} + +include ../../build2/ diff --git a/unit-tests/function/call.test b/unit-tests/function/call.test new file mode 100644 index 0000000..d459300 --- /dev/null +++ b/unit-tests/function/call.test @@ -0,0 +1,131 @@ +# file : unit-tests/function/call.test +# copyright : Copyright (c) 2014-2016 Code Synthesis Ltd +# license : MIT; see accompanying LICENSE file + +: qual-implicit +: +$* <'print $dummy.dummy0()' >'abc' + +: qual-explicit +: +$* <'print $dummy.qual()' >'abc' + +: qual-fail +: +$* <'print $qual()' 2>>EOE != 0 +buildfile:1:8: error: unmatched call to qual\() +EOE + +: variadic +: +# @@ TMP: add some args +$* <'print $variadic([bool] true)' >'1' + +: fail +: +$* <'$fail()' 2>>EOE != 0 +error: failed +buildfile:1:2: info: while calling fail\() +EOE + +: fail-invalid-arg +: +$* <'$fail_arg(abc)' 2>>EOE != 0 +error: invalid argument: invalid uint64 value: 'abc' +buildfile:1:2: info: while calling fail_arg\() +EOE + +: no-match-name +: +$* <'$bogus()' 2>>EOE != 0 +buildfile:1:2: error: unmatched call to bogus\() +EOE + +: no-match-count +: +$* <'$dummy0(abc)' 2>>EOE != 0 +buildfile:1:2: error: unmatched call to dummy0\() + info: candidate: dummy0\(), qualified name dummy.dummy0 +EOE + +: no-match-type +: +$* <'$dummy1([uint64] 123)' 2>>EOE != 0 +buildfile:1:2: error: unmatched call to dummy1\(uint64) + info: candidate: dummy1\(string), qualified name dummy.dummy1 +EOE + +: ambig +: +$* <'$ambig(abc)' 2>>EOE != 0 +buildfile:1:2: error: ambiguous call to ambig\() + info: candidate: ambig\( [, uint64]), qualified name dummy.ambig + info: candidate: ambig\( [, string]), qualified name dummy.ambig +EOE + +: optional-absent +: +$* <'print $optional()' >'true' + +: optional-present +: +$* <'print $optional(abc)' >'false' + +: null-true +: +$* <'print $null([null])' >'true' + +: null-false +: +$* <'print $null(nonull)' >'false' + +: null-fail +: +$* <'$dummy1([string null])' 2>>EOE != 0 +error: invalid argument: null value +buildfile:1:2: info: while calling dummy1\(string) +EOE + +: print-call-1-untyped +: +$* <'$bogus(abc)' 2>>EOE != 0 +buildfile:1:2: error: unmatched call to bogus\() +EOE + +: print-call-1-typed +: +$* <'$bogus([uint64] 123)' 2>>EOE != 0 +buildfile:1:2: error: unmatched call to bogus\(uint64) +EOE + +#\ +@@ TMP +: print-call-2 +: +$* <'$bogus(abc, [uint64] 123)' 2>>EOE != 0 +buildfile:1:2: error: unmatched call to bogus\(, uint64) +EOE +#\ + +: print-fovl +: +$* <'$ambig([bool] true)' 2>>EOE != 0 +buildfile:1:2: error: unmatched call to ambig\(bool) + info: candidate: ambig\( [, uint64]), qualified name dummy.ambig + info: candidate: ambig\( [, string]), qualified name dummy.ambig +EOE + +: print-fovl-variadic +: +$* <'$variadic(abc)' 2>>EOE != 0 +buildfile:1:2: error: unmatched call to variadic\() + info: candidate: variadic\(bool [, ...]) +EOE + +: member-function +: +$* <'print $dummy.length([string] abc)' >'3' + +: data-member +: +$* <'print $dummy.type([name] cxx{foo})' >'cxx' diff --git a/unit-tests/function/driver.cxx b/unit-tests/function/driver.cxx new file mode 100644 index 0000000..ba51662 --- /dev/null +++ b/unit-tests/function/driver.cxx @@ -0,0 +1,110 @@ +// file : unit-tests/function/driver.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include + +#include +#include + +#include +#include +#include +#include +#include + +using namespace std; + +namespace build2 +{ + static const optional arg_bool[1] = + { + &value_traits::value_type + }; + + int + main () + { + init ("false", 1); // No build system driver, default verbosity. + reset (strings ()); // No command line variables. + + function_family f ("dummy"); + + f["fail"] = []() {error << "failed"; throw failed ();}; + f["fail_arg"] = [](names a) {return convert (move (a[0]));}; + + f["null"] = [](names* a) {return a == nullptr;}; + f["optional"] = [](optional a) {return !a;}; + + f["dummy0"] = []() {return "abc";}; + f["dummy1"] = [](string s) {return s;}; + + f["ambig"] = [](names a, optional) {return a;}; + f["ambig"] = [](names a, optional) {return a;}; + + f[".qual"] = []() {return "abc";}; + + f[".length"] = &string::size; // Member function. + f[".type"] = &name::type; // Data member. + + // Variadic function with first required argument of type bool. Returns + // number of arguments passed. + // + functions.insert ( + "variadic", + function_overload ( + nullptr, + 1, + function_overload::arg_variadic, + function_overload::types (arg_bool, 1), + [] (vector_view args, const function_overload&) + { + return value (static_cast (args.size ())); + })); + + // Dump arguments. + // + functions.insert ( + "dump", + function_overload ( + nullptr, + 0, + function_overload::arg_variadic, + function_overload::types (), + [] (vector_view args, const function_overload&) + { + for (value& a: args) + { + if (a.null) + cout << "[null]"; + else if (!a.empty ()) + { + names storage; + cout << reverse (a, storage); + } + cout << endl; + } + return value (nullptr); + })); + + try + { + scope& s (*global_scope); + + parser p; + p.parse_buildfile (cin, path ("buildfile"), s, s); + } + catch (const failed&) + { + return 1; + } + + return 0; + } +} + +int +main () +{ + return build2::main (); +} diff --git a/unit-tests/function/syntax.test b/unit-tests/function/syntax.test new file mode 100644 index 0000000..9e653c8 --- /dev/null +++ b/unit-tests/function/syntax.test @@ -0,0 +1,29 @@ +# file : unit-tests/function/syntax.test +# copyright : Copyright (c) 2014-2016 Code Synthesis Ltd +# license : MIT; see accompanying LICENSE file + +$* <'$dump()' >:'' : none +$* <'$dump( )' >:'' : none-in-spaces +$* <'$dump ()' >:'' : none-out-spaces +$* <'$dump("")' >'{}' : one-empty +$* <'$dump(a)' >'a' : one-single +$* <'$dump(a b c)' >'a b c' : one-list +$* <'$dump(d/t{x y z})' >'d/t{x} d/t{y} d/t{z}' : one-names + +$* <'print a$dummy1 ([string] b)c' >'abc' : concat + +: quoting +: Verify we can inhibit function call with quoting +: +$* <>EOO +foo = FOO +bar = BAR + +print \$foo"\(\$bar)" +print "\$foo"\(\$bar) +print "\$foo""\(\$bar)" +EOI +FOOBAR +FOOBAR +FOOBAR +EOO -- cgit v1.1