diff options
Diffstat (limited to 'host/lib/rfnoc/nocscript/expression.hpp')
-rw-r--r-- | host/lib/rfnoc/nocscript/expression.hpp | 360 |
1 files changed, 0 insertions, 360 deletions
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 */ |