/** @file Lambda.hpp * * Author: Roland Conybeare **/ #pragma once #include "Expression.hpp" #include #include //#include namespace xo { namespace ast { /** @class Lambda * @brief abstract syntax tree for a function definition * **/ class Lambda : public Expression { public: /** @p argv Formal parameters, in left-to-right order * @p body Expression for body of this function **/ Lambda(const std::string & name, const std::vector & argv, const ref::rp & body); /** downcast from Expression **/ static ref::brw from(ref::brw x) { return ref::brw::from(x); } const std::string & name() const { return name_; } const std::string & type_str() const { return type_str_; } const std::vector & argv() const { return argv_; } const ref::rp & body() const { return body_; } /** return number of arguments expected by this function **/ int n_arg() const { return argv_.size(); } // ----- Expression ----- virtual void display(std::ostream & os) const override; private: /** lambda name. Initially supporting only form like * (define (foo x y z) * (+ (* x x) (* y y) (* z z))) * * In any case need to supply names for distinct things-for-which-code-is-generated * so that they can be linked etc. **/ std::string name_; /** e.g. * "double(double,double)" for function of two doubles that returns a double **/ std::string type_str_; /** formal argument names **/ std::vector argv_; /** function body **/ ref::rp body_; }; /*Lambda*/ inline ref::rp make_lambda(const std::string & name, const std::vector & argv, const ref::rp & body) { return new Lambda(name, argv, body); } } /*namespace ast*/ } /*namespace xo*/ /** end Lambda.hpp **/