mirror of
https://github.com/ChaiScript/ChaiScript.git
synced 2025-12-06 16:57:04 +08:00
parent
50a2773081
commit
8307663938
@ -62,7 +62,7 @@ namespace chaiscript
|
||||
|
||||
|
||||
/// Types of AST nodes available to the parser and eval
|
||||
enum class AST_Node_Type { Id, Fun_Call, Unused_Return_Fun_Call, Arg_List, Equation, Var_Decl,
|
||||
enum class AST_Node_Type { Id, Fun_Call, Unused_Return_Fun_Call, Arg_List, Equation, Var_Decl, Assign_Decl,
|
||||
Array_Call, Dot_Access,
|
||||
Lambda, Block, Scopeless_Block, Def, While, If, For, Ranged_For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range,
|
||||
Inline_Range, Try, Catch, Finally, Method, Attr_Decl,
|
||||
@ -77,7 +77,7 @@ namespace chaiscript
|
||||
{
|
||||
/// Helper lookup to get the name of each node type
|
||||
inline const char *ast_node_type_to_string(AST_Node_Type ast_node_type) {
|
||||
static const char * const ast_node_types[] = { "Id", "Fun_Call", "Unused_Return_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", "Assign_Decl",
|
||||
"Array_Call", "Dot_Access",
|
||||
"Lambda", "Block", "Scopeless_Block", "Def", "While", "If", "For", "Ranged_For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range",
|
||||
"Inline_Range", "Try", "Catch", "Finally", "Method", "Attr_Decl",
|
||||
|
||||
@ -555,6 +555,27 @@ namespace chaiscript
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct Assign_Decl_AST_Node final : AST_Node_Impl<T> {
|
||||
Assign_Decl_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::Assign_Decl, std::move(t_loc), std::move(t_children)) { }
|
||||
|
||||
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
|
||||
const std::string &idname = this->children[0]->text;
|
||||
|
||||
try {
|
||||
Boxed_Value bv(detail::clone_if_necessary(this->children[1]->eval(t_ss), m_loc, t_ss));
|
||||
bv.reset_return_value();
|
||||
t_ss.add_object(idname, bv);
|
||||
return bv;
|
||||
} catch (const exception::name_conflict_error &e) {
|
||||
throw exception::eval_error("Variable redefined '" + e.name() + "'");
|
||||
}
|
||||
}
|
||||
private:
|
||||
mutable std::atomic_uint_fast32_t m_loc = {0};
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
struct Array_Call_AST_Node final : AST_Node_Impl<T> {
|
||||
|
||||
@ -97,7 +97,7 @@ namespace chaiscript {
|
||||
template<typename T>
|
||||
bool contains_var_decl_in_scope(const eval::AST_Node_Impl<T> &node)
|
||||
{
|
||||
if (node.identifier == AST_Node_Type::Var_Decl) {
|
||||
if (node.identifier == AST_Node_Type::Var_Decl || node.identifier == AST_Node_Type::Assign_Decl) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -208,6 +208,27 @@ namespace chaiscript {
|
||||
}
|
||||
};
|
||||
|
||||
struct Assign_Decl {
|
||||
template<typename T>
|
||||
auto optimize(eval::AST_Node_Impl_Ptr<T> node) {
|
||||
if ((node->identifier == AST_Node_Type::Equation)
|
||||
&& node->text == "="
|
||||
&& node->children.size() == 2
|
||||
&& node->children[0]->identifier == AST_Node_Type::Var_Decl
|
||||
)
|
||||
{
|
||||
std::vector<eval::AST_Node_Impl_Ptr<T>> new_children;
|
||||
new_children.push_back(std::move(node->children[0]->children[0]));
|
||||
new_children.push_back(std::move(node->children[1]));
|
||||
return chaiscript::make_unique<eval::AST_Node_Impl<T>, eval::Assign_Decl_AST_Node<T>>(node->text,
|
||||
node->location, std::move(new_children) );
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct If {
|
||||
template<typename T>
|
||||
auto optimize(eval::AST_Node_Impl_Ptr<T> node) {
|
||||
@ -440,7 +461,7 @@ namespace chaiscript {
|
||||
};
|
||||
|
||||
typedef Optimizer<optimizer::Partial_Fold, optimizer::Unused_Return, optimizer::Constant_Fold,
|
||||
optimizer::If, optimizer::Return, optimizer::Dead_Code, optimizer::Block, optimizer::For_Loop> Optimizer_Default;
|
||||
optimizer::If, optimizer::Return, optimizer::Dead_Code, optimizer::Block, optimizer::For_Loop, optimizer::Assign_Decl> Optimizer_Default;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user