diff options
Diffstat (limited to 'src/ast')
-rw-r--r-- | src/ast/ast.cpp | 11 | ||||
-rw-r--r-- | src/ast/attrs.hpp | 4 | ||||
-rw-r--r-- | src/ast/expr.cpp | 162 | ||||
-rw-r--r-- | src/ast/expr.hpp | 10 | ||||
-rw-r--r-- | src/ast/macro.hpp | 7 | ||||
-rw-r--r-- | src/ast/path.cpp | 7 | ||||
-rw-r--r-- | src/ast/path.hpp | 1 | ||||
-rw-r--r-- | src/ast/pattern.cpp | 73 | ||||
-rw-r--r-- | src/ast/pattern.hpp | 7 | ||||
-rw-r--r-- | src/ast/types.cpp | 6 | ||||
-rw-r--r-- | src/ast/types.hpp | 2 |
11 files changed, 256 insertions, 34 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 2521a878..802bde37 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -22,6 +22,9 @@ namespace { }
}
+MetaItems::~MetaItems()
+{
+}
MetaItems MetaItems::clone() const
{
return MetaItems( m_span, clone_mivec(m_items) );
@@ -45,7 +48,9 @@ SERIALISE_TYPE_A(MetaItems::, "AST_MetaItems", { s.item(m_items);
})
-
+MetaItem::~MetaItem()
+{
+}
MetaItem MetaItem::clone() const
{
TU_MATCH(MetaItemData, (m_data), (e),
@@ -183,6 +188,10 @@ SERIALISE_TYPE_A(UseStmt::, "AST_UseStmt", { })
+MacroInvocation MacroInvocation::clone() const
+{
+ return MacroInvocation(m_span, m_attrs.clone(), m_macro_name, m_ident, m_input.clone());
+}
SERIALISE_TYPE_A(MacroInvocation::, "AST_MacroInvocation", {
s.item(m_attrs);
s.item(m_macro_name);
diff --git a/src/ast/attrs.hpp b/src/ast/attrs.hpp index a2b82c40..fbe63be4 100644 --- a/src/ast/attrs.hpp +++ b/src/ast/attrs.hpp @@ -14,6 +14,7 @@ public: Span m_span; ::std::vector<MetaItem> m_items; + virtual ~MetaItems(); MetaItems() {} MetaItems(MetaItems&&) = default; MetaItems& operator=(MetaItems&&) = default; @@ -57,7 +58,10 @@ class MetaItem: ::std::string m_name; MetaItemData m_data; public: + virtual ~MetaItem(); MetaItem() {} + MetaItem(MetaItem&& ) = default; + MetaItem& operator=(MetaItem&& ) = default; MetaItem(::std::string name): m_name(name), m_data( MetaItemData::make_None({}) ) 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(); diff --git a/src/ast/expr.hpp b/src/ast/expr.hpp index 95f74505..eab6f260 100644 --- a/src/ast/expr.hpp +++ b/src/ast/expr.hpp @@ -28,8 +28,8 @@ public: virtual ~ExprNode() = 0; virtual void visit(NodeVisitor& nv) = 0; - //virtual void visit(NodeVisitor& nv) const = 0; virtual void print(::std::ostream& os) const = 0; + virtual ::std::unique_ptr<ExprNode> clone() const = 0; void set_pos(Position p) { m_pos = ::std::move(p); } const Position& get_pos() const { return m_pos; } @@ -46,10 +46,10 @@ public: }; #define NODE_METHODS() \ - virtual void visit(NodeVisitor& nv) override;\ - virtual void print(::std::ostream& os) const override; \ - SERIALISABLE_PROTOTYPES();/* \ - virtual void visit(NodeVisitor& nv) const override;*/ + void visit(NodeVisitor& nv) override;\ + void print(::std::ostream& os) const override; \ + ::std::unique_ptr<ExprNode> clone() const override; \ + SERIALISABLE_PROTOTYPES(); struct ExprNode_Block: public ExprNode diff --git a/src/ast/macro.hpp b/src/ast/macro.hpp index 85f2dea2..5cd53e1f 100644 --- a/src/ast/macro.hpp +++ b/src/ast/macro.hpp @@ -18,6 +18,11 @@ class MacroInvocation: ::std::string m_ident; TokenTree m_input; public: + MacroInvocation(MacroInvocation&&) = default; + MacroInvocation& operator=(MacroInvocation&&) = default; + MacroInvocation(const MacroInvocation&) = delete; + MacroInvocation& operator=(const MacroInvocation&) = delete; + MacroInvocation() { } @@ -30,6 +35,8 @@ public: m_input( mv$(input) ) { } + + MacroInvocation clone() const; static ::std::unique_ptr<MacroInvocation> from_deserialiser(Deserialiser& s) { auto i = new MacroInvocation; diff --git a/src/ast/path.cpp b/src/ast/path.cpp index 1a1d3cc9..be8b5887 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -54,8 +54,8 @@ PathBinding PathBinding::clone() const // --- AST::PathNode PathNode::PathNode(::std::string name, ::std::vector<TypeRef> args): - m_name(name), - m_params(args) + m_name( mv$(name) ), + m_params( mv$(args) ) { } Ordering PathNode::ord(const PathNode& x) const @@ -101,6 +101,9 @@ typename ::std::vector<Named<T> >::const_iterator find_named(const ::std::vector } // --- AST::Path +AST::Path::~Path() +{ +} AST::Path::Path(TagUfcs, TypeRef type, ::std::vector<AST::PathNode> nodes): m_class( AST::Path::Class::make_UFCS({box$(type), nullptr, nodes}) ) { diff --git a/src/ast/path.hpp b/src/ast/path.hpp index 7eb17aab..4029f655 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -140,6 +140,7 @@ public: private: PathBinding m_binding; public: + virtual ~Path(); // INVALID Path(): m_class() diff --git a/src/ast/pattern.cpp b/src/ast/pattern.cpp index c3373206..80665008 100644 --- a/src/ast/pattern.cpp +++ b/src/ast/pattern.cpp @@ -163,6 +163,79 @@ void operator%(::Deserialiser& s, Pattern::Data::Tag& c) { s.item(n); c = Pattern::Data::tag_from_str(n); } + +Pattern::~Pattern() +{ +} + +AST::Pattern AST::Pattern::clone() const +{ + AST::Pattern rv; + rv.m_span = m_span; + rv.m_binding = m_binding; + rv.m_binding_mut = m_binding_mut; + + struct H { + static ::std::unique_ptr<Pattern> clone_sp(const ::std::unique_ptr<Pattern>& p) { + return ::std::make_unique<Pattern>( p->clone() ); + } + static ::std::vector<Pattern> clone_list(const ::std::vector<Pattern>& list) { + ::std::vector<Pattern> rv; + rv.reserve(list.size()); + for(const auto& p : list) + rv.push_back( p.clone() ); + return rv; + } + static AST::Pattern::Value clone_val(const AST::Pattern::Value& v) { + TU_MATCH(::AST::Pattern::Value, (v), (e), + (Invalid, return Value(e);), + (Integer, return Value(e);), + (String, return Value(e);), + (Named, return Value::make_Named( AST::Path(e) );) + ) + throw ""; + } + }; + + TU_MATCH(Pattern::Data, (m_data), (e), + (Any, + rv.m_data = Data::make_Any(e); + ), + (MaybeBind, + rv.m_data = Data::make_MaybeBind(e); + ), + (Macro, + rv.m_data = Data::make_Macro({ ::std::make_unique<AST::MacroInvocation>( e.inv->clone() ) }); + ), + (Box, + rv.m_data = Data::make_Box({ H::clone_sp(e.sub) }); + ), + (Ref, + rv.m_data = Data::make_Ref({ e.mut, H::clone_sp(e.sub) }); + ), + (Value, + rv.m_data = Data::make_Value({ H::clone_val(e.start), H::clone_val(e.end) }); + ), + (Tuple, + rv.m_data = Data::make_Tuple({ H::clone_list(e.sub_patterns) }); + ), + (StructTuple, + rv.m_data = Data::make_StructTuple({ ::AST::Path(e.path), H::clone_list(e.sub_patterns) }); + ), + (Struct, + ::std::vector< ::std::pair< ::std::string, Pattern> > sps; + for(const auto& sp : e.sub_patterns) + sps.push_back( ::std::make_pair(sp.first, sp.second.clone()) ); + rv.m_data = Data::make_Struct({ ::AST::Path(e.path), mv$(sps) }); + ), + (Slice, + rv.m_data = Data::make_Slice({ H::clone_list(e.leading), e.extra_bind, H::clone_list(e.trailing) }); + ) + ) + + return rv; +} + #define _D(VAR, ...) case Pattern::Data::TAG_##VAR: { m_data = Pattern::Data::make_##VAR({}); auto& ent = m_data.as_##VAR(); (void)&ent; __VA_ARGS__ } break; SERIALISE_TYPE(Pattern::, "Pattern", { s.item(m_binding); diff --git a/src/ast/pattern.hpp b/src/ast/pattern.hpp index 468bf306..a901ac89 100644 --- a/src/ast/pattern.hpp +++ b/src/ast/pattern.hpp @@ -52,8 +52,12 @@ private: Data m_data; public: + virtual ~Pattern(); + Pattern() {} + Pattern(Pattern&&) = default; + Pattern& operator=(Pattern&&) = default; struct TagMaybeBind {}; Pattern(TagMaybeBind, ::std::string name): @@ -128,6 +132,9 @@ public: const Span& span() const { return m_span; } void set_span(Span sp) { m_span = mv$(sp); } + + Pattern clone() const; + // Accessors const ::std::string& binding() const { return m_binding; } const BindType& binding_type() const { assert(m_binding != ""); return m_binding_type; } diff --git a/src/ast/types.cpp b/src/ast/types.cpp index 8a3ee638..8cc9b4ea 100644 --- a/src/ast/types.cpp +++ b/src/ast/types.cpp @@ -98,11 +98,15 @@ Ordering Type_Function::ord(const Type_Function& x) const return (*m_rettype).ord( *x.m_rettype ); } +TypeRef::~TypeRef() +{ +} + TypeRef::TypeRef(const TypeRef& other) { switch( other.m_data.tag() ) { - case TypeData::TAGDEAD: throw ""; + case TypeData::TAGDEAD: assert(!"Copying a destructed type"); #define _COPY(VAR) case TypeData::TAG_##VAR: m_data = TypeData::make_##VAR(other.m_data.as_##VAR()); break; #define _CLONE(VAR, code...) case TypeData::TAG_##VAR: { auto& old = other.m_data.as_##VAR(); m_data = TypeData::make_##VAR(code); } break; _COPY(None) diff --git a/src/ast/types.hpp b/src/ast/types.hpp index 72080723..a79a811d 100644 --- a/src/ast/types.hpp +++ b/src/ast/types.hpp @@ -108,6 +108,8 @@ class TypeRef: public:
TypeData m_data;
+ virtual ~TypeRef();
+
TypeRef(TypeRef&& other) noexcept:
m_data( mv$(other.m_data) )
{
|