diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2016-11-23 14:58:30 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2016-11-23 14:58:30 +0200 |
commit | 79cb3221c2babe6f560f2e3e463e899631a32b33 (patch) | |
tree | 2135159931dde6acde213d6e8de1bdbd06d222d4 | |
parent | c6265603e0e98c19f8d81c8edd5a34a550063c02 (diff) |
Implement few builtin functions that can operate on any value
type()
null()
empty ()
identity()
-rw-r--r-- | build2/buildfile | 1 | ||||
-rw-r--r-- | build2/function | 12 | ||||
-rw-r--r-- | build2/function.cxx | 2 | ||||
-rw-r--r-- | build2/functions-builtin.cxx | 24 | ||||
-rw-r--r-- | tests/function/buildfile | 2 | ||||
-rw-r--r-- | tests/function/builtin/buildfile | 7 | ||||
-rw-r--r-- | tests/function/builtin/testscript | 68 | ||||
-rw-r--r-- | unit-tests/function/buildfile | 4 | ||||
-rw-r--r-- | unit-tests/test/script/parser/buildfile | 2 |
9 files changed, 117 insertions, 5 deletions
diff --git a/build2/buildfile b/build2/buildfile index fa6faef..98494d8 100644 --- a/build2/buildfile +++ b/build2/buildfile @@ -15,6 +15,7 @@ exe{b}: \ {hxx ixx cxx}{ file } \ {hxx txx cxx}{ filesystem } \ {hxx cxx}{ function } \ + { cxx}{ functions-builtin } \ { cxx}{ functions-path } \ { cxx}{ functions-process-path } \ {hxx cxx}{ lexer } \ diff --git a/build2/function b/build2/function index 68edcde..192c4a3 100644 --- a/build2/function +++ b/build2/function @@ -37,7 +37,8 @@ namespace build2 // T - statically-typed (value_traits<T> must be defined) // names - untyped // value - any type - // T* - NULL-able argument (here T can be names, value). + // T* - NULL-able argument (here T can be names) + // value* - NULL-able any type (never NULL itself, use value::null) // optional<T> - optional argument (here T can be T*, names, value) // // Optional arguments must be last. In case of a failure the function is @@ -281,6 +282,15 @@ namespace build2 } }; + template <> + struct function_arg<value*>: function_arg<value> + { + static const bool null = true; + + static value* + cast (value* v) {return v;} // NULL indicator in value::null. + }; + template <typename T> struct function_arg<optional<T>>: function_arg<T> { diff --git a/build2/function.cxx b/build2/function.cxx index 46dc403..e76f0c2 100644 --- a/build2/function.cxx +++ b/build2/function.cxx @@ -295,6 +295,7 @@ namespace build2 // function_map functions; + void builtin_functions (); // functions-builtin.cxx void path_functions (); // functions-path.cxx void process_path_functions (); // functions-process-path.cxx @@ -302,6 +303,7 @@ namespace build2 { functions_init () { + builtin_functions (); path_functions (); process_path_functions (); } diff --git a/build2/functions-builtin.cxx b/build2/functions-builtin.cxx new file mode 100644 index 0000000..448bb53 --- /dev/null +++ b/build2/functions-builtin.cxx @@ -0,0 +1,24 @@ +// file : build2/functions-builtin.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include <build2/function> +#include <build2/variable> + +using namespace std; + +namespace build2 +{ + void + builtin_functions () + { + function_family f ("builtin"); + + f["type"] = [](value* v) {return v->type != nullptr ? v->type->name : "";}; + + f["null"] = [](value* v) {return v->null;}; + f["empty"] = [](value v) {return v.empty ();}; + + f["identity"] = [](value* v) {return move (*v);}; + } +} diff --git a/tests/function/buildfile b/tests/function/buildfile index 52288ca..6c26737 100644 --- a/tests/function/buildfile +++ b/tests/function/buildfile @@ -2,6 +2,6 @@ # copyright : Copyright (c) 2014-2016 Code Synthesis Ltd # license : MIT; see accompanying LICENSE file -d = path/ +d = builtin/ path/ ./: $d include $d diff --git a/tests/function/builtin/buildfile b/tests/function/builtin/buildfile new file mode 100644 index 0000000..5a49ad0 --- /dev/null +++ b/tests/function/builtin/buildfile @@ -0,0 +1,7 @@ +# file : tests/function/builtin/buildfile +# copyright : Copyright (c) 2014-2016 Code Synthesis Ltd +# license : MIT; see accompanying LICENSE file + +./: test{testscript} + +test{*}: test = $effect($build.path) diff --git a/tests/function/builtin/testscript b/tests/function/builtin/testscript new file mode 100644 index 0000000..1a4c5d1 --- /dev/null +++ b/tests/function/builtin/testscript @@ -0,0 +1,68 @@ +# file : tests/function/path/testscript +# copyright : Copyright (c) 2014-2016 Code Synthesis Ltd +# license : MIT; see accompanying LICENSE file + ++mkdir build ++cat <<EOI >>>build/bootstrap.build +project = test +amalgamation = +EOI + +test.options += -q --buildfile - noop + +: type +: +{ + $* <'print $type([string])' >'string' : empty-typed + $* <'print $type("")' >'' : empty-untyped + + $* <'print $type([string null])' >'string' : null-typed + $* <'print $type([null])' >'' : null-untyped + + $* <'print $type([string] abc)' >'string' : value-typed + $* <'print $type(abc)' >'' : value-untyped +} + +: null +: +{ + $* <'print $null("")' >'false' : empty + $* <'print $null(abc)' >'false' : value + $* <'print $null([null])' >'true' : null +} + +: empty +: +{ + $* <<EOI >'true' : empty-untyped + x = + print \$empty\(\$x) + EOI + + $* <'print $empty([string])' >'true' : empty-typed + $* <'print $empty(abc)' >'false' : name + $* <'print $empty(abc cxx{foo})' >'false' : names + $* <'print $empty([bool] false)' >'false' : bool +} + +: identity +: +{ + $* <'print $identity([string])' >''; + $* <'print $type($identity([string]))' >'string' : empty-typed + + $* <'print $identity("")' >'{}'; + $* <'print $type($identity(""))' >'' : empty-untyped + + $* <'print $identity([string null])' >'[null]'; + $* <'print $type($identity([string null]))' >'string' : null-typed + + $* <'print $identity([null])' >'[null]'; + $* <'print $type($identity([null]))' >'' : null-untyped + + $* <'print $identity([string] abc)' >'abc'; + $* <'print $type($identity([string] abc))' >'string' : null-typed + + $* <'print $identity(abc)' >'abc'; + $* <'print $type($identity(abc))' >'' : null-untyped +} diff --git a/unit-tests/function/buildfile b/unit-tests/function/buildfile index 1efc7e1..756fbcd 100644 --- a/unit-tests/function/buildfile +++ b/unit-tests/function/buildfile @@ -7,8 +7,8 @@ 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 functions-process-path algorithm search dump filesystem \ -config/{utility init operation} +functions-builtin functions-path functions-process-path algorithm search dump \ +filesystem config/{utility init operation} exe{driver}: cxx{driver} ../../build2/cxx{$src} $libs test{call syntax} diff --git a/unit-tests/test/script/parser/buildfile b/unit-tests/test/script/parser/buildfile index 5025e60..6cc319a 100644 --- a/unit-tests/test/script/parser/buildfile +++ b/unit-tests/test/script/parser/buildfile @@ -7,7 +7,7 @@ import libs = libbutl%lib{butl} src = token lexer parser diagnostics utility variable name context target \ scope prerequisite file module operation rule b-options algorithm search \ -filesystem function functions-path functions-process-path \ +filesystem function functions-builtin functions-path functions-process-path \ config/{utility init operation} dump types-parsers test/{target \ script/{token lexer parser script}} |