aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/rfnoc/nocscript
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2019-08-20 10:00:47 -0700
committerMartin Braun <martin.braun@ettus.com>2019-11-26 12:16:25 -0800
commit7d69dcdcc318ccdf87038b732acbf2bf7c087b60 (patch)
tree8179f2f4a14be591d7c856f77f13687b45f9a454 /host/lib/rfnoc/nocscript
parent1ac6e6f56100a7e8186481ab0715937759f52737 (diff)
downloaduhd-7d69dcdcc318ccdf87038b732acbf2bf7c087b60.tar.gz
uhd-7d69dcdcc318ccdf87038b732acbf2bf7c087b60.tar.bz2
uhd-7d69dcdcc318ccdf87038b732acbf2bf7c087b60.zip
Remove proto-RFNoC files
This commit removes all files and parts of files that are used by proto-RFNoC only. uhd: Fix include CMakeLists.txt, add missing files
Diffstat (limited to 'host/lib/rfnoc/nocscript')
-rw-r--r--host/lib/rfnoc/nocscript/CMakeLists.txt27
-rw-r--r--host/lib/rfnoc/nocscript/block_iface.cpp236
-rw-r--r--host/lib/rfnoc/nocscript/block_iface.hpp87
-rw-r--r--host/lib/rfnoc/nocscript/expression.cpp380
-rw-r--r--host/lib/rfnoc/nocscript/expression.hpp360
-rw-r--r--host/lib/rfnoc/nocscript/function_table.cpp100
-rw-r--r--host/lib/rfnoc/nocscript/function_table.hpp75
-rwxr-xr-xhost/lib/rfnoc/nocscript/gen_basic_funcs.py465
-rw-r--r--host/lib/rfnoc/nocscript/parser.cpp357
-rw-r--r--host/lib/rfnoc/nocscript/parser.hpp37
10 files changed, 0 insertions, 2124 deletions
diff --git a/host/lib/rfnoc/nocscript/CMakeLists.txt b/host/lib/rfnoc/nocscript/CMakeLists.txt
deleted file mode 100644
index 2eeb984bf..000000000
--- a/host/lib/rfnoc/nocscript/CMakeLists.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Copyright 2015 Ettus Research LLC
-# Copyright 2018 Ettus Research, a National Instruments Company
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-#
-
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-LIBUHD_PYTHON_GEN_SOURCE(
- ${CMAKE_CURRENT_SOURCE_DIR}/gen_basic_funcs.py
- ${CMAKE_CURRENT_BINARY_DIR}/basic_functions.hpp
-)
-
-if(ENABLE_MANUAL)
- LIBUHD_PYTHON_GEN_SOURCE(
- ${CMAKE_CURRENT_SOURCE_DIR}/gen_basic_funcs.py
- ${CMAKE_BINARY_DIR}/docs/nocscript_functions.dox
- )
-endif(ENABLE_MANUAL)
-
-LIBUHD_APPEND_SOURCES(
- ${CMAKE_CURRENT_SOURCE_DIR}/expression.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/function_table.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/parser.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/block_iface.cpp
-)
diff --git a/host/lib/rfnoc/nocscript/block_iface.cpp b/host/lib/rfnoc/nocscript/block_iface.cpp
deleted file mode 100644
index f029c3324..000000000
--- a/host/lib/rfnoc/nocscript/block_iface.cpp
+++ /dev/null
@@ -1,236 +0,0 @@
-//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "block_iface.hpp"
-#include "function_table.hpp"
-#include <uhd/exception.hpp>
-#include <uhd/utils/log.hpp>
-#include <boost/assign.hpp>
-#include <boost/bind.hpp>
-#include <boost/format.hpp>
-
-#define UHD_NOCSCRIPT_LOG() UHD_LOGGER_TRACE("RFNOC")
-
-using namespace uhd::rfnoc;
-using namespace uhd::rfnoc::nocscript;
-
-block_iface::block_iface(block_ctrl_base* block_ptr) : _block_ptr(block_ptr)
-{
- function_table::sptr ft = function_table::make();
-
- // Add the SR_WRITE() function
- expression_function::argtype_list_type sr_write_args_wo_port =
- boost::assign::list_of(expression::TYPE_STRING)(expression::TYPE_INT);
- expression_function::argtype_list_type sr_write_args_w_port = boost::assign::list_of(
- expression::TYPE_STRING)(expression::TYPE_INT)(expression::TYPE_INT);
- ft->register_function("SR_WRITE",
- boost::bind(&block_iface::_nocscript__sr_write, this, _1),
- expression::TYPE_BOOL,
- sr_write_args_wo_port);
- ft->register_function("SR_WRITE",
- boost::bind(&block_iface::_nocscript__sr_write, this, _1),
- expression::TYPE_BOOL,
- sr_write_args_w_port);
-
- // Add read access to arguments ($foo)
- expression_function::argtype_list_type arg_set_args_wo_port =
- boost::assign::list_of(expression::TYPE_STRING)(expression::TYPE_INT);
- expression_function::argtype_list_type arg_set_args_w_port = boost::assign::list_of(
- expression::TYPE_STRING)(expression::TYPE_INT)(expression::TYPE_INT);
-#define REGISTER_ARG_SETTER(noctype, setter_func) \
- arg_set_args_wo_port[1] = expression::noctype; \
- arg_set_args_w_port[1] = expression::noctype; \
- ft->register_function("SET_ARG", \
- boost::bind(&block_iface::setter_func, this, _1), \
- expression::TYPE_BOOL, \
- arg_set_args_wo_port); \
- ft->register_function("SET_ARG", \
- boost::bind(&block_iface::setter_func, this, _1), \
- expression::TYPE_BOOL, \
- arg_set_args_w_port);
- REGISTER_ARG_SETTER(TYPE_INT, _nocscript__arg_set_int);
- REGISTER_ARG_SETTER(TYPE_STRING, _nocscript__arg_set_string);
- REGISTER_ARG_SETTER(TYPE_DOUBLE, _nocscript__arg_set_double);
- REGISTER_ARG_SETTER(TYPE_INT_VECTOR, _nocscript__arg_set_intvec);
-
-
- // Add read/write access to local variables
- expression_function::argtype_list_type set_var_args =
- boost::assign::list_of(expression::TYPE_STRING)(expression::TYPE_INT);
- const expression_function::argtype_list_type get_var_args =
- boost::assign::list_of(expression::TYPE_STRING);
-#define REGISTER_VAR_ACCESS(noctype, typestr) \
- set_var_args[1] = expression::noctype; \
- ft->register_function("SET_VAR", \
- boost::bind(&block_iface::_nocscript__var_set, this, _1), \
- expression::TYPE_BOOL, \
- set_var_args); \
- ft->register_function("GET_" #typestr, \
- boost::bind(&block_iface::_nocscript__var_get, this, _1), \
- expression::noctype, \
- get_var_args);
- REGISTER_VAR_ACCESS(TYPE_INT, INT);
- REGISTER_VAR_ACCESS(TYPE_STRING, STRING);
- REGISTER_VAR_ACCESS(TYPE_DOUBLE, DOUBLE);
- REGISTER_VAR_ACCESS(TYPE_INT_VECTOR, INT_VECTOR);
-
- // Create the parser
- _parser = parser::make(ft,
- boost::bind(&block_iface::_nocscript__arg_get_type, this, _1),
- boost::bind(&block_iface::_nocscript__arg_get_val, this, _1));
-}
-
-
-void block_iface::run_and_check(const std::string& code, const std::string& error_message)
-{
- boost::mutex::scoped_lock local_interpreter_lock(_lil_mutex);
-
- UHD_NOCSCRIPT_LOG() << "[NocScript] Executing and asserting code: " << code;
- expression::sptr e = _parser->create_expr_tree(code);
- expression_literal result = e->eval();
- if (not result.to_bool()) {
- if (error_message.empty()) {
- throw uhd::runtime_error(
- str(boost::format("[NocScript] Code returned false: %s") % code));
- } else {
- throw uhd::runtime_error(
- str(boost::format("[NocScript] Error: %s") % error_message));
- }
- }
-
- _vars.clear(); // We go out of scope, and so do NocScript variables
-}
-
-
-expression_literal block_iface::_nocscript__sr_write(
- expression_container::expr_list_type args)
-{
- const std::string reg_name = args[0]->eval().get_string();
- const uint32_t reg_val = uint32_t(args[1]->eval().get_int());
- size_t port = 0;
- if (args.size() == 3) {
- port = size_t(args[2]->eval().get_int());
- }
-
- bool result = true;
- try {
- UHD_NOCSCRIPT_LOG() << "[NocScript] Executing SR_WRITE() ";
- _block_ptr->sr_write(reg_name, reg_val, port);
- } catch (const uhd::exception& e) {
- UHD_LOGGER_ERROR("RFNOC")
- << boost::format("[NocScript] Error while executing SR_WRITE(%s, 0x%X):\n%s")
- % reg_name % reg_val % e.what();
- result = false;
- }
-
- return expression_literal(result);
-}
-
-expression::type_t block_iface::_nocscript__arg_get_type(const std::string& varname)
-{
- const std::string var_type = _block_ptr->get_arg_type(varname);
- if (var_type == "int") {
- return expression::TYPE_INT;
- } else if (var_type == "string") {
- return expression::TYPE_STRING;
- } else if (var_type == "double") {
- return expression::TYPE_DOUBLE;
- } else if (var_type == "int_vector") {
- UHD_THROW_INVALID_CODE_PATH(); // TODO
- } else {
- UHD_THROW_INVALID_CODE_PATH();
- }
-}
-
-expression_literal block_iface::_nocscript__arg_get_val(const std::string& varname)
-{
- const std::string var_type = _block_ptr->get_arg_type(varname);
- if (var_type == "int") {
- return expression_literal(_block_ptr->get_arg<int>(varname));
- } else if (var_type == "string") {
- return expression_literal(_block_ptr->get_arg<std::string>(varname));
- } else if (var_type == "double") {
- return expression_literal(_block_ptr->get_arg<double>(varname));
- } else if (var_type == "int_vector") {
- UHD_THROW_INVALID_CODE_PATH(); // TODO
- } else {
- UHD_THROW_INVALID_CODE_PATH();
- }
-}
-
-expression_literal block_iface::_nocscript__arg_set_int(
- const expression_container::expr_list_type& args)
-{
- const std::string var_name = args[0]->eval().get_string();
- const int val = args[1]->eval().get_int();
- size_t port = 0;
- if (args.size() == 3) {
- port = size_t(args[2]->eval().get_int());
- }
- UHD_NOCSCRIPT_LOG() << "[NocScript] Setting $" << var_name;
- _block_ptr->set_arg<int>(var_name, val, port);
- return expression_literal(true);
-}
-
-expression_literal block_iface::_nocscript__arg_set_string(
- const expression_container::expr_list_type& args)
-{
- const std::string var_name = args[0]->eval().get_string();
- const std::string val = args[1]->eval().get_string();
- size_t port = 0;
- if (args.size() == 3) {
- port = size_t(args[2]->eval().get_int());
- }
- UHD_NOCSCRIPT_LOG() << "[NocScript] Setting $" << var_name;
- _block_ptr->set_arg<std::string>(var_name, val, port);
- return expression_literal(true);
-}
-
-expression_literal block_iface::_nocscript__arg_set_double(
- const expression_container::expr_list_type& args)
-{
- const std::string var_name = args[0]->eval().get_string();
- const double val = args[1]->eval().get_double();
- size_t port = 0;
- if (args.size() == 3) {
- port = size_t(args[2]->eval().get_int());
- }
- UHD_NOCSCRIPT_LOG() << "[NocScript] Setting $" << var_name;
- _block_ptr->set_arg<double>(var_name, val, port);
- return expression_literal(true);
-}
-
-expression_literal block_iface::_nocscript__arg_set_intvec(
- const expression_container::expr_list_type&)
-{
- UHD_THROW_INVALID_CODE_PATH();
-}
-
-block_iface::sptr block_iface::make(uhd::rfnoc::block_ctrl_base* block_ptr)
-{
- return sptr(new block_iface(block_ptr));
-}
-
-expression_literal block_iface::_nocscript__var_get(
- const expression_container::expr_list_type& args)
-{
- expression_literal expr = _vars[args[0]->eval().get_string()];
- // std::cout << "[NocScript] Getting var " << args[0]->eval().get_string() << " == "
- // << expr ; std::cout << "[NocScript] Type " << expr.infer_type() ; return
- // _vars[args[0]->eval().get_string()];
- return expr;
-}
-
-expression_literal block_iface::_nocscript__var_set(
- const expression_container::expr_list_type& args)
-{
- _vars[args[0]->eval().get_string()] = args[1]->eval();
- // std::cout << "[NocScript] Set var " << args[0]->eval().get_string() << " to " <<
- // _vars[args[0]->eval().get_string()] ; std::cout << "[NocScript] Type " <<
- // _vars[args[0]->eval().get_string()].infer_type() ;
- return expression_literal(true);
-}
diff --git a/host/lib/rfnoc/nocscript/block_iface.hpp b/host/lib/rfnoc/nocscript/block_iface.hpp
deleted file mode 100644
index 9d13fd4ab..000000000
--- a/host/lib/rfnoc/nocscript/block_iface.hpp
+++ /dev/null
@@ -1,87 +0,0 @@
-//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "expression.hpp"
-#include "parser.hpp"
-#include <uhd/rfnoc/block_ctrl_base.hpp>
-#include <boost/thread/mutex.hpp>
-
-#ifndef INCLUDED_LIBUHD_NOCSCRIPT_BLOCK_IFACE_HPP
-# define INCLUDED_LIBUHD_NOCSCRIPT_BLOCK_IFACE_HPP
-
-namespace uhd { namespace rfnoc { namespace nocscript {
-
-/*! NocScript / Block interface class.
- *
- * This class only exists as a member of an rfnoc::block_ctrl_base class.
- * It should never be instantiated anywhere else. It is used to execute
- * NocScript function calls that require access to the original block
- * controller class.
- */
-class block_iface
-{
-public:
- typedef boost::shared_ptr<block_iface> sptr;
-
- static sptr make(uhd::rfnoc::block_ctrl_base* block_ptr);
-
- block_iface(uhd::rfnoc::block_ctrl_base* block_ptr);
-
- /*! Execute \p code and make sure it returns 'true'.
- *
- * \param code Must be a valid NocScript expression that returns a boolean value.
- * If it returns false, this is interpreted as failure.
- * \param error_message If the expression fails, this error message is printed.
- * \throws uhd::runtime_error if the expression returns false.
- * \throws uhd::syntax_error if the expression is invalid.
- */
- void run_and_check(const std::string& code, const std::string& error_message = "");
-
-private:
- //! For the local interpreter lock (lil)
- boost::mutex _lil_mutex;
-
- //! Wrapper for block_ctrl_base::sr_write, so we can call it from within NocScript
- expression_literal _nocscript__sr_write(expression_container::expr_list_type);
-
- //! Argument type getter that can be used within NocScript
- expression::type_t _nocscript__arg_get_type(const std::string& argname);
-
- //! Argument value getter that can be used within NocScript
- expression_literal _nocscript__arg_get_val(const std::string& argname);
-
- //! Argument value setters:
- expression_literal _nocscript__arg_set_int(
- const expression_container::expr_list_type&);
- expression_literal _nocscript__arg_set_string(
- const expression_container::expr_list_type&);
- expression_literal _nocscript__arg_set_double(
- const expression_container::expr_list_type&);
- expression_literal _nocscript__arg_set_intvec(
- const expression_container::expr_list_type&);
-
- //! Variable value getter
- expression_literal _nocscript__var_get(const expression_container::expr_list_type&);
-
- //! Variable value setter
- expression_literal _nocscript__var_set(const expression_container::expr_list_type&);
-
- //! Raw pointer to the block class. Note that since block_iface may
- // only live as a member of a block_ctrl_base, we don't really need
- // the reference counting.
- uhd::rfnoc::block_ctrl_base* _block_ptr;
-
- //! Pointer to the parser object
- parser::sptr _parser;
-
- //! Container for scoped variables
- std::map<std::string, expression_literal> _vars;
-};
-
-}}} /* namespace uhd::rfnoc::nocscript */
-
-#endif /* INCLUDED_LIBUHD_NOCSCRIPT_BLOCK_IFACE_HPP */
diff --git a/host/lib/rfnoc/nocscript/expression.cpp b/host/lib/rfnoc/nocscript/expression.cpp
deleted file mode 100644
index 5e03485be..000000000
--- a/host/lib/rfnoc/nocscript/expression.cpp
+++ /dev/null
@@ -1,380 +0,0 @@
-//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "expression.hpp"
-#include "function_table.hpp"
-#include <uhd/utils/cast.hpp>
-#include <boost/algorithm/string.hpp>
-#include <boost/format.hpp>
-
-using namespace uhd::rfnoc::nocscript;
-
-std::map<expression::type_t, std::string> expression::type_repr{{TYPE_INT, "INT"},
- {TYPE_DOUBLE, "DOUBLE"},
- {TYPE_STRING, "STRING"},
- {TYPE_BOOL, "BOOL"},
- {TYPE_INT_VECTOR, "INT_VECTOR"}};
-
-/********************************************************************
- * Literal expressions (constants)
- *******************************************************************/
-expression_literal::expression_literal(
- const std::string token_val, expression::type_t type)
- : _bool_val(false), _int_val(0), _double_val(0.0), _val(token_val), _type(type)
-{
- switch (_type) {
- case expression::TYPE_STRING:
- // Remove the leading and trailing quotes:
- _val = _val.substr(1, _val.size() - 2);
- break;
-
- case expression::TYPE_INT:
- if (_val.substr(0, 2) == "0x") {
- _int_val = uhd::cast::hexstr_cast<int>(_val);
- } else {
- _int_val = std::stoi(_val);
- }
- break;
-
- case expression::TYPE_DOUBLE:
- _double_val = std::stod(_val);
- break;
-
- case expression::TYPE_BOOL:
- if (boost::to_upper_copy(_val) == "TRUE") {
- _bool_val = true;
- } else {
- // lexical cast to bool is too picky
- _bool_val = (std::stoi(_val) != 0);
- }
- break;
-
- case expression::TYPE_INT_VECTOR: {
- std::string str_vec = _val.substr(1, _val.size() - 2);
- std::vector<std::string> subtoken_list;
- boost::split(
- subtoken_list, str_vec, boost::is_any_of(", "), boost::token_compress_on);
- for (const std::string& t : subtoken_list) {
- _int_vector_val.push_back(std::stoi(t));
- }
- break;
- }
-
- default:
- UHD_THROW_INVALID_CODE_PATH();
- }
-}
-
-expression_literal::expression_literal(bool b)
- : _bool_val(b), _int_val(0), _double_val(0.0), _val(""), _type(expression::TYPE_BOOL)
-{
- // nop
-}
-
-expression_literal::expression_literal(int i)
- : _bool_val(false)
- , _int_val(i)
- , _double_val(0.0)
- , _val("")
- , _type(expression::TYPE_INT)
-{
- // nop
-}
-
-expression_literal::expression_literal(double d)
- : _bool_val(false)
- , _int_val(0)
- , _double_val(d)
- , _val("")
- , _type(expression::TYPE_DOUBLE)
-{
- // nop
-}
-
-expression_literal::expression_literal(const std::string& s)
- : _bool_val(false)
- , _int_val(0)
- , _double_val(0.0)
- , _val(s)
- , _type(expression::TYPE_STRING)
-{
- // nop
-}
-
-expression_literal::expression_literal(const std::vector<int> v)
- : _bool_val(false)
- , _int_val(0)
- , _double_val(0.0)
- , _int_vector_val(v)
- , _val("")
- , _type(expression::TYPE_INT_VECTOR)
-{
- // nop
-}
-
-bool expression_literal::to_bool() const
-{
- switch (_type) {
- case TYPE_INT:
- return bool(std::stoi(_val));
- case TYPE_STRING:
- return not _val.empty();
- case TYPE_DOUBLE:
- return bool(std::stod(_val));
- case TYPE_BOOL:
- return _bool_val;
- case TYPE_INT_VECTOR:
- return not _int_vector_val.empty();
- default:
- UHD_THROW_INVALID_CODE_PATH();
- }
-}
-
-int expression_literal::get_int() const
-{
- if (_type != TYPE_INT) {
- throw uhd::type_error("Cannot call get_int() on non-int value.");
- }
-
- return _int_val;
-}
-
-double expression_literal::get_double() const
-{
- if (_type != TYPE_DOUBLE) {
- throw uhd::type_error("Cannot call get_double() on non-double value.");
- }
-
- return _double_val;
-}
-
-std::string expression_literal::get_string() const
-{
- if (_type != TYPE_STRING) {
- throw uhd::type_error("Cannot call get_string() on non-string value.");
- }
-
- return _val;
-}
-
-bool expression_literal::get_bool() const
-{
- if (_type != TYPE_BOOL) {
- throw uhd::type_error("Cannot call get_bool() on non-boolean value.");
- }
-
- return _bool_val;
-}
-
-std::vector<int> expression_literal::get_int_vector() const
-{
- if (_type != TYPE_INT_VECTOR) {
- throw uhd::type_error("Cannot call get_bool() on non-boolean value.");
- }
-
- return _int_vector_val;
-}
-
-std::string expression_literal::repr() const
-{
- switch (_type) {
- case TYPE_INT:
- return std::to_string(_int_val);
- case TYPE_STRING:
- return _val;
- case TYPE_DOUBLE:
- return std::to_string(_double_val);
- case TYPE_BOOL:
- return _bool_val ? "TRUE" : "FALSE";
- case TYPE_INT_VECTOR: {
- std::stringstream sstr;
- sstr << "[";
- for (size_t i = 0; i < _int_vector_val.size(); i++) {
- if (i > 0) {
- sstr << ", ";
- }
- sstr << _int_vector_val[i];
- }
- sstr << "]";
- return sstr.str();
- }
- default:
- UHD_THROW_INVALID_CODE_PATH();
- }
-}
-
-bool expression_literal::operator==(const expression_literal& rhs) const
-{
- if (rhs.infer_type() != _type) {
- return false;
- }
-
- switch (_type) {
- case TYPE_INT:
- return get_int() == rhs.get_int();
- case TYPE_STRING:
- return get_string() == rhs.get_string();
- case TYPE_DOUBLE:
- return get_double() == rhs.get_double();
- case TYPE_BOOL:
- return get_bool() == rhs.get_bool();
- default:
- UHD_THROW_INVALID_CODE_PATH();
- }
-}
-
-/********************************************************************
- * Containers
- *******************************************************************/
-expression_container::sptr expression_container::make()
-{
- return sptr(new expression_container);
-}
-
-expression::type_t expression_container::infer_type() const
-{
- if (_combiner == COMBINE_OR or _combiner == COMBINE_AND) {
- return TYPE_BOOL;
- }
-
- if (_sub_exprs.empty()) {
- return TYPE_BOOL;
- }
-
- return _sub_exprs.back()->infer_type();
-}
-
-void expression_container::add(expression::sptr new_expr)
-{
- _sub_exprs.push_back(new_expr);
-}
-
-bool expression_container::empty() const
-{
- return _sub_exprs.empty();
-}
-
-void expression_container::set_combiner_safe(const combiner_type c)
-{
- if (_combiner == COMBINE_NOTSET) {
- _combiner = c;
- return;
- }
-
- throw uhd::syntax_error("Attempting to override combiner type");
-}
-
-expression_literal expression_container::eval()
-{
- if (_sub_exprs.empty()) {
- return expression_literal(true);
- }
-
- expression_literal ret_val;
- for (const expression::sptr& sub_expr : _sub_exprs) {
- ret_val = sub_expr->eval();
- if (_combiner == COMBINE_AND and ret_val.to_bool() == false) {
- return ret_val;
- }
- if (_combiner == COMBINE_OR and ret_val.to_bool() == true) {
- return ret_val;
- }
- // For ALL, we return the last one, so just overwrite it
- }
- return ret_val;
-}
-
-/********************************************************************
- * Functions
- *******************************************************************/
-std::string expression_function::to_string(
- const std::string& name, const argtype_list_type& types)
-{
- std::string s = name;
- int arg_count = 0;
- for (const expression::type_t type : types) {
- if (arg_count == 0) {
- s += "(";
- } else {
- s += ", ";
- }
- s += type_repr[type];
- arg_count++;
- }
- s += ")";
-
- return s;
-}
-
-expression_function::expression_function(
- const std::string& name, const function_table::sptr func_table)
- : _name(name), _func_table(func_table)
-{
- _combiner = COMBINE_ALL;
- if (not _func_table->function_exists(_name)) {
- throw uhd::syntax_error(str(boost::format("Unknown function: %s") % _name));
- }
-}
-
-void expression_function::add(expression::sptr new_expr)
-{
- expression_container::add(new_expr);
- _arg_types.push_back(new_expr->infer_type());
-}
-
-expression::type_t expression_function::infer_type() const
-{
- return _func_table->get_type(_name, _arg_types);
-}
-
-expression_literal expression_function::eval()
-{
- return _func_table->eval(_name, _arg_types, _sub_exprs);
-}
-
-
-std::string expression_function::repr() const
-{
- return to_string(_name, _arg_types);
-}
-
-expression_function::sptr expression_function::make(
- const std::string& name, const function_table::sptr func_table)
-{
- return sptr(new expression_function(name, func_table));
-}
-
-/********************************************************************
- * Variables
- *******************************************************************/
-expression_variable::expression_variable(const std::string& token_val,
- type_getter_type type_getter,
- value_getter_type value_getter)
- : _type_getter(type_getter), _value_getter(value_getter)
-{
- // We can assume this is true because otherwise, it's not a valid token:
- UHD_ASSERT_THROW(not token_val.empty() and token_val[0] == '$');
-
- _varname = token_val.substr(1);
-}
-
-expression::type_t expression_variable::infer_type() const
-{
- return _type_getter(_varname);
-}
-
-expression_literal expression_variable::eval()
-{
- return _value_getter(_varname);
-}
-
-expression_variable::sptr expression_variable::make(const std::string& token_val,
- type_getter_type type_getter,
- value_getter_type value_getter)
-{
- return sptr(new expression_variable(token_val, type_getter, value_getter));
-}
diff --git a/host/lib/rfnoc/nocscript/expression.hpp b/host/lib/rfnoc/nocscript/expression.hpp
deleted file mode 100644
index 309741295..000000000
--- a/host/lib/rfnoc/nocscript/expression.hpp
+++ /dev/null
@@ -1,360 +0,0 @@
-//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/exception.hpp>
-#include <boost/function.hpp>
-#include <boost/make_shared.hpp>
-#include <boost/shared_ptr.hpp>
-#include <map>
-#include <vector>
-
-#ifndef INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_EXPR_HPP
-# define INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_EXPR_HPP
-
-namespace uhd { namespace rfnoc { namespace nocscript {
-
-// Forward declaration for expression::eval()
-class expression_literal;
-
-/*! Virtual base class for Noc-Script expressions.
- */
-class expression
-{
-public:
- typedef boost::shared_ptr<expression> sptr;
-
- //! All the possible return types for expressions within Noc-Script
- enum type_t { TYPE_INT, TYPE_DOUBLE, TYPE_STRING, TYPE_BOOL, TYPE_INT_VECTOR };
-
- // TODO make this a const and fix the [] usage
- static std::map<type_t, std::string> type_repr;
-
- //! Returns the type of this expression without evaluating it
- virtual type_t infer_type() const = 0;
-
- //! Evaluate current expression and return its return value
- virtual expression_literal eval() = 0;
-};
-
-/*! Literal (constant) expression class
- *
- * A literal is any value that is literally given in the NoC-Script
- * source code, such as '5', '"FOO"', or '2.3'.
- */
-class expression_literal : public expression
-{
-public:
- typedef boost::shared_ptr<expression_literal> sptr;
-
- template <typename expr_type> static sptr make(expr_type x)
- {
- return boost::make_shared<expression_literal>(x);
- };
-
- /*! Generate the literal expression from its token string representation.
- * This includes markup, e.g. a string would still have the quotes, and
- * a hex value would still have leading 0x.
- */
- expression_literal(const std::string token_val, expression::type_t type);
-
- //! Create a boolean literal expression from a C++ bool.
- expression_literal(bool b = false);
- //! Create an integer literal expression from a C++ int.
- expression_literal(int i);
- //! Create a double literal expression from a C++ double.
- expression_literal(double d);
- //! Create a string literal expression from a C++ string.
- expression_literal(const std::string& s);
- //! Create an int vector literal expression from a C++ vector<int>.
- expression_literal(std::vector<int> v);
-
- virtual ~expression_literal() {}
-
- expression::type_t infer_type() const
- {
- return _type;
- }
-
- //! Literals aren't evaluated as such, so the evaluation
- // simply returns a copy of itself.
- expression_literal eval()
- {
- return *this; // TODO make sure this is copy
- }
-
- /*! A 'type cast' to bool. Cast rules are similar to most
- * scripting languages:
- * - Integers and doubles are false if zero, true otherwise
- * - Strings are false if empty, true otherwise
- * - Vectors are false if empty, true otherwise
- */
- bool to_bool() const;
-
- /*! Convenience function to typecast to C++ int
- *
- * Note that the current type must be TYPE_INT.
- *
- * \return C++ int representation of current literal
- * \throws uhd::type_error if type didn't match
- */
- int get_int() const;
-
- /*! Convenience function to typecast to C++ double
- *
- * Note that the current type must be TYPE_DOUBLE.
- *
- * \return C++ double representation of current literal
- * \throws uhd::type_error if type didn't match
- */
- double get_double() const;
-
- /*! Convenience function to typecast to C++ std::string.
- *
- * Note that the current type must be TYPE_STRING.
- *
- * \return String representation of current literal.
- * \throws uhd::type_error if type didn't match.
- */
- std::string get_string() const;
-
- /*! Convenience function to typecast to C++ int vector.
- *
- * Note that the current type must be TYPE_INT_VECTOR.
- *
- * \return String representation of current literal.
- * \throws uhd::type_error if type didn't match.
- */
- std::vector<int> get_int_vector() const;
-
- /*! Convenience function to typecast to C++ bool.
- *
- * Note that the current type must be TYPE_BOOL.
- * See also expression_literal::to_bool() for a type-cast
- * style function.
- *
- * \return bool representation of current literal.
- * \throws uhd::type_error if type didn't match.
- */
- bool get_bool() const;
-
- //! String representation
- std::string repr() const;
-
- bool operator==(const expression_literal& rhs) const;
-
-private:
- //! For TYPE_BOOL
- bool _bool_val;
-
- //! For TYPE_INT
- int _int_val;
-
- //! For TYPE_DOUBLE
- double _double_val;
-
- //! For TYPE_INT_VECTOR
- std::vector<int> _int_vector_val;
-
- //! Store the token value
- std::string _val;
-
- //! Current expression type
- expression::type_t _type;
-};
-
-UHD_INLINE std::ostream& operator<<(std::ostream& out, const expression_literal& l)
-{
- out << l.repr();
- return out;
-}
-
-UHD_INLINE std::ostream& operator<<(std::ostream& out, const expression_literal::sptr& l)
-{
- out << l->repr();
- return out;
-}
-
-/*! Contains multiple (sub-)expressions.
- */
-class expression_container : public expression
-{
-public:
- typedef boost::shared_ptr<expression_container> sptr;
- typedef std::vector<expression::sptr> expr_list_type;
-
- //! Return an sptr to an empty container
- static sptr make();
-
- //! List of valid combination types (see expression_container::eval()).
- enum combiner_type { COMBINE_ALL, COMBINE_AND, COMBINE_OR, COMBINE_NOTSET };
-
- //! Create an empty container
- expression_container() : _combiner(COMBINE_NOTSET){};
- virtual ~expression_container() {}
-
- /*! Type-deduction rules for containers are:
- * - If the combination type is COMBINE_ALL or COMBINE_AND,
- * return value must be TYPE_BOOL
- * - In all other cases, we return the last expression return
- * value, and hence its type is relevant
- */
- expression::type_t infer_type() const;
-
- /*! Add another expression container to this container.
- */
- virtual void add(expression::sptr new_expr);
-
- virtual bool empty() const;
-
- void set_combiner_safe(const combiner_type c);
-
- void set_combiner(const combiner_type c)
- {
- _combiner = c;
- };
-
- combiner_type get_combiner() const
- {
- return _combiner;
- };
-
- /*! Evaluate a container by evaluating its sub-expressions.
- *
- * If a container contains multiple sub-expressions, the rules
- * for evaluating them depend on the combiner_type:
- * - COMBINE_ALL: Run all the sub-expressions and return the last
- * expression's return value
- * - COMBINE_AND: Run sub-expressions, in order, until one of them
- * returns false. Following expressions are not evaluated (like
- * most C++ compilers).
- * - COMBINE_OR: Run sub-expressions, in order, until one of them
- * returns true. Following expressions are not evaluated.
- *
- * In the special case where no sub-expressions are contained, always
- * returns true.
- */
- virtual expression_literal eval();
-
-protected:
- //! Store all the sub-expressions, in order
- expr_list_type _sub_exprs;
- combiner_type _combiner;
-};
-
-// Forward declaration:
-class function_table;
-/*! A function call is a special type of container.
- *
- * All arguments are sub-expressions. The combiner type is
- * always COMBINE_ALL in this case (changing the combiner type
- * does not affect anything).
- *
- * The actual function maps to a C++ function available through
- * a uhd::rfnoc::nocscript::function_table object.
- *
- * The recommended to use this is:
- * 1. Create a function object giving its name (e.g. ADD)
- * 2. Use the add() method to add all the function arguments
- * in the right order (left to right).
- * 3. Once step 2 is complete, the function object can be used.
- * Call infer_type() to get the return value, if required.
- * 4. Calling eval() will call into the function table. The
- * argument expressions are evaluated, if so required, inside
- * the function (lazy evalulation). Functions do not need
- * to evaluate arguments.
- */
-class expression_function : public expression_container
-{
-public:
- typedef boost::shared_ptr<expression_function> sptr;
- typedef std::vector<expression::type_t> argtype_list_type;
-
- //! Return an sptr to a function object without args
- static sptr make(
- const std::string& name, const boost::shared_ptr<function_table> func_table);
-
- static std::string to_string(const std::string& name, const argtype_list_type& types);
-
- expression_function(
- const std::string& name, const boost::shared_ptr<function_table> func_table);
- ~expression_function() {}
-
- //! Add an argument expression
- virtual void add(expression::sptr new_expr);
-
- /*! Looks up the function type in the function table.
- *
- * Note that this will only work after all arguments have been
- * added, as they are also used to look up a function's type in the
- * function table.
- */
- expression::type_t infer_type() const;
-
- /*! Evaluate all arguments, then the function itself.
- */
- expression_literal eval();
-
- //! String representation
- std::string repr() const;
-
-private:
- std::string _name;
- const boost::shared_ptr<function_table> _func_table;
- std::vector<expression::type_t> _arg_types;
-};
-
-
-/*! Variable expression
- *
- * Variables are like literals, only their type and value aren't known
- * at parse-time. Instead, we provide a function object to look up
- * variable's types and value.
- */
-class expression_variable : public expression
-{
-public:
- typedef boost::shared_ptr<expression_variable> sptr;
- typedef boost::function<expression::type_t(const std::string&)> type_getter_type;
- typedef boost::function<expression_literal(const std::string&)> value_getter_type;
-
- static sptr make(const std::string& token_val,
- type_getter_type type_getter,
- value_getter_type value_getter);
-
- /*! Create a variable object from its token value
- * (e.g. '$spp', i.e. including the '$' symbol). The variable
- * does not have to exist at this point.
- */
- expression_variable(const std::string& token_val,
- type_getter_type type_getter,
- value_getter_type value_getter);
-
- virtual ~expression_variable() {}
-
- /*! Looks up the variable type in the variable table.
- *
- * \throws Depending on \p type_getter, this may throw when the variable does not
- * exist. Recommended behaviour is to throw uhd::syntax_error.
- */
- expression::type_t infer_type() const;
-
- /*! Look up a variable's value in the variable table.
- *
- * \throws Depending on \p value_getter, this may throw when the variable does not
- * exist. Recommended behaviour is to throw uhd::syntax_error.
- */
- expression_literal eval();
-
-private:
- std::string _varname;
- type_getter_type _type_getter;
- value_getter_type _value_getter;
-};
-
-}}} /* namespace uhd::rfnoc::nocscript */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_EXPR_HPP */
diff --git a/host/lib/rfnoc/nocscript/function_table.cpp b/host/lib/rfnoc/nocscript/function_table.cpp
deleted file mode 100644
index 57e32363d..000000000
--- a/host/lib/rfnoc/nocscript/function_table.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "function_table.hpp"
-#include "basic_functions.hpp"
-#include <boost/bind.hpp>
-#include <boost/format.hpp>
-#include <map>
-
-using namespace uhd::rfnoc::nocscript;
-
-class function_table_impl : public function_table
-{
-public:
- struct function_info
- {
- expression::type_t return_type;
- function_ptr function;
-
- function_info() : return_type(expression::TYPE_INT){};
- function_info(
- const expression::type_t return_type_, const function_ptr& function_)
- : return_type(return_type_), function(function_){};
- };
- // Should be an unordered_map... sigh, we'll get to C++11 someday.
- typedef std::map<std::string,
- std::map<expression_function::argtype_list_type, function_info>>
- table_type;
-
- /************************************************************************
- * Structors
- ***********************************************************************/
- function_table_impl()
- {
- _REGISTER_ALL_FUNCS();
- }
-
- ~function_table_impl(){};
-
-
- /************************************************************************
- * Interface implementation
- ***********************************************************************/
- bool function_exists(const std::string& name) const
- {
- return bool(_table.count(name));
- }
-
- bool function_exists(const std::string& name,
- const expression_function::argtype_list_type& arg_types) const
- {
- table_type::const_iterator it = _table.find(name);
- return (it != _table.end()) and bool(it->second.count(arg_types));
- }
-
- expression::type_t get_type(const std::string& name,
- const expression_function::argtype_list_type& arg_types) const
- {
- table_type::const_iterator it = _table.find(name);
- if (it == _table.end() or (it->second.find(arg_types) == it->second.end())) {
- throw uhd::syntax_error(
- str(boost::format("Unable to retrieve return value for function %s")
- % expression_function::to_string(name, arg_types)));
- }
- return it->second.find(arg_types)->second.return_type;
- }
-
- expression_literal eval(const std::string& name,
- const expression_function::argtype_list_type& arg_types,
- expression_container::expr_list_type& arguments)
- {
- if (not function_exists(name, arg_types)) {
- throw uhd::syntax_error(
- str(boost::format("Cannot eval() function %s, not a known signature")
- % expression_function::to_string(name, arg_types)));
- }
-
- return _table[name][arg_types].function(arguments);
- }
-
- void register_function(const std::string& name,
- const function_table::function_ptr& ptr,
- const expression::type_t return_type,
- const expression_function::argtype_list_type& sig)
- {
- _table[name][sig] = function_info(return_type, ptr);
- }
-
-private:
- table_type _table;
-};
-
-function_table::sptr function_table::make()
-{
- return sptr(new function_table_impl());
-}
diff --git a/host/lib/rfnoc/nocscript/function_table.hpp b/host/lib/rfnoc/nocscript/function_table.hpp
deleted file mode 100644
index 63125ab1b..000000000
--- a/host/lib/rfnoc/nocscript/function_table.hpp
+++ /dev/null
@@ -1,75 +0,0 @@
-//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "expression.hpp"
-#include <boost/function.hpp>
-#include <boost/shared_ptr.hpp>
-#include <vector>
-
-#ifndef INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_FUNCTABLE_HPP
-# define INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_FUNCTABLE_HPP
-
-namespace uhd { namespace rfnoc { namespace nocscript {
-
-class function_table
-{
-public:
- typedef boost::shared_ptr<function_table> sptr;
- typedef boost::function<expression_literal(expression_container::expr_list_type&)>
- function_ptr;
-
- static sptr make();
- virtual ~function_table(){};
-
- /*! Check if any function with a given name exists
- *
- * \returns True, if any function with name \p name is registered.
- */
- virtual bool function_exists(const std::string& name) const = 0;
-
- /*! Check if a function with a given name and list of argument types exists
- *
- * \returns True, if such a function is registered.
- */
- virtual bool function_exists(const std::string& name,
- const expression_function::argtype_list_type& arg_types) const = 0;
-
- /*! Get the return type of a function with given name and argument type list
- *
- * \returns The function's return type
- * \throws uhd::syntax_error if no such function is registered
- */
- virtual expression::type_t get_type(const std::string& name,
- const expression_function::argtype_list_type& arg_types) const = 0;
-
- /*! Calls the function \p name with the argument list \p arguments
- *
- * \param arg_types A list of types for each argument
- * \param arguments An expression list of the arguments
- * \returns The return value of the called function
- * \throws uhd::syntax_error if no such function is found
- */
- virtual expression_literal eval(const std::string& name,
- const expression_function::argtype_list_type& arg_types,
- expression_container::expr_list_type& arguments) = 0;
-
- /*! Register a new function
- *
- * \param name Name of the function (e.g. 'ADD')
- * \param ptr Function object
- * \param return_type The function's return value
- * \param sig The function signature (list of argument types)
- */
- virtual void register_function(const std::string& name,
- const function_ptr& ptr,
- const expression::type_t return_type,
- const expression_function::argtype_list_type& sig) = 0;
-};
-
-}}} /* namespace uhd::rfnoc::nocscript */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_FUNCTABLE_HPP */
diff --git a/host/lib/rfnoc/nocscript/gen_basic_funcs.py b/host/lib/rfnoc/nocscript/gen_basic_funcs.py
deleted file mode 100755
index fec6b04ad..000000000
--- a/host/lib/rfnoc/nocscript/gen_basic_funcs.py
+++ /dev/null
@@ -1,465 +0,0 @@
-#!/usr/bin/env python
-"""
-Generate the function list for the basic NocScript functions
-"""
-
-import re
-import os
-import sys
-from mako.template import Template
-
-#############################################################################
-# This is the interesting part: Add new functions in here
-#
-# Notes:
-# - Lines starting with # are considered comments, and will be removed from
-# the output
-# - C++ comments will be copied onto the generated file if inside functions
-# - Docstrings start with //! and are required
-# - Function signature is RETURN_TYPE NAME(ARG_TYPE1, ARG_TYPE2, ...)
-# - Function body is valid C++
-# - If your function requires special includes, put them in INCLUDE_LIST
-# - End of functions is delimited by s/^}/, so take care with the indents!
-# - Use these substitutions:
-# - ${RETURN}(...): Create a valid return value
-# - ${args[n]}: Access the n-th argument
-#
-INCLUDE_LIST = """
-#include <boost/math/special_functions/round.hpp>
-#include <chrono>
-#include <thread>
-"""
-FUNCTION_LIST = """
-CATEGORY: Math Functions
-//! Returns x + y
-INT ADD(INT, INT)
-{
- ${RETURN}(${args[0]} + ${args[1]});
-}
-
-//! Returns x + y
-DOUBLE ADD(DOUBLE, DOUBLE)
-{
- ${RETURN}(${args[0]} + ${args[1]});
-}
-
-//! Returns x * y
-DOUBLE MULT(DOUBLE, DOUBLE)
-{
- ${RETURN}(${args[0]} * ${args[1]});
-}
-
-//! Returns x * y
-INT MULT(INT, INT)
-{
- ${RETURN}(${args[0]} * ${args[1]});
-}
-
-//! Returns x / y
-DOUBLE DIV(DOUBLE, DOUBLE)
-{
- ${RETURN}(${args[0]} / ${args[1]});
-}
-
-//! Returns true if x <= y (Less or Equal)
-BOOL LE(INT, INT)
-{
- ${RETURN}(bool(${args[0]} <= ${args[1]}));
-}
-
-//! Returns true if x <= y (Less or Equal)
-BOOL LE(DOUBLE, DOUBLE)
-{
- ${RETURN}(bool(${args[0]} <= ${args[1]}));
-}
-
-//! Returns true if x >= y (Greater or Equal)
-BOOL GE(INT, INT)
-{
- ${RETURN}(bool(${args[0]} >= ${args[1]}));
-}
-
-//! Returns true if x >= y (Greater or Equal)
-BOOL GE(DOUBLE, DOUBLE)
-{
- ${RETURN}(bool(${args[0]} >= ${args[1]}));
-}
-
-//! Returns true if x < y (Less Than)
-BOOL LT(INT, INT)
-{
- ${RETURN}(bool(${args[0]} < ${args[1]}));
-}
-
-//! Returns true if x > y (Greater Than)
-BOOL GT(INT, INT)
-{
- ${RETURN}(bool(${args[0]} > ${args[1]}));
-}
-
-//! Returns true if x < y (Less Than)
-BOOL LT(DOUBLE, DOUBLE)
-{
- ${RETURN}(bool(${args[0]} < ${args[1]}));
-}
-
-//! Returns true if x > y (Greater Than)
-BOOL GT(DOUBLE, DOUBLE)
-{
- ${RETURN}(bool(${args[0]} > ${args[1]}));
-}
-
-//! Round x and return it as an integer
-INT IROUND(DOUBLE)
-{
- ${RETURN}(int(boost::math::iround(${args[0]})));
-}
-
-//! Returns true if x is a power of 2
-BOOL IS_PWR_OF_2(INT)
-{
- if (${args[0]} < 0) return ${FALSE};
- int i = ${args[0]};
- while ( (i & 1) == 0 and (i > 1) ) {
- i >>= 1;
- }
- ${RETURN}(bool(i == 1));
-}
-
-//! Returns floor(log2(x)).
-INT LOG2(INT)
-{
- if (${args[0]} < 0) {
- throw uhd::runtime_error(str(
- boost::format("In NocScript function ${func_name}: Cannot calculate log2() of negative number.")
- ));
- }
-
- int power_value = ${args[0]};
- int log2_value = 0;
- while ( (power_value & 1) == 0 and (power_value > 1) ) {
- power_value >>= 1;
- log2_value++;
- }
- ${RETURN}(log2_value);
-}
-
-//! Returns x % y
-INT MODULO(INT, INT)
-{
- ${RETURN}(${args[0]} % ${args[1]});
-}
-
-//! Returns true if x == y
-BOOL EQUAL(INT, INT)
-{
- ${RETURN}(bool(${args[0]} == ${args[1]}));
-}
-
-//! Returns true if x == y
-BOOL EQUAL(DOUBLE, DOUBLE)
-{
- ${RETURN}(bool(${args[0]} == ${args[1]}));
-}
-
-//! Returns true if x == y
-BOOL EQUAL(STRING, STRING)
-{
- ${RETURN}(bool(${args[0]} == ${args[1]}));
-}
-
-CATEGORY: Bitwise Operations
-//! Returns x >> y
-INT SHIFT_RIGHT(INT, INT)
-{
- ${RETURN}(${args[0]} >> ${args[1]});
-}
-
-//! Returns x << y
-INT SHIFT_LEFT(INT, INT)
-{
- ${RETURN}(${args[0]} << ${args[1]});
-}
-
-//! Returns x & y
-INT BITWISE_AND(INT, INT)
-{
- ${RETURN}(${args[0]} & ${args[1]});
-}
-
-//! Returns x | y
-INT BITWISE_OR(INT, INT)
-{
- ${RETURN}(${args[0]} | ${args[1]});
-}
-
-//! Returns x ^ y
-INT BITWISE_XOR(INT, INT)
-{
- ${RETURN}(${args[0]} ^ ${args[1]});
-}
-
-CATEGORY: Boolean Logic
-//! Returns x xor y.
-BOOL XOR(BOOL, BOOL)
-{
- ${RETURN}(${args[0]} xor ${args[1]});
-}
-
-//! Returns !x
-BOOL NOT(BOOL)
-{
- ${RETURN}(not ${args[0]});
-}
-
-//! Always returns true
-BOOL TRUE()
-{
- return ${TRUE};
-}
-
-//! Always returns false
-BOOL FALSE()
-{
- return ${FALSE};
-}
-
-CATEGORY: Conditional Execution
-//! Executes x, if true, execute y. Returns true if x is true.
-BOOL IF(BOOL, BOOL)
-{
- if (${args[0]}) {
- ${args[1]};
- ${RETURN}(true);
- }
- ${RETURN}(false);
-}
-
-//! Executes x, if true, execute y, otherwise, execute z. Returns true if x is true.
-BOOL IF_ELSE(BOOL, BOOL, BOOL)
-{
- if (${args[0]}) {
- ${args[1]};
- ${RETURN}(true);
- } else {
- ${args[2]};
- }
- ${RETURN}(false);
-}
-
-CATEGORY: Execution Control
-//! Sleep for x seconds. Fractions are allowed. Millisecond accuracy.
-BOOL SLEEP(DOUBLE)
-{
- int ms = ${args[0]} / 1000;
- std::this_thread::sleep_for(std::chrono::milliseconds(ms));
- ${RETURN}(true);
-}
-"""
-# End of interesting part. The rest will take this and turn into a C++
-# header file.
-#############################################################################
-
-HEADER = """<% import time %>//
-///////////////////////////////////////////////////////////////////////
-// This file was generated by ${file} on ${time.strftime("%c")}
-///////////////////////////////////////////////////////////////////////
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-/****************************************************************************
- * This file is autogenerated! Any manual changes in here will be
- * overwritten by calling nocscript_gen_basic_funcs.py!
- ***************************************************************************/
-
-#include "expression.hpp"
-#include "function_table.hpp"
-#include <uhd/exception.hpp>
-#include <boost/format.hpp>
-#include <boost/assign/list_of.hpp>
-${INCLUDE_LIST}
-
-#ifndef INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_BASICFUNCS_HPP
-#define INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_BASICFUNCS_HPP
-
-namespace uhd { namespace rfnoc { namespace nocscript {
-"""
-
-# Not a Mako template:
-FOOTER="""
-}}} /* namespace uhd::rfnoc::nocscript */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_BASICFUNCS_HPP */
-"""
-
-# Not a Mako template:
-FUNC_TEMPLATE = """
-expression_literal {NAME}(expression_container::expr_list_type &{ARGS})
-{BODY}
-"""
-
-REGISTER_MACRO_TEMPLATE = """#define _REGISTER_ALL_FUNCS()${registry}
-"""
-
-REGISTER_COMMANDS_TEMPLATE = """
- % if len(arglist):
- expression_function::argtype_list_type ${func_name}_args = boost::assign::list_of
- % for this_type in arglist:
- (expression::TYPE_${this_type})
- % endfor
- ;
- % else:
- expression_function::argtype_list_type ${func_name}_args;
- % endif
- register_function(
- "${name}",
- boost::bind(&${func_name}, _1),
- expression::TYPE_${retval},
- ${func_name}_args
- );"""
-
-DOXY_TEMPLATE = """/*! \page page_nocscript_funcs NocScript Function Reference
-% for cat, func_by_name in func_list_tree.items():
-- ${cat}
-% for func_name, func_info_list in func_by_name.items():
- - ${func_name}: ${func_info_list[0]['docstring']}
-% for func_info in func_info_list:
- - ${func_info['arglist']} -> ${func_info['retval']}
-% endfor
-% endfor
-% endfor
-
-*/
-"""
-
-def parse_tmpl(_tmpl_text, **kwargs):
- return Template(_tmpl_text).render(**kwargs)
-
-def make_cxx_func_name(func_dict):
- """
- Creates a unique C++ function name from a function description
- """
- return "{name}__{retval}__{arglist}".format(
- name=func_dict['name'],
- retval=func_dict['retval'],
- arglist="_".join(func_dict['arglist'])
- )
-
-def make_cxx_func_body(func_dict):
- """
- Formats the function body properly
- """
- type_lookup_methods = {
- 'INT': 'get_int',
- 'DOUBLE': 'get_double',
- 'BOOL': 'get_bool',
- 'STRING': 'get_string',
- }
- args_lookup = []
- for idx, arg_type in enumerate(func_dict['arglist']):
- args_lookup.append("args[{idx}]->eval().{getter}()".format(idx=idx, getter=type_lookup_methods[arg_type]))
- return parse_tmpl(
- func_dict['body'],
- args=args_lookup,
- FALSE='expression_literal(false)',
- TRUE='expression_literal(true)',
- RETURN='return expression_literal',
- **func_dict
- )
-
-def prep_function_list():
- """
- - Remove all comments
- - Split the function list into individual functions
- - Split the functions into return value, name, argument list and body
- """
- comment_remove_re = re.compile(r'^\s*#.*$', flags=re.MULTILINE)
- func_list_wo_comments = comment_remove_re.sub('', FUNCTION_LIST)
- func_splitter_re = re.compile(r'(?<=^})\s*$', flags=re.MULTILINE)
- func_list_split = func_splitter_re.split(func_list_wo_comments)
- func_list_split = [x.strip() for x in func_list_split if len(x.strip())]
- func_list = []
- last_category = ''
- for func in func_list_split:
- split_regex = r'(^CATEGORY: (?P<cat>[^\n]*)\s*)?' \
- r'//!(?P<docstring>[^\n]*)\s*' + \
- r'(?P<retval>[A-Z][A-Z0-9_]*)\s+' + \
- r'(?P<funcname>[A-Z][A-Z0-9_]*)\s*\((?P<arglist>[^\)]*)\)\s*' + \
- r'(?P<funcbody>^{.*)'
- split_re = re.compile(split_regex, flags=re.MULTILINE|re.DOTALL)
- mo = split_re.match(func)
- if mo.group('cat'):
- last_category = mo.group('cat').strip()
- func_dict = {
- 'docstring': mo.group('docstring').strip(),
- 'name': mo.group('funcname'),
- 'retval': mo.group('retval'),
- 'arglist': [x.strip() for x in mo.group('arglist').split(',') if len(x.strip())],
- 'body': mo.group('funcbody'),
- 'category': last_category,
- }
- func_dict['func_name'] = make_cxx_func_name(func_dict)
- func_list.append(func_dict)
- return func_list
-
-def write_function_header(output_filename):
- """
- Create the .hpp file that defines all the NocScript functions in C++.
- """
- func_list = prep_function_list()
- # Step 1: Write the prototypes
- func_prototypes = ''
- registry_commands = ''
- for func in func_list:
- func_prototypes += FUNC_TEMPLATE.format(
- NAME=func['func_name'],
- BODY=make_cxx_func_body(func),
- ARGS="args" if len(func['arglist']) else ""
- )
- registry_commands += parse_tmpl(
- REGISTER_COMMANDS_TEMPLATE,
- **func
- )
- # Step 2: Write the registry process
- register_func = parse_tmpl(REGISTER_MACRO_TEMPLATE, registry=registry_commands)
- register_func = register_func.replace('\n', ' \\\n')
-
- # Final step: Join parts and write to file
- full_file = "\n".join((
- parse_tmpl(HEADER, file = os.path.basename(__file__), INCLUDE_LIST=INCLUDE_LIST),
- func_prototypes,
- register_func,
- FOOTER,
- ))
- open(output_filename, 'w').write(full_file)
-
-def write_manual_file(output_filename):
- """
- Write the Doxygen file for the NocScript functions.
- """
- func_list = prep_function_list()
- func_list_tree = {}
- for func in func_list:
- if func['category'] not in func_list_tree:
- func_list_tree[func['category']] = {}
- if func['name'] not in func_list_tree[func['category']]:
- func_list_tree[func['category']][func['name']] = []
- func_list_tree[func['category']][func['name']].append(func)
- open(output_filename, 'w').write(parse_tmpl(DOXY_TEMPLATE, func_list_tree=func_list_tree))
-
-
-def main():
- if len(sys.argv) < 2:
- print("No output file specified!")
- exit(1)
- outfile = sys.argv[1]
- if os.path.splitext(outfile)[1] == '.dox':
- write_manual_file(outfile)
- else:
- write_function_header(outfile)
-
-if __name__ == "__main__":
- main()
diff --git a/host/lib/rfnoc/nocscript/parser.cpp b/host/lib/rfnoc/nocscript/parser.cpp
deleted file mode 100644
index 8ef1b7f44..000000000
--- a/host/lib/rfnoc/nocscript/parser.cpp
+++ /dev/null
@@ -1,357 +0,0 @@
-//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "parser.hpp"
-#include <uhd/utils/cast.hpp>
-#include <boost/assign.hpp>
-#include <boost/bind.hpp>
-#include <boost/format.hpp>
-#include <boost/make_shared.hpp>
-#include <boost/spirit/include/lex_lexertl.hpp>
-#include <sstream>
-#include <stack>
-
-using namespace uhd::rfnoc::nocscript;
-namespace lex = boost::spirit::lex;
-
-class parser_impl : public parser
-{
-public:
- /******************************************************************
- * Structors TODO make them protected
- *****************************************************************/
- parser_impl(function_table::sptr ftable,
- expression_variable::type_getter_type var_type_getter,
- expression_variable::value_getter_type var_value_getter)
- : _ftable(ftable)
- , _var_type_getter(var_type_getter)
- , _var_value_getter(var_value_getter)
- {
- // nop
- }
-
- virtual ~parser_impl() {}
-
-
- /******************************************************************
- * Parsing
- *****************************************************************/
- //! List of parser tokens
- enum token_ids {
- ID_WHITESPACE = lex::min_token_id + 42,
- ID_KEYWORD,
- ID_ARG_SEP,
- ID_PARENS_OPEN,
- ID_PARENS_CLOSE,
- ID_VARIABLE,
- ID_LITERAL_DOUBLE,
- ID_LITERAL_INT,
- ID_LITERAL_HEX,
- ID_LITERAL_STR,
- ID_LITERAL_VECTOR_INT
- };
-
- //! The Lexer object used for NocScript
- template <typename Lexer> struct ns_lexer : lex::lexer<Lexer>
- {
- ns_lexer()
- {
- this->self.add("\\s+", ID_WHITESPACE)(",", ID_ARG_SEP)(
- "[A-Z][A-Z0-9_]*", ID_KEYWORD)("\\(", ID_PARENS_OPEN)(
- "\\)", ID_PARENS_CLOSE)("\\$[a-z][a-z0-9_]*", ID_VARIABLE)(
- "-?\\d+\\.\\d+", ID_LITERAL_DOUBLE)("-?\\d+", ID_LITERAL_INT)(
- "0x[0-9A-F]+", ID_LITERAL_HEX)("\\\"[^\\\"]*\\\"", ID_LITERAL_STR)(
- "'[^']*'", ID_LITERAL_STR) // both work
- ("\\[[0-9]\\]", ID_LITERAL_VECTOR_INT);
- }
- };
-
-private:
- struct grammar_props
- {
- function_table::sptr ftable;
- expression_variable::type_getter_type var_type_getter;
- expression_variable::value_getter_type var_value_getter;
-
- //! Store the last keyword
- std::string function_name;
- std::string error;
- std::stack<expression_container::sptr> expr_stack;
-
- grammar_props(function_table::sptr ftable_,
- expression_variable::type_getter_type var_type_getter_,
- expression_variable::value_getter_type var_value_getter_)
- : ftable(ftable_)
- , var_type_getter(var_type_getter_)
- , var_value_getter(var_value_getter_)
- , function_name("")
- {
- UHD_ASSERT_THROW(expr_stack.empty());
- // Push an empty container to the stack to hold the result
- expr_stack.push(expression_container::make());
- }
-
- expression::sptr get_result()
- {
- UHD_ASSERT_THROW(expr_stack.size() == 1);
- return expr_stack.top();
- }
- };
-
- //! This isn't strictly a grammar, as it also includes semantic
- // actions etc. I'm not going to spend ages thinking of a better
- // name at this point.
- struct grammar
- {
- // Implementation detail specific to boost::bind (see Boost::Spirit
- // examples)
- typedef bool result_type;
-
- static const int VALID_COMMA = 0x1;
- static const int VALID_PARENS_OPEN = 0x2;
- static const int VALID_PARENS_CLOSE = 0x4;
- static const int VALID_EXPRESSION = 0x8 + 0x02;
- static const int VALID_OPERATOR = 0x10;
-
- // !This function operator gets called for each of the matched tokens.
- template <typename Token>
- bool operator()(Token const& t, grammar_props& P, int& next_valid_state) const
- {
- //! This is totally not how Boost::Spirit is meant to be used,
- // as there's token types etc. But for now let's just convert
- // every token to a string, and then handle it as such.
- std::stringstream sstr;
- sstr << t.value();
- std::string val = sstr.str();
- // std::cout << "VAL: " << val << std::endl;
- // std::cout << "Next valid states:\n"
- //<< boost::format("VALID_COMMA [%s]\n") % ((next_valid_state & 0x1) ?
- //"x" : " ")
- //<< boost::format("VALID_PARENS_OPEN [%s]\n") % ((next_valid_state & 0x2) ?
- //"x" : " ")
- //<< boost::format("VALID_PARENS_CLOSE [%s]\n") % ((next_valid_state & 0x4) ?
- //"x" : " ")
- //<< boost::format("VALID_EXPRESSION [%s]\n") % ((next_valid_state & (0x8 +
- //0x02)) ? "x" : " ")
- //<< boost::format("VALID_OPERATOR [%s]\n") % ((next_valid_state & 0x10)
- //? "x" : " ")
- //<< std::endl;
-
- switch (t.id()) {
- case ID_WHITESPACE:
- // Ignore
- break;
-
- case ID_KEYWORD:
- // Ambiguous, could be an operator (AND, OR) or a function name (ADD,
- // MULT...). So first, check which it is:
- if (val == "AND" or val == "OR") {
- if (not(next_valid_state & VALID_OPERATOR)) {
- P.error = str(boost::format("Unexpected operator: %s") % val);
- return false;
- }
- next_valid_state = VALID_EXPRESSION;
- try {
- if (val == "AND") {
- P.expr_stack.top()->set_combiner_safe(
- expression_container::COMBINE_AND);
- } else if (val == "OR") {
- P.expr_stack.top()->set_combiner_safe(
- expression_container::COMBINE_OR);
- }
- } catch (const uhd::syntax_error&) {
- P.error = str(boost::format("Operator %s is mixing operator "
- "types within this container.")
- % val);
- }
- // Right now, we can't have multiple operator types within a
- // container. We might be able to change that, if there's enough
- // demand. Either we keep track of multiple operators, or we open
- // a new container. In the latter case, we'd need a way of keeping
- // track of those containers, so it's a bit tricky.
- break;
- }
- // If it's not a keyword, it has to be a function, so check the
- // function table:
- if (not(next_valid_state & VALID_EXPRESSION)) {
- P.error = str(boost::format("Unexpected expression: %s") % val);
- return false;
- }
- if (not P.ftable->function_exists(val)) {
- P.error = str(boost::format("Unknown function: %s") % val);
- return false;
- }
- P.function_name = val;
- next_valid_state = VALID_PARENS_OPEN;
- break;
-
- // Every () creates a new container, either a raw container or
- // a function.
- case ID_PARENS_OPEN:
- if (not(next_valid_state & VALID_PARENS_OPEN)) {
- P.error = str(boost::format("Unexpected parentheses."));
- return false;
- }
- if (not P.function_name.empty()) {
- // We've already checked the function name exists
- P.expr_stack.push(
- expression_function::make(P.function_name, P.ftable));
- P.function_name.clear();
- } else {
- P.expr_stack.push(expression_container::make());
- }
- // Push another empty container to hold the first element/argument
- // in this container:
- P.expr_stack.push(expression_container::make());
- next_valid_state = VALID_EXPRESSION | VALID_PARENS_CLOSE;
- break;
-
- case ID_PARENS_CLOSE: {
- if (not(next_valid_state & VALID_PARENS_CLOSE)) {
- P.error = str(boost::format("Unexpected parentheses."));
- return false;
- }
- if (P.expr_stack.size() < 2) {
- P.error = str(boost::format("Unbalanced closing parentheses."));
- return false;
- }
- // First pop the last expression inside the parentheses,
- // if it's not empty, add it to the top container (this also avoids
- // adding arguments to functions if none were provided):
- expression_container::sptr c = P.expr_stack.top();
- P.expr_stack.pop();
- if (not c->empty()) {
- P.expr_stack.top()->add(c);
- }
- // At the end of (), either a function or container is complete,
- // so pop that and add it to its top container:
- expression_container::sptr c2 = P.expr_stack.top();
- P.expr_stack.pop();
- P.expr_stack.top()->add(c2);
- next_valid_state = VALID_OPERATOR | VALID_COMMA | VALID_PARENS_CLOSE;
- } break;
-
- case ID_ARG_SEP: {
- if (not(next_valid_state & VALID_COMMA)) {
- P.error = str(boost::format("Unexpected comma."));
- return false;
- }
- next_valid_state = VALID_EXPRESSION;
- // If stack size is 1, we're on the base container, which means we
- // simply string stuff.
- if (P.expr_stack.size() == 1) {
- break;
- }
- // Otherwise, a ',' always means we add the previous expression to
- // the current container:
- expression_container::sptr c = P.expr_stack.top();
- P.expr_stack.pop();
- P.expr_stack.top()->add(c);
- // It also means another expression is following, so create another
- // empty container for that:
- P.expr_stack.push(expression_container::make());
- } break;
-
- // All the atomic expressions just get added to the current container:
-
- case ID_VARIABLE: {
- if (not(next_valid_state & VALID_EXPRESSION)) {
- P.error = str(boost::format("Unexpected expression."));
- return false;
- }
- expression_variable::sptr v = expression_variable::make(
- val, P.var_type_getter, P.var_value_getter);
- P.expr_stack.top()->add(v);
- next_valid_state = VALID_OPERATOR | VALID_COMMA | VALID_PARENS_CLOSE;
- } break;
-
- default:
- // If we get here, we assume it's a literal expression
- {
- if (not(next_valid_state & VALID_EXPRESSION)) {
- P.error = str(boost::format("Unexpected expression."));
- return false;
- }
- expression::type_t token_type;
- switch (t.id()) { // A map lookup would be more elegant, but we'd
- // need a nicer C++ for that
- case ID_LITERAL_DOUBLE:
- token_type = expression::TYPE_DOUBLE;
- break;
- case ID_LITERAL_INT:
- token_type = expression::TYPE_INT;
- break;
- case ID_LITERAL_HEX:
- token_type = expression::TYPE_INT;
- break;
- case ID_LITERAL_STR:
- token_type = expression::TYPE_STRING;
- break;
- case ID_LITERAL_VECTOR_INT:
- token_type = expression::TYPE_INT_VECTOR;
- break;
- default:
- UHD_THROW_INVALID_CODE_PATH();
- }
- P.expr_stack.top()->add(
- boost::make_shared<expression_literal>(val, token_type));
- next_valid_state = VALID_OPERATOR | VALID_COMMA
- | VALID_PARENS_CLOSE;
- break;
- }
-
- } // end switch
- return true;
- }
- };
-
-public:
- expression::sptr create_expr_tree(const std::string& code)
- {
- // Create empty stack and keyword states
- grammar_props P(_ftable, _var_type_getter, _var_value_getter);
- int next_valid_state = grammar::VALID_EXPRESSION;
-
- // Create a lexer instance
- ns_lexer<lex::lexertl::lexer<>> lexer_functor;
-
- // Tokenize the string
- char const* first = code.c_str();
- char const* last = &first[code.size()];
- bool r = lex::tokenize(first,
- last, // Iterators
- lexer_functor, // Lexer
- boost::bind(grammar(),
- _1,
- boost::ref(P),
- boost::ref(next_valid_state)) // Function object
- );
-
- // Check the parsing worked:
- if (not r or P.expr_stack.size() != 1) {
- std::string rest(first, last);
- throw uhd::syntax_error(
- str(boost::format("Parsing stopped at: %s\nError message: %s") % rest
- % P.error));
- }
-
- // Clear stack and return result
- return P.get_result();
- }
-
-private:
- function_table::sptr _ftable;
- expression_variable::type_getter_type _var_type_getter;
- expression_variable::value_getter_type _var_value_getter;
-};
-
-parser::sptr parser::make(function_table::sptr ftable,
- expression_variable::type_getter_type var_type_getter,
- expression_variable::value_getter_type var_value_getter)
-{
- return sptr(new parser_impl(ftable, var_type_getter, var_value_getter));
-}
diff --git a/host/lib/rfnoc/nocscript/parser.hpp b/host/lib/rfnoc/nocscript/parser.hpp
deleted file mode 100644
index e9d9f0820..000000000
--- a/host/lib/rfnoc/nocscript/parser.hpp
+++ /dev/null
@@ -1,37 +0,0 @@
-//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "expression.hpp"
-#include "function_table.hpp"
-#include <boost/shared_ptr.hpp>
-
-#ifndef INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_PARSER_HPP
-# define INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_PARSER_HPP
-
-namespace uhd { namespace rfnoc { namespace nocscript {
-
-class parser
-{
-public:
- typedef boost::shared_ptr<parser> sptr;
-
- static sptr make(function_table::sptr ftable,
- expression_variable::type_getter_type var_type_getter,
- expression_variable::value_getter_type var_value_getter);
-
- /*! The main parsing call: Turn a string of code into an expression tree.
- *
- * Evaluating the returned object will execute the code.
- *
- * \throws uhd::syntax_error if \p code contains syntax errors
- */
- virtual expression::sptr create_expr_tree(const std::string& code) = 0;
-};
-
-}}} /* namespace uhd::rfnoc::nocscript */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_PARSER_HPP */