Get & variable declarations working
This commit is contained in:
@@ -112,7 +112,7 @@ namespace chaiscript
|
|||||||
struct AST_Node : std::enable_shared_from_this<AST_Node> {
|
struct AST_Node : std::enable_shared_from_this<AST_Node> {
|
||||||
public:
|
public:
|
||||||
const std::string text;
|
const std::string text;
|
||||||
const int identifier;
|
const int identifier; //< \todo shouldn't this be a strongly typed enum value?
|
||||||
std::shared_ptr<const std::string> filename;
|
std::shared_ptr<const std::string> filename;
|
||||||
File_Position start, end;
|
File_Position start, end;
|
||||||
std::vector<AST_NodePtr> children;
|
std::vector<AST_NodePtr> children;
|
||||||
|
@@ -295,7 +295,16 @@ namespace chaiscript
|
|||||||
} else if (this->children[1]->text == "=") {
|
} else if (this->children[1]->text == "=") {
|
||||||
try {
|
try {
|
||||||
if (lhs.is_undef()) {
|
if (lhs.is_undef()) {
|
||||||
|
if (!this->children.empty() &&
|
||||||
|
!this->children[0]->children.empty()
|
||||||
|
&& this->children[0]->children[0]->identifier == AST_Node_Type::Reference)
|
||||||
|
{
|
||||||
|
/// \todo This does not handle the case of an unassigned reference variable
|
||||||
|
/// being assigned outside of its declaration
|
||||||
|
lhs.assign(retval);
|
||||||
|
} else {
|
||||||
retval = t_ss.call_function("clone", retval);
|
retval = t_ss.call_function("clone", retval);
|
||||||
|
}
|
||||||
retval.clear_dependencies();
|
retval.clear_dependencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,13 +344,21 @@ namespace chaiscript
|
|||||||
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Var_Decl_AST_Node() {}
|
virtual ~Var_Decl_AST_Node() {}
|
||||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
|
if (this->children[0]->identifier == AST_Node_Type::Reference)
|
||||||
|
{
|
||||||
|
return this->children[0]->eval(t_ss);
|
||||||
|
} else {
|
||||||
|
std::string idname = this->children[0]->text;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
t_ss.add_object(this->children[0]->text, Boxed_Value());
|
t_ss.add_object(idname, Boxed_Value());
|
||||||
}
|
}
|
||||||
catch (const exception::reserved_word_error &) {
|
catch (const exception::reserved_word_error &) {
|
||||||
throw exception::eval_error("Reserved word used as variable '" + this->children[0]->text + "'");
|
throw exception::eval_error("Reserved word used as variable '" + idname + "'");
|
||||||
}
|
}
|
||||||
return t_ss.get_object(this->children[0]->text);
|
return t_ss.get_object(idname);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -848,16 +865,23 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Reference_Node : public AST_Node {
|
struct Reference_AST_Node : public AST_Node {
|
||||||
public:
|
public:
|
||||||
Reference_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Prefix, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
|
Reference_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Reference, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
|
||||||
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col)
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual ~Reference_Node() {}
|
|
||||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
return Boxed_Value();
|
try {
|
||||||
|
t_ss.add_object(this->children[0]->text, Boxed_Value());
|
||||||
}
|
}
|
||||||
|
catch (const exception::reserved_word_error &) {
|
||||||
|
throw exception::eval_error("Reserved word used as variable '" + this->children[0]->text + "'");
|
||||||
|
}
|
||||||
|
return t_ss.get_object(this->children[0]->text);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~Reference_AST_Node() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Prefix_AST_Node : public AST_Node {
|
struct Prefix_AST_Node : public AST_Node {
|
||||||
|
@@ -1634,8 +1634,11 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Incomplete '&' expression", File_Position(m_line, m_col), *m_filename);
|
throw exception::eval_error("Incomplete '&' expression", File_Position(m_line, m_col), *m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_match(AST_NodePtr(new eval::Reference_Node()), prev_stack_top);
|
build_match(AST_NodePtr(
|
||||||
|
new eval::Reference_AST_Node()), prev_stack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
19
unittests/var_ref_decl.chai
Normal file
19
unittests/var_ref_decl.chai
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
auto l = 5
|
||||||
|
auto & k = l;
|
||||||
|
|
||||||
|
|
||||||
|
assert_equal(l, k)
|
||||||
|
|
||||||
|
l = 10
|
||||||
|
|
||||||
|
assert_equal(10, l)
|
||||||
|
assert_equal(k, l)
|
||||||
|
|
||||||
|
auto & j
|
||||||
|
j = l // assignment outside of declaration does *not* result in reference assignment
|
||||||
|
j = 15
|
||||||
|
|
||||||
|
assert_equal(15, j)
|
||||||
|
assert_equal(k, l)
|
||||||
|
assert_equal(10, l)
|
||||||
|
|
Reference in New Issue
Block a user