Added initial support for proper function scoping rules

This commit is contained in:
Jonathan Turner
2009-06-11 13:17:31 +00:00
parent 82daa9b63b
commit 6b60a5b12c
2 changed files with 50 additions and 10 deletions

15
samples/scope.wes Normal file
View File

@@ -0,0 +1,15 @@
/*
This should print:
1
10
4
*/
var x = 4
def do_it() {
var x = 1
print(x)
var y = function(x) { x + 1 }
print(y(9))
}
do_it()
print(x)

View File

@@ -4,6 +4,8 @@
#ifndef WESLEY_EVAL_HPP_ #ifndef WESLEY_EVAL_HPP_
#define WESLEY_EVAL_HPP_ #define WESLEY_EVAL_HPP_
#include <map>
struct ParserError { struct ParserError {
std::string reason; std::string reason;
TokenPtr location; TokenPtr location;
@@ -33,10 +35,15 @@ struct BreakLoop {
template <typename Eval_System> template <typename Eval_System>
const Boxed_Value eval_function (Eval_System &ss, TokenPtr node, const std::vector<std::string> &param_names, const std::vector<Boxed_Value> &vals) { const Boxed_Value eval_function (Eval_System &ss, TokenPtr node, const std::vector<std::string> &param_names, const std::vector<Boxed_Value> &vals) {
ss.new_scope();
for (unsigned int i = 0; i < param_names.size(); ++i) { for (unsigned int i = 0; i < param_names.size(); ++i) {
ss.add_object(param_names[i], vals[i]); ss.add_object(param_names[i], vals[i]);
} }
return eval_token(ss, node);
Boxed_Value retval = eval_token(ss, node);
ss.pop_scope();
return retval;
} }
template <typename Eval_System> template <typename Eval_System>
@@ -96,7 +103,7 @@ Boxed_Value eval_token(Eval_System &ss, TokenPtr node) {
} }
break; break;
case (TokenType::Variable_Decl): { case (TokenType::Variable_Decl): {
ss.set_object(node->children[0]->text, Boxed_Value()); ss.add_object(node->children[0]->text, Boxed_Value());
retval = ss.get_object(node->children[0]->text); retval = ss.get_object(node->children[0]->text);
} }
break; break;
@@ -199,31 +206,43 @@ Boxed_Value eval_token(Eval_System &ss, TokenPtr node) {
break; break;
case (TokenType::Fun_Call) : { case (TokenType::Fun_Call) : {
//BoxedCPP_System::Stack prev_stack = ss.set_stack(BoxedCPP_System::Stack()); std::vector<std::pair<std::string, BoxedCPP_System::Function_Map::mapped_type> > fn;
BoxedCPP_System::Stack prev_stack = ss.get_stack();
BoxedCPP_System::Stack new_stack;
new_stack.push_back(BoxedCPP_System::Scope());
Param_List_Builder plb; Param_List_Builder plb;
for (i = 1; i < node->children.size(); ++i) { for (i = 1; i < node->children.size(); ++i) {
plb << eval_token(ss, node->children[i]); plb << eval_token(ss, node->children[i]);
} }
try { try {
retval = dispatch(ss.get_function(node->children[0]->text), plb); fn = ss.get_function(node->children[0]->text);
//ss.set_stack(prev_stack); ss.set_stack(new_stack);
retval = dispatch(fn, plb);
ss.set_stack(prev_stack);
} }
catch(EvalError &ee) { catch(EvalError &ee) {
//ss.set_stack(prev_stack); ss.set_stack(prev_stack);
throw EvalError(ee.reason, node->children[0]); throw EvalError(ee.reason, node->children[0]);
} }
catch(std::exception &e){ catch(std::exception &e){
//ss.set_stack(prev_stack); ss.set_stack(prev_stack);
throw EvalError("Engine error: " + std::string(e.what()), node->children[0]); throw EvalError("Engine error: " + std::string(e.what()) + " on '" + node->children[0]->text + "'", node->children[0]);
} }
catch(ReturnValue &rv) { catch(ReturnValue &rv) {
//ss.set_stack(prev_stack); ss.set_stack(prev_stack);
retval = rv.retval; retval = rv.retval;
} }
} }
break; break;
case (TokenType::Method_Call) : { case (TokenType::Method_Call) : {
std::vector<std::pair<std::string, BoxedCPP_System::Function_Map::mapped_type> > fn;
BoxedCPP_System::Stack prev_stack = ss.get_stack();
BoxedCPP_System::Stack new_stack;
new_stack.push_back(BoxedCPP_System::Scope());
retval = eval_token(ss, node->children[0]); retval = eval_token(ss, node->children[0]);
if (node->children.size() > 1) { if (node->children.size() > 1) {
for (i = 1; i < node->children.size(); ++i) { for (i = 1; i < node->children.size(); ++i) {
@@ -235,15 +254,21 @@ Boxed_Value eval_token(Eval_System &ss, TokenPtr node) {
} }
try { try {
retval = dispatch(ss.get_function(node->children[i]->children[0]->text), plb); fn = ss.get_function(node->children[i]->children[0]->text);
ss.set_stack(new_stack);
retval = dispatch(fn, plb);
ss.set_stack(prev_stack);
} }
catch(EvalError &ee) { catch(EvalError &ee) {
ss.set_stack(prev_stack);
throw EvalError(ee.reason, node->children[0]); throw EvalError(ee.reason, node->children[0]);
} }
catch(std::exception &e){ catch(std::exception &e){
ss.set_stack(prev_stack);
throw EvalError("Can not find appropriate '" + node->children[i]->children[0]->text + "'", node->children[0]); throw EvalError("Can not find appropriate '" + node->children[i]->children[0]->text + "'", node->children[0]);
} }
catch(ReturnValue &rv) { catch(ReturnValue &rv) {
ss.set_stack(prev_stack);
retval = rv.retval; retval = rv.retval;
} }
} }