summaryrefslogtreecommitdiff
path: root/src/ast/expr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ast/expr.cpp')
-rw-r--r--src/ast/expr.cpp162
1 files changed, 137 insertions, 25 deletions
diff --git a/src/ast/expr.cpp b/src/ast/expr.cpp
index 675c26b8..42010868 100644
--- a/src/ast/expr.cpp
+++ b/src/ast/expr.cpp
@@ -89,11 +89,20 @@ SERIALISE_TYPE(Expr::, "Expr", {
ExprNode::~ExprNode() {
}
-#define NODE(class, serialise, _print)\
- void class::visit(NodeVisitor& nv) { nv.visit(*this); } \
- /*void class::visit(NodeVisitor& nv) const { nv.visit(*this); }*/ \
- void class::print(::std::ostream& os) const _print \
- SERIALISE_TYPE_S(class, serialise) \
+#define NODE(class, serialise, _print, _clone)\
+ void class::visit(NodeVisitor& nv) { nv.visit(*this); } \
+ void class::print(::std::ostream& os) const _print \
+ ::std::unique_ptr<ExprNode> class::clone() const _clone \
+ SERIALISE_TYPE_S(class, serialise)
+#define OPT_CLONE(node) (node.get() ? node->clone() : ::AST::ExprNodeP())
+
+namespace {
+ static inline ExprNodeP mk_exprnodep(const Position& pos, AST::ExprNode* en) {
+ en->set_pos(pos);
+ return ExprNodeP(en);
+ }
+ #define NEWNODE(type, ...) mk_exprnodep(get_pos(), new type(__VA_ARGS__))
+}
NODE(ExprNode_Block, {
s.item(m_nodes);
@@ -102,6 +111,13 @@ NODE(ExprNode_Block, {
for(const auto& n : m_nodes)
os << *n << ";";
os << "}";
+},{
+ ::std::vector<ExprNodeP> nodes;
+ for(const auto& n : m_nodes)
+ nodes.push_back( n->clone() );
+ if( m_local_mod )
+ TODO(get_pos(), "Handle cloning ExprNode_Block with a module");
+ return NEWNODE(ExprNode_Block, mv$(nodes), nullptr);
})
NODE(ExprNode_Macro, {
@@ -115,6 +131,8 @@ NODE(ExprNode_Macro, {
os << " " << m_ident << " ";
}
os << "(" << ")";
+},{
+ return NEWNODE(ExprNode_Macro, m_name, m_ident, m_tokens.clone());
})
void operator%(::Serialiser& s, const ExprNode_Flow::Type t) {
@@ -151,6 +169,8 @@ NODE(ExprNode_Flow, {
case CONTINUE: os << "continue"; break;
}
os << " " << *m_value;
+},{
+ return NEWNODE(ExprNode_Flow, m_type, m_target, m_value->clone());
})
@@ -160,6 +180,8 @@ NODE(ExprNode_LetBinding, {
s.item(m_value);
},{
os << "let " << m_pat << ": " << m_type << " = " << *m_value;
+},{
+ return NEWNODE(ExprNode_LetBinding, m_pat.clone(), TypeRef(m_type), OPT_CLONE(m_value));
})
NODE(ExprNode_Assign, {
@@ -167,6 +189,8 @@ NODE(ExprNode_Assign, {
s.item(m_value);
},{
os << *m_slot << " = " << *m_value;
+},{
+ return NEWNODE(ExprNode_Assign, m_op, m_slot->clone(), m_value->clone());
})
NODE(ExprNode_CallPath, {
@@ -178,6 +202,12 @@ NODE(ExprNode_CallPath, {
os << *a << ",";
}
os << ")";
+},{
+ ::std::vector<ExprNodeP> args;
+ for(const auto& a : m_args) {
+ args.push_back( a->clone() );
+ }
+ return NEWNODE(ExprNode_CallPath, AST::Path(m_path), mv$(args));
})
NODE(ExprNode_CallMethod, {
@@ -190,6 +220,12 @@ NODE(ExprNode_CallMethod, {
os << *a << ",";
}
os << ")";
+},{
+ ::std::vector<ExprNodeP> args;
+ for(const auto& a : m_args) {
+ args.push_back( a->clone() );
+ }
+ return NEWNODE(ExprNode_CallMethod, m_val->clone(), m_method, mv$(args));
})
NODE(ExprNode_CallObject, {
@@ -201,6 +237,12 @@ NODE(ExprNode_CallObject, {
os << *a << ",";
}
os << ")";
+},{
+ ::std::vector<ExprNodeP> args;
+ for(const auto& a : m_args) {
+ args.push_back( a->clone() );
+ }
+ return NEWNODE(ExprNode_CallObject, m_val->clone(), mv$(args));
})
void operator%(::Serialiser& s, const ExprNode_Loop::Type t) {
@@ -235,6 +277,8 @@ NODE(ExprNode_Loop, {
s.item(m_code);
},{
os << "LOOP [" << m_label << "] " << m_pattern << " in/= " << *m_cond << " " << *m_code;
+},{
+ return NEWNODE(ExprNode_Loop, m_label, m_type, m_pattern.clone(), OPT_CLONE(m_cond), m_code->clone());
})
SERIALISE_TYPE_A(ExprNode_Match_Arm::, "ExprNode_Match_Arm", {
@@ -256,6 +300,17 @@ NODE(ExprNode_Match, {
os << " => " << *arm.m_code << ",";
}
os << "}";
+},{
+ ::std::vector< ExprNode_Match_Arm> arms;
+ for(const auto& arm : m_arms) {
+ ::std::vector< AST::Pattern> patterns;
+ for( const auto& pat : arm.m_patterns ) {
+ patterns.push_back( pat.clone() );
+ }
+ arms.push_back( ExprNode_Match_Arm( mv$(patterns), OPT_CLONE(arm.m_cond), arm.m_code->clone() ) );
+ arms.back().m_attrs = arm.m_attrs.clone();
+ }
+ return NEWNODE(ExprNode_Match, m_val->clone(), mv$(arms));
})
NODE(ExprNode_If, {
@@ -264,6 +319,8 @@ NODE(ExprNode_If, {
s.item(m_false);
},{
os << "if " << *m_cond << " { " << *m_true << " } else { " << *m_false << " }";
+},{
+ return NEWNODE(ExprNode_If, m_cond->clone(), m_true->clone(), OPT_CLONE(m_false));
})
NODE(ExprNode_IfLet, {
s.item(m_pattern);
@@ -272,6 +329,8 @@ NODE(ExprNode_IfLet, {
s.item(m_false);
},{
os << "if let " << m_pattern << " = (" << *m_value << ") { " << *m_true << " } else { " << *m_false << " }";
+},{
+ return NEWNODE(ExprNode_IfLet, m_pattern.clone(), m_value->clone(), m_true->clone(), OPT_CLONE(m_false));
})
NODE(ExprNode_Integer, {
@@ -279,22 +338,30 @@ NODE(ExprNode_Integer, {
s.item(m_value);
},{
os << m_value;
+},{
+ return NEWNODE(ExprNode_Integer, m_value, m_datatype);
})
NODE(ExprNode_Float, {
s % m_datatype;
s.item(m_value);
},{
os << m_value;
+},{
+ return NEWNODE(ExprNode_Float, m_value, m_datatype);
})
NODE(ExprNode_Bool, {
s.item(m_value);
},{
os << m_value;
+},{
+ return NEWNODE(ExprNode_Bool, m_value);
})
NODE(ExprNode_String, {
s.item(m_value);
},{
os << "\"" << m_value << "\"";
+},{
+ return NEWNODE(ExprNode_String, m_value);
})
NODE(ExprNode_Closure, {
@@ -303,6 +370,12 @@ NODE(ExprNode_Closure, {
s.item(m_code);
},{
os << "/* todo: closure */";
+},{
+ ExprNode_Closure::args_t args;
+ for(const auto& a : m_args) {
+ args.push_back( ::std::make_pair(a.first.clone(), TypeRef(a.second)) );
+ }
+ return NEWNODE(ExprNode_Closure, mv$(args), TypeRef(m_return), m_code->clone());
});
NODE(ExprNode_StructLiteral, {
@@ -311,6 +384,14 @@ NODE(ExprNode_StructLiteral, {
s.item(m_values);
},{
os << "/* todo: sl */";
+},{
+ ExprNode_StructLiteral::t_values vals;
+
+ for(const auto& v : m_values) {
+ vals.push_back( ::std::make_pair(v.first, v.second->clone()) );
+ }
+
+ return NEWNODE(ExprNode_StructLiteral, AST::Path(m_path), OPT_CLONE(m_base_value), mv$(vals) );
})
NODE(ExprNode_Array, {
@@ -324,6 +405,18 @@ NODE(ExprNode_Array, {
for(const auto& a : m_values)
os << *a << ",";
os << "]";
+},{
+ if( m_size.get() )
+ {
+ return NEWNODE(ExprNode_Array, m_values[0]->clone(), m_size->clone());
+ }
+ else
+ {
+ ::std::vector<ExprNodeP> nodes;
+ for(const auto& n : m_values)
+ nodes.push_back( n->clone() );
+ return NEWNODE(ExprNode_Array, mv$(nodes));
+ }
})
NODE(ExprNode_Tuple, {
@@ -334,12 +427,19 @@ NODE(ExprNode_Tuple, {
os << *a << ",";
}
os << ")";
+},{
+ ::std::vector<ExprNodeP> nodes;
+ for(const auto& n : m_values)
+ nodes.push_back( n->clone() );
+ return NEWNODE(ExprNode_Tuple, mv$(nodes));
})
NODE(ExprNode_NamedValue, {
s.item(m_path);
},{
os << m_path;
+},{
+ return NEWNODE(ExprNode_NamedValue, AST::Path(m_path));
})
NODE(ExprNode_Field, {
@@ -347,6 +447,8 @@ NODE(ExprNode_Field, {
s.item(m_name);
},{
os << "(" << *m_obj << ")." << m_name;
+},{
+ return NEWNODE(ExprNode_Field, m_obj->clone(), m_name);
})
NODE(ExprNode_Index, {
@@ -354,12 +456,16 @@ NODE(ExprNode_Index, {
s.item(m_idx);
},{
os << "(" << *m_obj << ")[" << *m_idx << "]";
+},{
+ return NEWNODE(ExprNode_Index, m_obj->clone(), m_idx->clone());
})
NODE(ExprNode_Deref, {
s.item(m_value);
},{
os << "*(" << *m_value << ")";
+},{
+ return NEWNODE(ExprNode_Deref, m_value->clone());
});
NODE(ExprNode_Cast, {
@@ -367,9 +473,11 @@ NODE(ExprNode_Cast, {
s.item(m_type);
},{
os << "(" << *m_value << " as " << m_type << ")";
+},{
+ return NEWNODE(ExprNode_Cast, m_value->clone(), TypeRef(m_type));
})
-void operator%(::Serialiser& s, const ExprNode_BinOp::Type t) {
+void operator%(::Serialiser& s, const ExprNode_BinOp::Type& t) {
switch(t)
{
#define _(v) case ExprNode_BinOp::v: s << #v; return
@@ -388,11 +496,11 @@ void operator%(::Serialiser& s, const ExprNode_BinOp::Type t) {
_(BITXOR);
_(SHL);
_(SHR);
- _(MULTIPLY);
- _(DIVIDE);
- _(MODULO);
- _(ADD);
- _(SUB);
+ _(MULTIPLY);
+ _(DIVIDE);
+ _(MODULO);
+ _(ADD);
+ _(SUB);
_(PLACE_IN);
#undef _
}
@@ -417,11 +525,11 @@ void operator%(::Deserialiser& s, ExprNode_BinOp::Type& t) {
_(BITXOR);
_(SHL);
_(SHR);
- _(MULTIPLY);
- _(DIVIDE);
- _(MODULO);
- _(ADD);
- _(SUB);
+ _(MULTIPLY);
+ _(DIVIDE);
+ _(MODULO);
+ _(ADD);
+ _(SUB);
#undef _
else
throw ::std::runtime_error("");
@@ -447,16 +555,18 @@ NODE(ExprNode_BinOp, {
case BITXOR: os << "^"; break;
case SHR: os << ">>"; break;
case SHL: os << "<<"; break;
- case MULTIPLY: os << "*"; break;
- case DIVIDE: os << "/"; break;
- case MODULO: os << "%"; break;
- case ADD: os << "+"; break;
- case SUB: os << "-"; break;
- case RANGE: os << ".."; break;
- case RANGE_INC: os << "..."; break;
+ case MULTIPLY: os << "*"; break;
+ case DIVIDE: os << "/"; break;
+ case MODULO: os << "%"; break;
+ case ADD: os << "+"; break;
+ case SUB: os << "-"; break;
+ case RANGE: os << ".."; break;
+ case RANGE_INC: os << "..."; break;
case PLACE_IN: os << "<-"; break;
}
os << " " << *m_right << ")";
+},{
+ return NEWNODE(ExprNode_BinOp, m_type, OPT_CLONE(m_left), OPT_CLONE(m_right));
})
void operator%(::Serialiser& s, const ExprNode_UniOp::Type t) {
@@ -501,12 +611,14 @@ NODE(ExprNode_UniOp, {
case QMARK: os << "(" << *m_value << "?)"; return;
}
os << *m_value << ")";
+},{
+ return NEWNODE(ExprNode_UniOp, m_type, m_value->clone());
})
#define NV(type, actions)\
- void NodeVisitorDef::visit(type& node) { DEBUG("DEF - "#type); actions }
-// void NodeVisitorDef::visit(const type& node) { DEBUG("DEF - "#type" (const)"); actions }
+ void NodeVisitorDef::visit(type& node) { DEBUG("DEF - "#type); actions }
+// void NodeVisitorDef::visit(const type& node) { DEBUG("DEF - "#type" (const)"); actions }
NV(ExprNode_Block, {
INDENT();