Save local variable location after first pass

This commit is contained in:
Jason Turner 2015-06-20 10:28:27 -06:00
parent 3eb7700912
commit c7689f18ec
2 changed files with 33 additions and 9 deletions

View File

@ -569,19 +569,41 @@ namespace chaiscript
/// Searches the current stack for an object of the given name /// Searches the current stack for an object of the given name
/// includes a special overload for the _ place holder object to /// includes a special overload for the _ place holder object to
/// ensure that it is always in scope. /// ensure that it is always in scope.
Boxed_Value get_object(const std::string &name) const Boxed_Value get_object(const std::string &name, uint32_t &t_loc) const
{ {
auto &stack = get_stack_data(); enum class Loc : uint32_t {
located = 0x80000000,
is_local = 0x40000000,
stack_mask = 0x0FFF0000,
loc_mask = 0x0000FFFF
};
// Is it in the stack? unsigned int loc = t_loc;
for (auto stack_elem = stack.rbegin(); stack_elem != stack.rend(); ++stack_elem)
if (loc == 0)
{ {
for (auto &s : (*stack_elem) ) auto &stack = get_stack_data();
// Is it in the stack?
for (auto stack_elem = stack.rbegin(); stack_elem != stack.rend(); ++stack_elem)
{ {
if (s.first == name) { for (auto s = stack_elem->begin(); s != stack_elem->end(); ++s )
return s.second; {
if (s->first == name) {
t_loc = static_cast<uint32_t>(std::distance(stack.rbegin(), stack_elem) << 16)
| static_cast<uint32_t>(std::distance(stack_elem->begin(), s))
| static_cast<uint32_t>(Loc::located)
| static_cast<uint32_t>(Loc::is_local);
return s->second;
}
} }
} }
t_loc = static_cast<uint32_t>(Loc::located);
} else if (loc & static_cast<uint32_t>(Loc::is_local)) {
auto &stack = get_stack_data();
return stack[stack.size() - 1 - ((loc & static_cast<uint32_t>(Loc::stack_mask)) >> 16)][loc & static_cast<uint32_t>(Loc::loc_mask)].second;
} }
// Is the value we are looking for a global? // Is the value we are looking for a global?

View File

@ -147,7 +147,7 @@ namespace chaiscript
public: public:
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(t_ast_node_text, AST_Node_Type::Id, std::move(t_loc)),
m_value(get_value(t_ast_node_text)) m_value(get_value(t_ast_node_text)), m_loc(0)
{ } { }
virtual ~Id_AST_Node() {} virtual ~Id_AST_Node() {}
@ -157,7 +157,7 @@ namespace chaiscript
return m_value; return m_value;
} else { } else {
try { try {
return t_ss.get_object(this->text); return t_ss.get_object(this->text, m_loc);
} }
catch (std::exception &) { catch (std::exception &) {
throw exception::eval_error("Can not find object: " + this->text); throw exception::eval_error("Can not find object: " + this->text);
@ -184,6 +184,8 @@ namespace chaiscript
} }
Boxed_Value m_value; Boxed_Value m_value;
mutable uint32_t m_loc;
}; };
struct Char_AST_Node : public AST_Node { struct Char_AST_Node : public AST_Node {