Save stack & and prevent lookups
This commit is contained in:
@@ -384,10 +384,31 @@ namespace chaiscript
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct Stack_Holder
|
||||
{
|
||||
typedef std::vector<std::pair<std::string, Boxed_Value>> Scope;
|
||||
typedef std::vector<Scope> StackData;
|
||||
|
||||
Stack_Holder()
|
||||
: call_depth(0)
|
||||
{
|
||||
stacks.reserve(2);
|
||||
stacks.emplace_back(1);
|
||||
call_params.emplace_back();
|
||||
call_params.back().reserve(2);
|
||||
}
|
||||
|
||||
std::vector<StackData> stacks;
|
||||
|
||||
std::vector<std::vector<Boxed_Value>> call_params;
|
||||
int call_depth;
|
||||
};
|
||||
|
||||
/// Main class for the dispatchkit. Handles management
|
||||
/// of the object stack, functions and registered types.
|
||||
class Dispatch_Engine
|
||||
{
|
||||
|
||||
public:
|
||||
typedef std::map<std::string, chaiscript::Type_Info> Type_Name_Map;
|
||||
typedef std::vector<std::pair<std::string, Boxed_Value>> Scope;
|
||||
@@ -536,15 +557,27 @@ namespace chaiscript
|
||||
/// Adds a new scope to the stack
|
||||
void new_scope()
|
||||
{
|
||||
get_stack_data().emplace_back();
|
||||
m_stack_holder->call_params.emplace_back();
|
||||
new_scope(*m_stack_holder);
|
||||
}
|
||||
|
||||
/// Pops the current scope from the stack
|
||||
void pop_scope()
|
||||
{
|
||||
m_stack_holder->call_params.pop_back();
|
||||
StackData &stack = get_stack_data();
|
||||
pop_scope(*m_stack_holder);
|
||||
}
|
||||
|
||||
/// Adds a new scope to the stack
|
||||
void new_scope(Stack_Holder &t_holder)
|
||||
{
|
||||
get_stack_data(t_holder).emplace_back();
|
||||
t_holder.call_params.emplace_back();
|
||||
}
|
||||
|
||||
/// Pops the current scope from the stack
|
||||
void pop_scope(Stack_Holder &t_holder)
|
||||
{
|
||||
t_holder.call_params.pop_back();
|
||||
StackData &stack = get_stack_data(t_holder);
|
||||
if (stack.size() > 1)
|
||||
{
|
||||
stack.pop_back();
|
||||
@@ -555,15 +588,15 @@ namespace chaiscript
|
||||
|
||||
|
||||
/// Pushes a new stack on to the list of stacks
|
||||
void new_stack()
|
||||
void new_stack(Stack_Holder &t_holder)
|
||||
{
|
||||
// add a new Stack with 1 element
|
||||
m_stack_holder->stacks.emplace_back(1);
|
||||
t_holder.stacks.emplace_back(1);
|
||||
}
|
||||
|
||||
void pop_stack()
|
||||
void pop_stack(Stack_Holder &t_holder)
|
||||
{
|
||||
m_stack_holder->stacks.pop_back();
|
||||
t_holder.stacks.pop_back();
|
||||
}
|
||||
|
||||
/// Searches the current stack for an object of the given name
|
||||
@@ -1091,55 +1124,79 @@ namespace chaiscript
|
||||
m_state = t_state;
|
||||
}
|
||||
|
||||
void save_function_params(Stack_Holder &t_s, std::initializer_list<Boxed_Value> t_params)
|
||||
{
|
||||
t_s.call_params.back().insert(t_s.call_params.back().begin(), std::move(t_params));
|
||||
}
|
||||
|
||||
void save_function_params(Stack_Holder &t_s, std::vector<Boxed_Value> &&t_params)
|
||||
{
|
||||
for (auto &¶m : t_params)
|
||||
{
|
||||
t_s.call_params.back().insert(t_s.call_params.back().begin(), std::move(param));
|
||||
}
|
||||
}
|
||||
|
||||
void save_function_params(Stack_Holder &t_s, const std::vector<Boxed_Value> &t_params)
|
||||
{
|
||||
t_s.call_params.back().insert(t_s.call_params.back().begin(), t_params.begin(), t_params.end());
|
||||
}
|
||||
|
||||
void save_function_params(std::initializer_list<Boxed_Value> t_params)
|
||||
{
|
||||
Stack_Holder &s = *m_stack_holder;
|
||||
s.call_params.back().insert(s.call_params.back().begin(), std::move(t_params));
|
||||
save_function_params(*m_stack_holder, std::move(t_params));
|
||||
}
|
||||
|
||||
void save_function_params(std::vector<Boxed_Value> &&t_params)
|
||||
{
|
||||
Stack_Holder &s = *m_stack_holder;
|
||||
|
||||
for (auto &¶m : t_params)
|
||||
{
|
||||
s.call_params.back().insert(s.call_params.back().begin(), std::move(param));
|
||||
}
|
||||
save_function_params(*m_stack_holder, std::move(t_params));
|
||||
}
|
||||
|
||||
void save_function_params(const std::vector<Boxed_Value> &t_params)
|
||||
{
|
||||
Stack_Holder &s = *m_stack_holder;
|
||||
s.call_params.back().insert(s.call_params.back().begin(), t_params.begin(), t_params.end());
|
||||
save_function_params(*m_stack_holder, t_params);
|
||||
}
|
||||
|
||||
void new_function_call()
|
||||
void new_function_call(Stack_Holder &t_s)
|
||||
{
|
||||
Stack_Holder &s = *m_stack_holder;
|
||||
if (s.call_depth == 0)
|
||||
if (t_s.call_depth == 0)
|
||||
{
|
||||
m_conversions.enable_conversion_saves(true);
|
||||
}
|
||||
|
||||
++s.call_depth;
|
||||
++t_s.call_depth;
|
||||
|
||||
save_function_params(m_conversions.take_saves());
|
||||
}
|
||||
|
||||
void pop_function_call()
|
||||
void pop_function_call(Stack_Holder &t_s)
|
||||
{
|
||||
Stack_Holder &s = *m_stack_holder;
|
||||
--s.call_depth;
|
||||
--t_s.call_depth;
|
||||
|
||||
assert(s.call_depth >= 0);
|
||||
assert(t_s.call_depth >= 0);
|
||||
|
||||
if (s.call_depth == 0)
|
||||
if (t_s.call_depth == 0)
|
||||
{
|
||||
s.call_params.back().clear();
|
||||
t_s.call_params.back().clear();
|
||||
m_conversions.enable_conversion_saves(false);
|
||||
}
|
||||
}
|
||||
|
||||
void new_function_call()
|
||||
{
|
||||
new_function_call(*m_stack_holder);
|
||||
}
|
||||
|
||||
void pop_function_call()
|
||||
{
|
||||
pop_function_call(*m_stack_holder);
|
||||
}
|
||||
|
||||
Stack_Holder &get_stack_holder()
|
||||
{
|
||||
return *m_stack_holder;
|
||||
}
|
||||
|
||||
private:
|
||||
/// Returns the current stack
|
||||
/// make const/non const versions
|
||||
@@ -1148,6 +1205,11 @@ namespace chaiscript
|
||||
return m_stack_holder->stacks.back();
|
||||
}
|
||||
|
||||
StackData &get_stack_data(Stack_Holder &t_holder)
|
||||
{
|
||||
return t_holder.stacks.back();
|
||||
}
|
||||
|
||||
StackData &get_stack_data()
|
||||
{
|
||||
return m_stack_holder->stacks.back();
|
||||
@@ -1341,22 +1403,6 @@ namespace chaiscript
|
||||
mutable chaiscript::detail::threading::shared_mutex m_mutex;
|
||||
mutable chaiscript::detail::threading::shared_mutex m_global_object_mutex;
|
||||
|
||||
struct Stack_Holder
|
||||
{
|
||||
Stack_Holder()
|
||||
: call_depth(0)
|
||||
{
|
||||
stacks.reserve(2);
|
||||
stacks.emplace_back(1);
|
||||
call_params.emplace_back();
|
||||
call_params.back().reserve(2);
|
||||
}
|
||||
|
||||
std::vector<StackData> stacks;
|
||||
|
||||
std::vector<std::vector<Boxed_Value>> call_params;
|
||||
int call_depth;
|
||||
};
|
||||
|
||||
Type_Conversions m_conversions;
|
||||
chaiscript::detail::threading::Thread_Storage<Stack_Holder> m_stack_holder;
|
||||
@@ -1364,6 +1410,32 @@ namespace chaiscript
|
||||
|
||||
State m_state;
|
||||
};
|
||||
|
||||
class Dispatch_State
|
||||
{
|
||||
public:
|
||||
Dispatch_State(Dispatch_Engine &t_engine)
|
||||
: m_engine(t_engine),
|
||||
m_stack_holder(t_engine.get_stack_holder())
|
||||
{
|
||||
}
|
||||
|
||||
Dispatch_Engine *operator->() const {
|
||||
return &m_engine.get();
|
||||
}
|
||||
|
||||
Dispatch_Engine &operator*() const {
|
||||
return m_engine.get();
|
||||
}
|
||||
|
||||
Stack_Holder &stack_holder() const {
|
||||
return m_stack_holder.get();
|
||||
}
|
||||
|
||||
private:
|
||||
std::reference_wrapper<Dispatch_Engine> m_engine;
|
||||
std::reference_wrapper<Stack_Holder> m_stack_holder;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -476,7 +476,7 @@ namespace chaiscript
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_e) const
|
||||
Boxed_Value eval(const chaiscript::detail::Dispatch_State &t_e) const
|
||||
{
|
||||
try {
|
||||
return eval_internal(t_e);
|
||||
@@ -512,7 +512,7 @@ namespace chaiscript
|
||||
{
|
||||
}
|
||||
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &) const
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const
|
||||
{
|
||||
throw std::runtime_error("Undispatched ast_node (internal error)");
|
||||
}
|
||||
@@ -554,21 +554,20 @@ namespace chaiscript
|
||||
Scope_Push_Pop(const Scope_Push_Pop &) = delete;
|
||||
Scope_Push_Pop& operator=(const Scope_Push_Pop &) = delete;
|
||||
|
||||
Scope_Push_Pop(chaiscript::detail::Dispatch_Engine &t_de)
|
||||
: m_de(t_de)
|
||||
Scope_Push_Pop(const chaiscript::detail::Dispatch_State &t_ds)
|
||||
: m_ds(t_ds)
|
||||
{
|
||||
m_de.new_scope();
|
||||
m_ds.get()->new_scope(m_ds.get().stack_holder());
|
||||
}
|
||||
|
||||
~Scope_Push_Pop()
|
||||
{
|
||||
m_de.pop_scope();
|
||||
m_ds.get()->pop_scope(m_ds.get().stack_holder());
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
chaiscript::detail::Dispatch_Engine &m_de;
|
||||
std::reference_wrapper<const chaiscript::detail::Dispatch_State> m_ds;
|
||||
};
|
||||
|
||||
/// Creates a new function call and pops it on destruction
|
||||
@@ -577,31 +576,30 @@ namespace chaiscript
|
||||
Function_Push_Pop(const Function_Push_Pop &) = delete;
|
||||
Function_Push_Pop& operator=(const Function_Push_Pop &) = delete;
|
||||
|
||||
Function_Push_Pop(chaiscript::detail::Dispatch_Engine &t_de)
|
||||
: m_de(t_de)
|
||||
Function_Push_Pop(const chaiscript::detail::Dispatch_State &t_ds)
|
||||
: m_ds(t_ds)
|
||||
{
|
||||
m_de.new_function_call();
|
||||
m_ds.get()->new_function_call(m_ds.get().stack_holder());
|
||||
}
|
||||
|
||||
~Function_Push_Pop()
|
||||
{
|
||||
m_de.pop_function_call();
|
||||
m_ds.get()->pop_function_call(m_ds.get().stack_holder());
|
||||
}
|
||||
|
||||
void save_params(const std::vector<Boxed_Value> &t_params)
|
||||
{
|
||||
m_de.save_function_params(t_params);
|
||||
m_ds.get()->save_function_params(t_params);
|
||||
}
|
||||
|
||||
void save_params(std::initializer_list<Boxed_Value> t_params)
|
||||
{
|
||||
m_de.save_function_params(std::move(t_params));
|
||||
m_ds.get()->save_function_params(std::move(t_params));
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
chaiscript::detail::Dispatch_Engine &m_de;
|
||||
std::reference_wrapper<const chaiscript::detail::Dispatch_State> m_ds;
|
||||
};
|
||||
|
||||
/// Creates a new scope then pops it on destruction
|
||||
@@ -610,21 +608,20 @@ namespace chaiscript
|
||||
Stack_Push_Pop(const Stack_Push_Pop &) = delete;
|
||||
Stack_Push_Pop& operator=(const Stack_Push_Pop &) = delete;
|
||||
|
||||
Stack_Push_Pop(chaiscript::detail::Dispatch_Engine &t_de)
|
||||
: m_de(t_de)
|
||||
Stack_Push_Pop(const chaiscript::detail::Dispatch_State &t_ds)
|
||||
: m_ds(t_ds)
|
||||
{
|
||||
m_de.new_stack();
|
||||
m_ds.get()->new_stack(m_ds.get().stack_holder());
|
||||
}
|
||||
|
||||
~Stack_Push_Pop()
|
||||
{
|
||||
m_de.pop_stack();
|
||||
m_ds.get()->pop_stack(m_ds.get().stack_holder());
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
chaiscript::detail::Dispatch_Engine &m_de;
|
||||
std::reference_wrapper<const chaiscript::detail::Dispatch_State> m_ds;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -45,7 +45,8 @@ namespace chaiscript
|
||||
{
|
||||
/// Helper function that will set up the scope around a function call, including handling the named function parameters
|
||||
static Boxed_Value eval_function(chaiscript::detail::Dispatch_Engine &t_ss, const AST_NodePtr &t_node, const std::vector<std::string> &t_param_names, const std::vector<Boxed_Value> &t_vals, const std::map<std::string, Boxed_Value> &t_locals=std::map<std::string, Boxed_Value>()) {
|
||||
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
||||
chaiscript::detail::Dispatch_State state(t_ss);
|
||||
chaiscript::eval::detail::Scope_Push_Pop spp(state);
|
||||
|
||||
for (const auto &local : t_locals) {
|
||||
t_ss.add_object(local.first, local.second);
|
||||
@@ -56,7 +57,7 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
try {
|
||||
return t_node->eval(t_ss);
|
||||
return t_node->eval(state);
|
||||
} catch (detail::Return_Value &rv) {
|
||||
return std::move(rv.retval);
|
||||
}
|
||||
@@ -71,7 +72,7 @@ namespace chaiscript
|
||||
{ }
|
||||
|
||||
virtual ~Binary_Operator_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
return do_oper(t_ss, m_oper, text,
|
||||
this->children[0]->eval(t_ss),
|
||||
this->children[1]->eval(t_ss));
|
||||
@@ -83,7 +84,7 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
protected:
|
||||
Boxed_Value do_oper(chaiscript::detail::Dispatch_Engine &t_ss,
|
||||
Boxed_Value do_oper(const chaiscript::detail::Dispatch_State &t_ss,
|
||||
Operators::Opers t_oper, const std::string &t_oper_string, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) const
|
||||
{
|
||||
try {
|
||||
@@ -101,11 +102,11 @@ namespace chaiscript
|
||||
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
|
||||
fpp.save_params({t_lhs, t_rhs});
|
||||
chaiscript::eval::detail::Stack_Push_Pop spp(t_ss);
|
||||
return t_ss.call_function(t_oper_string, t_lhs, t_rhs);
|
||||
return t_ss->call_function(t_oper_string, t_lhs, t_rhs);
|
||||
}
|
||||
}
|
||||
catch(const exception::dispatch_error &e){
|
||||
throw exception::eval_error("Can not find appropriate '" + t_oper_string + "' operator.", e.parameters, e.functions, false, t_ss);
|
||||
throw exception::eval_error("Can not find appropriate '" + t_oper_string + "' operator.", e.parameters, e.functions, false, *t_ss);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +120,7 @@ namespace chaiscript
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Int, std::move(t_loc)),
|
||||
m_value(std::move(t_bv)) { }
|
||||
virtual ~Int_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const CHAISCRIPT_OVERRIDE{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
@@ -134,7 +135,7 @@ namespace chaiscript
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Float, std::move(t_loc)),
|
||||
m_value(std::move(t_bv)) { }
|
||||
virtual ~Float_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const CHAISCRIPT_OVERRIDE{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
@@ -151,13 +152,13 @@ namespace chaiscript
|
||||
{ }
|
||||
|
||||
virtual ~Id_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
if (!m_value.is_undef())
|
||||
{
|
||||
return m_value;
|
||||
} else {
|
||||
try {
|
||||
return t_ss.get_object(this->text, m_loc);
|
||||
return t_ss->get_object(this->text, m_loc);
|
||||
}
|
||||
catch (std::exception &) {
|
||||
throw exception::eval_error("Can not find object: " + this->text);
|
||||
@@ -220,7 +221,7 @@ namespace chaiscript
|
||||
Fun_Call_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Fun_Call, std::move(t_loc), std::move(t_children)) { }
|
||||
virtual ~Fun_Call_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
|
||||
|
||||
std::vector<Boxed_Value> params;
|
||||
@@ -236,16 +237,16 @@ namespace chaiscript
|
||||
|
||||
try {
|
||||
chaiscript::eval::detail::Stack_Push_Pop spp(t_ss);
|
||||
return (*t_ss.boxed_cast<const Const_Proxy_Function &>(fn))(params, t_ss.conversions());
|
||||
return (*t_ss->boxed_cast<const Const_Proxy_Function &>(fn))(params, t_ss->conversions());
|
||||
}
|
||||
catch(const exception::dispatch_error &e){
|
||||
throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'", e.parameters, e.functions, false, t_ss);
|
||||
throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'", e.parameters, e.functions, false, *t_ss);
|
||||
}
|
||||
catch(const exception::bad_boxed_cast &){
|
||||
try {
|
||||
Const_Proxy_Function f = t_ss.boxed_cast<const Const_Proxy_Function &>(fn);
|
||||
Const_Proxy_Function f = t_ss->boxed_cast<const Const_Proxy_Function &>(fn);
|
||||
// handle the case where there is only 1 function to try to call and dispatch fails on it
|
||||
throw exception::eval_error("Error calling function '" + this->children[0]->text + "'", params, {f}, false, t_ss);
|
||||
throw exception::eval_error("Error calling function '" + this->children[0]->text + "'", params, {f}, false, *t_ss);
|
||||
} catch (const exception::bad_boxed_cast &) {
|
||||
throw exception::eval_error("'" + this->children[0]->pretty_print() + "' does not evaluate to a function.");
|
||||
}
|
||||
@@ -293,7 +294,7 @@ namespace chaiscript
|
||||
{ assert(children.size() == 2); }
|
||||
|
||||
virtual ~Inplace_Fun_Call_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
|
||||
|
||||
std::vector<Boxed_Value> params;
|
||||
@@ -307,18 +308,18 @@ namespace chaiscript
|
||||
try {
|
||||
Boxed_Value bv = this->children[0]->eval(t_ss);
|
||||
try {
|
||||
fn = t_ss.boxed_cast<const Const_Proxy_Function &>(bv);
|
||||
fn = t_ss->boxed_cast<const Const_Proxy_Function &>(bv);
|
||||
} catch (const exception::bad_boxed_cast &) {
|
||||
throw exception::eval_error("'" + this->children[0]->pretty_print() + "' does not evaluate to a function.");
|
||||
}
|
||||
return (*fn)(params, t_ss.conversions());
|
||||
return (*fn)(params, t_ss->conversions());
|
||||
}
|
||||
catch(const exception::dispatch_error &e){
|
||||
throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'", e.parameters, e.functions, false, t_ss);
|
||||
throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'", e.parameters, e.functions, false, *t_ss);
|
||||
}
|
||||
catch(const exception::bad_boxed_cast &){
|
||||
// handle the case where there is only 1 function to try to call and dispatch fails on it
|
||||
throw exception::eval_error("Error calling function '" + this->children[0]->text + "'", params, {fn}, false, t_ss);
|
||||
throw exception::eval_error("Error calling function '" + this->children[0]->text + "'", params, {fn}, false, *t_ss);
|
||||
}
|
||||
catch(const exception::arity_error &e){
|
||||
throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'");
|
||||
@@ -417,17 +418,17 @@ namespace chaiscript
|
||||
return retval;
|
||||
}
|
||||
|
||||
static std::pair<std::string, Type_Info> get_arg_type(const AST_NodePtr &t_node, chaiscript::detail::Dispatch_Engine &t_ss)
|
||||
static std::pair<std::string, Type_Info> get_arg_type(const AST_NodePtr &t_node, const chaiscript::detail::Dispatch_State &t_ss)
|
||||
{
|
||||
if (t_node->children.size() < 2)
|
||||
{
|
||||
return std::pair<std::string, Type_Info>();
|
||||
} else {
|
||||
return std::pair<std::string, Type_Info>(t_node->children[0]->text, t_ss.get_type(t_node->children[0]->text, false));
|
||||
return std::pair<std::string, Type_Info>(t_node->children[0]->text, t_ss->get_type(t_node->children[0]->text, false));
|
||||
}
|
||||
}
|
||||
|
||||
static dispatch::Param_Types get_arg_types(const AST_NodePtr &t_node, chaiscript::detail::Dispatch_Engine &t_ss) {
|
||||
static dispatch::Param_Types get_arg_types(const AST_NodePtr &t_node, const chaiscript::detail::Dispatch_State &t_ss) {
|
||||
std::vector<std::pair<std::string, Type_Info>> retval;
|
||||
|
||||
for (const auto &child : t_node->children)
|
||||
@@ -449,7 +450,7 @@ namespace chaiscript
|
||||
Operators::Opers m_oper;
|
||||
|
||||
virtual ~Equation_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
|
||||
Boxed_Value rhs = this->children[2]->eval(t_ss);
|
||||
Boxed_Value lhs = this->children[0]->eval(t_ss);
|
||||
@@ -482,21 +483,21 @@ namespace chaiscript
|
||||
} else {
|
||||
if (!rhs.is_return_value())
|
||||
{
|
||||
rhs = t_ss.call_function("clone", rhs);
|
||||
rhs = t_ss->call_function("clone", rhs);
|
||||
}
|
||||
rhs.reset_return_value();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return t_ss.call_function(this->children[1]->text, std::move(lhs), rhs);
|
||||
return t_ss->call_function(this->children[1]->text, std::move(lhs), rhs);
|
||||
}
|
||||
catch(const exception::dispatch_error &e){
|
||||
throw exception::eval_error("Unable to find appropriate'" + this->children[1]->text + "' operator.", e.parameters, e.functions, false, t_ss);
|
||||
throw exception::eval_error("Unable to find appropriate'" + this->children[1]->text + "' operator.", e.parameters, e.functions, false, *t_ss);
|
||||
}
|
||||
}
|
||||
catch(const exception::dispatch_error &e){
|
||||
throw exception::eval_error("Missing clone or copy constructor for right hand side of equation", e.parameters, e.functions, false, t_ss);
|
||||
throw exception::eval_error("Missing clone or copy constructor for right hand side of equation", e.parameters, e.functions, false, *t_ss);
|
||||
}
|
||||
}
|
||||
else if (this->children[1]->text == ":=") {
|
||||
@@ -508,9 +509,9 @@ namespace chaiscript
|
||||
}
|
||||
else {
|
||||
try {
|
||||
return t_ss.call_function(this->children[1]->text, std::move(lhs), rhs);
|
||||
return t_ss->call_function(this->children[1]->text, std::move(lhs), rhs);
|
||||
} catch(const exception::dispatch_error &e){
|
||||
throw exception::eval_error("Unable to find appropriate'" + this->children[1]->text + "' operator.", e.parameters, e.functions, false, t_ss);
|
||||
throw exception::eval_error("Unable to find appropriate'" + this->children[1]->text + "' operator.", e.parameters, e.functions, false, *t_ss);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -523,7 +524,7 @@ namespace chaiscript
|
||||
Global_Decl_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Global_Decl, std::move(t_loc), std::move(t_children)) { }
|
||||
virtual ~Global_Decl_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
|
||||
const std::string &idname =
|
||||
[&]()->const std::string &{
|
||||
@@ -535,7 +536,7 @@ namespace chaiscript
|
||||
}();
|
||||
|
||||
try {
|
||||
return t_ss.add_global_no_throw(Boxed_Value(), idname);
|
||||
return t_ss->add_global_no_throw(Boxed_Value(), idname);
|
||||
}
|
||||
catch (const exception::reserved_word_error &) {
|
||||
throw exception::eval_error("Reserved word used as global '" + idname + "'");
|
||||
@@ -550,7 +551,7 @@ namespace chaiscript
|
||||
Var_Decl_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Var_Decl, std::move(t_loc), std::move(t_children)) { }
|
||||
virtual ~Var_Decl_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
if (this->children[0]->identifier == AST_Node_Type::Reference)
|
||||
{
|
||||
return this->children[0]->eval(t_ss);
|
||||
@@ -559,7 +560,7 @@ namespace chaiscript
|
||||
|
||||
try {
|
||||
Boxed_Value bv;
|
||||
t_ss.add_object(idname, bv);
|
||||
t_ss->add_object(idname, bv);
|
||||
return bv;
|
||||
}
|
||||
catch (const exception::reserved_word_error &) {
|
||||
@@ -584,7 +585,7 @@ namespace chaiscript
|
||||
Array_Call_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Array_Call, std::move(t_loc), std::move(t_children)) { }
|
||||
virtual ~Array_Call_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
|
||||
|
||||
std::vector<Boxed_Value> params{children[0]->eval(t_ss), children[1]->eval(t_ss)};
|
||||
@@ -592,10 +593,10 @@ namespace chaiscript
|
||||
try {
|
||||
chaiscript::eval::detail::Stack_Push_Pop spp(t_ss);
|
||||
fpp.save_params(params);
|
||||
return t_ss.call_function("[]", params);
|
||||
return t_ss->call_function("[]", params);
|
||||
}
|
||||
catch(const exception::dispatch_error &e){
|
||||
throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, e.functions, false, t_ss );
|
||||
throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, e.functions, false, *t_ss );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -625,7 +626,7 @@ namespace chaiscript
|
||||
children[2]->children[0]->text:children[2]->text) { }
|
||||
|
||||
virtual ~Dot_Access_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
|
||||
|
||||
Boxed_Value retval = children[0]->eval(t_ss);
|
||||
@@ -643,15 +644,15 @@ namespace chaiscript
|
||||
|
||||
try {
|
||||
chaiscript::eval::detail::Stack_Push_Pop spp(t_ss);
|
||||
t_ss.add_object("this", retval);
|
||||
retval = t_ss.call_member(m_fun_name, std::move(params), has_function_params);
|
||||
t_ss->add_object("this", retval);
|
||||
retval = t_ss->call_member(m_fun_name, std::move(params), has_function_params);
|
||||
}
|
||||
catch(const exception::dispatch_error &e){
|
||||
if (e.functions.empty())
|
||||
{
|
||||
throw exception::eval_error("'" + m_fun_name + "' is not a function.");
|
||||
} else {
|
||||
throw exception::eval_error(std::string(e.what()) + " for function '" + m_fun_name + "'", e.parameters, e.functions, true, t_ss);
|
||||
throw exception::eval_error(std::string(e.what()) + " for function '" + m_fun_name + "'", e.parameters, e.functions, true, *t_ss);
|
||||
}
|
||||
}
|
||||
catch(detail::Return_Value &rv) {
|
||||
@@ -660,10 +661,10 @@ namespace chaiscript
|
||||
|
||||
if (this->children[2]->identifier == AST_Node_Type::Array_Call) {
|
||||
try {
|
||||
retval = t_ss.call_function("[]", retval, this->children[2]->children[1]->eval(t_ss));
|
||||
retval = t_ss->call_function("[]", retval, this->children[2]->children[1]->eval(t_ss));
|
||||
}
|
||||
catch(const exception::dispatch_error &e){
|
||||
throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, e.functions, true, t_ss);
|
||||
throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, e.functions, true, *t_ss);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -681,7 +682,7 @@ namespace chaiscript
|
||||
m_value(const_var(text)) { }
|
||||
virtual ~Quoted_String_AST_Node() {}
|
||||
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &) const CHAISCRIPT_OVERRIDE {
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const CHAISCRIPT_OVERRIDE {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
@@ -702,7 +703,7 @@ namespace chaiscript
|
||||
m_value(const_var(char(text.at(0)))) { }
|
||||
|
||||
virtual ~Single_Quoted_String_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const CHAISCRIPT_OVERRIDE{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
@@ -723,7 +724,7 @@ namespace chaiscript
|
||||
|
||||
virtual ~Lambda_AST_Node() {}
|
||||
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
|
||||
const auto captures = [&]()->std::map<std::string, Boxed_Value>{
|
||||
std::map<std::string, Boxed_Value> named_captures;
|
||||
@@ -738,12 +739,13 @@ namespace chaiscript
|
||||
const auto param_types = Arg_List_AST_Node::get_arg_types(this->children[1], t_ss);
|
||||
|
||||
const auto &lambda_node = this->children.back();
|
||||
std::reference_wrapper<chaiscript::detail::Dispatch_Engine> engine(*t_ss);
|
||||
|
||||
return Boxed_Value(
|
||||
dispatch::make_dynamic_proxy_function(
|
||||
[&t_ss, lambda_node, param_names, captures](const std::vector<Boxed_Value> &t_params)
|
||||
[engine, lambda_node, param_names, captures](const std::vector<Boxed_Value> &t_params)
|
||||
{
|
||||
return detail::eval_function(t_ss, lambda_node, param_names, t_params, captures);
|
||||
return detail::eval_function(engine, lambda_node, param_names, t_params, captures);
|
||||
},
|
||||
static_cast<int>(numparams), lambda_node, param_types
|
||||
)
|
||||
@@ -761,7 +763,7 @@ namespace chaiscript
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Block, std::move(t_loc), std::move(t_children)) { }
|
||||
virtual ~Block_AST_Node() {}
|
||||
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
||||
|
||||
const auto num_children = children.size();
|
||||
@@ -779,7 +781,7 @@ namespace chaiscript
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Def, std::move(t_loc), std::move(t_children)) { }
|
||||
|
||||
virtual ~Def_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
std::vector<std::string> t_param_names;
|
||||
size_t numparams = 0;
|
||||
AST_NodePtr guardnode;
|
||||
@@ -804,12 +806,13 @@ namespace chaiscript
|
||||
}
|
||||
}
|
||||
|
||||
std::reference_wrapper<chaiscript::detail::Dispatch_Engine> engine(*t_ss);
|
||||
std::shared_ptr<dispatch::Proxy_Function_Base> guard;
|
||||
if (guardnode) {
|
||||
guard = dispatch::make_dynamic_proxy_function(
|
||||
[&t_ss, guardnode, t_param_names](const std::vector<Boxed_Value> &t_params)
|
||||
[engine, guardnode, t_param_names](const std::vector<Boxed_Value> &t_params)
|
||||
{
|
||||
return detail::eval_function(t_ss, guardnode, t_param_names, t_params);
|
||||
return detail::eval_function(engine, guardnode, t_param_names, t_params);
|
||||
},
|
||||
static_cast<int>(numparams), guardnode);
|
||||
}
|
||||
@@ -818,11 +821,11 @@ namespace chaiscript
|
||||
const std::string & l_function_name = this->children[0]->text;
|
||||
const std::string & l_annotation = this->annotation?this->annotation->text:"";
|
||||
const auto & func_node = this->children.back();
|
||||
t_ss.add(
|
||||
t_ss->add(
|
||||
dispatch::make_dynamic_proxy_function(
|
||||
[&t_ss, guardnode, func_node, t_param_names](const std::vector<Boxed_Value> &t_params)
|
||||
[engine, guardnode, func_node, t_param_names](const std::vector<Boxed_Value> &t_params)
|
||||
{
|
||||
return detail::eval_function(t_ss, func_node, t_param_names, t_params);
|
||||
return detail::eval_function(engine, func_node, t_param_names, t_params);
|
||||
},
|
||||
static_cast<int>(numparams), this->children.back(),
|
||||
param_types, l_annotation, guard), l_function_name);
|
||||
@@ -842,7 +845,7 @@ namespace chaiscript
|
||||
While_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::While, std::move(t_loc), std::move(t_children)) { }
|
||||
virtual ~While_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
||||
|
||||
try {
|
||||
@@ -868,12 +871,12 @@ namespace chaiscript
|
||||
Class_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Class, std::move(t_loc), std::move(t_children)) { }
|
||||
virtual ~Class_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
||||
|
||||
/// \todo do this better
|
||||
// put class name in current scope so it can be looked up by the attrs and methods
|
||||
t_ss.add_object("_current_class_name", const_var(children[0]->text));
|
||||
t_ss->add_object("_current_class_name", const_var(children[0]->text));
|
||||
|
||||
children[1]->eval(t_ss);
|
||||
|
||||
@@ -887,7 +890,7 @@ namespace chaiscript
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::If, std::move(t_loc), std::move(t_children))
|
||||
{ assert(children.size() == 3); }
|
||||
virtual ~Ternary_Cond_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
if (get_bool_condition(children[0]->eval(t_ss))) {
|
||||
return children[1]->eval(t_ss);
|
||||
}
|
||||
@@ -903,7 +906,7 @@ namespace chaiscript
|
||||
If_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::If, std::move(t_loc), std::move(t_children)) { }
|
||||
virtual ~If_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
|
||||
if (get_bool_condition(children[0]->eval(t_ss))) {
|
||||
return children[1]->eval(t_ss);
|
||||
@@ -936,7 +939,7 @@ namespace chaiscript
|
||||
{ assert(children.size() == 4); }
|
||||
virtual ~For_AST_Node() {}
|
||||
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
||||
|
||||
try {
|
||||
@@ -968,7 +971,7 @@ namespace chaiscript
|
||||
Switch_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Switch, std::move(t_loc), std::move(t_children)) { }
|
||||
virtual ~Switch_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
bool breaking = false;
|
||||
size_t currentCase = 1;
|
||||
bool hasMatched = false;
|
||||
@@ -982,7 +985,7 @@ namespace chaiscript
|
||||
if (this->children[currentCase]->identifier == AST_Node_Type::Case) {
|
||||
//This is a little odd, but because want to see both the switch and the case simultaneously, I do a downcast here.
|
||||
try {
|
||||
if (hasMatched || boxed_cast<bool>(t_ss.call_function("==", match_value, this->children[currentCase]->children[0]->eval(t_ss)))) {
|
||||
if (hasMatched || boxed_cast<bool>(t_ss->call_function("==", match_value, this->children[currentCase]->children[0]->eval(t_ss)))) {
|
||||
this->children[currentCase]->eval(t_ss);
|
||||
hasMatched = true;
|
||||
}
|
||||
@@ -1012,7 +1015,7 @@ namespace chaiscript
|
||||
{ assert(children.size() == 2); /* how many children does it have? */ }
|
||||
|
||||
virtual ~Case_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
||||
|
||||
children[1]->eval(t_ss);
|
||||
@@ -1027,7 +1030,7 @@ namespace chaiscript
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Default, std::move(t_loc), std::move(t_children))
|
||||
{ assert(children.size() == 1); }
|
||||
virtual ~Default_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
||||
|
||||
children[0]->eval(t_ss);
|
||||
@@ -1042,12 +1045,12 @@ namespace chaiscript
|
||||
Inline_Array_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Inline_Array, std::move(t_loc), std::move(t_children)) { }
|
||||
virtual ~Inline_Array_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
try {
|
||||
std::vector<Boxed_Value> vec;
|
||||
if (!children.empty()) {
|
||||
for (const auto &child : children[0]->children) {
|
||||
vec.push_back(t_ss.call_function("clone", child->eval(t_ss)));
|
||||
vec.push_back(t_ss->call_function("clone", child->eval(t_ss)));
|
||||
}
|
||||
}
|
||||
return const_var(std::move(vec));
|
||||
@@ -1068,19 +1071,19 @@ namespace chaiscript
|
||||
Inline_Map_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Inline_Map, std::move(t_loc), std::move(t_children)) { }
|
||||
virtual ~Inline_Map_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
try {
|
||||
std::map<std::string, Boxed_Value> retval;
|
||||
|
||||
for (const auto &child : children[0]->children) {
|
||||
Boxed_Value bv = t_ss.call_function("clone", child->children[1]->eval(t_ss));
|
||||
retval[t_ss.boxed_cast<std::string>(child->children[0]->eval(t_ss))] = std::move(bv);
|
||||
Boxed_Value bv = t_ss->call_function("clone", child->children[1]->eval(t_ss));
|
||||
retval[t_ss->boxed_cast<std::string>(child->children[0]->eval(t_ss))] = std::move(bv);
|
||||
}
|
||||
|
||||
return const_var(std::move(retval));
|
||||
}
|
||||
catch (const exception::dispatch_error &e) {
|
||||
throw exception::eval_error("Can not find appropriate copy constructor or 'clone' while inserting into Map.", e.parameters, e.functions, false, t_ss);
|
||||
throw exception::eval_error("Can not find appropriate copy constructor or 'clone' while inserting into Map.", e.parameters, e.functions, false, *t_ss);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1091,7 +1094,7 @@ namespace chaiscript
|
||||
Return_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Return, std::move(t_loc), std::move(t_children)) { }
|
||||
virtual ~Return_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
if (!this->children.empty()) {
|
||||
throw detail::Return_Value(children[0]->eval(t_ss));
|
||||
}
|
||||
@@ -1107,7 +1110,7 @@ namespace chaiscript
|
||||
File_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::File, std::move(t_loc), std::move(t_children)) { }
|
||||
virtual ~File_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
const auto num_children = children.size();
|
||||
for (size_t i = 0; i < num_children-1; ++i) {
|
||||
children[i]->eval(t_ss);
|
||||
@@ -1122,10 +1125,10 @@ namespace chaiscript
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Reference, std::move(t_loc), std::move(t_children))
|
||||
{ assert(children.size() == 1); }
|
||||
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
try {
|
||||
Boxed_Value bv;
|
||||
t_ss.add_object(this->children[0]->text, bv);
|
||||
t_ss->add_object(this->children[0]->text, bv);
|
||||
return bv;
|
||||
}
|
||||
catch (const exception::reserved_word_error &) {
|
||||
@@ -1144,7 +1147,7 @@ namespace chaiscript
|
||||
{ }
|
||||
|
||||
virtual ~Prefix_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
Boxed_Value bv(children[1]->eval(t_ss));
|
||||
|
||||
try {
|
||||
@@ -1156,10 +1159,10 @@ namespace chaiscript
|
||||
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
|
||||
chaiscript::eval::detail::Stack_Push_Pop spp(t_ss);
|
||||
fpp.save_params({bv});
|
||||
return t_ss.call_function(children[0]->text, std::move(bv));
|
||||
return t_ss->call_function(children[0]->text, std::move(bv));
|
||||
}
|
||||
} catch (const exception::dispatch_error &e) {
|
||||
throw exception::eval_error("Error with prefix operator evaluation: '" + children[0]->text + "'", e.parameters, e.functions, false, t_ss);
|
||||
throw exception::eval_error("Error with prefix operator evaluation: '" + children[0]->text + "'", e.parameters, e.functions, false, *t_ss);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1172,7 +1175,7 @@ namespace chaiscript
|
||||
Break_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Break, std::move(t_loc), std::move(t_children)) { }
|
||||
virtual ~Break_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const CHAISCRIPT_OVERRIDE{
|
||||
throw detail::Break_Loop();
|
||||
}
|
||||
};
|
||||
@@ -1182,7 +1185,7 @@ namespace chaiscript
|
||||
Continue_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Continue, std::move(t_loc), std::move(t_children)) { }
|
||||
virtual ~Continue_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const CHAISCRIPT_OVERRIDE{
|
||||
throw detail::Continue_Loop();
|
||||
}
|
||||
};
|
||||
@@ -1195,7 +1198,7 @@ namespace chaiscript
|
||||
{ }
|
||||
|
||||
virtual ~Noop_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const CHAISCRIPT_OVERRIDE{
|
||||
// It's a no-op, that evaluates to "true"
|
||||
return m_value;
|
||||
}
|
||||
@@ -1223,14 +1226,14 @@ namespace chaiscript
|
||||
Inline_Range_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Inline_Range, std::move(t_loc), std::move(t_children)) { }
|
||||
virtual ~Inline_Range_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
try {
|
||||
return t_ss.call_function("generate_range",
|
||||
return t_ss->call_function("generate_range",
|
||||
children[0]->children[0]->children[0]->eval(t_ss),
|
||||
children[0]->children[0]->children[1]->eval(t_ss));
|
||||
}
|
||||
catch (const exception::dispatch_error &e) {
|
||||
throw exception::eval_error("Unable to generate range vector, while calling 'generate_range'", e.parameters, e.functions, false, t_ss);
|
||||
throw exception::eval_error("Unable to generate range vector, while calling 'generate_range'", e.parameters, e.functions, false, *t_ss);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1249,7 +1252,7 @@ namespace chaiscript
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Try, std::move(t_loc), std::move(t_children)) { }
|
||||
virtual ~Try_AST_Node() {}
|
||||
|
||||
Boxed_Value handle_exception(chaiscript::detail::Dispatch_Engine &t_ss, const Boxed_Value &t_except) const
|
||||
Boxed_Value handle_exception(const chaiscript::detail::Dispatch_State &t_ss, const Boxed_Value &t_except) const
|
||||
{
|
||||
Boxed_Value retval;
|
||||
|
||||
@@ -1271,9 +1274,9 @@ namespace chaiscript
|
||||
|
||||
if (dispatch::Param_Types(
|
||||
std::vector<std::pair<std::string, Type_Info>>{Arg_List_AST_Node::get_arg_type(catch_block->children[0], t_ss)}
|
||||
).match(std::vector<Boxed_Value>{t_except}, t_ss.conversions()))
|
||||
).match(std::vector<Boxed_Value>{t_except}, t_ss->conversions()))
|
||||
{
|
||||
t_ss.add_object(name, t_except);
|
||||
t_ss->add_object(name, t_except);
|
||||
|
||||
if (catch_block->children.size() == 2) {
|
||||
//Variable capture, no guards
|
||||
@@ -1310,7 +1313,7 @@ namespace chaiscript
|
||||
return retval;
|
||||
}
|
||||
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
Boxed_Value retval;
|
||||
|
||||
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
||||
@@ -1373,11 +1376,11 @@ namespace chaiscript
|
||||
Method_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Method, std::move(t_loc), std::move(t_children)) { }
|
||||
virtual ~Method_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
|
||||
AST_NodePtr guardnode;
|
||||
|
||||
const auto d = t_ss.get_parent_locals();
|
||||
const auto d = t_ss->get_parent_locals();
|
||||
const auto itr = d.find("_current_class_name");
|
||||
const auto class_offset = (itr != d.end())?-1:0;
|
||||
const std::string & class_name = (itr != d.end())?std::string(boxed_cast<std::string>(itr->second)):this->children[0]->text;
|
||||
@@ -1406,10 +1409,11 @@ namespace chaiscript
|
||||
const size_t numparams = t_param_names.size();
|
||||
|
||||
std::shared_ptr<dispatch::Proxy_Function_Base> guard;
|
||||
std::reference_wrapper<chaiscript::detail::Dispatch_Engine> engine(*t_ss);
|
||||
if (guardnode) {
|
||||
guard = dispatch::make_dynamic_proxy_function(
|
||||
[&t_ss, t_param_names, guardnode](const std::vector<Boxed_Value> &t_params) {
|
||||
return chaiscript::eval::detail::eval_function(t_ss, guardnode, t_param_names, t_params, std::map<std::string, Boxed_Value>());
|
||||
[engine, t_param_names, guardnode](const std::vector<Boxed_Value> &t_params) {
|
||||
return chaiscript::eval::detail::eval_function(engine, guardnode, t_param_names, t_params, std::map<std::string, Boxed_Value>());
|
||||
},
|
||||
static_cast<int>(numparams), guardnode);
|
||||
}
|
||||
@@ -1422,11 +1426,11 @@ namespace chaiscript
|
||||
if (function_name == class_name) {
|
||||
param_types.push_front(class_name, Type_Info());
|
||||
|
||||
t_ss.add(
|
||||
t_ss->add(
|
||||
std::make_shared<dispatch::detail::Dynamic_Object_Constructor>(class_name,
|
||||
dispatch::make_dynamic_proxy_function(
|
||||
[&t_ss, t_param_names, node](const std::vector<Boxed_Value> &t_params) {
|
||||
return chaiscript::eval::detail::eval_function(t_ss, node, t_param_names, t_params, std::map<std::string, Boxed_Value>());
|
||||
[engine, t_param_names, node](const std::vector<Boxed_Value> &t_params) {
|
||||
return chaiscript::eval::detail::eval_function(engine, node, t_param_names, t_params, std::map<std::string, Boxed_Value>());
|
||||
},
|
||||
static_cast<int>(numparams), node, param_types, l_annotation, guard
|
||||
)
|
||||
@@ -1436,13 +1440,13 @@ namespace chaiscript
|
||||
} else {
|
||||
// if the type is unknown, then this generates a function that looks up the type
|
||||
// at runtime. Defining the type first before this is called is better
|
||||
auto type = t_ss.get_type(class_name, false);
|
||||
auto type = t_ss->get_type(class_name, false);
|
||||
param_types.push_front(class_name, type);
|
||||
|
||||
t_ss.add(std::make_shared<dispatch::detail::Dynamic_Object_Function>(class_name,
|
||||
t_ss->add(std::make_shared<dispatch::detail::Dynamic_Object_Function>(class_name,
|
||||
dispatch::make_dynamic_proxy_function(
|
||||
[&t_ss, t_param_names, node](const std::vector<Boxed_Value> &t_params) {
|
||||
return chaiscript::eval::detail::eval_function(t_ss, node, t_param_names, t_params, std::map<std::string, Boxed_Value>());
|
||||
[engine, t_param_names, node](const std::vector<Boxed_Value> &t_params) {
|
||||
return chaiscript::eval::detail::eval_function(engine, node, t_param_names, t_params, std::map<std::string, Boxed_Value>());
|
||||
},
|
||||
static_cast<int>(numparams), node, param_types, l_annotation, guard), type),
|
||||
function_name);
|
||||
@@ -1463,9 +1467,9 @@ namespace chaiscript
|
||||
Attr_Decl_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Attr_Decl, std::move(t_loc), std::move(t_children)) { }
|
||||
virtual ~Attr_Decl_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE
|
||||
{
|
||||
const auto &d = t_ss.get_parent_locals();
|
||||
const auto &d = t_ss->get_parent_locals();
|
||||
const auto itr = d.find("_current_class_name");
|
||||
const auto class_offset = (itr != d.end())?-1:0;
|
||||
std::string class_name = (itr != d.end())?std::string(boxed_cast<std::string>(itr->second)):this->children[0]->text;
|
||||
@@ -1473,7 +1477,7 @@ namespace chaiscript
|
||||
try {
|
||||
std::string attr_name = this->children[static_cast<size_t>(1 + class_offset)]->text;
|
||||
|
||||
t_ss.add(
|
||||
t_ss->add(
|
||||
std::make_shared<dispatch::detail::Dynamic_Object_Function>(
|
||||
std::move(class_name),
|
||||
fun([attr_name](dispatch::Dynamic_Object &t_obj) {
|
||||
@@ -1502,7 +1506,7 @@ namespace chaiscript
|
||||
{ assert(children.size() == 3); }
|
||||
|
||||
virtual ~Logical_And_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
return const_var(get_bool_condition(children[0]->eval(t_ss))
|
||||
&& get_bool_condition(children[2]->eval(t_ss)));
|
||||
}
|
||||
@@ -1519,7 +1523,7 @@ namespace chaiscript
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Logical_Or, std::move(t_loc), std::move(t_children))
|
||||
{ assert(children.size() == 3); }
|
||||
virtual ~Logical_Or_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
|
||||
return const_var(get_bool_condition(children[0]->eval(t_ss))
|
||||
|| get_bool_condition(children[2]->eval(t_ss)));
|
||||
}
|
||||
|
Reference in New Issue
Block a user