aboutsummaryrefslogtreecommitdiffstats
path: root/host/tests/nocscript_parser_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/tests/nocscript_parser_test.cpp')
-rw-r--r--host/tests/nocscript_parser_test.cpp167
1 files changed, 167 insertions, 0 deletions
diff --git a/host/tests/nocscript_parser_test.cpp b/host/tests/nocscript_parser_test.cpp
new file mode 100644
index 000000000..a9c25977e
--- /dev/null
+++ b/host/tests/nocscript_parser_test.cpp
@@ -0,0 +1,167 @@
+//
+// Copyright 2015 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include "../lib/rfnoc/nocscript/function_table.hpp"
+#include "../lib/rfnoc/nocscript/parser.hpp"
+#include <uhd/exception.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/floating_point_comparison.hpp>
+#include <boost/assign/list_of.hpp>
+#include <boost/foreach.hpp>
+#include <boost/bind.hpp>
+#include <boost/make_shared.hpp>
+#include <algorithm>
+#include <iostream>
+
+#include "nocscript_common.hpp"
+
+const int SPP_VALUE = 64;
+
+// Need those for the variable testing:
+expression::type_t variable_get_type(const std::string &var_name)
+{
+ if (var_name == "spp") {
+ std::cout << "Returning type for $spp..." << std::endl;
+ return expression::TYPE_INT;
+ }
+ if (var_name == "is_true") {
+ std::cout << "Returning type for $is_true..." << std::endl;
+ return expression::TYPE_BOOL;
+ }
+
+ throw uhd::syntax_error("Cannot infer type (unknown variable)");
+}
+
+expression_literal variable_get_value(const std::string &var_name)
+{
+ if (var_name == "spp") {
+ std::cout << "Returning value for $spp..." << std::endl;
+ return expression_literal(SPP_VALUE);
+ }
+ if (var_name == "is_true") {
+ std::cout << "Returning value for $is_true..." << std::endl;
+ return expression_literal(true);
+ }
+
+ throw uhd::syntax_error("Cannot read value (unknown variable)");
+}
+
+#define SETUP_FT_AND_PARSER() \
+ function_table::sptr ft = function_table::make(); \
+ parser::sptr p = parser::make( \
+ ft, \
+ boost::bind(&variable_get_type, _1), \
+ boost::bind(&variable_get_value, _1) \
+ );
+
+BOOST_AUTO_TEST_CASE(test_fail)
+{
+ SETUP_FT_AND_PARSER();
+
+ // Missing closing parens:
+ BOOST_REQUIRE_THROW(p->create_expr_tree("ADD1(1, "), uhd::syntax_error);
+ // Double comma:
+ BOOST_REQUIRE_THROW(p->create_expr_tree("ADD(1,, 2)"), uhd::syntax_error);
+ // No comma:
+ BOOST_REQUIRE_THROW(p->create_expr_tree("ADD(1 2)"), uhd::syntax_error);
+ // Double closing parens:
+ BOOST_REQUIRE_THROW(p->create_expr_tree("ADD(1, 2))"), uhd::syntax_error);
+ // Unknown function:
+ BOOST_REQUIRE_THROW(p->create_expr_tree("GLORPGORP(1, 2)"), uhd::syntax_error);
+}
+
+BOOST_AUTO_TEST_CASE(test_adds_no_vars)
+{
+ SETUP_FT_AND_PARSER();
+ BOOST_REQUIRE(ft->function_exists("ADD"));
+
+ const std::string line("ADD(1, ADD(2, ADD(3, 4)))");
+ expression::sptr e = p->create_expr_tree(line);
+ expression_literal result = e->eval();
+
+ BOOST_REQUIRE_EQUAL(result.infer_type(), expression::TYPE_INT);
+ BOOST_CHECK_EQUAL(result.get_int(), 1+2+3+4);
+}
+
+BOOST_AUTO_TEST_CASE(test_adds_with_vars)
+{
+ SETUP_FT_AND_PARSER();
+
+ const std::string line("ADD(1, ADD(2, $spp))");
+ expression::sptr e = p->create_expr_tree(line);
+ expression_literal result = e->eval();
+
+ BOOST_REQUIRE_EQUAL(result.infer_type(), expression::TYPE_INT);
+ BOOST_CHECK_EQUAL(result.get_int(), 1+2+SPP_VALUE);
+}
+
+BOOST_AUTO_TEST_CASE(test_fft_check)
+{
+ SETUP_FT_AND_PARSER();
+
+ const std::string line("GE($spp, 16) AND LE($spp, 4096) AND IS_PWR_OF_2($spp)");
+ expression::sptr e = p->create_expr_tree(line);
+ expression_literal result = e->eval();
+
+ BOOST_REQUIRE_EQUAL(result.infer_type(), expression::TYPE_BOOL);
+ BOOST_CHECK(result.get_bool());
+}
+
+BOOST_AUTO_TEST_CASE(test_pure_string)
+{
+ SETUP_FT_AND_PARSER();
+
+ // Eval all, return last expression
+ const std::string line("'foo foo', \"bar\"");
+ expression_literal result = p->create_expr_tree(line)->eval();
+
+ BOOST_REQUIRE_EQUAL(result.infer_type(), expression::TYPE_STRING);
+ BOOST_CHECK_EQUAL(result.get_string(), "bar");
+}
+
+int dummy_false_counter = 0;
+expression_literal dummy_false(expression_container::expr_list_type)
+{
+ dummy_false_counter++;
+ std::cout << "Running dummy/false statement." << std::endl;
+ return expression_literal(false);
+}
+
+BOOST_AUTO_TEST_CASE(test_multi_commmand)
+{
+ SETUP_FT_AND_PARSER();
+
+ ft->register_function(
+ "DUMMY",
+ boost::bind(&dummy_false, _1),
+ expression::TYPE_BOOL,
+ no_args
+ );
+
+ dummy_false_counter = 0;
+ p->create_expr_tree("DUMMY(), DUMMY(), DUMMY()")->eval();
+ BOOST_CHECK_EQUAL(dummy_false_counter, 3);
+
+ dummy_false_counter = 0;
+ p->create_expr_tree("DUMMY() AND DUMMY() AND DUMMY()")->eval();
+ BOOST_CHECK_EQUAL(dummy_false_counter, 1);
+
+ dummy_false_counter = 0;
+ p->create_expr_tree("DUMMY() OR DUMMY() OR DUMMY()")->eval();
+ BOOST_CHECK_EQUAL(dummy_false_counter, 3);
+}
+