aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-11-23 14:58:30 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-11-23 14:58:30 +0200
commit79cb3221c2babe6f560f2e3e463e899631a32b33 (patch)
tree2135159931dde6acde213d6e8de1bdbd06d222d4
parentc6265603e0e98c19f8d81c8edd5a34a550063c02 (diff)
Implement few builtin functions that can operate on any value
type() null() empty () identity()
-rw-r--r--build2/buildfile1
-rw-r--r--build2/function12
-rw-r--r--build2/function.cxx2
-rw-r--r--build2/functions-builtin.cxx24
-rw-r--r--tests/function/buildfile2
-rw-r--r--tests/function/builtin/buildfile7
-rw-r--r--tests/function/builtin/testscript68
-rw-r--r--unit-tests/function/buildfile4
-rw-r--r--unit-tests/test/script/parser/buildfile2
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}}