Initial take on Tracer hooks
This will allow the user to add hooks in for debugging / execution tracing / throttling / etc for each node execution The cost is *almost* 0 if no tracing is enabled.
This commit is contained in:
parent
dcedd64032
commit
03803ee4c4
@ -580,7 +580,8 @@ namespace chaiscript
|
|||||||
{fun(&AST_Node::to_string), "to_string"},
|
{fun(&AST_Node::to_string), "to_string"},
|
||||||
{fun([](const chaiscript::AST_Node &t_node) -> std::vector<Boxed_Value> {
|
{fun([](const chaiscript::AST_Node &t_node) -> std::vector<Boxed_Value> {
|
||||||
std::vector<Boxed_Value> retval;
|
std::vector<Boxed_Value> retval;
|
||||||
std::transform(t_node.children.begin(), t_node.children.end(),
|
const auto children = t_node.get_children();
|
||||||
|
std::transform(children.begin(), children.end(),
|
||||||
std::back_inserter(retval),
|
std::back_inserter(retval),
|
||||||
&chaiscript::var<const std::shared_ptr<chaiscript::AST_Node> &>);
|
&chaiscript::var<const std::shared_ptr<chaiscript::AST_Node> &>);
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -37,6 +37,9 @@ class Boxed_Number;
|
|||||||
} // namespace chaiscript
|
} // namespace chaiscript
|
||||||
|
|
||||||
namespace chaiscript {
|
namespace chaiscript {
|
||||||
|
namespace parser {
|
||||||
|
class ChaiScript_Parser_Base;
|
||||||
|
}
|
||||||
namespace dispatch {
|
namespace dispatch {
|
||||||
class Dynamic_Proxy_Function;
|
class Dynamic_Proxy_Function;
|
||||||
class Proxy_Function_Base;
|
class Proxy_Function_Base;
|
||||||
@ -45,6 +48,7 @@ struct Placeholder_Object;
|
|||||||
} // namespace chaiscript
|
} // namespace chaiscript
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// \namespace chaiscript::dispatch
|
/// \namespace chaiscript::dispatch
|
||||||
/// \brief Classes and functions specific to the runtime dispatch side of ChaiScript. Some items may be of use to the end user.
|
/// \brief Classes and functions specific to the runtime dispatch side of ChaiScript. Some items may be of use to the end user.
|
||||||
|
|
||||||
@ -411,8 +415,10 @@ namespace chaiscript
|
|||||||
"return", "break", "true", "false", "class", "attr", "var", "global", "GLOBAL", "_"};
|
"return", "break", "true", "false", "class", "attr", "var", "global", "GLOBAL", "_"};
|
||||||
};
|
};
|
||||||
|
|
||||||
Dispatch_Engine()
|
Dispatch_Engine(chaiscript::parser::ChaiScript_Parser_Base &parser)
|
||||||
: m_stack_holder(this)
|
: m_stack_holder(this),
|
||||||
|
m_parser(parser)
|
||||||
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1231,6 +1237,11 @@ namespace chaiscript
|
|||||||
return m_stack_holder->stacks.back();
|
return m_stack_holder->stacks.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parser::ChaiScript_Parser_Base &get_parser()
|
||||||
|
{
|
||||||
|
return m_parser.get();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const std::vector<std::pair<std::string, Boxed_Value>> &get_boxed_functions_int() const
|
const std::vector<std::pair<std::string, Boxed_Value>> &get_boxed_functions_int() const
|
||||||
@ -1456,6 +1467,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
Type_Conversions m_conversions;
|
Type_Conversions m_conversions;
|
||||||
chaiscript::detail::threading::Thread_Storage<Stack_Holder> m_stack_holder;
|
chaiscript::detail::threading::Thread_Storage<Stack_Holder> m_stack_holder;
|
||||||
|
std::reference_wrapper<parser::ChaiScript_Parser_Base> m_parser;
|
||||||
|
|
||||||
mutable std::atomic_uint_fast32_t m_method_missing_loc;
|
mutable std::atomic_uint_fast32_t m_method_missing_loc;
|
||||||
|
|
||||||
|
@ -465,7 +465,6 @@ namespace chaiscript
|
|||||||
const AST_Node_Type identifier;
|
const AST_Node_Type identifier;
|
||||||
const std::string text;
|
const std::string text;
|
||||||
Parse_Location location;
|
Parse_Location location;
|
||||||
std::vector<AST_NodePtr> children;
|
|
||||||
|
|
||||||
const std::string &filename() const {
|
const std::string &filename() const {
|
||||||
return *location.filename;
|
return *location.filename;
|
||||||
@ -485,13 +484,16 @@ namespace chaiscript
|
|||||||
|
|
||||||
oss << text;
|
oss << text;
|
||||||
|
|
||||||
for (auto & elem : this->children) {
|
for (auto & elem : this->get_children()) {
|
||||||
oss << elem->pretty_print() << ' ';
|
oss << elem->pretty_print() << ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual std::vector<AST_NodePtr> get_children() const = 0;
|
||||||
|
virtual Boxed_Value eval(const chaiscript::detail::Dispatch_State &t_e) const = 0;
|
||||||
|
|
||||||
|
|
||||||
/// Prints the contents of an AST node, including its children, recursively
|
/// Prints the contents of an AST node, including its children, recursively
|
||||||
std::string to_string(const std::string &t_prepend = "") const {
|
std::string to_string(const std::string &t_prepend = "") const {
|
||||||
@ -500,21 +502,12 @@ namespace chaiscript
|
|||||||
oss << t_prepend << "(" << ast_node_type_to_string(this->identifier) << ") "
|
oss << t_prepend << "(" << ast_node_type_to_string(this->identifier) << ") "
|
||||||
<< this->text << " : " << this->location.start.line << ", " << this->location.start.column << '\n';
|
<< this->text << " : " << this->location.start.line << ", " << this->location.start.column << '\n';
|
||||||
|
|
||||||
for (auto & elem : this->children) {
|
for (auto & elem : this->get_children()) {
|
||||||
oss << elem->to_string(t_prepend + " ");
|
oss << elem->to_string(t_prepend + " ");
|
||||||
}
|
}
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
Boxed_Value eval(const chaiscript::detail::Dispatch_State &t_e) const
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
return eval_internal(t_e);
|
|
||||||
} catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(shared_from_this());
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool get_bool_condition(const Boxed_Value &t_bv) {
|
static bool get_bool_condition(const Boxed_Value &t_bv) {
|
||||||
try {
|
try {
|
||||||
@ -534,21 +527,39 @@ namespace chaiscript
|
|||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AST_Node(std::string t_ast_node_text, AST_Node_Type t_id, Parse_Location t_loc,
|
AST_Node(std::string t_ast_node_text, AST_Node_Type t_id, Parse_Location t_loc)
|
||||||
std::vector<AST_NodePtr> t_children = std::vector<AST_NodePtr>()) :
|
: identifier(t_id), text(std::move(t_ast_node_text)),
|
||||||
identifier(t_id), text(std::move(t_ast_node_text)),
|
location(std::move(t_loc))
|
||||||
location(std::move(t_loc)),
|
|
||||||
children(std::move(t_children))
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Undispatched ast_node (internal error)");
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace parser {
|
||||||
|
class ChaiScript_Parser_Base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual AST_NodePtr parse(const std::string &t_input, const std::string &t_fname) = 0;
|
||||||
|
virtual void debug_print(AST_NodePtr t, std::string prepend = "") const = 0;
|
||||||
|
virtual void *get_tracer_ptr() = 0;
|
||||||
|
virtual ~ChaiScript_Parser_Base() = default;
|
||||||
|
ChaiScript_Parser_Base() = default;
|
||||||
|
ChaiScript_Parser_Base(ChaiScript_Parser_Base &&) = default;
|
||||||
|
ChaiScript_Parser_Base &operator=(ChaiScript_Parser_Base &&) = delete;
|
||||||
|
ChaiScript_Parser_Base &operator=(const ChaiScript_Parser_Base &&) = delete;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T &get_tracer()
|
||||||
|
{
|
||||||
|
// to do type check this somehow?
|
||||||
|
return static_cast<T&>(*get_tracer_ptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ChaiScript_Parser_Base(const ChaiScript_Parser_Base &) = default;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
namespace eval
|
namespace eval
|
||||||
{
|
{
|
||||||
|
@ -70,10 +70,10 @@ namespace chaiscript
|
|||||||
std::vector<std::string> m_module_paths;
|
std::vector<std::string> m_module_paths;
|
||||||
std::vector<std::string> m_use_paths;
|
std::vector<std::string> m_use_paths;
|
||||||
|
|
||||||
chaiscript::detail::Dispatch_Engine m_engine;
|
|
||||||
|
|
||||||
std::unique_ptr<parser::ChaiScript_Parser_Base> m_parser;
|
std::unique_ptr<parser::ChaiScript_Parser_Base> m_parser;
|
||||||
|
|
||||||
|
chaiscript::detail::Dispatch_Engine m_engine;
|
||||||
|
|
||||||
/// Evaluates the given string in by parsing it and running the results through the evaluator
|
/// Evaluates the given string in by parsing it and running the results through the evaluator
|
||||||
Boxed_Value do_eval(const std::string &t_input, const std::string &t_filename = "__EVAL__", bool /* t_internal*/ = false)
|
Boxed_Value do_eval(const std::string &t_input, const std::string &t_filename = "__EVAL__", bool /* t_internal*/ = false)
|
||||||
{
|
{
|
||||||
@ -219,7 +219,9 @@ namespace chaiscript
|
|||||||
std::vector<std::string> t_modulepaths = std::vector<std::string>(),
|
std::vector<std::string> t_modulepaths = std::vector<std::string>(),
|
||||||
std::vector<std::string> t_usepaths = std::vector<std::string>())
|
std::vector<std::string> t_usepaths = std::vector<std::string>())
|
||||||
: m_module_paths(std::move(t_modulepaths)), m_use_paths(std::move(t_usepaths)),
|
: m_module_paths(std::move(t_modulepaths)), m_use_paths(std::move(t_usepaths)),
|
||||||
m_parser(std::make_unique<parser::ChaiScript_Parser<optimizer::Optimizer<optimizer::Block, optimizer::Constant_Fold, optimizer::If, optimizer::Return, optimizer::For_Loop>>>())
|
m_parser(std::make_unique<parser::ChaiScript_Parser<eval::Noop_Tracer, optimizer::Optimizer<optimizer::Block, optimizer::Constant_Fold, optimizer::If, optimizer::Return, optimizer::For_Loop>>>()),
|
||||||
|
m_engine(*m_parser)
|
||||||
|
|
||||||
{
|
{
|
||||||
if (m_module_paths.empty())
|
if (m_module_paths.empty())
|
||||||
{
|
{
|
||||||
@ -244,7 +246,8 @@ namespace chaiscript
|
|||||||
ChaiScript( std::vector<std::string> t_modulepaths = std::vector<std::string>(),
|
ChaiScript( std::vector<std::string> t_modulepaths = std::vector<std::string>(),
|
||||||
std::vector<std::string> t_usepaths = std::vector<std::string>())
|
std::vector<std::string> t_usepaths = std::vector<std::string>())
|
||||||
: m_module_paths(std::move(t_modulepaths)), m_use_paths(std::move(t_usepaths)),
|
: m_module_paths(std::move(t_modulepaths)), m_use_paths(std::move(t_usepaths)),
|
||||||
m_parser(std::make_unique<parser::ChaiScript_Parser<optimizer::Optimizer<optimizer::Block, optimizer::Constant_Fold, optimizer::If, optimizer::Return, optimizer::For_Loop>>>())
|
m_parser(std::make_unique<parser::ChaiScript_Parser<eval::Noop_Tracer, optimizer::Optimizer<optimizer::Block, optimizer::Constant_Fold, optimizer::If, optimizer::Return, optimizer::For_Loop>>>()),
|
||||||
|
m_engine(*m_parser)
|
||||||
{
|
{
|
||||||
if (m_module_paths.empty())
|
if (m_module_paths.empty())
|
||||||
{
|
{
|
||||||
|
@ -41,10 +41,15 @@ namespace chaiscript
|
|||||||
/// \brief Classes and functions that are part of the runtime eval system
|
/// \brief Classes and functions that are part of the runtime eval system
|
||||||
namespace eval
|
namespace eval
|
||||||
{
|
{
|
||||||
|
template<typename T> struct AST_Node_Impl;
|
||||||
|
|
||||||
|
template<typename T> using AST_Node_Impl_Ptr = typename std::shared_ptr<AST_Node_Impl<T>>;
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
/// Helper function that will set up the scope around a function call, including handling the named function parameters
|
/// 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=nullptr) {
|
template<typename T>
|
||||||
|
static Boxed_Value eval_function(chaiscript::detail::Dispatch_Engine &t_ss, const AST_Node_Impl_Ptr<T> &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=nullptr) {
|
||||||
chaiscript::detail::Dispatch_State state(t_ss);
|
chaiscript::detail::Dispatch_State state(t_ss);
|
||||||
|
|
||||||
const Boxed_Value *thisobj = [&]() -> const Boxed_Value *{
|
const Boxed_Value *thisobj = [&]() -> const Boxed_Value *{
|
||||||
@ -81,32 +86,72 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Compiled_AST_Node : AST_Node {
|
|
||||||
Compiled_AST_Node(AST_NodePtr t_original_node, std::vector<AST_NodePtr> t_children,
|
|
||||||
std::function<Boxed_Value (const std::vector<AST_NodePtr> &, const chaiscript::detail::Dispatch_State &t_ss)> t_func) :
|
template<typename T>
|
||||||
AST_Node(t_original_node->text, AST_Node_Type::Compiled, t_original_node->location, std::move(t_children)),
|
struct AST_Node_Impl : AST_Node
|
||||||
|
{
|
||||||
|
AST_Node_Impl(std::string t_ast_node_text, AST_Node_Type t_id, Parse_Location t_loc,
|
||||||
|
std::vector<AST_Node_Impl_Ptr<T>> t_children = std::vector<AST_Node_Impl_Ptr<T>>())
|
||||||
|
: AST_Node(std::move(t_ast_node_text), std::move(t_id), std::move(t_loc)),
|
||||||
|
children(std::move(t_children))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<AST_NodePtr> get_children() const final {
|
||||||
|
return {children.begin(), children.end()};
|
||||||
|
}
|
||||||
|
|
||||||
|
Boxed_Value eval(const chaiscript::detail::Dispatch_State &t_e) const final
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
T::trace(t_e, this);
|
||||||
|
return eval_internal(t_e);
|
||||||
|
} catch (exception::eval_error &ee) {
|
||||||
|
ee.call_stack.push_back(shared_from_this());
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<AST_Node_Impl_Ptr<T>> children;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Undispatched ast_node (internal error)");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Compiled_AST_Node : AST_Node_Impl<T> {
|
||||||
|
Compiled_AST_Node(AST_Node_Impl_Ptr<T> t_original_node, std::vector<AST_Node_Impl_Ptr<T>> t_children,
|
||||||
|
std::function<Boxed_Value (const std::vector<AST_Node_Impl_Ptr<T>> &, const chaiscript::detail::Dispatch_State &t_ss)> t_func) :
|
||||||
|
AST_Node_Impl<T>(t_original_node->text, AST_Node_Type::Compiled, t_original_node->location, std::move(t_children)),
|
||||||
m_func(std::move(t_func)),
|
m_func(std::move(t_func)),
|
||||||
m_original_node(std::move(t_original_node))
|
m_original_node(std::move(t_original_node))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
||||||
return m_func(children, t_ss);
|
return m_func(this->children, t_ss);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::function<Boxed_Value (const std::vector<AST_NodePtr> &, const chaiscript::detail::Dispatch_State &t_ss)> m_func;
|
std::function<Boxed_Value (const std::vector<AST_Node_Impl_Ptr<T>> &, const chaiscript::detail::Dispatch_State &t_ss)> m_func;
|
||||||
AST_NodePtr m_original_node;
|
AST_Node_Impl_Ptr<T> m_original_node;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Binary_Operator_AST_Node : AST_Node {
|
template<typename T>
|
||||||
Binary_Operator_AST_Node(const std::string &t_oper, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Binary_Operator_AST_Node : AST_Node_Impl<T> {
|
||||||
AST_Node(t_oper, AST_Node_Type::Binary, std::move(t_loc), std::move(t_children)),
|
Binary_Operator_AST_Node(const std::string &t_oper, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) :
|
||||||
|
AST_Node_Impl<T>(t_oper, AST_Node_Type::Binary, std::move(t_loc), std::move(t_children)),
|
||||||
m_oper(Operators::to_operator(t_oper))
|
m_oper(Operators::to_operator(t_oper))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
||||||
auto lhs = this->children[0]->eval(t_ss);
|
auto lhs = this->children[0]->eval(t_ss);
|
||||||
auto rhs = this->children[1]->eval(t_ss);
|
auto rhs = this->children[1]->eval(t_ss);
|
||||||
return do_oper(t_ss, m_oper, text, lhs, rhs);
|
return do_oper(t_ss, m_oper, this->text, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -141,10 +186,10 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
struct Constant_AST_Node final : AST_Node {
|
struct Constant_AST_Node final : AST_Node_Impl<T> {
|
||||||
Constant_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, Boxed_Value t_value)
|
Constant_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, Boxed_Value t_value)
|
||||||
: AST_Node(t_ast_node_text, AST_Node_Type::Constant, std::move(t_loc)),
|
: AST_Node_Impl<T>(t_ast_node_text, AST_Node_Type::Constant, std::move(t_loc)),
|
||||||
m_value(std::move(t_value))
|
m_value(std::move(t_value))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -156,9 +201,10 @@ namespace chaiscript
|
|||||||
Boxed_Value m_value;
|
Boxed_Value m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Id_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
|
struct Id_AST_Node final : AST_Node_Impl<T> {
|
||||||
Id_AST_Node(const std::string &t_ast_node_text, Parse_Location t_loc) :
|
Id_AST_Node(const std::string &t_ast_node_text, Parse_Location t_loc) :
|
||||||
AST_Node(t_ast_node_text, AST_Node_Type::Id, std::move(t_loc)),
|
AST_Node_Impl<T>(t_ast_node_text, AST_Node_Type::Id, std::move(t_loc)),
|
||||||
m_loc(0)
|
m_loc(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@ -177,9 +223,10 @@ namespace chaiscript
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct Fun_Call_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Fun_Call_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Fun_Call_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Fun_Call, std::move(t_loc), std::move(t_children)) { }
|
Fun_Call_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::Fun_Call, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override
|
||||||
{
|
{
|
||||||
@ -227,18 +274,20 @@ namespace chaiscript
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct Arg_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Arg_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Arg_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Arg_List, std::move(t_loc), std::move(t_children)) { }
|
Arg_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::Arg_List, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Arg_List_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Arg_List_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Arg_List_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Arg_List, std::move(t_loc), std::move(t_children)) { }
|
Arg_List_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::Arg_List, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
|
|
||||||
static std::string get_arg_name(const AST_NodePtr &t_node) {
|
static std::string get_arg_name(const AST_Node_Impl_Ptr<T> &t_node) {
|
||||||
if (t_node->children.empty())
|
if (t_node->children.empty())
|
||||||
{
|
{
|
||||||
return t_node->text;
|
return t_node->text;
|
||||||
@ -249,7 +298,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<std::string> get_arg_names(const AST_NodePtr &t_node) {
|
static std::vector<std::string> get_arg_names(const AST_Node_Impl_Ptr<T> &t_node) {
|
||||||
std::vector<std::string> retval;
|
std::vector<std::string> retval;
|
||||||
|
|
||||||
for (const auto &node : t_node->children)
|
for (const auto &node : t_node->children)
|
||||||
@ -260,7 +309,7 @@ namespace chaiscript
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::pair<std::string, Type_Info> get_arg_type(const AST_NodePtr &t_node, const chaiscript::detail::Dispatch_State &t_ss)
|
static std::pair<std::string, Type_Info> get_arg_type(const AST_Node_Impl_Ptr<T> &t_node, const chaiscript::detail::Dispatch_State &t_ss)
|
||||||
{
|
{
|
||||||
if (t_node->children.size() < 2)
|
if (t_node->children.size() < 2)
|
||||||
{
|
{
|
||||||
@ -270,7 +319,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static dispatch::Param_Types get_arg_types(const AST_NodePtr &t_node, const chaiscript::detail::Dispatch_State &t_ss) {
|
static dispatch::Param_Types get_arg_types(const AST_Node_Impl_Ptr<T> &t_node, const chaiscript::detail::Dispatch_State &t_ss) {
|
||||||
std::vector<std::pair<std::string, Type_Info>> retval;
|
std::vector<std::pair<std::string, Type_Info>> retval;
|
||||||
|
|
||||||
for (const auto &child : t_node->children)
|
for (const auto &child : t_node->children)
|
||||||
@ -282,10 +331,11 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Equation_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Equation_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Equation_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Equation, std::move(t_loc), std::move(t_children)),
|
Equation_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) :
|
||||||
m_oper(Operators::to_operator(text))
|
AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::Equation, std::move(t_loc), std::move(t_children)),
|
||||||
|
m_oper(Operators::to_operator(this->text))
|
||||||
{ assert(children.size() == 2); }
|
{ assert(children.size() == 2); }
|
||||||
|
|
||||||
|
|
||||||
@ -368,17 +418,18 @@ namespace chaiscript
|
|||||||
mutable std::atomic_uint_fast32_t m_clone_loc;
|
mutable std::atomic_uint_fast32_t m_clone_loc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Global_Decl_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Global_Decl_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Global_Decl_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Global_Decl, std::move(t_loc), std::move(t_children)) { }
|
Global_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::Global_Decl, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
||||||
const std::string &idname =
|
const std::string &idname =
|
||||||
[&]()->const std::string & {
|
[&]()->const std::string & {
|
||||||
if (children[0]->identifier == AST_Node_Type::Reference) {
|
if (this->children[0]->identifier == AST_Node_Type::Reference) {
|
||||||
return children[0]->children[0]->text;
|
return this->children[0]->children[0]->text;
|
||||||
} else {
|
} else {
|
||||||
return children[0]->text;
|
return this->children[0]->text;
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
|
|
||||||
@ -393,9 +444,10 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Var_Decl_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Var_Decl_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Var_Decl_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Var_Decl, std::move(t_loc), std::move(t_children)) { }
|
Var_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::Var_Decl, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
||||||
const std::string &idname = this->children[0]->text;
|
const std::string &idname = this->children[0]->text;
|
||||||
@ -414,14 +466,15 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Array_Call_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Array_Call_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Array_Call_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Array_Call, std::move(t_loc), std::move(t_children)) { }
|
Array_Call_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::Array_Call, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
||||||
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
|
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
|
||||||
|
|
||||||
const std::vector<Boxed_Value> params{children[0]->eval(t_ss), children[1]->eval(t_ss)};
|
const std::vector<Boxed_Value> params{this->children[0]->eval(t_ss), this->children[1]->eval(t_ss)};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fpp.save_params(params);
|
fpp.save_params(params);
|
||||||
@ -437,24 +490,25 @@ namespace chaiscript
|
|||||||
mutable std::atomic_uint_fast32_t m_loc;
|
mutable std::atomic_uint_fast32_t m_loc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Dot_Access_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Dot_Access_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Dot_Access_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Dot_Access, std::move(t_loc), std::move(t_children)),
|
Dot_Access_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::Dot_Access, std::move(t_loc), std::move(t_children)),
|
||||||
m_fun_name(
|
m_fun_name(
|
||||||
((children[1]->identifier == AST_Node_Type::Fun_Call) || (children[1]->identifier == AST_Node_Type::Array_Call))?
|
((this->children[1]->identifier == AST_Node_Type::Fun_Call) || (this->children[1]->identifier == AST_Node_Type::Array_Call))?
|
||||||
children[1]->children[0]->text:children[1]->text) { }
|
this->children[1]->children[0]->text:this->children[1]->text) { }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
||||||
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
|
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
|
||||||
|
|
||||||
|
|
||||||
Boxed_Value retval = children[0]->eval(t_ss);
|
Boxed_Value retval = this->children[0]->eval(t_ss);
|
||||||
std::vector<Boxed_Value> params{retval};
|
std::vector<Boxed_Value> params{retval};
|
||||||
|
|
||||||
bool has_function_params = false;
|
bool has_function_params = false;
|
||||||
if (children[1]->children.size() > 1) {
|
if (this->children[1]->children.size() > 1) {
|
||||||
has_function_params = true;
|
has_function_params = true;
|
||||||
for (const auto &child : children[1]->children[1]->children) {
|
for (const auto &child : this->children[1]->children[1]->children) {
|
||||||
params.push_back(child->eval(t_ss));
|
params.push_back(child->eval(t_ss));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -495,23 +549,24 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Lambda_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Lambda_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Lambda_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(t_ast_node_text, AST_Node_Type::Lambda, std::move(t_loc), std::move(t_children)),
|
Lambda_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) :
|
||||||
m_param_names(Arg_List_AST_Node::get_arg_names(children[1])) { }
|
AST_Node_Impl<T>(t_ast_node_text, AST_Node_Type::Lambda, std::move(t_loc), std::move(t_children)),
|
||||||
|
m_param_names(Arg_List_AST_Node<T>::get_arg_names(this->children[1])) { }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
||||||
|
|
||||||
const auto captures = [&]()->std::map<std::string, Boxed_Value>{
|
const auto captures = [&]()->std::map<std::string, Boxed_Value>{
|
||||||
std::map<std::string, Boxed_Value> named_captures;
|
std::map<std::string, Boxed_Value> named_captures;
|
||||||
for (const auto &capture : children[0]->children) {
|
for (const auto &capture : this->children[0]->children) {
|
||||||
named_captures.insert(std::make_pair(capture->children[0]->text, capture->children[0]->eval(t_ss)));
|
named_captures.insert(std::make_pair(capture->children[0]->text, capture->children[0]->eval(t_ss)));
|
||||||
}
|
}
|
||||||
return named_captures;
|
return named_captures;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
const auto numparams = this->children[1]->children.size();
|
const auto numparams = this->children[1]->children.size();
|
||||||
const auto param_types = Arg_List_AST_Node::get_arg_types(this->children[1], t_ss);
|
const auto param_types = Arg_List_AST_Node<T>::get_arg_types(this->children[1], t_ss);
|
||||||
|
|
||||||
const auto &lambda_node = this->children.back();
|
const auto &lambda_node = this->children.back();
|
||||||
std::reference_wrapper<chaiscript::detail::Dispatch_Engine> engine(*t_ss);
|
std::reference_wrapper<chaiscript::detail::Dispatch_Engine> engine(*t_ss);
|
||||||
@ -532,36 +587,38 @@ namespace chaiscript
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Block_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Block_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Block_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Block, std::move(t_loc), std::move(t_children)) { }
|
Block_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::Block, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
||||||
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
||||||
|
|
||||||
const auto num_children = children.size();
|
const auto num_children = this->children.size();
|
||||||
for (size_t i = 0; i < num_children-1; ++i) {
|
for (size_t i = 0; i < num_children-1; ++i) {
|
||||||
children[i]->eval(t_ss);
|
this->children[i]->eval(t_ss);
|
||||||
}
|
}
|
||||||
return children.back()->eval(t_ss);
|
return this->children.back()->eval(t_ss);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Def_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Def_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Def_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Def, std::move(t_loc), std::move(t_children)) { }
|
Def_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::Def, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
|
||||||
std::vector<std::string> t_param_names;
|
std::vector<std::string> t_param_names;
|
||||||
size_t numparams = 0;
|
size_t numparams = 0;
|
||||||
AST_NodePtr guardnode;
|
AST_Node_Impl_Ptr<T> guardnode;
|
||||||
|
|
||||||
dispatch::Param_Types param_types;
|
dispatch::Param_Types param_types;
|
||||||
|
|
||||||
if ((this->children.size() > 2) && (this->children[1]->identifier == AST_Node_Type::Arg_List)) {
|
if ((this->children.size() > 2) && (this->children[1]->identifier == AST_Node_Type::Arg_List)) {
|
||||||
numparams = this->children[1]->children.size();
|
numparams = this->children[1]->children.size();
|
||||||
t_param_names = Arg_List_AST_Node::get_arg_names(this->children[1]);
|
t_param_names = Arg_List_AST_Node<T>::get_arg_names(this->children[1]);
|
||||||
param_types = Arg_List_AST_Node::get_arg_types(this->children[1], t_ss);
|
param_types = Arg_List_AST_Node<T>::get_arg_types(this->children[1], t_ss);
|
||||||
|
|
||||||
if (this->children.size() > 3) {
|
if (this->children.size() > 3) {
|
||||||
guardnode = this->children[2];
|
guardnode = this->children[2];
|
||||||
@ -609,15 +666,16 @@ namespace chaiscript
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct While_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
While_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct While_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::While, std::move(t_loc), std::move(t_children)) { }
|
While_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::While, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
||||||
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while (get_bool_condition(this->children[0]->eval(t_ss))) {
|
while (this->get_bool_condition(this->children[0]->eval(t_ss))) {
|
||||||
try {
|
try {
|
||||||
this->children[1]->eval(t_ss);
|
this->children[1]->eval(t_ss);
|
||||||
} catch (detail::Continue_Loop &) {
|
} catch (detail::Continue_Loop &) {
|
||||||
@ -634,51 +692,54 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Class_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Class_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Class_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Class, std::move(t_loc), std::move(t_children)) { }
|
Class_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::Class, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
||||||
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
||||||
|
|
||||||
/// \todo do this better
|
/// \todo do this better
|
||||||
// put class name in current scope so it can be looked up by the attrs and methods
|
// 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(this->children[0]->text));
|
||||||
|
|
||||||
children[1]->eval(t_ss);
|
this->children[1]->eval(t_ss);
|
||||||
|
|
||||||
return void_var();
|
return void_var();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Ternary_Cond_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Ternary_Cond_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Ternary_Cond_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Ternary_Cond, std::move(t_loc), std::move(t_children))
|
Ternary_Cond_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) :
|
||||||
{ assert(children.size() == 3); }
|
AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::Ternary_Cond, std::move(t_loc), std::move(t_children))
|
||||||
|
{ assert(this->children.size() == 3); }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
||||||
if (get_bool_condition(children[0]->eval(t_ss))) {
|
if (this->get_bool_condition(this->children[0]->eval(t_ss))) {
|
||||||
return children[1]->eval(t_ss);
|
return this->children[1]->eval(t_ss);
|
||||||
} else {
|
} else {
|
||||||
return children[2]->eval(t_ss);
|
return this->children[2]->eval(t_ss);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct If_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
If_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct If_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::If, std::move(t_loc), std::move(t_children))
|
If_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::If, std::move(t_loc), std::move(t_children))
|
||||||
{
|
{
|
||||||
assert(children.size() == 2 || children.size() == 3);
|
assert(this->children.size() == 2 || this->children.size() == 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
||||||
if (get_bool_condition(children[0]->eval(t_ss))) {
|
if (this->get_bool_condition(this->children[0]->eval(t_ss))) {
|
||||||
return children[1]->eval(t_ss);
|
return this->children[1]->eval(t_ss);
|
||||||
} else {
|
} else {
|
||||||
if (children.size() == 3) {
|
if (this->children.size() == 3) {
|
||||||
return children[2]->eval(t_ss);
|
return this->children[2]->eval(t_ss);
|
||||||
} else {
|
} else {
|
||||||
return void_var();
|
return void_var();
|
||||||
}
|
}
|
||||||
@ -686,23 +747,24 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct For_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
For_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct For_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::For, std::move(t_loc), std::move(t_children))
|
For_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) :
|
||||||
{ assert(children.size() == 4); }
|
AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::For, std::move(t_loc), std::move(t_children))
|
||||||
|
{ assert(this->children.size() == 4); }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
|
||||||
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (
|
for (
|
||||||
children[0]->eval(t_ss);
|
this->children[0]->eval(t_ss);
|
||||||
get_bool_condition(children[1]->eval(t_ss));
|
this->get_bool_condition(this->children[1]->eval(t_ss));
|
||||||
children[2]->eval(t_ss)
|
this->children[2]->eval(t_ss)
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
// Body of Loop
|
// Body of Loop
|
||||||
children[3]->eval(t_ss);
|
this->children[3]->eval(t_ss);
|
||||||
} catch (detail::Continue_Loop &) {
|
} catch (detail::Continue_Loop &) {
|
||||||
// we got a continue exception, which means all of the remaining
|
// we got a continue exception, which means all of the remaining
|
||||||
// loop implementation is skipped and we just need to continue to
|
// loop implementation is skipped and we just need to continue to
|
||||||
@ -718,9 +780,10 @@ namespace chaiscript
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Switch_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Switch_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Switch_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Switch, std::move(t_loc), std::move(t_children)) { }
|
Switch_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::Switch, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
||||||
bool breaking = false;
|
bool breaking = false;
|
||||||
@ -761,45 +824,48 @@ namespace chaiscript
|
|||||||
mutable std::atomic_uint_fast32_t m_loc;
|
mutable std::atomic_uint_fast32_t m_loc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Case_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Case_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Case_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Case, std::move(t_loc), std::move(t_children))
|
Case_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::Case, std::move(t_loc), std::move(t_children))
|
||||||
{ assert(children.size() == 2); /* how many children does it have? */ }
|
{ assert(children.size() == 2); /* how many children does it have? */ }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
||||||
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
||||||
|
|
||||||
children[1]->eval(t_ss);
|
this->children[1]->eval(t_ss);
|
||||||
|
|
||||||
return void_var();
|
return void_var();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Default_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Default_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Default_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Default, std::move(t_loc), std::move(t_children))
|
Default_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::Default, std::move(t_loc), std::move(t_children))
|
||||||
{ assert(children.size() == 1); }
|
{ assert(children.size() == 1); }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
||||||
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
||||||
|
|
||||||
children[0]->eval(t_ss);
|
this->children[0]->eval(t_ss);
|
||||||
|
|
||||||
return void_var();
|
return void_var();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Inline_Array_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Inline_Array_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Inline_Array_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Inline_Array, std::move(t_loc), std::move(t_children)) { }
|
Inline_Array_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::Inline_Array, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
||||||
try {
|
try {
|
||||||
std::vector<Boxed_Value> vec;
|
std::vector<Boxed_Value> vec;
|
||||||
if (!children.empty()) {
|
if (!this->children.empty()) {
|
||||||
vec.reserve(children[0]->children.size());
|
vec.reserve(this->children[0]->children.size());
|
||||||
for (const auto &child : children[0]->children) {
|
for (const auto &child : this->children[0]->children) {
|
||||||
auto obj = child->eval(t_ss);
|
auto obj = child->eval(t_ss);
|
||||||
if (!obj.is_return_value()) {
|
if (!obj.is_return_value()) {
|
||||||
vec.push_back(t_ss->call_function("clone", m_loc, {obj}, t_ss.conversions()));
|
vec.push_back(t_ss->call_function("clone", m_loc, {obj}, t_ss.conversions()));
|
||||||
@ -819,15 +885,16 @@ namespace chaiscript
|
|||||||
mutable std::atomic_uint_fast32_t m_loc;
|
mutable std::atomic_uint_fast32_t m_loc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Inline_Map_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Inline_Map_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Inline_Map_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Inline_Map, std::move(t_loc), std::move(t_children)) { }
|
Inline_Map_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::Inline_Map, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
|
||||||
try {
|
try {
|
||||||
std::map<std::string, Boxed_Value> retval;
|
std::map<std::string, Boxed_Value> retval;
|
||||||
|
|
||||||
for (const auto &child : children[0]->children) {
|
for (const auto &child : this->children[0]->children) {
|
||||||
auto obj = child->children[1]->eval(t_ss);
|
auto obj = child->children[1]->eval(t_ss);
|
||||||
if (!obj.is_return_value()) {
|
if (!obj.is_return_value()) {
|
||||||
obj = t_ss->call_function("clone", m_loc, {obj}, t_ss.conversions());
|
obj = t_ss->call_function("clone", m_loc, {obj}, t_ss.conversions());
|
||||||
@ -847,13 +914,14 @@ namespace chaiscript
|
|||||||
mutable std::atomic_uint_fast32_t m_loc;
|
mutable std::atomic_uint_fast32_t m_loc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Return_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Return_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Return_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Return, std::move(t_loc), std::move(t_children)) { }
|
Return_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::Return, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
|
||||||
if (!this->children.empty()) {
|
if (!this->children.empty()) {
|
||||||
throw detail::Return_Value(children[0]->eval(t_ss));
|
throw detail::Return_Value(this->children[0]->eval(t_ss));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw detail::Return_Value(void_var());
|
throw detail::Return_Value(void_var());
|
||||||
@ -861,19 +929,20 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct File_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
File_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct File_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::File, std::move(t_loc), std::move(t_children)) { }
|
File_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::File, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
||||||
try {
|
try {
|
||||||
const auto num_children = children.size();
|
const auto num_children = this->children.size();
|
||||||
|
|
||||||
if (num_children > 0) {
|
if (num_children > 0) {
|
||||||
for (size_t i = 0; i < num_children-1; ++i) {
|
for (size_t i = 0; i < num_children-1; ++i) {
|
||||||
children[i]->eval(t_ss);
|
this->children[i]->eval(t_ss);
|
||||||
}
|
}
|
||||||
return children.back()->eval(t_ss);
|
return this->children.back()->eval(t_ss);
|
||||||
} else {
|
} else {
|
||||||
return void_var();
|
return void_var();
|
||||||
}
|
}
|
||||||
@ -885,9 +954,10 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Reference_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Reference_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Reference_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Reference, std::move(t_loc), std::move(t_children))
|
Reference_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::Reference, std::move(t_loc), std::move(t_children))
|
||||||
{ assert(children.size() == 1); }
|
{ assert(children.size() == 1); }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
|
||||||
@ -902,14 +972,15 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Prefix_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Prefix_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Prefix_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Prefix, std::move(t_loc), std::move(t_children)),
|
Prefix_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) :
|
||||||
m_oper(Operators::to_operator(text, true))
|
AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::Prefix, std::move(t_loc), std::move(t_children)),
|
||||||
|
m_oper(Operators::to_operator(this->text, true))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
|
||||||
Boxed_Value bv(children[0]->eval(t_ss));
|
Boxed_Value bv(this->children[0]->eval(t_ss));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// short circuit arithmetic operations
|
// short circuit arithmetic operations
|
||||||
@ -919,10 +990,10 @@ namespace chaiscript
|
|||||||
} else {
|
} else {
|
||||||
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
|
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
|
||||||
fpp.save_params({bv});
|
fpp.save_params({bv});
|
||||||
return t_ss->call_function(text, m_loc, {std::move(bv)}, t_ss.conversions());
|
return t_ss->call_function(this->text, m_loc, {std::move(bv)}, t_ss.conversions());
|
||||||
}
|
}
|
||||||
} catch (const exception::dispatch_error &e) {
|
} catch (const exception::dispatch_error &e) {
|
||||||
throw exception::eval_error("Error with prefix operator evaluation: '" + text + "'", e.parameters, e.functions, false, *t_ss);
|
throw exception::eval_error("Error with prefix operator evaluation: '" + this->text + "'", e.parameters, e.functions, false, *t_ss);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -931,27 +1002,30 @@ namespace chaiscript
|
|||||||
mutable std::atomic_uint_fast32_t m_loc;
|
mutable std::atomic_uint_fast32_t m_loc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Break_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Break_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Break_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Break, std::move(t_loc), std::move(t_children)) { }
|
Break_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::Break, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const override{
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const override{
|
||||||
throw detail::Break_Loop();
|
throw detail::Break_Loop();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Continue_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Continue_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Continue_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Continue, std::move(t_loc), std::move(t_children)) { }
|
Continue_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::Continue, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const override{
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const override{
|
||||||
throw detail::Continue_Loop();
|
throw detail::Continue_Loop();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Noop_AST_Node final : public AST_Node {
|
template<typename T>
|
||||||
|
struct Noop_AST_Node final : AST_Node_Impl<T> {
|
||||||
Noop_AST_Node() :
|
Noop_AST_Node() :
|
||||||
AST_Node("", AST_Node_Type::Noop, Parse_Location())
|
AST_Node_Impl<T>("", AST_Node_Type::Noop, Parse_Location())
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const override{
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const override{
|
||||||
@ -961,24 +1035,27 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Map_Pair_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Map_Pair_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Map_Pair_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Map_Pair, std::move(t_loc), std::move(t_children)) { }
|
Map_Pair_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::Map_Pair, std::move(t_loc), std::move(t_children)) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Value_Range_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Value_Range_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Value_Range_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Value_Range, std::move(t_loc), std::move(t_children)) { }
|
Value_Range_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::Value_Range, std::move(t_loc), std::move(t_children)) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Inline_Range_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Inline_Range_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Inline_Range_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Inline_Range, std::move(t_loc), std::move(t_children)) { }
|
Inline_Range_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::Inline_Range, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
|
||||||
try {
|
try {
|
||||||
auto oper1 = children[0]->children[0]->children[0]->eval(t_ss);
|
auto oper1 = this->children[0]->children[0]->children[0]->eval(t_ss);
|
||||||
auto oper2 = children[0]->children[0]->children[1]->eval(t_ss);
|
auto oper2 = this->children[0]->children[0]->children[1]->eval(t_ss);
|
||||||
return t_ss->call_function("generate_range", m_loc, {oper1, oper2}, t_ss.conversions());
|
return t_ss->call_function("generate_range", m_loc, {oper1, oper2}, t_ss.conversions());
|
||||||
}
|
}
|
||||||
catch (const exception::dispatch_error &e) {
|
catch (const exception::dispatch_error &e) {
|
||||||
@ -990,9 +1067,10 @@ namespace chaiscript
|
|||||||
mutable std::atomic_uint_fast32_t m_loc;
|
mutable std::atomic_uint_fast32_t m_loc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Try_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Try_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Try_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Try, std::move(t_loc), std::move(t_children)) { }
|
Try_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::Try, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
Boxed_Value handle_exception(const chaiscript::detail::Dispatch_State &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
|
||||||
{
|
{
|
||||||
@ -1005,17 +1083,17 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
for (size_t i = 1; i < end_point; ++i) {
|
for (size_t i = 1; i < end_point; ++i) {
|
||||||
chaiscript::eval::detail::Scope_Push_Pop catch_scope(t_ss);
|
chaiscript::eval::detail::Scope_Push_Pop catch_scope(t_ss);
|
||||||
AST_NodePtr catch_block = this->children[i];
|
AST_Node_Impl_Ptr<T> catch_block = this->children[i];
|
||||||
|
|
||||||
if (catch_block->children.size() == 1) {
|
if (catch_block->children.size() == 1) {
|
||||||
//No variable capture, no guards
|
//No variable capture, no guards
|
||||||
retval = catch_block->children[0]->eval(t_ss);
|
retval = catch_block->children[0]->eval(t_ss);
|
||||||
break;
|
break;
|
||||||
} else if (catch_block->children.size() == 2 || catch_block->children.size() == 3) {
|
} else if (catch_block->children.size() == 2 || catch_block->children.size() == 3) {
|
||||||
const auto name = Arg_List_AST_Node::get_arg_name(catch_block->children[0]);
|
const auto name = Arg_List_AST_Node<T>::get_arg_name(catch_block->children[0]);
|
||||||
|
|
||||||
if (dispatch::Param_Types(
|
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)}
|
std::vector<std::pair<std::string, Type_Info>>{Arg_List_AST_Node<T>::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);
|
||||||
@ -1099,23 +1177,26 @@ namespace chaiscript
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Catch_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Catch_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Catch_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Catch, std::move(t_loc), std::move(t_children)) { }
|
Catch_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::Catch, std::move(t_loc), std::move(t_children)) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Finally_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Finally_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Finally_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Finally, std::move(t_loc), std::move(t_children)) { }
|
Finally_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::Finally, std::move(t_loc), std::move(t_children)) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Method_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Method_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Method_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Method, std::move(t_loc), std::move(t_children)) { }
|
Method_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::Method, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
|
||||||
|
|
||||||
AST_NodePtr guardnode;
|
AST_Node_Impl_Ptr<T> 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 itr = d.find("_current_class_name");
|
||||||
@ -1126,20 +1207,21 @@ namespace chaiscript
|
|||||||
std::vector<std::string> t_param_names{"this"};
|
std::vector<std::string> t_param_names{"this"};
|
||||||
dispatch::Param_Types param_types;
|
dispatch::Param_Types param_types;
|
||||||
|
|
||||||
if ((children.size() > static_cast<size_t>(3 + class_offset)) && (children[static_cast<size_t>(2 + class_offset)]->identifier == AST_Node_Type::Arg_List)) {
|
if ((this->children.size() > static_cast<size_t>(3 + class_offset))
|
||||||
auto args = Arg_List_AST_Node::get_arg_names(children[static_cast<size_t>(2 + class_offset)]);
|
&& (this->children[static_cast<size_t>(2 + class_offset)]->identifier == AST_Node_Type::Arg_List)) {
|
||||||
|
auto args = Arg_List_AST_Node<T>::get_arg_names(this->children[static_cast<size_t>(2 + class_offset)]);
|
||||||
t_param_names.insert(t_param_names.end(), args.begin(), args.end());
|
t_param_names.insert(t_param_names.end(), args.begin(), args.end());
|
||||||
param_types = Arg_List_AST_Node::get_arg_types(children[static_cast<size_t>(2 + class_offset)], t_ss);
|
param_types = Arg_List_AST_Node<T>::get_arg_types(this->children[static_cast<size_t>(2 + class_offset)], t_ss);
|
||||||
|
|
||||||
if (children.size() > static_cast<size_t>(4 + class_offset)) {
|
if (this->children.size() > static_cast<size_t>(4 + class_offset)) {
|
||||||
guardnode = children[static_cast<size_t>(3 + class_offset)];
|
guardnode = this->children[static_cast<size_t>(3 + class_offset)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//no parameters
|
//no parameters
|
||||||
|
|
||||||
if (children.size() > static_cast<size_t>(3 + class_offset)) {
|
if (this->children.size() > static_cast<size_t>(3 + class_offset)) {
|
||||||
guardnode = children[static_cast<size_t>(2 + class_offset)];
|
guardnode = this->children[static_cast<size_t>(2 + class_offset)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1156,8 +1238,8 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const std::string & function_name = children[static_cast<size_t>(1 + class_offset)]->text;
|
const std::string & function_name = this->children[static_cast<size_t>(1 + class_offset)]->text;
|
||||||
auto node = children.back();
|
auto node = this->children.back();
|
||||||
|
|
||||||
if (function_name == class_name) {
|
if (function_name == class_name) {
|
||||||
param_types.push_front(class_name, Type_Info());
|
param_types.push_front(class_name, Type_Info());
|
||||||
@ -1198,9 +1280,10 @@ namespace chaiscript
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Attr_Decl_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Attr_Decl_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Attr_Decl_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Attr_Decl, std::move(t_loc), std::move(t_children)) { }
|
Attr_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::Attr_Decl, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override
|
||||||
{
|
{
|
||||||
@ -1234,28 +1317,30 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Logical_And_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Logical_And_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Logical_And_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Logical_And, std::move(t_loc), std::move(t_children))
|
Logical_And_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) :
|
||||||
{ assert(children.size() == 2); }
|
AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::Logical_And, std::move(t_loc), std::move(t_children))
|
||||||
|
{ assert(this->children.size() == 2); }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override
|
||||||
{
|
{
|
||||||
return const_var(get_bool_condition(children[0]->eval(t_ss))
|
return const_var(this->get_bool_condition(this->children[0]->eval(t_ss))
|
||||||
&& get_bool_condition(children[1]->eval(t_ss)));
|
&& this->get_bool_condition(this->children[1]->eval(t_ss)));
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Logical_Or_AST_Node final : AST_Node {
|
template<typename T>
|
||||||
Logical_Or_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
|
struct Logical_Or_AST_Node final : AST_Node_Impl<T> {
|
||||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Logical_Or, std::move(t_loc), std::move(t_children))
|
Logical_Or_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) :
|
||||||
{ assert(children.size() == 2); }
|
AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::Logical_Or, std::move(t_loc), std::move(t_children))
|
||||||
|
{ assert(this->children.size() == 2); }
|
||||||
|
|
||||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override
|
||||||
{
|
{
|
||||||
return const_var(get_bool_condition(children[0]->eval(t_ss))
|
return const_var(this->get_bool_condition(this->children[0]->eval(t_ss))
|
||||||
|| get_bool_condition(children[1]->eval(t_ss)));
|
|| this->get_bool_condition(this->children[1]->eval(t_ss)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -22,39 +22,41 @@ namespace chaiscript {
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
AST_NodePtr optimize(AST_NodePtr p) {
|
template<typename Tracer>
|
||||||
|
auto optimize(eval::AST_Node_Impl_Ptr<Tracer> p) {
|
||||||
(void)std::initializer_list<int>{ (p = T::optimize(p), 0)... };
|
(void)std::initializer_list<int>{ (p = T::optimize(p), 0)... };
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto child_at(const T &node, const size_t offset) {
|
auto child_at(const eval::AST_Node_Impl_Ptr<T> &node, const size_t offset) {
|
||||||
if (node->identifier == AST_Node_Type::Compiled) {
|
if (node->identifier == AST_Node_Type::Compiled) {
|
||||||
return dynamic_cast<const eval::Compiled_AST_Node&>(*node).m_original_node->children[offset];
|
return dynamic_cast<const eval::Compiled_AST_Node<T>&>(*node).m_original_node->children[offset];
|
||||||
} else {
|
} else {
|
||||||
return node->children[offset];
|
return node->children[offset];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto child_count(const T &node) {
|
auto child_count(const eval::AST_Node_Impl_Ptr<T> &node) {
|
||||||
if (node->identifier == AST_Node_Type::Compiled) {
|
if (node->identifier == AST_Node_Type::Compiled) {
|
||||||
return dynamic_cast<const eval::Compiled_AST_Node&>(*node).m_original_node->children.size();
|
return dynamic_cast<const eval::Compiled_AST_Node<T>&>(*node).m_original_node->children.size();
|
||||||
} else {
|
} else {
|
||||||
return node->children.size();
|
return node->children.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, typename Callable>
|
||||||
AST_NodePtr make_compiled_node(const AST_NodePtr &original_node, std::vector<AST_NodePtr> children, T callable)
|
auto make_compiled_node(const eval::AST_Node_Impl_Ptr<T> &original_node, std::vector<eval::AST_Node_Impl_Ptr<T>> children, Callable callable)
|
||||||
{
|
{
|
||||||
return chaiscript::make_shared<AST_Node, eval::Compiled_AST_Node>(original_node, std::move(children), std::move(callable));
|
return chaiscript::make_shared<eval::AST_Node_Impl<T>, eval::Compiled_AST_Node<T>>(original_node, std::move(children), std::move(callable));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct Return {
|
struct Return {
|
||||||
AST_NodePtr optimize(const AST_NodePtr &p)
|
template<typename T>
|
||||||
|
auto optimize(const eval::AST_Node_Impl_Ptr<T> &p)
|
||||||
{
|
{
|
||||||
if (p->identifier == AST_Node_Type::Def
|
if (p->identifier == AST_Node_Type::Def
|
||||||
&& !p->children.empty())
|
&& !p->children.empty())
|
||||||
@ -95,7 +97,8 @@ namespace chaiscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Block {
|
struct Block {
|
||||||
AST_NodePtr optimize(const AST_NodePtr &node) {
|
template<typename T>
|
||||||
|
auto optimize(const eval::AST_Node_Impl_Ptr<T> &node) {
|
||||||
if (node->identifier == AST_Node_Type::Block
|
if (node->identifier == AST_Node_Type::Block
|
||||||
&& node->children.size() == 1
|
&& node->children.size() == 1
|
||||||
&& !contains_var_decl_in_scope(node))
|
&& !contains_var_decl_in_scope(node))
|
||||||
@ -108,12 +111,13 @@ namespace chaiscript {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct If {
|
struct If {
|
||||||
AST_NodePtr optimize(const AST_NodePtr &node) {
|
template<typename T>
|
||||||
|
auto optimize(const eval::AST_Node_Impl_Ptr<T> &node) {
|
||||||
if ((node->identifier == AST_Node_Type::If || node->identifier == AST_Node_Type::Ternary_Cond)
|
if ((node->identifier == AST_Node_Type::If || node->identifier == AST_Node_Type::Ternary_Cond)
|
||||||
&& node->children.size() >= 2
|
&& node->children.size() >= 2
|
||||||
&& node->children[0]->identifier == AST_Node_Type::Constant)
|
&& node->children[0]->identifier == AST_Node_Type::Constant)
|
||||||
{
|
{
|
||||||
const auto condition = std::dynamic_pointer_cast<eval::Constant_AST_Node>(node->children[0])->m_value;
|
const auto condition = std::dynamic_pointer_cast<eval::Constant_AST_Node<T>>(node->children[0])->m_value;
|
||||||
if (condition.get_type_info().bare_equal_type_info(typeid(bool))) {
|
if (condition.get_type_info().bare_equal_type_info(typeid(bool))) {
|
||||||
if (boxed_cast<bool>(condition)) {
|
if (boxed_cast<bool>(condition)) {
|
||||||
return node->children[1];
|
return node->children[1];
|
||||||
@ -128,7 +132,8 @@ namespace chaiscript {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Constant_Fold {
|
struct Constant_Fold {
|
||||||
AST_NodePtr optimize(const AST_NodePtr &node) {
|
template<typename T>
|
||||||
|
auto optimize(const eval::AST_Node_Impl_Ptr<T> &node) {
|
||||||
|
|
||||||
if (node->identifier == AST_Node_Type::Binary
|
if (node->identifier == AST_Node_Type::Binary
|
||||||
&& node->children.size() == 2
|
&& node->children.size() == 2
|
||||||
@ -139,12 +144,12 @@ namespace chaiscript {
|
|||||||
const auto oper = node->text;
|
const auto oper = node->text;
|
||||||
const auto parsed = Operators::to_operator(oper);
|
const auto parsed = Operators::to_operator(oper);
|
||||||
if (parsed != Operators::Opers::invalid) {
|
if (parsed != Operators::Opers::invalid) {
|
||||||
const auto lhs = std::dynamic_pointer_cast<eval::Constant_AST_Node>(node->children[0])->m_value;
|
const auto lhs = std::dynamic_pointer_cast<eval::Constant_AST_Node<T>>(node->children[0])->m_value;
|
||||||
const auto rhs = std::dynamic_pointer_cast<eval::Constant_AST_Node>(node->children[1])->m_value;
|
const auto rhs = std::dynamic_pointer_cast<eval::Constant_AST_Node<T>>(node->children[1])->m_value;
|
||||||
if (lhs.get_type_info().is_arithmetic() && rhs.get_type_info().is_arithmetic()) {
|
if (lhs.get_type_info().is_arithmetic() && rhs.get_type_info().is_arithmetic()) {
|
||||||
const auto val = Boxed_Number::do_oper(parsed, lhs, rhs);
|
const auto val = Boxed_Number::do_oper(parsed, lhs, rhs);
|
||||||
const auto match = node->children[0]->text + " " + oper + " " + node->children[1]->text;
|
const auto match = node->children[0]->text + " " + oper + " " + node->children[1]->text;
|
||||||
return chaiscript::make_shared<AST_Node, eval::Constant_AST_Node>(std::move(match), node->location, std::move(val));
|
return chaiscript::make_shared<eval::AST_Node_Impl<T>, eval::Constant_AST_Node<T>>(std::move(match), node->location, std::move(val));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (const std::exception &) {
|
} catch (const std::exception &) {
|
||||||
@ -157,7 +162,8 @@ namespace chaiscript {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct For_Loop {
|
struct For_Loop {
|
||||||
AST_NodePtr optimize(const AST_NodePtr &for_node) {
|
template<typename T>
|
||||||
|
auto optimize(const eval::AST_Node_Impl_Ptr<T> &for_node) {
|
||||||
|
|
||||||
if (for_node->identifier != AST_Node_Type::For) {
|
if (for_node->identifier != AST_Node_Type::For) {
|
||||||
return for_node;
|
return for_node;
|
||||||
@ -183,8 +189,8 @@ namespace chaiscript {
|
|||||||
&& child_at(prefix_node, 0)->identifier == AST_Node_Type::Id
|
&& child_at(prefix_node, 0)->identifier == AST_Node_Type::Id
|
||||||
&& child_at(prefix_node, 0)->text == child_at(child_at(eq_node,0), 0)->text)
|
&& child_at(prefix_node, 0)->text == child_at(child_at(eq_node,0), 0)->text)
|
||||||
{
|
{
|
||||||
const Boxed_Value &begin = std::dynamic_pointer_cast<const eval::Constant_AST_Node>(child_at(eq_node, 1))->m_value;
|
const Boxed_Value &begin = std::dynamic_pointer_cast<const eval::Constant_AST_Node<T>>(child_at(eq_node, 1))->m_value;
|
||||||
const Boxed_Value &end = std::dynamic_pointer_cast<const eval::Constant_AST_Node>(child_at(binary_node, 1))->m_value;
|
const Boxed_Value &end = std::dynamic_pointer_cast<const eval::Constant_AST_Node<T>>(child_at(binary_node, 1))->m_value;
|
||||||
const std::string &id = child_at(prefix_node, 0)->text;
|
const std::string &id = child_at(prefix_node, 0)->text;
|
||||||
|
|
||||||
if (begin.get_type_info().bare_equal(user_type<int>())
|
if (begin.get_type_info().bare_equal(user_type<int>())
|
||||||
@ -196,7 +202,7 @@ namespace chaiscript {
|
|||||||
const auto body = child_at(for_node, 3);
|
const auto body = child_at(for_node, 3);
|
||||||
|
|
||||||
return make_compiled_node(for_node, {body},
|
return make_compiled_node(for_node, {body},
|
||||||
[id, start_int, end_int](const std::vector<AST_NodePtr> &children, const chaiscript::detail::Dispatch_State &t_ss) {
|
[id, start_int, end_int](const std::vector<eval::AST_Node_Impl_Ptr<T>> &children, const chaiscript::detail::Dispatch_State &t_ss) {
|
||||||
assert(children.size() == 1);
|
assert(children.size() == 1);
|
||||||
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "../dispatchkit/boxed_value.hpp"
|
#include "../dispatchkit/boxed_value.hpp"
|
||||||
#include "chaiscript_common.hpp"
|
#include "chaiscript_common.hpp"
|
||||||
#include "chaiscript_optimizer.hpp"
|
#include "chaiscript_optimizer.hpp"
|
||||||
|
#include "chaiscript_tracer.hpp"
|
||||||
|
|
||||||
#if defined(CHAISCRIPT_MSVC) && defined(max) && defined(min)
|
#if defined(CHAISCRIPT_MSVC) && defined(max) && defined(min)
|
||||||
#define CHAISCRIPT_PUSHED_MIN_MAX
|
#define CHAISCRIPT_PUSHED_MIN_MAX
|
||||||
@ -57,23 +58,12 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChaiScript_Parser_Base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual AST_NodePtr parse(const std::string &t_input, const std::string &t_fname) = 0;
|
|
||||||
virtual void debug_print(AST_NodePtr t, std::string prepend = "") const = 0;
|
|
||||||
virtual ~ChaiScript_Parser_Base() = default;
|
|
||||||
ChaiScript_Parser_Base() = default;
|
|
||||||
ChaiScript_Parser_Base(ChaiScript_Parser_Base &&) = default;
|
|
||||||
ChaiScript_Parser_Base &operator=(ChaiScript_Parser_Base &&) = delete;
|
|
||||||
ChaiScript_Parser_Base &operator=(const ChaiScript_Parser_Base &&) = delete;
|
|
||||||
|
|
||||||
protected:
|
template<typename Tracer, typename Optimizer>
|
||||||
ChaiScript_Parser_Base(const ChaiScript_Parser_Base &) = default;
|
class ChaiScript_Parser final : public ChaiScript_Parser_Base {
|
||||||
};
|
void *get_tracer_ptr() {
|
||||||
|
return &m_tracer;
|
||||||
template<typename Optimizer>
|
}
|
||||||
class ChaiScript_Parser : public ChaiScript_Parser_Base {
|
|
||||||
|
|
||||||
static std::array<std::array<bool, detail::lengthof_alphabet>, detail::max_alphabet> build_alphabet()
|
static std::array<std::array<bool, detail::lengthof_alphabet>, detail::max_alphabet> build_alphabet()
|
||||||
{
|
{
|
||||||
@ -190,7 +180,7 @@ namespace chaiscript
|
|||||||
const std::array<Operator_Precidence, 11> &m_operators = create_operators();
|
const std::array<Operator_Precidence, 11> &m_operators = create_operators();
|
||||||
|
|
||||||
std::shared_ptr<std::string> m_filename;
|
std::shared_ptr<std::string> m_filename;
|
||||||
std::vector<AST_NodePtr> m_match_stack;
|
std::vector<eval::AST_Node_Impl_Ptr<Tracer>> m_match_stack;
|
||||||
|
|
||||||
|
|
||||||
struct Position
|
struct Position
|
||||||
@ -293,11 +283,13 @@ namespace chaiscript
|
|||||||
|
|
||||||
Position m_position;
|
Position m_position;
|
||||||
|
|
||||||
|
Tracer m_tracer;
|
||||||
Optimizer m_optimizer;
|
Optimizer m_optimizer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ChaiScript_Parser(Optimizer optimizer=Optimizer())
|
explicit ChaiScript_Parser(Tracer tracer = Tracer(), Optimizer optimizer=Optimizer())
|
||||||
: m_optimizer(std::move(optimizer))
|
: m_tracer(std::move(tracer)),
|
||||||
|
m_optimizer(std::move(optimizer))
|
||||||
{
|
{
|
||||||
m_match_stack.reserve(2);
|
m_match_stack.reserve(2);
|
||||||
}
|
}
|
||||||
@ -314,8 +306,8 @@ namespace chaiscript
|
|||||||
/// Prints the parsed ast_nodes as a tree
|
/// Prints the parsed ast_nodes as a tree
|
||||||
void debug_print(AST_NodePtr t, std::string prepend = "") const override {
|
void debug_print(AST_NodePtr t, std::string prepend = "") const override {
|
||||||
std::cout << prepend << "(" << ast_node_type_to_string(t->identifier) << ") " << t->text << " : " << t->start().line << ", " << t->start().column << '\n';
|
std::cout << prepend << "(" << ast_node_type_to_string(t->identifier) << ") " << t->text << " : " << t->start().line << ", " << t->start().column << '\n';
|
||||||
for (unsigned int j = 0; j < t->children.size(); ++j) {
|
for (const auto &node : t->get_children()) {
|
||||||
debug_print(t->children[j], prepend + " ");
|
debug_print(node, prepend + " ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,7 +339,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
|
|
||||||
std::vector<AST_NodePtr> new_children;
|
std::vector<eval::AST_Node_Impl_Ptr<Tracer>> new_children;
|
||||||
|
|
||||||
if (is_deep) {
|
if (is_deep) {
|
||||||
new_children.assign(std::make_move_iterator(m_match_stack.begin() + static_cast<int>(t_match_start)),
|
new_children.assign(std::make_move_iterator(m_match_stack.begin() + static_cast<int>(t_match_start)),
|
||||||
@ -358,7 +350,7 @@ namespace chaiscript
|
|||||||
/// \todo fix the fact that a successful match that captured no ast_nodes doesn't have any real start position
|
/// \todo fix the fact that a successful match that captured no ast_nodes doesn't have any real start position
|
||||||
m_match_stack.push_back(
|
m_match_stack.push_back(
|
||||||
m_optimizer.optimize(
|
m_optimizer.optimize(
|
||||||
chaiscript::make_shared<chaiscript::AST_Node, NodeType>(
|
chaiscript::make_shared<chaiscript::eval::AST_Node_Impl<Tracer>, NodeType>(
|
||||||
std::move(t_text),
|
std::move(t_text),
|
||||||
std::move(filepos),
|
std::move(filepos),
|
||||||
std::move(new_children)))
|
std::move(new_children)))
|
||||||
@ -669,9 +661,9 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename ... Param>
|
template<typename T, typename ... Param>
|
||||||
std::shared_ptr<AST_Node> make_node(std::string t_match, const int t_prev_line, const int t_prev_col, Param && ...param)
|
std::shared_ptr<eval::AST_Node_Impl<Tracer>> make_node(std::string t_match, const int t_prev_line, const int t_prev_col, Param && ...param)
|
||||||
{
|
{
|
||||||
return chaiscript::make_shared<AST_Node, T>(std::move(t_match), Parse_Location(m_filename, t_prev_line, t_prev_col, m_position.line, m_position.col), std::forward<Param>(param)...);
|
return chaiscript::make_shared<eval::AST_Node_Impl<Tracer>, T>(std::move(t_match), Parse_Location(m_filename, t_prev_line, t_prev_col, m_position.line, m_position.col), std::forward<Param>(param)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reads a number from the input, detecting if it's an integer or floating point
|
/// Reads a number from the input, detecting if it's an integer or floating point
|
||||||
@ -687,20 +679,20 @@ namespace chaiscript
|
|||||||
if (Hex_()) {
|
if (Hex_()) {
|
||||||
auto match = Position::str(start, m_position);
|
auto match = Position::str(start, m_position);
|
||||||
auto bv = buildInt(16, match, true);
|
auto bv = buildInt(16, match, true);
|
||||||
m_match_stack.emplace_back(make_node<eval::Constant_AST_Node>(std::move(match), start.line, start.col, std::move(bv)));
|
m_match_stack.emplace_back(make_node<eval::Constant_AST_Node<Tracer>>(std::move(match), start.line, start.col, std::move(bv)));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Binary_()) {
|
if (Binary_()) {
|
||||||
auto match = Position::str(start, m_position);
|
auto match = Position::str(start, m_position);
|
||||||
auto bv = buildInt(2, match, true);
|
auto bv = buildInt(2, match, true);
|
||||||
m_match_stack.push_back(make_node<eval::Constant_AST_Node>(std::move(match), start.line, start.col, std::move(bv)));
|
m_match_stack.push_back(make_node<eval::Constant_AST_Node<Tracer>>(std::move(match), start.line, start.col, std::move(bv)));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (Float_()) {
|
if (Float_()) {
|
||||||
auto match = Position::str(start, m_position);
|
auto match = Position::str(start, m_position);
|
||||||
auto bv = buildFloat(match);
|
auto bv = buildFloat(match);
|
||||||
m_match_stack.push_back(make_node<eval::Constant_AST_Node>(std::move(match), start.line, start.col, std::move(bv)));
|
m_match_stack.push_back(make_node<eval::Constant_AST_Node<Tracer>>(std::move(match), start.line, start.col, std::move(bv)));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -708,11 +700,11 @@ namespace chaiscript
|
|||||||
auto match = Position::str(start, m_position);
|
auto match = Position::str(start, m_position);
|
||||||
if (!match.empty() && (match[0] == '0')) {
|
if (!match.empty() && (match[0] == '0')) {
|
||||||
auto bv = buildInt(8, match, false);
|
auto bv = buildInt(8, match, false);
|
||||||
m_match_stack.push_back(make_node<eval::Constant_AST_Node>(std::move(match), start.line, start.col, std::move(bv)));
|
m_match_stack.push_back(make_node<eval::Constant_AST_Node<Tracer>>(std::move(match), start.line, start.col, std::move(bv)));
|
||||||
}
|
}
|
||||||
else if (!match.empty()) {
|
else if (!match.empty()) {
|
||||||
auto bv = buildInt(10, match, false);
|
auto bv = buildInt(10, match, false);
|
||||||
m_match_stack.push_back(make_node<eval::Constant_AST_Node>(std::move(match), start.line, start.col, std::move(bv)));
|
m_match_stack.push_back(make_node<eval::Constant_AST_Node<Tracer>>(std::move(match), start.line, start.col, std::move(bv)));
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -773,20 +765,20 @@ namespace chaiscript
|
|||||||
|
|
||||||
const auto text = Position::str(start, m_position);
|
const auto text = Position::str(start, m_position);
|
||||||
if (text == "true") {
|
if (text == "true") {
|
||||||
m_match_stack.push_back(make_node<eval::Constant_AST_Node>(text, start.line, start.col, const_var(true)));
|
m_match_stack.push_back(make_node<eval::Constant_AST_Node<Tracer>>(text, start.line, start.col, const_var(true)));
|
||||||
} else if (text == "false") {
|
} else if (text == "false") {
|
||||||
m_match_stack.push_back(make_node<eval::Constant_AST_Node>(text, start.line, start.col, const_var(false)));
|
m_match_stack.push_back(make_node<eval::Constant_AST_Node<Tracer>>(text, start.line, start.col, const_var(false)));
|
||||||
} else if (text == "Infinity") {
|
} else if (text == "Infinity") {
|
||||||
m_match_stack.push_back(make_node<eval::Constant_AST_Node>(text, start.line, start.col,
|
m_match_stack.push_back(make_node<eval::Constant_AST_Node<Tracer>>(text, start.line, start.col,
|
||||||
const_var(std::numeric_limits<double>::infinity())));
|
const_var(std::numeric_limits<double>::infinity())));
|
||||||
} else if (text == "NaN") {
|
} else if (text == "NaN") {
|
||||||
m_match_stack.push_back(make_node<eval::Constant_AST_Node>(text, start.line, start.col,
|
m_match_stack.push_back(make_node<eval::Constant_AST_Node<Tracer>>(text, start.line, start.col,
|
||||||
const_var(std::numeric_limits<double>::quiet_NaN())));
|
const_var(std::numeric_limits<double>::quiet_NaN())));
|
||||||
} else if (text == "_") {
|
} else if (text == "_") {
|
||||||
m_match_stack.push_back(make_node<eval::Constant_AST_Node>(text, start.line, start.col,
|
m_match_stack.push_back(make_node<eval::Constant_AST_Node<Tracer>>(text, start.line, start.col,
|
||||||
Boxed_Value(std::make_shared<dispatch::Placeholder_Object>())));
|
Boxed_Value(std::make_shared<dispatch::Placeholder_Object>())));
|
||||||
} else {
|
} else {
|
||||||
m_match_stack.push_back(make_node<eval::Id_AST_Node>(
|
m_match_stack.push_back(make_node<eval::Id_AST_Node<Tracer>>(
|
||||||
[&]()->std::string{
|
[&]()->std::string{
|
||||||
if (*start == '`') {
|
if (*start == '`') {
|
||||||
// 'escaped' literal, like an operator name
|
// 'escaped' literal, like an operator name
|
||||||
@ -820,7 +812,7 @@ namespace chaiscript
|
|||||||
Id();
|
Id();
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::Arg_AST_Node>(prev_stack_top);
|
build_match<eval::Arg_AST_Node<Tracer>>(prev_stack_top);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1020,11 +1012,11 @@ namespace chaiscript
|
|||||||
if (*s == '{') {
|
if (*s == '{') {
|
||||||
//We've found an interpolation point
|
//We've found an interpolation point
|
||||||
|
|
||||||
m_match_stack.push_back(make_node<eval::Constant_AST_Node>(match, start.line, start.col, const_var(match)));
|
m_match_stack.push_back(make_node<eval::Constant_AST_Node<Tracer>>(match, start.line, start.col, const_var(match)));
|
||||||
|
|
||||||
if (cparser.is_interpolated) {
|
if (cparser.is_interpolated) {
|
||||||
//If we've seen previous interpolation, add on instead of making a new one
|
//If we've seen previous interpolation, add on instead of making a new one
|
||||||
build_match<eval::Binary_Operator_AST_Node>(prev_stack_top, "+");
|
build_match<eval::Binary_Operator_AST_Node<Tracer>>(prev_stack_top, "+");
|
||||||
}
|
}
|
||||||
|
|
||||||
//We've finished with the part of the string up to this point, so clear it
|
//We've finished with the part of the string up to this point, so clear it
|
||||||
@ -1044,19 +1036,19 @@ namespace chaiscript
|
|||||||
|
|
||||||
const auto tostr_stack_top = m_match_stack.size();
|
const auto tostr_stack_top = m_match_stack.size();
|
||||||
|
|
||||||
m_match_stack.push_back(make_node<eval::Id_AST_Node>("to_string", start.line, start.col));
|
m_match_stack.push_back(make_node<eval::Id_AST_Node<Tracer>>("to_string", start.line, start.col));
|
||||||
|
|
||||||
const auto ev_stack_top = m_match_stack.size();
|
const auto ev_stack_top = m_match_stack.size();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
m_match_stack.push_back(parse(eval_match, "instr eval"));
|
m_match_stack.push_back(parse_instr_eval(eval_match));
|
||||||
} catch (const exception::eval_error &e) {
|
} catch (const exception::eval_error &e) {
|
||||||
throw exception::eval_error(e.what(), File_Position(start.line, start.col), *m_filename);
|
throw exception::eval_error(e.what(), File_Position(start.line, start.col), *m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::Arg_List_AST_Node>(ev_stack_top);
|
build_match<eval::Arg_List_AST_Node<Tracer>>(ev_stack_top);
|
||||||
build_match<eval::Fun_Call_AST_Node>(tostr_stack_top);
|
build_match<eval::Fun_Call_AST_Node<Tracer>>(tostr_stack_top);
|
||||||
build_match<eval::Binary_Operator_AST_Node>(prev_stack_top, "+");
|
build_match<eval::Binary_Operator_AST_Node<Tracer>>(prev_stack_top, "+");
|
||||||
} else {
|
} else {
|
||||||
throw exception::eval_error("Unclosed in-string eval", File_Position(start.line, start.col), *m_filename);
|
throw exception::eval_error("Unclosed in-string eval", File_Position(start.line, start.col), *m_filename);
|
||||||
}
|
}
|
||||||
@ -1073,10 +1065,10 @@ namespace chaiscript
|
|||||||
return cparser.is_interpolated;
|
return cparser.is_interpolated;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
m_match_stack.push_back(make_node<eval::Constant_AST_Node>(match, start.line, start.col, const_var(match)));
|
m_match_stack.push_back(make_node<eval::Constant_AST_Node<Tracer>>(match, start.line, start.col, const_var(match)));
|
||||||
|
|
||||||
if (is_interpolated) {
|
if (is_interpolated) {
|
||||||
build_match<eval::Binary_Operator_AST_Node>(prev_stack_top, "+");
|
build_match<eval::Binary_Operator_AST_Node<Tracer>>(prev_stack_top, "+");
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -1138,7 +1130,7 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Single-quoted strings must be 1 character long", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Single-quoted strings must be 1 character long", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_match_stack.push_back(make_node<eval::Constant_AST_Node>(match, start.line, start.col, const_var(char(match.at(0)))));
|
m_match_stack.push_back(make_node<eval::Constant_AST_Node<Tracer>>(match, start.line, start.col, const_var(char(match.at(0)))));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1291,7 +1283,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
build_match<eval::Arg_List_AST_Node>(prev_stack_top);
|
build_match<eval::Arg_List_AST_Node<Tracer>>(prev_stack_top);
|
||||||
|
|
||||||
SkipWS(true);
|
SkipWS(true);
|
||||||
|
|
||||||
@ -1316,7 +1308,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
build_match<eval::Arg_List_AST_Node>(prev_stack_top);
|
build_match<eval::Arg_List_AST_Node<Tracer>>(prev_stack_top);
|
||||||
|
|
||||||
SkipWS(true);
|
SkipWS(true);
|
||||||
|
|
||||||
@ -1342,7 +1334,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::Arg_List_AST_Node>(prev_stack_top);
|
build_match<eval::Arg_List_AST_Node<Tracer>>(prev_stack_top);
|
||||||
|
|
||||||
SkipWS(true);
|
SkipWS(true);
|
||||||
|
|
||||||
@ -1358,7 +1350,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
if (Value_Range()) {
|
if (Value_Range()) {
|
||||||
retval = true;
|
retval = true;
|
||||||
build_match<eval::Arg_List_AST_Node>(prev_stack_top);
|
build_match<eval::Arg_List_AST_Node<Tracer>>(prev_stack_top);
|
||||||
} else if (Map_Pair()) {
|
} else if (Map_Pair()) {
|
||||||
retval = true;
|
retval = true;
|
||||||
while (Eol()) {}
|
while (Eol()) {}
|
||||||
@ -1368,7 +1360,7 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Unexpected value in container", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Unexpected value in container", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
build_match<eval::Arg_List_AST_Node>(prev_stack_top);
|
build_match<eval::Arg_List_AST_Node<Tracer>>(prev_stack_top);
|
||||||
} else if (Operator()) {
|
} else if (Operator()) {
|
||||||
retval = true;
|
retval = true;
|
||||||
while (Eol()) {}
|
while (Eol()) {}
|
||||||
@ -1378,7 +1370,7 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Unexpected value in container", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Unexpected value in container", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
build_match<eval::Arg_List_AST_Node>(prev_stack_top);
|
build_match<eval::Arg_List_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
SkipWS(true);
|
SkipWS(true);
|
||||||
@ -1402,7 +1394,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// make sure we always have the same number of nodes
|
// make sure we always have the same number of nodes
|
||||||
build_match<eval::Arg_List_AST_Node>(prev_stack_top);
|
build_match<eval::Arg_List_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Char('(')) {
|
if (Char('(')) {
|
||||||
@ -1421,7 +1413,7 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Incomplete anonymous function", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Incomplete anonymous function", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::Lambda_AST_Node>(prev_stack_top);
|
build_match<eval::Lambda_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
@ -1472,9 +1464,9 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_method || t_class_context) {
|
if (is_method || t_class_context) {
|
||||||
build_match<eval::Method_AST_Node>(prev_stack_top);
|
build_match<eval::Method_AST_Node<Tracer>>(prev_stack_top);
|
||||||
} else {
|
} else {
|
||||||
build_match<eval::Def_AST_Node>(prev_stack_top);
|
build_match<eval::Def_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1519,7 +1511,7 @@ namespace chaiscript
|
|||||||
if (!Block()) {
|
if (!Block()) {
|
||||||
throw exception::eval_error("Incomplete 'catch' block", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Incomplete 'catch' block", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
build_match<eval::Catch_AST_Node>(catch_stack_top);
|
build_match<eval::Catch_AST_Node<Tracer>>(catch_stack_top);
|
||||||
has_matches = true;
|
has_matches = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1532,10 +1524,10 @@ namespace chaiscript
|
|||||||
if (!Block()) {
|
if (!Block()) {
|
||||||
throw exception::eval_error("Incomplete 'finally' block", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Incomplete 'finally' block", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
build_match<eval::Finally_AST_Node>(finally_stack_top);
|
build_match<eval::Finally_AST_Node<Tracer>>(finally_stack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::Try_AST_Node>(prev_stack_top);
|
build_match<eval::Try_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
@ -1582,7 +1574,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::If_AST_Node>(prev_stack_top);
|
build_match<eval::If_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
@ -1608,7 +1600,7 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Incomplete 'class' block", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Incomplete 'class' block", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::Class_AST_Node>(prev_stack_top);
|
build_match<eval::Class_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
@ -1638,7 +1630,7 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Incomplete 'while' block", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Incomplete 'while' block", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::While_AST_Node>(prev_stack_top);
|
build_match<eval::While_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
@ -1653,7 +1645,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
throw exception::eval_error("'for' loop initial statment missing", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("'for' loop initial statment missing", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
} else {
|
} else {
|
||||||
m_match_stack.push_back(chaiscript::make_shared<AST_Node, eval::Noop_AST_Node>());
|
m_match_stack.push_back(chaiscript::make_shared<eval::AST_Node_Impl<Tracer>, eval::Noop_AST_Node<Tracer>>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1663,13 +1655,13 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
throw exception::eval_error("'for' loop condition missing", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("'for' loop condition missing", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
} else {
|
} else {
|
||||||
m_match_stack.push_back(chaiscript::make_shared<AST_Node, eval::Noop_AST_Node>());
|
m_match_stack.push_back(chaiscript::make_shared<eval::AST_Node_Impl<Tracer>, eval::Noop_AST_Node<Tracer>>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Equation())
|
if (!Equation())
|
||||||
{
|
{
|
||||||
m_match_stack.push_back(chaiscript::make_shared<AST_Node, eval::Noop_AST_Node>());
|
m_match_stack.push_back(chaiscript::make_shared<eval::AST_Node_Impl<Tracer>, eval::Noop_AST_Node<Tracer>>());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -1699,7 +1691,7 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Incomplete 'for' block", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Incomplete 'for' block", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::For_AST_Node>(prev_stack_top);
|
build_match<eval::For_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
@ -1729,7 +1721,7 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Incomplete 'case' block", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Incomplete 'case' block", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::Case_AST_Node>(prev_stack_top);
|
build_match<eval::Case_AST_Node<Tracer>>(prev_stack_top);
|
||||||
} else if (Keyword("default")) {
|
} else if (Keyword("default")) {
|
||||||
retval = true;
|
retval = true;
|
||||||
|
|
||||||
@ -1739,7 +1731,7 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Incomplete 'default' block", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Incomplete 'default' block", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::Default_AST_Node>(prev_stack_top);
|
build_match<eval::Default_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
@ -1779,7 +1771,7 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Incomplete block", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Incomplete block", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::Switch_AST_Node>(prev_stack_top);
|
build_match<eval::Switch_AST_Node<Tracer>>(prev_stack_top);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -1804,10 +1796,10 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_match_stack.size() == prev_stack_top) {
|
if (m_match_stack.size() == prev_stack_top) {
|
||||||
m_match_stack.push_back(chaiscript::make_shared<AST_Node, eval::Noop_AST_Node>());
|
m_match_stack.push_back(chaiscript::make_shared<eval::AST_Node_Impl<Tracer>, eval::Noop_AST_Node<Tracer>>());
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::Block_AST_Node>(prev_stack_top);
|
build_match<eval::Block_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
@ -1828,10 +1820,10 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_match_stack.size() == prev_stack_top) {
|
if (m_match_stack.size() == prev_stack_top) {
|
||||||
m_match_stack.push_back(chaiscript::make_shared<AST_Node, eval::Noop_AST_Node>());
|
m_match_stack.push_back(chaiscript::make_shared<eval::AST_Node_Impl<Tracer>, eval::Noop_AST_Node<Tracer>>());
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::Block_AST_Node>(prev_stack_top);
|
build_match<eval::Block_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
@ -1843,7 +1835,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
if (Keyword("return")) {
|
if (Keyword("return")) {
|
||||||
Operator();
|
Operator();
|
||||||
build_match<eval::Return_AST_Node>(prev_stack_top);
|
build_match<eval::Return_AST_Node<Tracer>>(prev_stack_top);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -1855,7 +1847,7 @@ namespace chaiscript
|
|||||||
const auto prev_stack_top = m_match_stack.size();
|
const auto prev_stack_top = m_match_stack.size();
|
||||||
|
|
||||||
if (Keyword("break")) {
|
if (Keyword("break")) {
|
||||||
build_match<eval::Break_AST_Node>(prev_stack_top);
|
build_match<eval::Break_AST_Node<Tracer>>(prev_stack_top);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -1867,7 +1859,7 @@ namespace chaiscript
|
|||||||
const auto prev_stack_top = m_match_stack.size();
|
const auto prev_stack_top = m_match_stack.size();
|
||||||
|
|
||||||
if (Keyword("continue")) {
|
if (Keyword("continue")) {
|
||||||
build_match<eval::Continue_AST_Node>(prev_stack_top);
|
build_match<eval::Continue_AST_Node<Tracer>>(prev_stack_top);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -1896,14 +1888,14 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Incomplete function call", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Incomplete function call", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::Fun_Call_AST_Node>(prev_stack_top);
|
build_match<eval::Fun_Call_AST_Node<Tracer>>(prev_stack_top);
|
||||||
/// \todo Work around for method calls until we have a better solution
|
/// \todo Work around for method calls until we have a better solution
|
||||||
if (!m_match_stack.back()->children.empty()) {
|
if (!m_match_stack.back()->children.empty()) {
|
||||||
if (m_match_stack.back()->children[0]->identifier == AST_Node_Type::Dot_Access) {
|
if (m_match_stack.back()->children[0]->identifier == AST_Node_Type::Dot_Access) {
|
||||||
if (m_match_stack.empty()) throw exception::eval_error("Incomplete dot access fun call", File_Position(m_position.line, m_position.col), *m_filename);
|
if (m_match_stack.empty()) throw exception::eval_error("Incomplete dot access fun call", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
if (m_match_stack.back()->children.empty()) throw exception::eval_error("Incomplete dot access fun call", File_Position(m_position.line, m_position.col), *m_filename);
|
if (m_match_stack.back()->children.empty()) throw exception::eval_error("Incomplete dot access fun call", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
AST_NodePtr dot_access = m_match_stack.back()->children[0];
|
auto dot_access = m_match_stack.back()->children[0];
|
||||||
AST_NodePtr func_call = m_match_stack.back();
|
auto func_call = m_match_stack.back();
|
||||||
m_match_stack.pop_back();
|
m_match_stack.pop_back();
|
||||||
func_call->children.erase(func_call->children.begin());
|
func_call->children.erase(func_call->children.begin());
|
||||||
if (dot_access->children.empty()) throw exception::eval_error("Incomplete dot access fun call", File_Position(m_position.line, m_position.col), *m_filename);
|
if (dot_access->children.empty()) throw exception::eval_error("Incomplete dot access fun call", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
@ -1921,7 +1913,7 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Incomplete array access", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Incomplete array access", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::Array_Call_AST_Node>(prev_stack_top);
|
build_match<eval::Array_Call_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
else if (Symbol(".")) {
|
else if (Symbol(".")) {
|
||||||
has_more = true;
|
has_more = true;
|
||||||
@ -1932,7 +1924,7 @@ namespace chaiscript
|
|||||||
if ( std::distance(m_match_stack.begin() + static_cast<int>(prev_stack_top), m_match_stack.end()) != 2) {
|
if ( std::distance(m_match_stack.begin() + static_cast<int>(prev_stack_top), m_match_stack.end()) != 2) {
|
||||||
throw exception::eval_error("Incomplete dot access fun call", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Incomplete dot access fun call", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
build_match<eval::Dot_Access_AST_Node>(prev_stack_top);
|
build_match<eval::Dot_Access_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1953,14 +1945,14 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Incomplete attribute declaration", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Incomplete attribute declaration", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::Attr_Decl_AST_Node>(prev_stack_top);
|
build_match<eval::Attr_Decl_AST_Node<Tracer>>(prev_stack_top);
|
||||||
} else if (Keyword("auto") || Keyword("var") ) {
|
} else if (Keyword("auto") || Keyword("var") ) {
|
||||||
retval = true;
|
retval = true;
|
||||||
|
|
||||||
if (Reference()) {
|
if (Reference()) {
|
||||||
// we built a reference node - continue
|
// we built a reference node - continue
|
||||||
} else if (Id()) {
|
} else if (Id()) {
|
||||||
build_match<eval::Var_Decl_AST_Node>(prev_stack_top);
|
build_match<eval::Var_Decl_AST_Node<Tracer>>(prev_stack_top);
|
||||||
} else {
|
} else {
|
||||||
throw exception::eval_error("Incomplete variable declaration", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Incomplete variable declaration", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
@ -1972,7 +1964,7 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Incomplete global declaration", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Incomplete global declaration", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::Global_Decl_AST_Node>(prev_stack_top);
|
build_match<eval::Global_Decl_AST_Node<Tracer>>(prev_stack_top);
|
||||||
} else if (Keyword("attr")) {
|
} else if (Keyword("attr")) {
|
||||||
retval = true;
|
retval = true;
|
||||||
|
|
||||||
@ -1987,7 +1979,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
build_match<eval::Attr_Decl_AST_Node>(prev_stack_top);
|
build_match<eval::Attr_Decl_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
@ -2020,17 +2012,17 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
if ((prev_stack_top != m_match_stack.size()) && (m_match_stack.back()->children.size() > 0)) {
|
if ((prev_stack_top != m_match_stack.size()) && (m_match_stack.back()->children.size() > 0)) {
|
||||||
if (m_match_stack.back()->children[0]->identifier == AST_Node_Type::Value_Range) {
|
if (m_match_stack.back()->children[0]->identifier == AST_Node_Type::Value_Range) {
|
||||||
build_match<eval::Inline_Range_AST_Node>(prev_stack_top);
|
build_match<eval::Inline_Range_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
else if (m_match_stack.back()->children[0]->identifier == AST_Node_Type::Map_Pair) {
|
else if (m_match_stack.back()->children[0]->identifier == AST_Node_Type::Map_Pair) {
|
||||||
build_match<eval::Inline_Map_AST_Node>(prev_stack_top);
|
build_match<eval::Inline_Map_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
build_match<eval::Inline_Array_AST_Node>(prev_stack_top);
|
build_match<eval::Inline_Array_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
build_match<eval::Inline_Array_AST_Node>(prev_stack_top);
|
build_match<eval::Inline_Array_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -2048,7 +2040,7 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Incomplete '&' expression", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Incomplete '&' expression", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::Reference_AST_Node>(prev_stack_top);
|
build_match<eval::Reference_AST_Node<Tracer>>(prev_stack_top);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -2069,7 +2061,7 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Incomplete prefix '" + oper + "' expression", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Incomplete prefix '" + oper + "' expression", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::Prefix_AST_Node>(prev_stack_top, oper);
|
build_match<eval::Prefix_AST_Node<Tracer>>(prev_stack_top, oper);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2114,7 +2106,7 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Incomplete '" + oper + "' expression",
|
throw exception::eval_error("Incomplete '" + oper + "' expression",
|
||||||
File_Position(m_position.line, m_position.col), *m_filename);
|
File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
build_match<eval::Ternary_Cond_AST_Node>(prev_stack_top);
|
build_match<eval::Ternary_Cond_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw exception::eval_error("Incomplete '" + oper + "' expression",
|
throw exception::eval_error("Incomplete '" + oper + "' expression",
|
||||||
@ -2130,14 +2122,14 @@ namespace chaiscript
|
|||||||
case(Operator_Precidence::Bitwise_Xor) :
|
case(Operator_Precidence::Bitwise_Xor) :
|
||||||
case(Operator_Precidence::Bitwise_Or) :
|
case(Operator_Precidence::Bitwise_Or) :
|
||||||
case(Operator_Precidence::Comparison) :
|
case(Operator_Precidence::Comparison) :
|
||||||
build_match<eval::Binary_Operator_AST_Node>(prev_stack_top, oper);
|
build_match<eval::Binary_Operator_AST_Node<Tracer>>(prev_stack_top, oper);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case(Operator_Precidence::Logical_And) :
|
case(Operator_Precidence::Logical_And) :
|
||||||
build_match<eval::Logical_And_AST_Node>(prev_stack_top, oper);
|
build_match<eval::Logical_And_AST_Node<Tracer>>(prev_stack_top, oper);
|
||||||
break;
|
break;
|
||||||
case(Operator_Precidence::Logical_Or) :
|
case(Operator_Precidence::Logical_Or) :
|
||||||
build_match<eval::Logical_Or_AST_Node>(prev_stack_top, oper);
|
build_match<eval::Logical_Or_AST_Node<Tracer>>(prev_stack_top, oper);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -2167,7 +2159,7 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Incomplete map pair", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Incomplete map pair", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::Map_Pair_AST_Node>(prev_stack_top);
|
build_match<eval::Map_Pair_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_position = prev_pos;
|
m_position = prev_pos;
|
||||||
@ -2194,7 +2186,7 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Incomplete value range", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Incomplete value range", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::Value_Range_AST_Node>(prev_stack_top);
|
build_match<eval::Value_Range_AST_Node<Tracer>>(prev_stack_top);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_position = prev_pos;
|
m_position = prev_pos;
|
||||||
@ -2220,7 +2212,7 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Incomplete equation", File_Position(m_position.line, m_position.col), *m_filename);
|
throw exception::eval_error("Incomplete equation", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::Equation_AST_Node>(prev_stack_top, sym);
|
build_match<eval::Equation_AST_Node<Tracer>>(prev_stack_top, sym);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2298,11 +2290,26 @@ namespace chaiscript
|
|||||||
|
|
||||||
AST_NodePtr parse(const std::string &t_input, const std::string &t_fname) override
|
AST_NodePtr parse(const std::string &t_input, const std::string &t_fname) override
|
||||||
{
|
{
|
||||||
ChaiScript_Parser<Optimizer> parser(*this);
|
ChaiScript_Parser<Tracer, Optimizer> parser(*this);
|
||||||
parser.m_match_stack.clear();
|
parser.m_match_stack.clear();
|
||||||
return parser.parse_internal(t_input, t_fname);
|
return parser.parse_internal(t_input, t_fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eval::AST_Node_Impl_Ptr<Tracer> parse_instr_eval(const std::string &t_input)
|
||||||
|
{
|
||||||
|
const auto last_position = m_position;
|
||||||
|
const auto last_filename = m_filename;
|
||||||
|
const auto last_match_stack = std::exchange(m_match_stack, decltype(m_match_stack){});
|
||||||
|
|
||||||
|
const auto retval = parse_internal(t_input, "instr eval");
|
||||||
|
|
||||||
|
m_position = std::move(last_position);
|
||||||
|
m_filename = std::move(last_filename);
|
||||||
|
m_match_stack = std::move(last_match_stack);
|
||||||
|
|
||||||
|
return std::dynamic_pointer_cast<eval::AST_Node_Impl<Tracer>>(retval);
|
||||||
|
}
|
||||||
|
|
||||||
/// Parses the given input string, tagging parsed ast_nodes with the given m_filename.
|
/// Parses the given input string, tagging parsed ast_nodes with the given m_filename.
|
||||||
AST_NodePtr parse_internal(const std::string &t_input, std::string t_fname) {
|
AST_NodePtr parse_internal(const std::string &t_input, std::string t_fname) {
|
||||||
m_position = Position(t_input.begin(), t_input.end());
|
m_position = Position(t_input.begin(), t_input.end());
|
||||||
@ -2319,10 +2326,10 @@ namespace chaiscript
|
|||||||
if (m_position.has_more()) {
|
if (m_position.has_more()) {
|
||||||
throw exception::eval_error("Unparsed input", File_Position(m_position.line, m_position.col), t_fname);
|
throw exception::eval_error("Unparsed input", File_Position(m_position.line, m_position.col), t_fname);
|
||||||
} else {
|
} else {
|
||||||
build_match<eval::File_AST_Node>(0);
|
build_match<eval::File_AST_Node<Tracer>>(0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_match_stack.push_back(chaiscript::make_shared<AST_Node, eval::Noop_AST_Node>());
|
m_match_stack.push_back(chaiscript::make_shared<eval::AST_Node_Impl<Tracer>, eval::Noop_AST_Node<Tracer>>());
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_match_stack.front();
|
return m_match_stack.front();
|
||||||
|
43
include/chaiscript/language/chaiscript_tracer.hpp
Normal file
43
include/chaiscript/language/chaiscript_tracer.hpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// This file is distributed under the BSD License.
|
||||||
|
// See "license.txt" for details.
|
||||||
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
|
#ifndef CHAISCRIPT_TRACER_HPP_
|
||||||
|
#define CHAISCRIPT_TRACER_HPP_
|
||||||
|
|
||||||
|
namespace chaiscript {
|
||||||
|
namespace eval {
|
||||||
|
|
||||||
|
struct Noop_Tracer
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
static void trace(const chaiscript::detail::Dispatch_State &, const AST_Node_Impl<T> *)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ... T>
|
||||||
|
struct Tracer : T...
|
||||||
|
{
|
||||||
|
Tracer() = default;
|
||||||
|
Tracer(T ... t)
|
||||||
|
: T(std::move(t))...
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_trace(const chaiscript::detail::Dispatch_State &ds, const AST_Node_Impl<Tracer<T...>> *node) {
|
||||||
|
(void)std::initializer_list<int>{ (T::trace(ds, node), 0)... };
|
||||||
|
}
|
||||||
|
|
||||||
|
static void trace(const chaiscript::detail::Dispatch_State &ds, const AST_Node_Impl<Tracer<T...>> *node) {
|
||||||
|
ds->get_parser().get_tracer<Tracer<T...>>().do_trace(ds, node);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user