mirror of
https://github.com/ChaiScript/ChaiScript.git
synced 2026-02-07 18:26:49 +08:00
Add optimization for unused return values
This commit is contained in:
parent
228c942b6c
commit
52a191df9e
@ -32,7 +32,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
|
|
||||||
/// Types of AST nodes available to the parser and eval
|
/// Types of AST nodes available to the parser and eval
|
||||||
enum class AST_Node_Type { Id, Fun_Call, Arg_List, Equation, Var_Decl,
|
enum class AST_Node_Type { Id, Fun_Call, Unused_Return_Fun_Call, Arg_List, Equation, Var_Decl,
|
||||||
Array_Call, Dot_Access,
|
Array_Call, Dot_Access,
|
||||||
Lambda, Block, Scopeless_Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range,
|
Lambda, Block, Scopeless_Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range,
|
||||||
Inline_Range, Try, Catch, Finally, Method, Attr_Decl,
|
Inline_Range, Try, Catch, Finally, Method, Attr_Decl,
|
||||||
@ -45,7 +45,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
/// Helper lookup to get the name of each node type
|
/// Helper lookup to get the name of each node type
|
||||||
const char *ast_node_type_to_string(AST_Node_Type ast_node_type) {
|
const char *ast_node_type_to_string(AST_Node_Type ast_node_type) {
|
||||||
static const char * const ast_node_types[] = { "Id", "Fun_Call", "Arg_List", "Equation", "Var_Decl",
|
static const char * const ast_node_types[] = { "Id", "Fun_Call", "Unused_Return_Fun_Call", "Arg_List", "Equation", "Var_Decl",
|
||||||
"Array_Call", "Dot_Access",
|
"Array_Call", "Dot_Access",
|
||||||
"Lambda", "Block", "Scopeless_Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range",
|
"Lambda", "Block", "Scopeless_Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range",
|
||||||
"Inline_Range", "Try", "Catch", "Finally", "Method", "Attr_Decl",
|
"Inline_Range", "Try", "Catch", "Finally", "Method", "Attr_Decl",
|
||||||
|
|||||||
@ -219,7 +219,7 @@ 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<eval::Noop_Tracer, optimizer::Optimizer<optimizer::Block, optimizer::Partial_Fold, 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::Partial_Fold, optimizer::Unused_Return, optimizer::Constant_Fold, optimizer::If, optimizer::Return, optimizer::For_Loop>>>()),
|
||||||
m_engine(*m_parser)
|
m_engine(*m_parser)
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -246,7 +246,7 @@ 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<eval::Noop_Tracer, optimizer::Optimizer<optimizer::Block, optimizer::Partial_Fold, 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::Partial_Fold, optimizer::Unused_Return, optimizer::Constant_Fold, optimizer::If, optimizer::Return, optimizer::For_Loop>>>()),
|
||||||
m_engine(*m_parser)
|
m_engine(*m_parser)
|
||||||
{
|
{
|
||||||
if (m_module_paths.empty())
|
if (m_module_paths.empty())
|
||||||
|
|||||||
@ -270,6 +270,52 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Unused_Return_Fun_Call_AST_Node final : AST_Node_Impl<T> {
|
||||||
|
Unused_Return_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::Unused_Return_Fun_Call, std::move(t_loc), std::move(t_children)) { }
|
||||||
|
|
||||||
|
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override
|
||||||
|
{
|
||||||
|
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
|
||||||
|
|
||||||
|
std::vector<Boxed_Value> params;
|
||||||
|
|
||||||
|
params.reserve(this->children[1]->children.size());
|
||||||
|
for (const auto &child : this->children[1]->children) {
|
||||||
|
params.push_back(child->eval(t_ss));
|
||||||
|
}
|
||||||
|
|
||||||
|
Boxed_Value fn(this->children[0]->eval(t_ss));
|
||||||
|
|
||||||
|
try {
|
||||||
|
return (*t_ss->boxed_cast<const dispatch::Proxy_Function_Base *>(fn))(params, t_ss.conversions());
|
||||||
|
}
|
||||||
|
catch(const exception::dispatch_error &e){
|
||||||
|
throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'", e.parameters, e.functions, false, *t_ss);
|
||||||
|
}
|
||||||
|
catch(const exception::bad_boxed_cast &){
|
||||||
|
try {
|
||||||
|
Const_Proxy_Function f = t_ss->boxed_cast<const Const_Proxy_Function &>(fn);
|
||||||
|
// handle the case where there is only 1 function to try to call and dispatch fails on it
|
||||||
|
throw exception::eval_error("Error calling function '" + this->children[0]->text + "'", params, {f}, false, *t_ss);
|
||||||
|
} catch (const exception::bad_boxed_cast &) {
|
||||||
|
throw exception::eval_error("'" + this->children[0]->pretty_print() + "' does not evaluate to a function.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(const exception::arity_error &e){
|
||||||
|
throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'");
|
||||||
|
}
|
||||||
|
catch(const exception::guard_error &e){
|
||||||
|
throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'");
|
||||||
|
}
|
||||||
|
catch(detail::Return_Value &rv) {
|
||||||
|
return rv.retval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Fun_Call_AST_Node final : AST_Node_Impl<T> {
|
struct Fun_Call_AST_Node final : AST_Node_Impl<T> {
|
||||||
|
|||||||
@ -125,6 +125,39 @@ namespace chaiscript {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Unused_Return {
|
||||||
|
template<typename T>
|
||||||
|
auto optimize(const eval::AST_Node_Impl_Ptr<T> &node) {
|
||||||
|
if ((node->identifier == AST_Node_Type::Block
|
||||||
|
|| node->identifier == AST_Node_Type::Scopeless_Block)
|
||||||
|
&& node->children.size() > 0)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < node->children.size()-1; ++i) {
|
||||||
|
auto child = node->children[i];
|
||||||
|
if (child->identifier == AST_Node_Type::Fun_Call) {
|
||||||
|
node->children[i] = chaiscript::make_shared<eval::AST_Node_Impl<T>, eval::Unused_Return_Fun_Call_AST_Node<T>>(child->text, child->location, std::move(child->children));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ((node->identifier == AST_Node_Type::For
|
||||||
|
|| node->identifier == AST_Node_Type::While)
|
||||||
|
&& child_count(node) > 0) {
|
||||||
|
auto child = child_at(node, child_count(node) - 1);
|
||||||
|
if (child->identifier == AST_Node_Type::Block
|
||||||
|
|| child->identifier == AST_Node_Type::Scopeless_Block)
|
||||||
|
{
|
||||||
|
auto num_sub_children = child_count(child);
|
||||||
|
for (size_t i = 0; i < num_sub_children; ++i) {
|
||||||
|
auto sub_child = child_at(child, i);
|
||||||
|
if (sub_child->identifier == AST_Node_Type::Fun_Call) {
|
||||||
|
child->children[i] = chaiscript::make_shared<eval::AST_Node_Impl<T>, eval::Unused_Return_Fun_Call_AST_Node<T>>(sub_child->text, sub_child->location, std::move(sub_child->children));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct If {
|
struct If {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto optimize(const eval::AST_Node_Impl_Ptr<T> &node) {
|
auto optimize(const eval::AST_Node_Impl_Ptr<T> &node) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user