mirror of
https://github.com/ChaiScript/ChaiScript.git
synced 2026-05-01 03:19:28 +08:00
* Fix #146: Add configuration options to selectively disable built-in functions Add new Options enum values (No_Stdlib, No_IO, No_Prelude, No_JSON) that allow users to control which parts of the standard library are registered. Std_Lib::library() now accepts an options vector, and the ChaiScript convenience class forwards its options to the library builder. This enables use cases where only custom functions should be exposed to script users. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Address review: split Options into Options and Library_Options enums Separate system-level options (No_Load_Modules, Load_Modules, No_External_Scripts, External_Scripts) from library-level options (No_Stdlib, No_IO, No_Prelude, No_JSON) into two distinct enum types. Add Library_Options as a parameter to the ChaiScript constructor. Update tests to demonstrate both ChaiScript_Basic (explicit Std_Lib::library call) and ChaiScript (library options via constructor parameter) usage. Requested by @lefticus in PR #642 review. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Add cheatsheet documentation for Options and Library_Options Documents the two-enum configuration system: Options (engine-level: load_module, use, eval_file) and Library_Options (stdlib-level: No_Stdlib, No_IO, No_Prelude, No_JSON), with usage examples for both ChaiScript and ChaiScript_Basic constructors. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: leftibot <leftibot@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
516 lines
24 KiB
C++
516 lines
24 KiB
C++
// This file is distributed under the BSD License.
|
|
// See "license.txt" for details.
|
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
|
// Copyright 2009-2018, Jason Turner (jason@emptycrate.com)
|
|
// http://www.chaiscript.com
|
|
|
|
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
|
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
|
|
|
#ifndef CHAISCRIPT_BOOTSTRAP_HPP_
|
|
#define CHAISCRIPT_BOOTSTRAP_HPP_
|
|
|
|
#include "../utility/utility.hpp"
|
|
#include "register_function.hpp"
|
|
|
|
/// \brief Classes and functions useful for bootstrapping of ChaiScript and adding of new types
|
|
namespace chaiscript::bootstrap {
|
|
template<typename T, typename = typename std::enable_if<std::is_array<T>::value>::type>
|
|
void array(const std::string &type, Module &m) {
|
|
using ReturnType = typename std::remove_extent<T>::type;
|
|
|
|
m.add(user_type<T>(), type);
|
|
m.add(fun([](T &t, size_t index) -> ReturnType & {
|
|
constexpr const auto extent = std::extent<T>::value;
|
|
if (extent > 0 && index >= extent) {
|
|
throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < "
|
|
+ std::to_string(extent));
|
|
} else {
|
|
return t[index];
|
|
}
|
|
}),
|
|
"[]");
|
|
|
|
m.add(fun([](const T &t, size_t index) -> const ReturnType & {
|
|
constexpr const auto extent = std::extent<T>::value;
|
|
if (extent > 0 && index >= extent) {
|
|
throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < "
|
|
+ std::to_string(extent));
|
|
} else {
|
|
return t[index];
|
|
}
|
|
}),
|
|
"[]");
|
|
|
|
m.add(fun([](const T &) { return std::extent<T>::value; }), "size");
|
|
}
|
|
|
|
/// \brief Adds a copy constructor for the given type to the given Model
|
|
/// \param[in] type The name of the type. The copy constructor will be named "type".
|
|
/// \param[in,out] m The Module to add the copy constructor to
|
|
/// \tparam T The type to add a copy constructor for
|
|
/// \returns The passed in Module
|
|
template<typename T>
|
|
void copy_constructor(const std::string &type, Module &m) {
|
|
m.add(constructor<T(const T &)>(), type);
|
|
}
|
|
|
|
/// \brief Add all comparison operators for the templated type. Used during bootstrap, also available to users.
|
|
/// \tparam T Type to create comparison operators for
|
|
/// \param[in,out] m module to add comparison operators to
|
|
/// \returns the passed in Module.
|
|
template<typename T>
|
|
void opers_comparison(Module &m) {
|
|
operators::equal<T>(m);
|
|
operators::greater_than<T>(m);
|
|
operators::greater_than_equal<T>(m);
|
|
operators::less_than<T>(m);
|
|
operators::less_than_equal<T>(m);
|
|
operators::not_equal<T>(m);
|
|
}
|
|
|
|
/// \brief Adds default and copy constructors for the given type
|
|
/// \param[in] type The name of the type to add the constructors for.
|
|
/// \param[in,out] m The Module to add the basic constructors to
|
|
/// \tparam T Type to generate basic constructors for
|
|
/// \returns The passed in Module
|
|
/// \sa copy_constructor
|
|
/// \sa constructor
|
|
template<typename T>
|
|
void basic_constructors(const std::string &type, Module &m) {
|
|
m.add(constructor<T()>(), type);
|
|
copy_constructor<T>(type, m);
|
|
}
|
|
|
|
/// \brief Adds a constructor for a POD type
|
|
/// \tparam T The type to add the constructor for
|
|
/// \param[in] type The name of the type
|
|
/// \param[in,out] m The Module to add the constructor to
|
|
template<typename T>
|
|
void construct_pod(const std::string &type, Module &m) {
|
|
m.add(fun([](const Boxed_Number &bn) { return bn.get_as<T>(); }), type);
|
|
}
|
|
|
|
/// Internal function for converting from a string to a value
|
|
/// uses ostream operator >> to perform the conversion
|
|
template<typename Input>
|
|
Input parse_string(const std::string &i) {
|
|
if constexpr (!std::is_same<Input, wchar_t>::value && !std::is_same<Input, char16_t>::value && !std::is_same<Input, char32_t>::value) {
|
|
std::stringstream ss(i);
|
|
Input t;
|
|
ss >> t;
|
|
return t;
|
|
} else {
|
|
throw std::runtime_error("Parsing of wide characters is not yet supported");
|
|
}
|
|
}
|
|
|
|
/// Add all common functions for a POD type. All operators, and
|
|
/// common conversions
|
|
template<typename T>
|
|
void bootstrap_pod_type(const std::string &name, Module &m) {
|
|
m.add(user_type<T>(), name);
|
|
m.add(constructor<T()>(), name);
|
|
construct_pod<T>(name, m);
|
|
|
|
m.add(fun(&parse_string<T>), "to_" + name);
|
|
m.add(fun([](const T t) { return t; }), "to_" + name);
|
|
m.add(fun([](const Boxed_Number &bn) { return bn.get_as<T>(); }), "to_" + name);
|
|
m.add(fun(&parse_string<T>), name);
|
|
}
|
|
|
|
/// "clone" function for a shared_ptr type. This is used in the case
|
|
/// where you do not want to make a deep copy of an object during cloning
|
|
/// but want to instead maintain the shared_ptr. It is needed internally
|
|
/// for handling of Proxy_Function object (that is,
|
|
/// function variables.
|
|
template<typename Type>
|
|
auto shared_ptr_clone(const std::shared_ptr<Type> &p) {
|
|
return p;
|
|
}
|
|
|
|
/// Specific version of shared_ptr_clone just for Proxy_Functions
|
|
template<typename Type>
|
|
std::shared_ptr<std::remove_const_t<Type>> shared_ptr_unconst_clone(const std::shared_ptr<std::add_const_t<Type>> &p) {
|
|
return std::const_pointer_cast<typename std::remove_const<Type>::type>(p);
|
|
}
|
|
|
|
/// Assignment function for shared_ptr objects, does not perform a copy of the
|
|
/// object pointed to, instead maintains the shared_ptr concept.
|
|
/// Similar to shared_ptr_clone. Used for Proxy_Function.
|
|
template<typename Type>
|
|
Boxed_Value ptr_assign(Boxed_Value lhs, const std::shared_ptr<Type> &rhs) {
|
|
if (lhs.is_undef() || (!lhs.get_type_info().is_const() && lhs.get_type_info().bare_equal(chaiscript::detail::Get_Type_Info<Type>::get()))) {
|
|
lhs.assign(Boxed_Value(rhs));
|
|
return lhs;
|
|
} else {
|
|
throw exception::bad_boxed_cast("type mismatch in pointer assignment");
|
|
}
|
|
}
|
|
|
|
/// Class consisting of only static functions. All default bootstrapping occurs
|
|
/// from this class.
|
|
class Bootstrap {
|
|
private:
|
|
/// Function allowing for assignment of an unknown type to any other value
|
|
static Boxed_Value unknown_assign(Boxed_Value lhs, Boxed_Value rhs) {
|
|
if (lhs.is_undef()) {
|
|
return (lhs.assign(rhs));
|
|
} else {
|
|
throw exception::bad_boxed_cast("boxed_value has a set type already");
|
|
}
|
|
}
|
|
|
|
static void print(const std::string &s) noexcept { fwrite(s.c_str(), 1, s.size(), stdout); }
|
|
|
|
static void println(const std::string &s) noexcept { puts(s.c_str()); }
|
|
|
|
/// Add all arithmetic operators for PODs
|
|
static void opers_arithmetic_pod(Module &m) {
|
|
m.add(fun(&Boxed_Number::equals), "==");
|
|
m.add(fun(&Boxed_Number::less_than), "<");
|
|
m.add(fun(&Boxed_Number::greater_than), ">");
|
|
m.add(fun(&Boxed_Number::greater_than_equal), ">=");
|
|
m.add(fun(&Boxed_Number::less_than_equal), "<=");
|
|
m.add(fun(&Boxed_Number::not_equal), "!=");
|
|
|
|
m.add(fun(&Boxed_Number::pre_decrement), "--");
|
|
m.add(fun(&Boxed_Number::pre_increment), "++");
|
|
m.add(fun(&Boxed_Number::sum), "+");
|
|
m.add(fun(&Boxed_Number::unary_plus), "+");
|
|
m.add(fun(&Boxed_Number::unary_minus), "-");
|
|
m.add(fun(&Boxed_Number::difference), "-");
|
|
m.add(fun(&Boxed_Number::assign_bitwise_and), "&=");
|
|
m.add(fun(&Boxed_Number::assign), "=");
|
|
m.add(fun(&Boxed_Number::assign_bitwise_or), "|=");
|
|
m.add(fun(&Boxed_Number::assign_bitwise_xor), "^=");
|
|
m.add(fun(&Boxed_Number::assign_remainder), "%=");
|
|
m.add(fun(&Boxed_Number::assign_shift_left), "<<=");
|
|
m.add(fun(&Boxed_Number::assign_shift_right), ">>=");
|
|
m.add(fun(&Boxed_Number::bitwise_and), "&");
|
|
m.add(fun(&Boxed_Number::bitwise_complement), "~");
|
|
m.add(fun(&Boxed_Number::bitwise_xor), "^");
|
|
m.add(fun(&Boxed_Number::bitwise_or), "|");
|
|
m.add(fun(&Boxed_Number::assign_product), "*=");
|
|
m.add(fun(&Boxed_Number::assign_quotient), "/=");
|
|
m.add(fun(&Boxed_Number::assign_sum), "+=");
|
|
m.add(fun(&Boxed_Number::assign_difference), "-=");
|
|
m.add(fun(&Boxed_Number::quotient), "/");
|
|
m.add(fun(&Boxed_Number::shift_left), "<<");
|
|
m.add(fun(&Boxed_Number::product), "*");
|
|
m.add(fun(&Boxed_Number::remainder), "%");
|
|
m.add(fun(&Boxed_Number::shift_right), ">>");
|
|
}
|
|
|
|
/// Create a bound function object. The first param is the function to bind
|
|
/// the remaining parameters are the args to bind into the result
|
|
static Boxed_Value bind_function(const Function_Params ¶ms) {
|
|
if (params.empty()) {
|
|
throw exception::arity_error(0, 1);
|
|
}
|
|
|
|
Const_Proxy_Function f = boxed_cast<Const_Proxy_Function>(params[0]);
|
|
|
|
if (f->get_arity() != -1 && size_t(f->get_arity()) != params.size() - 1) {
|
|
throw exception::arity_error(static_cast<int>(params.size()), f->get_arity());
|
|
}
|
|
|
|
return Boxed_Value(Const_Proxy_Function(
|
|
std::make_shared<dispatch::Bound_Function>(std::move(f), std::vector<Boxed_Value>(params.begin() + 1, params.end()))));
|
|
}
|
|
|
|
static bool has_guard(const Const_Proxy_Function &t_pf) noexcept {
|
|
auto pf = std::dynamic_pointer_cast<const dispatch::Dynamic_Proxy_Function>(t_pf);
|
|
return pf && pf->has_guard();
|
|
}
|
|
|
|
static Const_Proxy_Function get_guard(const Const_Proxy_Function &t_pf) {
|
|
const auto pf = std::dynamic_pointer_cast<const dispatch::Dynamic_Proxy_Function>(t_pf);
|
|
if (pf && pf->get_guard()) {
|
|
return pf->get_guard();
|
|
} else {
|
|
throw std::runtime_error("Function does not have a guard");
|
|
}
|
|
}
|
|
|
|
template<typename FunctionType>
|
|
static std::vector<Boxed_Value> do_return_boxed_value_vector(FunctionType f, const dispatch::Proxy_Function_Base *b) {
|
|
auto v = (b->*f)();
|
|
|
|
std::vector<Boxed_Value> vbv;
|
|
|
|
for (const auto &o : v) {
|
|
vbv.push_back(const_var(o));
|
|
}
|
|
|
|
return vbv;
|
|
}
|
|
|
|
static bool has_parse_tree(const chaiscript::Const_Proxy_Function &t_pf) noexcept {
|
|
const auto pf = std::dynamic_pointer_cast<const chaiscript::dispatch::Dynamic_Proxy_Function>(t_pf);
|
|
return bool(pf);
|
|
}
|
|
|
|
static const chaiscript::AST_Node &get_parse_tree(const chaiscript::Const_Proxy_Function &t_pf) {
|
|
const auto pf = std::dynamic_pointer_cast<const chaiscript::dispatch::Dynamic_Proxy_Function>(t_pf);
|
|
if (pf) {
|
|
return pf->get_parse_tree();
|
|
} else {
|
|
throw std::runtime_error("Function does not have a parse tree");
|
|
}
|
|
}
|
|
|
|
template<typename Function>
|
|
static auto return_boxed_value_vector(const Function &f) {
|
|
return [f](const dispatch::Proxy_Function_Base *b) { return do_return_boxed_value_vector(f, b); };
|
|
}
|
|
|
|
public:
|
|
/// \brief perform all common bootstrap functions for std::string, void and POD types
|
|
/// \param[in,out] m Module to add bootstrapped functions to
|
|
/// \param[in] t_no_io If true, skip registering print_string and println_string
|
|
static void bootstrap(Module &m, const bool t_no_io = false) {
|
|
m.add(user_type<void>(), "void");
|
|
m.add(user_type<bool>(), "bool");
|
|
m.add(user_type<Boxed_Value>(), "Object");
|
|
m.add(user_type<Boxed_Number>(), "Number");
|
|
m.add(user_type<Proxy_Function>(), "Function");
|
|
m.add(user_type<dispatch::Assignable_Proxy_Function>(), "Assignable_Function");
|
|
m.add(user_type<std::exception>(), "exception");
|
|
|
|
m.add(fun(&dispatch::Proxy_Function_Base::get_arity), "get_arity");
|
|
m.add(fun(&dispatch::Proxy_Function_Base::operator==), "==");
|
|
|
|
m.add(fun(return_boxed_value_vector(&dispatch::Proxy_Function_Base::get_param_types)), "get_param_types");
|
|
m.add(fun(return_boxed_value_vector(&dispatch::Proxy_Function_Base::get_contained_functions)), "get_contained_functions");
|
|
|
|
m.add(fun([](const std::exception &e) { return std::string(e.what()); }), "what");
|
|
|
|
m.add(user_type<std::out_of_range>(), "out_of_range");
|
|
m.add(user_type<std::logic_error>(), "logic_error");
|
|
m.add(chaiscript::base_class<std::exception, std::logic_error>());
|
|
m.add(chaiscript::base_class<std::logic_error, std::out_of_range>());
|
|
m.add(chaiscript::base_class<std::exception, std::out_of_range>());
|
|
|
|
m.add(user_type<std::runtime_error>(), "runtime_error");
|
|
m.add(chaiscript::base_class<std::exception, std::runtime_error>());
|
|
|
|
m.add(constructor<std::runtime_error(const std::string &)>(), "runtime_error");
|
|
|
|
m.add(user_type<dispatch::Dynamic_Object>(), "Dynamic_Object");
|
|
m.add(constructor<dispatch::Dynamic_Object(const std::string &)>(), "Dynamic_Object");
|
|
m.add(constructor<dispatch::Dynamic_Object()>(), "Dynamic_Object");
|
|
m.add(fun(&dispatch::Dynamic_Object::get_type_name), "get_type_name");
|
|
m.add(fun(&dispatch::Dynamic_Object::get_attrs), "get_attrs");
|
|
m.add(fun(&dispatch::Dynamic_Object::set_explicit), "set_explicit");
|
|
m.add(fun(&dispatch::Dynamic_Object::is_explicit), "is_explicit");
|
|
m.add(fun(&dispatch::Dynamic_Object::has_attr), "has_attr");
|
|
|
|
m.add(fun(static_cast<Boxed_Value &(dispatch::Dynamic_Object::*)(const std::string &)>(&dispatch::Dynamic_Object::get_attr)), "get_attr");
|
|
m.add(fun(static_cast<const Boxed_Value &(dispatch::Dynamic_Object::*)(const std::string &) const>(&dispatch::Dynamic_Object::get_attr)),
|
|
"get_attr");
|
|
|
|
m.add(fun(static_cast<Boxed_Value &(dispatch::Dynamic_Object::*)(const std::string &)>(&dispatch::Dynamic_Object::method_missing)),
|
|
"method_missing");
|
|
m.add(fun(static_cast<const Boxed_Value &(dispatch::Dynamic_Object::*)(const std::string &) const>(
|
|
&dispatch::Dynamic_Object::method_missing)),
|
|
"method_missing");
|
|
|
|
m.add(fun(static_cast<Boxed_Value &(dispatch::Dynamic_Object::*)(const std::string &)>(&dispatch::Dynamic_Object::get_attr)), "[]");
|
|
m.add(fun(static_cast<const Boxed_Value &(dispatch::Dynamic_Object::*)(const std::string &) const>(&dispatch::Dynamic_Object::get_attr)),
|
|
"[]");
|
|
|
|
m.eval(R"chaiscript(
|
|
def Dynamic_Object::clone() {
|
|
auto &new_o = Dynamic_Object(this.get_type_name());
|
|
for_each(this.get_attrs(), fun[new_o](x) { new_o.get_attr(x.first) = x.second; } );
|
|
new_o;
|
|
}
|
|
|
|
def `=`(Dynamic_Object lhs, Dynamic_Object rhs) : lhs.get_type_name() == rhs.get_type_name()
|
|
{
|
|
for_each(rhs.get_attrs(), fun[lhs](x) { lhs.get_attr(x.first) = clone(x.second); } );
|
|
}
|
|
|
|
def `!=`(Dynamic_Object lhs, Dynamic_Object rhs) : lhs.get_type_name() == rhs.get_type_name()
|
|
{
|
|
var rhs_attrs := rhs.get_attrs();
|
|
var lhs_attrs := lhs.get_attrs();
|
|
|
|
if (rhs_attrs.size() != lhs_attrs.size()) {
|
|
true;
|
|
} else {
|
|
return any_of(rhs_attrs, fun[lhs](x) { !lhs.has_attr(x.first) || lhs.get_attr(x.first) != x.second; } );
|
|
}
|
|
}
|
|
|
|
def `==`(Dynamic_Object lhs, Dynamic_Object rhs) : lhs.get_type_name() == rhs.get_type_name()
|
|
{
|
|
var rhs_attrs := rhs.get_attrs();
|
|
var lhs_attrs := lhs.get_attrs();
|
|
|
|
if (rhs_attrs.size() != lhs_attrs.size()) {
|
|
false;
|
|
} else {
|
|
return all_of(rhs_attrs, fun[lhs](x) { lhs.has_attr(x.first) && lhs.get_attr(x.first) == x.second; } );
|
|
}
|
|
}
|
|
)chaiscript");
|
|
|
|
m.add(fun(&has_guard), "has_guard");
|
|
m.add(fun(&get_guard), "get_guard");
|
|
|
|
m.add(fun(&Boxed_Value::is_undef), "is_var_undef");
|
|
m.add(fun(&Boxed_Value::is_null), "is_var_null");
|
|
m.add(fun(&Boxed_Value::is_const), "is_var_const");
|
|
m.add(fun(&Boxed_Value::is_ref), "is_var_reference");
|
|
m.add(fun(&Boxed_Value::is_pointer), "is_var_pointer");
|
|
m.add(fun(&Boxed_Value::is_return_value), "is_var_return_value");
|
|
m.add(fun(&Boxed_Value::reset_return_value), "reset_var_return_value");
|
|
m.add(fun(&Boxed_Value::is_type), "is_type");
|
|
m.add(fun(&Boxed_Value::get_attr), "get_var_attr");
|
|
m.add(fun(&Boxed_Value::copy_attrs), "copy_var_attrs");
|
|
m.add(fun(&Boxed_Value::clone_attrs), "clone_var_attrs");
|
|
|
|
m.add(fun(&Boxed_Value::get_type_info), "get_type_info");
|
|
m.add(user_type<Type_Info>(), "Type_Info");
|
|
m.add(constructor<Type_Info(const Type_Info &)>(), "Type_Info");
|
|
|
|
operators::equal<Type_Info>(m);
|
|
|
|
m.add(fun(&Type_Info::is_const), "is_type_const");
|
|
m.add(fun(&Type_Info::is_reference), "is_type_reference");
|
|
m.add(fun(&Type_Info::is_void), "is_type_void");
|
|
m.add(fun(&Type_Info::is_undef), "is_type_undef");
|
|
m.add(fun(&Type_Info::is_pointer), "is_type_pointer");
|
|
m.add(fun(&Type_Info::is_arithmetic), "is_type_arithmetic");
|
|
m.add(fun(&Type_Info::name), "cpp_name");
|
|
m.add(fun(&Type_Info::bare_name), "cpp_bare_name");
|
|
m.add(fun(&Type_Info::bare_equal), "bare_equal");
|
|
|
|
basic_constructors<bool>("bool", m);
|
|
operators::assign<bool>(m);
|
|
operators::equal<bool>(m);
|
|
operators::not_equal<bool>(m);
|
|
|
|
m.add(fun([](const std::string &s) { return s; }), "to_string");
|
|
m.add(fun([](const bool b) { return std::string(b ? "true" : "false"); }), "to_string");
|
|
m.add(fun(&unknown_assign), "=");
|
|
m.add(fun([](const Boxed_Value &bv) { throw bv; }), "throw");
|
|
|
|
m.add(fun([](const char c) { return std::string(1, c); }), "to_string");
|
|
m.add(fun(&Boxed_Number::to_string), "to_string");
|
|
|
|
bootstrap_pod_type<double>("double", m);
|
|
bootstrap_pod_type<long double>("long_double", m);
|
|
bootstrap_pod_type<float>("float", m);
|
|
bootstrap_pod_type<int>("int", m);
|
|
bootstrap_pod_type<long>("long", m);
|
|
bootstrap_pod_type<unsigned int>("unsigned_int", m);
|
|
bootstrap_pod_type<unsigned long>("unsigned_long", m);
|
|
bootstrap_pod_type<long long>("long_long", m);
|
|
bootstrap_pod_type<unsigned long long>("unsigned_long_long", m);
|
|
bootstrap_pod_type<size_t>("size_t", m);
|
|
bootstrap_pod_type<char>("char", m);
|
|
bootstrap_pod_type<wchar_t>("wchar_t", m);
|
|
bootstrap_pod_type<char16_t>("char16_t", m);
|
|
bootstrap_pod_type<char32_t>("char32_t", m);
|
|
bootstrap_pod_type<std::int8_t>("int8_t", m);
|
|
bootstrap_pod_type<std::int16_t>("int16_t", m);
|
|
bootstrap_pod_type<std::int32_t>("int32_t", m);
|
|
bootstrap_pod_type<std::int64_t>("int64_t", m);
|
|
bootstrap_pod_type<std::uint8_t>("uint8_t", m);
|
|
bootstrap_pod_type<std::uint16_t>("uint16_t", m);
|
|
bootstrap_pod_type<std::uint32_t>("uint32_t", m);
|
|
bootstrap_pod_type<std::uint64_t>("uint64_t", m);
|
|
|
|
operators::logical_compliment<bool>(m);
|
|
|
|
opers_arithmetic_pod(m);
|
|
|
|
m.add(fun(&Build_Info::version_major), "version_major");
|
|
m.add(fun(&Build_Info::version_minor), "version_minor");
|
|
m.add(fun(&Build_Info::version_patch), "version_patch");
|
|
m.add(fun(&Build_Info::version), "version");
|
|
m.add(fun(&Build_Info::compiler_version), "compiler_version");
|
|
m.add(fun(&Build_Info::compiler_name), "compiler_name");
|
|
m.add(fun(&Build_Info::compiler_id), "compiler_id");
|
|
m.add(fun(&Build_Info::debug_build), "debug_build");
|
|
|
|
if (!t_no_io) {
|
|
m.add(fun(&print), "print_string");
|
|
m.add(fun(&println), "println_string");
|
|
}
|
|
|
|
m.add(dispatch::make_dynamic_proxy_function(&bind_function), "bind");
|
|
|
|
m.add(fun(&shared_ptr_unconst_clone<dispatch::Proxy_Function_Base>), "clone");
|
|
m.add(fun(&ptr_assign<std::remove_const<dispatch::Proxy_Function_Base>::type>), "=");
|
|
m.add(fun(&ptr_assign<std::add_const<dispatch::Proxy_Function_Base>::type>), "=");
|
|
m.add(chaiscript::base_class<dispatch::Proxy_Function_Base, dispatch::Assignable_Proxy_Function>());
|
|
m.add(fun([](dispatch::Assignable_Proxy_Function &t_lhs, const std::shared_ptr<const dispatch::Proxy_Function_Base> &t_rhs) {
|
|
t_lhs.assign(t_rhs);
|
|
}),
|
|
"=");
|
|
|
|
m.add(fun(&Boxed_Value::type_match), "type_match");
|
|
|
|
m.add(chaiscript::fun(&has_parse_tree), "has_parse_tree");
|
|
m.add(chaiscript::fun(&get_parse_tree), "get_parse_tree");
|
|
|
|
m.add(chaiscript::base_class<std::runtime_error, chaiscript::exception::eval_error>());
|
|
m.add(chaiscript::base_class<std::exception, chaiscript::exception::eval_error>());
|
|
|
|
m.add(chaiscript::user_type<chaiscript::exception::arithmetic_error>(), "arithmetic_error");
|
|
m.add(chaiscript::base_class<std::runtime_error, chaiscript::exception::arithmetic_error>());
|
|
m.add(chaiscript::base_class<std::exception, chaiscript::exception::arithmetic_error>());
|
|
|
|
// chaiscript::bootstrap::standard_library::vector_type<std::vector<std::shared_ptr<chaiscript::AST_Node> >
|
|
// >("AST_NodeVector", m);
|
|
|
|
chaiscript::utility::add_class<chaiscript::exception::eval_error>(m,
|
|
"eval_error",
|
|
{},
|
|
{{fun(&chaiscript::exception::eval_error::reason), "reason"},
|
|
{fun(&chaiscript::exception::eval_error::pretty_print), "pretty_print"},
|
|
{fun([](const chaiscript::exception::eval_error &t_eval_error) {
|
|
std::vector<Boxed_Value> retval;
|
|
std::transform(t_eval_error.call_stack.begin(),
|
|
t_eval_error.call_stack.end(),
|
|
std::back_inserter(retval),
|
|
&chaiscript::var<const chaiscript::AST_Node_Trace &>);
|
|
return retval;
|
|
}),
|
|
"call_stack"}});
|
|
|
|
chaiscript::utility::add_class<chaiscript::File_Position>(m,
|
|
"File_Position",
|
|
{constructor<File_Position()>(), constructor<File_Position(int, int)>()},
|
|
{{fun(&File_Position::line), "line"},
|
|
{fun(&File_Position::column), "column"}});
|
|
|
|
chaiscript::utility::add_class<AST_Node>(m,
|
|
"AST_Node",
|
|
{},
|
|
{{fun(&AST_Node::text), "text"},
|
|
{fun(&AST_Node::identifier), "identifier"},
|
|
{fun(&AST_Node::filename), "filename"},
|
|
{fun(&AST_Node::start), "start"},
|
|
{fun(&AST_Node::end), "end"},
|
|
{fun(&AST_Node::to_string), "to_string"},
|
|
{fun([](const chaiscript::AST_Node &t_node) -> std::vector<Boxed_Value> {
|
|
std::vector<Boxed_Value> retval;
|
|
const auto children = t_node.get_children();
|
|
std::transform(children.begin(),
|
|
children.end(),
|
|
std::back_inserter(retval),
|
|
&chaiscript::var<const std::reference_wrapper<chaiscript::AST_Node> &>);
|
|
return retval;
|
|
}),
|
|
"children"}});
|
|
}
|
|
};
|
|
} // namespace chaiscript::bootstrap
|
|
|
|
#endif
|