Shave a few cycles off by reducing copies and assignments of objects in eval
This commit is contained in:
parent
94e4b671f3
commit
ff639a267d
@ -15,34 +15,31 @@ namespace chaiscript
|
||||
* Helper function that will set up the scope around a function call, including handling the named function parameters
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
const Boxed_Value eval_function (Eval_System &ss, TokenPtr node, const std::vector<std::string> ¶m_names, const std::vector<Boxed_Value> &vals) {
|
||||
const Boxed_Value eval_function (Eval_System &ss, const TokenPtr &node, const std::vector<std::string> ¶m_names, const std::vector<Boxed_Value> &vals) {
|
||||
ss.new_scope();
|
||||
|
||||
for (unsigned int i = 0; i < param_names.size(); ++i) {
|
||||
ss.add_object(param_names[i], vals[i]);
|
||||
}
|
||||
|
||||
Boxed_Value retval;
|
||||
|
||||
try {
|
||||
retval = eval_token(ss, node);
|
||||
Boxed_Value retval(eval_token(ss, node));
|
||||
ss.pop_scope();
|
||||
return retval;
|
||||
} catch (const Return_Value &rv) {
|
||||
retval = rv.retval;
|
||||
ss.pop_scope();
|
||||
return rv.retval;
|
||||
} catch (...) {
|
||||
ss.pop_scope();
|
||||
throw;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates the top-level file node
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_file(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value eval_file(Eval_System &ss, const TokenPtr &node) {
|
||||
Boxed_Value retval;
|
||||
unsigned int i;
|
||||
for (i = 0; i < node->children.size(); ++i) {
|
||||
@ -55,7 +52,7 @@ namespace chaiscript
|
||||
* Evaluates a variable or function name identifier
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_id(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value eval_id(Eval_System &ss, const TokenPtr &node) {
|
||||
|
||||
if (node->text == "true") {
|
||||
return Boxed_Value(true);
|
||||
@ -77,7 +74,7 @@ namespace chaiscript
|
||||
* Evaluates a floating point number
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_float(Eval_System &, TokenPtr node) {
|
||||
Boxed_Value eval_float(Eval_System &, const TokenPtr &node) {
|
||||
return Boxed_Value(double(atof(node->text.c_str())));
|
||||
}
|
||||
|
||||
@ -85,7 +82,7 @@ namespace chaiscript
|
||||
* Evaluates an integer
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_int(Eval_System &, TokenPtr node) {
|
||||
Boxed_Value eval_int(Eval_System &, const TokenPtr &node) {
|
||||
return Boxed_Value(atoi(node->text.c_str()));
|
||||
}
|
||||
|
||||
@ -93,7 +90,7 @@ namespace chaiscript
|
||||
* Evaluates a quoted string
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_quoted_string(Eval_System &, TokenPtr node) {
|
||||
Boxed_Value eval_quoted_string(Eval_System &, const TokenPtr &node) {
|
||||
return Boxed_Value(node->text);
|
||||
}
|
||||
|
||||
@ -101,7 +98,7 @@ namespace chaiscript
|
||||
* Evaluates a char group
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_single_quoted_string(Eval_System &, TokenPtr node) {
|
||||
Boxed_Value eval_single_quoted_string(Eval_System &, const TokenPtr &node) {
|
||||
if (node->text.size() == 1) {
|
||||
return Boxed_Value(char(node->text[0]));
|
||||
}
|
||||
@ -114,10 +111,9 @@ namespace chaiscript
|
||||
* Evaluates a string of equations in reverse order so that the right-most side has precedence
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_equation(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value retval;
|
||||
Boxed_Value eval_equation(Eval_System &ss, const TokenPtr &node) {
|
||||
unsigned int i;
|
||||
retval = eval_token(ss, node->children.back());
|
||||
Boxed_Value retval = eval_token(ss, node->children.back());
|
||||
if (node->children.size() > 1) {
|
||||
for (i = node->children.size()-3; ((int)i) >= 0; i -= 2) {
|
||||
if (node->children[i+1]->text == "=") {
|
||||
@ -170,7 +166,7 @@ namespace chaiscript
|
||||
* Evaluates a variable declaration
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_var_decl(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value eval_var_decl(Eval_System &ss, const TokenPtr &node) {
|
||||
try {
|
||||
ss.add_object(node->children[0]->text, Boxed_Value());
|
||||
}
|
||||
@ -184,11 +180,10 @@ namespace chaiscript
|
||||
* Evaluates binary boolean operators. Respects short-circuiting rules.
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_expression(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value retval;
|
||||
Boxed_Value eval_expression(Eval_System &ss, const TokenPtr &node) {
|
||||
unsigned int i;
|
||||
|
||||
retval = eval_token(ss, node->children[0]);
|
||||
Boxed_Value retval = eval_token(ss, node->children[0]);
|
||||
if (node->children.size() > 1) {
|
||||
for (i = 1; i < node->children.size(); i += 2) {
|
||||
bool lhs;
|
||||
@ -223,11 +218,10 @@ namespace chaiscript
|
||||
* Evaluates comparison, additions, and multiplications and their relatives
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_comp_add_mul(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value retval;
|
||||
Boxed_Value eval_comp_add_mul(Eval_System &ss, const TokenPtr &node) {
|
||||
unsigned int i;
|
||||
|
||||
retval = eval_token(ss, node->children[0]);
|
||||
Boxed_Value retval = eval_token(ss, node->children[0]);
|
||||
if (node->children.size() > 1) {
|
||||
for (i = 1; i < node->children.size(); i += 2) {
|
||||
Param_List_Builder plb;
|
||||
@ -250,11 +244,10 @@ namespace chaiscript
|
||||
* Evaluates an array lookup
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_array_call(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value retval;
|
||||
Boxed_Value eval_array_call(Eval_System &ss, const TokenPtr &node) {
|
||||
unsigned int i;
|
||||
|
||||
retval = eval_token(ss, node->children[0]);
|
||||
Boxed_Value retval = eval_token(ss, node->children[0]);
|
||||
for (i = 1; i < node->children.size(); ++i) {
|
||||
Param_List_Builder plb;
|
||||
plb << retval;
|
||||
@ -277,10 +270,8 @@ namespace chaiscript
|
||||
* Evaluates a unary negation
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_negate(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value retval;
|
||||
|
||||
retval = eval_token(ss, node->children[0]);
|
||||
Boxed_Value eval_negate(Eval_System &ss, const TokenPtr &node) {
|
||||
Boxed_Value retval = eval_token(ss, node->children[0]);
|
||||
Param_List_Builder plb;
|
||||
plb << retval;
|
||||
plb << Boxed_Value(-1.0);
|
||||
@ -297,30 +288,22 @@ namespace chaiscript
|
||||
* Evaluates a unary boolean not
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_not(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value retval;
|
||||
|
||||
bool cond;
|
||||
Boxed_Value eval_not(Eval_System &ss, const TokenPtr &node) {
|
||||
try {
|
||||
retval = eval_token(ss, node->children[0]);
|
||||
cond = boxed_cast<bool &>(retval);
|
||||
return Boxed_Value(!boxed_cast<bool>(eval_token(ss, node->children[0])));
|
||||
}
|
||||
catch (const bad_boxed_cast &) {
|
||||
throw Eval_Error("Boolean not('!') condition not boolean", node->children[0]);
|
||||
}
|
||||
return Boxed_Value(!cond);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates any unary prefix
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_prefix(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value retval;
|
||||
|
||||
retval = eval_token(ss, node->children[1]);
|
||||
Boxed_Value eval_prefix(Eval_System &ss, const TokenPtr &node) {
|
||||
Param_List_Builder plb;
|
||||
plb << retval;
|
||||
plb << eval_token(ss, node->children[1]);
|
||||
|
||||
try {
|
||||
return ss.call_function(node->children[0]->text, plb);
|
||||
@ -334,12 +317,11 @@ namespace chaiscript
|
||||
* Evaluates (and generates) an inline array initialization
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_inline_array(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value retval;
|
||||
Boxed_Value eval_inline_array(Eval_System &ss, const TokenPtr &node) {
|
||||
unsigned int i;
|
||||
|
||||
try {
|
||||
retval = ss.call_function("Vector", Param_List_Builder());
|
||||
Boxed_Value retval = ss.call_function("Vector", Param_List_Builder());
|
||||
if (node->children.size() > 0) {
|
||||
for (i = 0; i < node->children[0]->children.size(); ++i) {
|
||||
try {
|
||||
@ -351,19 +333,20 @@ namespace chaiscript
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
catch (const dispatch_error &) {
|
||||
throw Eval_Error("Can not find appropriate 'Vector()'", node);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates (and generates) an inline range initialization
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_inline_range(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value eval_inline_range(Eval_System &ss, const TokenPtr &node) {
|
||||
try {
|
||||
return ss.call_function("generate_range", Param_List_Builder()
|
||||
<< eval_token(ss, node->children[0]->children[0]->children[0])
|
||||
@ -378,12 +361,11 @@ namespace chaiscript
|
||||
* Evaluates (and generates) an inline map initialization
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_inline_map(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value retval;
|
||||
Boxed_Value eval_inline_map(Eval_System &ss, const TokenPtr &node) {
|
||||
unsigned int i;
|
||||
|
||||
try {
|
||||
retval = ss.call_function("Map", Param_List_Builder());
|
||||
Boxed_Value retval = ss.call_function("Map", Param_List_Builder());
|
||||
for (i = 0; i < node->children[0]->children.size(); ++i) {
|
||||
try {
|
||||
Boxed_Value key = eval_token(ss, node->children[0]->children[i]->children[0]);
|
||||
@ -394,20 +376,18 @@ namespace chaiscript
|
||||
throw Eval_Error("Can not find appropriate '=' for map init", node->children[0]->children[i]);
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
catch (const dispatch_error &) {
|
||||
throw Eval_Error("Can not find appropriate 'Map()'", node);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates a function call, starting with its arguments. Handles resetting the scope to the previous one after the call.
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_fun_call(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value retval;
|
||||
Boxed_Value eval_fun_call(Eval_System &ss, const TokenPtr &node) {
|
||||
Param_List_Builder plb;
|
||||
Dispatch_Engine::Stack prev_stack = ss.get_stack();
|
||||
Dispatch_Engine::Stack new_stack = ss.new_stack();
|
||||
@ -418,41 +398,41 @@ namespace chaiscript
|
||||
plb << eval_token(ss, node->children[1]->children[i]);
|
||||
}
|
||||
}
|
||||
Boxed_Value fn;
|
||||
|
||||
try {
|
||||
fn = eval_token(ss, node->children[0]);
|
||||
Boxed_Value fn = eval_token(ss, node->children[0]);
|
||||
|
||||
try {
|
||||
ss.set_stack(new_stack);
|
||||
Boxed_Value retval = (*boxed_cast<Proxy_Function >(fn))(plb);
|
||||
ss.set_stack(prev_stack);
|
||||
return retval;
|
||||
}
|
||||
catch(const dispatch_error &e){
|
||||
ss.set_stack(prev_stack);
|
||||
throw Eval_Error(std::string(e.what()) + " with function '" + node->children[0]->text + "'", node->children[0]);
|
||||
}
|
||||
catch(Return_Value &rv) {
|
||||
ss.set_stack(prev_stack);
|
||||
return rv.retval;
|
||||
}
|
||||
catch(...) {
|
||||
ss.set_stack(prev_stack);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch(Eval_Error &ee) {
|
||||
ss.set_stack(prev_stack);
|
||||
throw Eval_Error(ee.reason, node->children[0]);
|
||||
}
|
||||
try {
|
||||
ss.set_stack(new_stack);
|
||||
retval = (*boxed_cast<Proxy_Function >(fn))(plb);
|
||||
ss.set_stack(prev_stack);
|
||||
}
|
||||
catch(const dispatch_error &e){
|
||||
ss.set_stack(prev_stack);
|
||||
throw Eval_Error(std::string(e.what()) + " with function '" + node->children[0]->text + "'", node->children[0]);
|
||||
}
|
||||
catch(Return_Value &rv) {
|
||||
ss.set_stack(prev_stack);
|
||||
retval = rv.retval;
|
||||
}
|
||||
catch(...) {
|
||||
ss.set_stack(prev_stack);
|
||||
throw;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates a method/attributes invocation
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_dot_access(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value retval;
|
||||
Boxed_Value eval_dot_access(Eval_System &ss, const TokenPtr &node) {
|
||||
std::vector<std::pair<std::string, Proxy_Function > > fn;
|
||||
Dispatch_Engine::Stack prev_stack = ss.get_stack();
|
||||
Dispatch_Engine::Stack new_stack = ss.new_stack();
|
||||
@ -460,7 +440,7 @@ namespace chaiscript
|
||||
|
||||
//todo: Please extract a single way of doing function calls between this and eval_fun_call
|
||||
|
||||
retval = eval_token(ss, node->children[0]);
|
||||
Boxed_Value retval = eval_token(ss, node->children[0]);
|
||||
if (node->children.size() > 1) {
|
||||
for (i = 1; i < node->children.size(); ++i) {
|
||||
Param_List_Builder plb;
|
||||
@ -517,11 +497,10 @@ namespace chaiscript
|
||||
* Evaluates an if/elseif/else block
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_if(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value retval;
|
||||
Boxed_Value eval_if(Eval_System &ss, const TokenPtr &node) {
|
||||
unsigned int i;
|
||||
|
||||
retval = eval_token(ss, node->children[0]);
|
||||
Boxed_Value retval = eval_token(ss, node->children[0]);
|
||||
bool cond;
|
||||
try {
|
||||
cond = boxed_cast<bool &>(retval);
|
||||
@ -564,7 +543,7 @@ namespace chaiscript
|
||||
* Evaluates a while block
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_while(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value eval_while(Eval_System &ss, const TokenPtr &node) {
|
||||
bool cond;
|
||||
|
||||
ss.new_scope();
|
||||
@ -599,7 +578,7 @@ namespace chaiscript
|
||||
* Evaluates a for block, including the for's conditions, from left to right
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_for(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value eval_for(Eval_System &ss, const TokenPtr &node) {
|
||||
bool cond;
|
||||
|
||||
ss.new_scope();
|
||||
@ -646,8 +625,7 @@ namespace chaiscript
|
||||
* Evaluates a function definition
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_def(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value retval;
|
||||
Boxed_Value eval_def(Eval_System &ss, const TokenPtr &node) {
|
||||
unsigned int i;
|
||||
|
||||
std::vector<std::string> param_names;
|
||||
@ -693,15 +671,14 @@ namespace chaiscript
|
||||
catch (reserved_word_error &rwe) {
|
||||
throw Eval_Error("Reserved word used as function name '" + function_name + "'", node);
|
||||
}
|
||||
return retval;
|
||||
return Boxed_Value();
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates a lambda (anonymous function)
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_lambda(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value retval;
|
||||
Boxed_Value eval_lambda(Eval_System &ss, const TokenPtr &node) {
|
||||
unsigned int i;
|
||||
|
||||
std::vector<std::string> param_names;
|
||||
@ -728,7 +705,7 @@ namespace chaiscript
|
||||
* Evaluates a scoped block. Handles resetting the scope after the block has completed.
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_block(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value eval_block(Eval_System &ss, const TokenPtr &node) {
|
||||
Boxed_Value retval;
|
||||
unsigned int i;
|
||||
|
||||
@ -756,22 +733,20 @@ namespace chaiscript
|
||||
* Evaluates a return statement
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_return(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value retval;
|
||||
Boxed_Value eval_return(Eval_System &ss, const TokenPtr &node) {
|
||||
if (node->children.size() > 0) {
|
||||
retval = eval_token(ss, node->children[0]);
|
||||
throw Return_Value(eval_token(ss, node->children[0]), node);
|
||||
}
|
||||
else {
|
||||
retval = Boxed_Value();
|
||||
throw Return_Value(Boxed_Value(), node);
|
||||
}
|
||||
throw Return_Value(retval, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates a break statement
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_break(Eval_System &, TokenPtr node) {
|
||||
Boxed_Value eval_break(Eval_System &, const TokenPtr &node) {
|
||||
throw Break_Loop(node);
|
||||
}
|
||||
|
||||
@ -779,7 +754,7 @@ namespace chaiscript
|
||||
* Top-level evaluation dispatch for all AST node types
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_token(Eval_System &ss, TokenPtr node) {
|
||||
Boxed_Value eval_token(Eval_System &ss, const TokenPtr &node) {
|
||||
switch (node->identifier) {
|
||||
case (Token_Type::File) :
|
||||
return eval_file(ss, node);
|
||||
|
Loading…
x
Reference in New Issue
Block a user