/** @file Primitive.hpp * * Author: Roland Conybeare **/ #pragma once #include "PrimitiveInterface.hpp" //#include namespace xo { namespace ast { /** @class Primitive * @brief syntax for a constant that refers to a known function. * * Two cases here: * 1. primitive refers to a function that is supported directly in llvm * (e.g. floating-point addition) * 2. primitive refers to a compiled (C/C++) function that we can invoke at runtime * * In any case, a primitive serves as both declaration and definition * (May be possible to relax this to declaration-only using null value_ as sentinel..?) **/ template class Primitive: public PrimitiveInterface { public: using Reflect = xo::reflect::Reflect; using TaggedPtr = xo::reflect::TaggedPtr; using TypeDescr = xo::reflect::TypeDescr; public: Primitive(const std::string & name, FunctionPointer fnptr) : PrimitiveInterface(), name_{name}, value_td_{Reflect::require()}, value_{fnptr} {} FunctionPointer value() const { return value_; } // ----- PrimitiveInterface ----- virtual std::string const & name() const { return name_; } // ----- ConstantInterface ----- virtual TypeDescr value_td() const override { return value_td_; } virtual TaggedPtr value_tp() const override { /* note: idk why, but need to spell this out in two steps with gcc 13.2 */ const void * erased_cptr = &value_; void * erased_ptr = const_cast(erased_cptr); return TaggedPtr(value_td_, erased_ptr); } // ----- Expression ----- virtual void display(std::ostream & os) const override { os << "value_td()->short_name()) << xtag("value", this->value()) << ">"; } private: // from Expression: // exprtype extype_ /** name of this primitive, e.g. '+', 'sqrt' **/ std::string name_; /** type description for FunctionPointer **/ TypeDescr value_td_; /** address of executable function **/ FunctionPointer value_; }; /*Primitive*/ /** adopt function @p x as a callable primitive function named @p name **/ template ref::rp> make_primitive(const std::string & name, FunctionPointer x) { return new Primitive(name, x); } } /*namespace ast*/ } /*namespace xo*/ /** end Primitive.hpp **/