mirror of
https://github.com/ChaiScript/ChaiScript.git
synced 2025-12-07 01:06:54 +08:00
Merge remote-tracking branch 'origin/develop' into best_practices
This commit is contained in:
commit
8b523c73b8
@ -580,6 +580,8 @@ namespace chaiscript
|
|||||||
m.add(fun([](const String *s, const String &f, size_t pos) { return s->find_last_of(f, pos); } ), "find_last_of");
|
m.add(fun([](const String *s, const String &f, size_t pos) { return s->find_last_of(f, pos); } ), "find_last_of");
|
||||||
m.add(fun([](const String *s, const String &f, size_t pos) { return s->find_last_not_of(f, pos); } ), "find_last_not_of");
|
m.add(fun([](const String *s, const String &f, size_t pos) { return s->find_last_not_of(f, pos); } ), "find_last_not_of");
|
||||||
m.add(fun([](const String *s, const String &f, size_t pos) { return s->find_first_not_of(f, pos); } ), "find_first_not_of");
|
m.add(fun([](const String *s, const String &f, size_t pos) { return s->find_first_not_of(f, pos); } ), "find_first_not_of");
|
||||||
|
|
||||||
|
m.add(fun([](String *s, typename String::value_type c) -> decltype(auto) { return (*s += c); } ), "+=");
|
||||||
|
|
||||||
m.add(fun([](String *s) { s->clear(); } ), "clear");
|
m.add(fun([](String *s) { s->clear(); } ), "clear");
|
||||||
m.add(fun([](const String *s) { return s->empty(); } ), "empty");
|
m.add(fun([](const String *s) { return s->empty(); } ), "empty");
|
||||||
@ -599,7 +601,7 @@ namespace chaiscript
|
|||||||
m.add(user_type<FutureType>(), type);
|
m.add(user_type<FutureType>(), type);
|
||||||
|
|
||||||
m.add(fun([](const FutureType &t) { return t.valid(); }), "valid");
|
m.add(fun([](const FutureType &t) { return t.valid(); }), "valid");
|
||||||
m.add(fun(&FutureType::get), "get");
|
m.add(fun([](FutureType &t) { return t.get(); }), "get");
|
||||||
m.add(fun(&FutureType::wait), "wait");
|
m.add(fun(&FutureType::wait), "wait");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -375,6 +375,10 @@ namespace chaiscript
|
|||||||
validate_boxed_number(bv);
|
validate_boxed_number(bv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Boxed_Value clone(const Boxed_Value &t_bv) {
|
||||||
|
return Boxed_Number(t_bv).get_as(t_bv.get_type_info()).bv;
|
||||||
|
}
|
||||||
|
|
||||||
static bool is_floating_point(const Boxed_Value &t_bv)
|
static bool is_floating_point(const Boxed_Value &t_bv)
|
||||||
{
|
{
|
||||||
const Type_Info &inp_ = t_bv.get_type_info();
|
const Type_Info &inp_ = t_bv.get_type_info();
|
||||||
|
|||||||
@ -88,7 +88,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
|
|
||||||
/// Types of AST nodes available to the parser and eval
|
/// Types of AST nodes available to the parser and eval
|
||||||
enum class AST_Node_Type { Id, Fun_Call, Unused_Return_Fun_Call, Arg_List, Equation, Var_Decl,
|
enum class AST_Node_Type { Id, Fun_Call, Unused_Return_Fun_Call, Arg_List, Equation, Var_Decl, Assign_Decl,
|
||||||
Array_Call, Dot_Access,
|
Array_Call, Dot_Access,
|
||||||
Lambda, Block, Scopeless_Block, Def, While, If, For, Ranged_For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range,
|
Lambda, Block, Scopeless_Block, Def, While, If, For, Ranged_For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range,
|
||||||
Inline_Range, Try, Catch, Finally, Method, Attr_Decl,
|
Inline_Range, Try, Catch, Finally, Method, Attr_Decl,
|
||||||
@ -103,7 +103,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
/// Helper lookup to get the name of each node type
|
/// Helper lookup to get the name of each node type
|
||||||
constexpr const char *ast_node_type_to_string(AST_Node_Type ast_node_type) noexcept {
|
constexpr const char *ast_node_type_to_string(AST_Node_Type ast_node_type) noexcept {
|
||||||
constexpr const char * const ast_node_types[] = { "Id", "Fun_Call", "Unused_Return_Fun_Call", "Arg_List", "Equation", "Var_Decl",
|
constexpr const char * const ast_node_types[] = { "Id", "Fun_Call", "Unused_Return_Fun_Call", "Arg_List", "Equation", "Var_Decl", "Assign_Decl",
|
||||||
"Array_Call", "Dot_Access",
|
"Array_Call", "Dot_Access",
|
||||||
"Lambda", "Block", "Scopeless_Block", "Def", "While", "If", "For", "Ranged_For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range",
|
"Lambda", "Block", "Scopeless_Block", "Def", "While", "If", "For", "Ranged_For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range",
|
||||||
"Inline_Range", "Try", "Catch", "Finally", "Method", "Attr_Decl",
|
"Inline_Range", "Try", "Catch", "Finally", "Method", "Attr_Decl",
|
||||||
|
|||||||
@ -87,6 +87,24 @@ namespace chaiscript
|
|||||||
return std::move(rv.retval);
|
return std::move(rv.retval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Boxed_Value clone_if_necessary(Boxed_Value incoming, std::atomic_uint_fast32_t &t_loc, const chaiscript::detail::Dispatch_State &t_ss)
|
||||||
|
{
|
||||||
|
if (!incoming.is_return_value())
|
||||||
|
{
|
||||||
|
if (incoming.get_type_info().is_arithmetic()) {
|
||||||
|
return Boxed_Number::clone(incoming);
|
||||||
|
} else if (incoming.get_type_info().bare_equal_type_info(typeid(bool))) {
|
||||||
|
return Boxed_Value(*static_cast<const bool*>(incoming.get_const_ptr()));
|
||||||
|
} else {
|
||||||
|
std::array params{std::move(incoming)};
|
||||||
|
return t_ss->call_function("clone", t_loc, Function_Params{params}, t_ss.conversions());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
incoming.reset_return_value();
|
||||||
|
return incoming;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -470,11 +488,7 @@ namespace chaiscript
|
|||||||
params[0].reset_return_value();
|
params[0].reset_return_value();
|
||||||
return params[1];
|
return params[1];
|
||||||
} else {
|
} else {
|
||||||
if (!params[1].is_return_value())
|
params[1] = detail::clone_if_necessary(std::move(params[1]), m_clone_loc, t_ss);
|
||||||
{
|
|
||||||
params[1] = t_ss->call_function("clone", m_clone_loc, Function_Params{¶ms[1], std::end(params)}, t_ss.conversions());
|
|
||||||
}
|
|
||||||
params[1].reset_return_value();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -553,6 +567,27 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Assign_Decl_AST_Node final : AST_Node_Impl<T> {
|
||||||
|
Assign_Decl_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) :
|
||||||
|
AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::Assign_Decl, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
||||||
|
const std::string &idname = this->children[0]->text;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Boxed_Value bv(detail::clone_if_necessary(this->children[1]->eval(t_ss), m_loc, t_ss));
|
||||||
|
bv.reset_return_value();
|
||||||
|
t_ss.add_object(idname, bv);
|
||||||
|
return bv;
|
||||||
|
} catch (const exception::name_conflict_error &e) {
|
||||||
|
throw exception::eval_error("Variable redefined '" + e.name() + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
mutable std::atomic_uint_fast32_t m_loc = {0};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Array_Call_AST_Node final : AST_Node_Impl<T> {
|
struct Array_Call_AST_Node final : AST_Node_Impl<T> {
|
||||||
@ -1070,12 +1105,7 @@ namespace chaiscript
|
|||||||
if (!this->children.empty()) {
|
if (!this->children.empty()) {
|
||||||
vec.reserve(this->children[0]->children.size());
|
vec.reserve(this->children[0]->children.size());
|
||||||
for (const auto &child : this->children[0]->children) {
|
for (const auto &child : this->children[0]->children) {
|
||||||
if (auto obj = child->eval(t_ss);
|
vec.push_back(detail::clone_if_necessary(child->eval(t_ss), m_loc, t_ss));
|
||||||
!obj.is_return_value()) {
|
|
||||||
vec.push_back(t_ss->call_function("clone", m_loc, Function_Params{obj}, t_ss.conversions()));
|
|
||||||
} else {
|
|
||||||
vec.push_back(std::move(obj));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return const_var(std::move(vec));
|
return const_var(std::move(vec));
|
||||||
@ -1100,12 +1130,8 @@ namespace chaiscript
|
|||||||
std::map<std::string, Boxed_Value> retval;
|
std::map<std::string, Boxed_Value> retval;
|
||||||
|
|
||||||
for (const auto &child : this->children[0]->children) {
|
for (const auto &child : this->children[0]->children) {
|
||||||
auto obj = child->children[1]->eval(t_ss);
|
retval.insert(std::make_pair(t_ss->boxed_cast<std::string>(child->children[0]->eval(t_ss)),
|
||||||
if (!obj.is_return_value()) {
|
detail::clone_if_necessary(child->children[1]->eval(t_ss), m_loc, t_ss)));
|
||||||
obj = t_ss->call_function("clone", m_loc, Function_Params{obj}, t_ss.conversions());
|
|
||||||
}
|
|
||||||
|
|
||||||
retval[t_ss->boxed_cast<std::string>(child->children[0]->eval(t_ss))] = std::move(obj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return const_var(std::move(retval));
|
return const_var(std::move(retval));
|
||||||
|
|||||||
@ -97,7 +97,7 @@ namespace chaiscript {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
bool contains_var_decl_in_scope(const eval::AST_Node_Impl<T> &node) noexcept
|
bool contains_var_decl_in_scope(const eval::AST_Node_Impl<T> &node) noexcept
|
||||||
{
|
{
|
||||||
if (node.identifier == AST_Node_Type::Var_Decl) {
|
if (node.identifier == AST_Node_Type::Var_Decl || node.identifier == AST_Node_Type::Assign_Decl) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,6 +208,27 @@ namespace chaiscript {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Assign_Decl {
|
||||||
|
template<typename T>
|
||||||
|
auto optimize(eval::AST_Node_Impl_Ptr<T> node) {
|
||||||
|
if ((node->identifier == AST_Node_Type::Equation)
|
||||||
|
&& node->text == "="
|
||||||
|
&& node->children.size() == 2
|
||||||
|
&& node->children[0]->identifier == AST_Node_Type::Var_Decl
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<eval::AST_Node_Impl_Ptr<T>> new_children;
|
||||||
|
new_children.push_back(std::move(node->children[0]->children[0]));
|
||||||
|
new_children.push_back(std::move(node->children[1]));
|
||||||
|
return chaiscript::make_unique<eval::AST_Node_Impl<T>, eval::Assign_Decl_AST_Node<T>>(node->text,
|
||||||
|
node->location, std::move(new_children) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct If {
|
struct If {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto optimize(eval::AST_Node_Impl_Ptr<T> node) {
|
auto optimize(eval::AST_Node_Impl_Ptr<T> node) {
|
||||||
@ -440,7 +461,7 @@ namespace chaiscript {
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef Optimizer<optimizer::Partial_Fold, optimizer::Unused_Return, optimizer::Constant_Fold,
|
typedef Optimizer<optimizer::Partial_Fold, optimizer::Unused_Return, optimizer::Constant_Fold,
|
||||||
optimizer::If, optimizer::Return, optimizer::Dead_Code, optimizer::Block, optimizer::For_Loop> Optimizer_Default;
|
optimizer::If, optimizer::Return, optimizer::Dead_Code, optimizer::Block, optimizer::For_Loop, optimizer::Assign_Decl> Optimizer_Default;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1030,7 +1030,7 @@ namespace chaiscript
|
|||||||
int in_interpolation = 0;
|
int in_interpolation = 0;
|
||||||
bool in_quote = false;
|
bool in_quote = false;
|
||||||
|
|
||||||
while (m_position.has_more() && ((*m_position != '\"') || ((*m_position == '\"') && (in_interpolation > 0)) || ((*m_position == '\"') && (prev_char == '\\')))) {
|
while (m_position.has_more() && ((*m_position != '\"') || (in_interpolation > 0) || (prev_char == '\\'))) {
|
||||||
|
|
||||||
if (!Eol_()) {
|
if (!Eol_()) {
|
||||||
if (prev_char == '$' && *m_position == '{') {
|
if (prev_char == '$' && *m_position == '{') {
|
||||||
@ -1328,7 +1328,7 @@ namespace chaiscript
|
|||||||
char prev_char = *m_position;
|
char prev_char = *m_position;
|
||||||
++m_position;
|
++m_position;
|
||||||
|
|
||||||
while (m_position.has_more() && ((*m_position != '\'') || ((*m_position == '\'') && (prev_char == '\\')))) {
|
while (m_position.has_more() && ((*m_position != '\'') || (prev_char == '\\'))) {
|
||||||
if (!Eol_()) {
|
if (!Eol_()) {
|
||||||
if (prev_char == '\\') {
|
if (prev_char == '\\') {
|
||||||
prev_char = 0;
|
prev_char = 0;
|
||||||
|
|||||||
@ -41,7 +41,7 @@ namespace chaiscript
|
|||||||
struct DLSym
|
struct DLSym
|
||||||
{
|
{
|
||||||
DLSym(DLModule &t_mod, const std::string &t_symbol)
|
DLSym(DLModule &t_mod, const std::string &t_symbol)
|
||||||
: m_symbol(cast_symbol(dlsym(t_mod.m_data, t_symbol.c_str())))
|
: m_symbol(reinterpret_cast<T>(dlsym(t_mod.m_data, t_symbol.c_str())))
|
||||||
{
|
{
|
||||||
if (!m_symbol)
|
if (!m_symbol)
|
||||||
{
|
{
|
||||||
@ -49,19 +49,6 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static T cast_symbol(void *p) noexcept
|
|
||||||
{
|
|
||||||
union cast_union
|
|
||||||
{
|
|
||||||
T func_ptr;
|
|
||||||
void *in_ptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
cast_union c;
|
|
||||||
c.in_ptr = p;
|
|
||||||
return c.func_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
T m_symbol;
|
T m_symbol;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -50,7 +50,7 @@ class JSON
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
||||||
using Data = std::variant<nullptr_t, chaiscript::utility::QuickFlatMap<std::string, JSON>, std::vector<JSON>, std::string, double, int, bool>;
|
using Data = std::variant<nullptr_t, chaiscript::utility::QuickFlatMap<std::string, JSON>, std::vector<JSON>, std::string, double, int64_t, bool>;
|
||||||
|
|
||||||
struct Internal
|
struct Internal
|
||||||
{
|
{
|
||||||
@ -66,7 +66,7 @@ class JSON
|
|||||||
case Class::Array: return std::vector<JSON>{};
|
case Class::Array: return std::vector<JSON>{};
|
||||||
case Class::String: return std::string{};
|
case Class::String: return std::string{};
|
||||||
case Class::Floating: return double{};
|
case Class::Floating: return double{};
|
||||||
case Class::Integral: return int{};
|
case Class::Integral: return int64_t{};
|
||||||
case Class::Boolean: return bool{};
|
case Class::Boolean: return bool{};
|
||||||
}
|
}
|
||||||
throw std::runtime_error("unknown type");
|
throw std::runtime_error("unknown type");
|
||||||
@ -137,7 +137,6 @@ class JSON
|
|||||||
return std::get_if<static_cast<std::size_t>(Class::Boolean)>(&d);
|
return std::get_if<static_cast<std::size_t>(Class::Boolean)>(&d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Data d;
|
Data d;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -192,7 +191,7 @@ class JSON
|
|||||||
explicit JSON( T b, typename enable_if<is_same<T,bool>::value>::type* = nullptr ) noexcept : internal( static_cast<bool>(b) ) {}
|
explicit JSON( T b, typename enable_if<is_same<T,bool>::value>::type* = nullptr ) noexcept : internal( static_cast<bool>(b) ) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
explicit JSON( T i, typename enable_if<is_integral<T>::value && !is_same<T,bool>::value>::type* = nullptr ) noexcept : internal( static_cast<int>(i) ) {}
|
explicit JSON( T i, typename enable_if<is_integral<T>::value && !is_same<T,bool>::value>::type* = nullptr ) noexcept : internal( static_cast<int64_t>(i) ) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
explicit JSON( T f, typename enable_if<is_floating_point<T>::value>::type* = nullptr ) noexcept : internal( static_cast<double>(f) ) {}
|
explicit JSON( T f, typename enable_if<is_floating_point<T>::value>::type* = nullptr ) noexcept : internal( static_cast<double>(f) ) {}
|
||||||
@ -281,10 +280,10 @@ class JSON
|
|||||||
[](){ return double{}; }
|
[](){ return double{}; }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
int to_int() const noexcept {
|
int64_t to_int() const noexcept {
|
||||||
return internal.visit_or<Class::Integral>(
|
return internal.visit_or<Class::Integral>(
|
||||||
[](const auto &o){ return o; },
|
[](const auto &o){ return o; },
|
||||||
[](){ return int{}; }
|
[](){ return int64_t{}; }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
bool to_bool() const noexcept {
|
bool to_bool() const noexcept {
|
||||||
@ -498,7 +497,8 @@ struct JSONParser {
|
|||||||
char c = '\0';
|
char c = '\0';
|
||||||
bool isDouble = false;
|
bool isDouble = false;
|
||||||
bool isNegative = false;
|
bool isNegative = false;
|
||||||
long exp = 0;
|
int64_t exp = 0;
|
||||||
|
bool isExpNegative = false;
|
||||||
if( offset < str.size() && str.at(offset) == '-' ) {
|
if( offset < str.size() && str.at(offset) == '-' ) {
|
||||||
isNegative = true;
|
isNegative = true;
|
||||||
++offset;
|
++offset;
|
||||||
@ -517,7 +517,7 @@ struct JSONParser {
|
|||||||
if( offset < str.size() && (c == 'E' || c == 'e' )) {
|
if( offset < str.size() && (c == 'E' || c == 'e' )) {
|
||||||
c = str.at(offset++);
|
c = str.at(offset++);
|
||||||
if( c == '-' ) {
|
if( c == '-' ) {
|
||||||
exp_str += '-';
|
isExpNegative = true;
|
||||||
} else if( c == '+' ) {
|
} else if( c == '+' ) {
|
||||||
// do nothing
|
// do nothing
|
||||||
} else {
|
} else {
|
||||||
@ -533,9 +533,9 @@ struct JSONParser {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exp = chaiscript::parse_num<long>( exp_str );
|
exp = chaiscript::parse_num<int64_t>( exp_str ) * (isExpNegative?-1:1);
|
||||||
}
|
}
|
||||||
else if( offset < str.size() && (!isspace( c ) && c != ',' && c != ']' && c != '}' )) {
|
else if( offset < str.size() && (!isspace( c ) && c != ',' && c != ']' && c != '}' )) {
|
||||||
throw std::runtime_error(std::string("JSON ERROR: Number: unexpected character '") + c + "'");
|
throw std::runtime_error(std::string("JSON ERROR: Number: unexpected character '") + c + "'");
|
||||||
@ -546,9 +546,9 @@ struct JSONParser {
|
|||||||
return JSON((isNegative?-1:1) * chaiscript::parse_num<double>( val ) * std::pow( 10, exp ));
|
return JSON((isNegative?-1:1) * chaiscript::parse_num<double>( val ) * std::pow( 10, exp ));
|
||||||
} else {
|
} else {
|
||||||
if( !exp_str.empty() ) {
|
if( !exp_str.empty() ) {
|
||||||
return JSON((isNegative?-1:1) * static_cast<double>(chaiscript::parse_num<long>( val )) * std::pow( 10, exp ));
|
return JSON((isNegative?-1:1) * static_cast<double>(chaiscript::parse_num<int64_t>( val )) * std::pow( 10, exp ));
|
||||||
} else {
|
} else {
|
||||||
return JSON((isNegative?-1:1) * chaiscript::parse_num<long>( val ));
|
return JSON((isNegative?-1:1) * chaiscript::parse_num<int64_t>( val ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
11
performance_tests/create_variables.chai
Normal file
11
performance_tests/create_variables.chai
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
def var_test(int n)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < n; ++i) {
|
||||||
|
var j = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var n = 500000
|
||||||
|
var_test(n) // takes 2.6 s
|
||||||
|
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ Release under the BSD license, see "license.txt" for details.
|
|||||||
Introduction
|
Introduction
|
||||||
============
|
============
|
||||||
|
|
||||||
[](https://gitter.im/ChaiScript/ChaiScript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[](https://gitter.im/ChaiScript/ChaiScript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|
|
||||||
ChaiScript is one of the only embedded scripting language designed from the
|
ChaiScript is one of the only embedded scripting language designed from the
|
||||||
ground up to directly target C++ and take advantage of modern C++ development
|
ground up to directly target C++ and take advantage of modern C++ development
|
||||||
|
|||||||
@ -51,11 +51,9 @@ struct System
|
|||||||
void do_callbacks(const std::string &inp)
|
void do_callbacks(const std::string &inp)
|
||||||
{
|
{
|
||||||
log("Running Callbacks: " + inp);
|
log("Running Callbacks: " + inp);
|
||||||
for (std::map<std::string, std::function<std::string (const std::string &)> >::iterator itr = m_callbacks.begin();
|
for (auto & m_callback : m_callbacks)
|
||||||
itr != m_callbacks.end();
|
|
||||||
++itr)
|
|
||||||
{
|
{
|
||||||
log("Callback: " + itr->first, itr->second(inp));
|
log("Callback: " + m_callback.first, m_callback.second(inp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -88,25 +86,25 @@ int main(int /*argc*/, char * /*argv*/[]) {
|
|||||||
// The function "{ 'Callback1' + x }" is created in chaiscript and passed into our C++ application
|
// The function "{ 'Callback1' + x }" is created in chaiscript and passed into our C++ application
|
||||||
// in the "add_callback" function of struct System the chaiscript function is converted into a
|
// in the "add_callback" function of struct System the chaiscript function is converted into a
|
||||||
// std::function, so it can be handled and called easily and type-safely
|
// std::function, so it can be handled and called easily and type-safely
|
||||||
chai.eval("system.add_callback(\"#1\", fun(x) { \"Callback1 \" + x });");
|
chai.eval(R"(system.add_callback("#1", fun(x) { "Callback1 " + x });)");
|
||||||
|
|
||||||
// Because we are sharing the "system" object with the chaiscript engine we have equal
|
// Because we are sharing the "system" object with the chaiscript engine we have equal
|
||||||
// access to it both from within chaiscript and from C++ code
|
// access to it both from within chaiscript and from C++ code
|
||||||
system.do_callbacks("TestString");
|
system.do_callbacks("TestString");
|
||||||
chai.eval("system.do_callbacks(\"TestString\");");
|
chai.eval(R"(system.do_callbacks("TestString");)");
|
||||||
|
|
||||||
// The log function is overloaded, therefore we have to give the C++ compiler a hint as to which
|
// The log function is overloaded, therefore we have to give the C++ compiler a hint as to which
|
||||||
// version we want to register. One way to do this is to create a typedef of the function pointer
|
// version we want to register. One way to do this is to create a typedef of the function pointer
|
||||||
// then cast your function to that typedef.
|
// then cast your function to that typedef.
|
||||||
typedef void (*PlainLog)(const std::string &);
|
using PlainLog = void (*)(const std::string &);
|
||||||
typedef void (*ModuleLog)(const std::string &, const std::string &);
|
using ModuleLog = void (*)(const std::string &, const std::string &);
|
||||||
chai.add(fun(PlainLog(&log)), "log");
|
chai.add(fun(PlainLog(&log)), "log");
|
||||||
chai.add(fun(ModuleLog(&log)), "log");
|
chai.add(fun(ModuleLog(&log)), "log");
|
||||||
|
|
||||||
chai.eval("log(\"Test Message\")");
|
chai.eval(R"(log("Test Message"))");
|
||||||
|
|
||||||
// A shortcut to using eval is just to use the chai operator()
|
// A shortcut to using eval is just to use the chai operator()
|
||||||
chai("log(\"Test Module\", \"Test Message\");");
|
chai(R"(log("Test Module", "Test Message");)");
|
||||||
|
|
||||||
//Finally, it is possible to register a lambda as a system function, in this
|
//Finally, it is possible to register a lambda as a system function, in this
|
||||||
//way, we can, for instance add a bound member function to the system
|
//way, we can, for instance add a bound member function to the system
|
||||||
@ -115,7 +113,9 @@ int main(int /*argc*/, char * /*argv*/[]) {
|
|||||||
//Call bound version of do_callbacks
|
//Call bound version of do_callbacks
|
||||||
chai("do_callbacks()");
|
chai("do_callbacks()");
|
||||||
|
|
||||||
std::function<void ()> caller = chai.eval<std::function<void ()> >("fun() { system.do_callbacks(\"From Functor\"); }");
|
std::function<void ()> caller = chai.eval<std::function<void ()> >(
|
||||||
|
R"(fun() { system.do_callbacks("From Functor"); })"
|
||||||
|
);
|
||||||
caller();
|
caller();
|
||||||
|
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ int main(int /*argc*/, char * /*argv*/[]) {
|
|||||||
std::cout << "scripti: " << scripti << '\n';
|
std::cout << "scripti: " << scripti << '\n';
|
||||||
scripti *= 2;
|
scripti *= 2;
|
||||||
std::cout << "scripti (updated): " << scripti << '\n';
|
std::cout << "scripti (updated): " << scripti << '\n';
|
||||||
chai("print(\"Scripti from chai: \" + to_string(scripti))");
|
chai(R"(print("Scripti from chai: " + to_string(scripti)))");
|
||||||
|
|
||||||
//To do: Add examples of handling Boxed_Values directly when needed
|
//To do: Add examples of handling Boxed_Values directly when needed
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ int main(int /*argc*/, char * /*argv*/[]) {
|
|||||||
log("Functor test output", ss.str());
|
log("Functor test output", ss.str());
|
||||||
|
|
||||||
chai.add(var(std::shared_ptr<int>()), "nullvar");
|
chai.add(var(std::shared_ptr<int>()), "nullvar");
|
||||||
chai("print(\"This should be true.\"); print(nullvar.is_var_null())");
|
chai(R"(print("This should be true."); print(nullvar.is_var_null()))");
|
||||||
|
|
||||||
// test the global const action
|
// test the global const action
|
||||||
chai.add_global_const(const_var(1), "constvar");
|
chai.add_global_const(const_var(1), "constvar");
|
||||||
@ -160,7 +160,7 @@ int main(int /*argc*/, char * /*argv*/[]) {
|
|||||||
|
|
||||||
|
|
||||||
// Test ability to register a function that excepts a shared_ptr version of a type
|
// Test ability to register a function that excepts a shared_ptr version of a type
|
||||||
chai("take_shared_ptr(\"Hello World as a shared_ptr\");");
|
chai(R"(take_shared_ptr("Hello World as a shared_ptr");)");
|
||||||
|
|
||||||
chai.add(fun(&bound_log, std::string("Msg")), "BoundFun");
|
chai.add(fun(&bound_log, std::string("Msg")), "BoundFun");
|
||||||
|
|
||||||
|
|||||||
@ -122,7 +122,7 @@ int main()
|
|||||||
assert(myderived.getValue() == "1234");
|
assert(myderived.getValue() == "1234");
|
||||||
|
|
||||||
|
|
||||||
chai.eval("myderived.setValue(\"new\")"); // set the value via chaiscript
|
chai.eval(R"(myderived.setValue("new"))"); // set the value via chaiscript
|
||||||
assert(myderived.getValue() == "new");
|
assert(myderived.getValue() == "new");
|
||||||
|
|
||||||
// call the other derived method via chaiscript and return the value to c++ land:
|
// call the other derived method via chaiscript and return the value to c++ land:
|
||||||
|
|||||||
5
unittests/json_14.chai
Normal file
5
unittests/json_14.chai
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
assert_equal(from_json("9.9e-02"), 9.9e-02)
|
||||||
|
assert_equal(from_json("-13.57e+3"), -13570.0)
|
||||||
|
assert_equal(from_json("1E-01"), 0.1)
|
||||||
|
assert_equal(from_json("-314159e-5"), -3.14159)
|
||||||
|
assert_equal(from_json("5e+04"), 50000)
|
||||||
Loading…
x
Reference in New Issue
Block a user