diff options
Diffstat (limited to 'src/ast')
-rw-r--r-- | src/ast/ast.cpp | 188 | ||||
-rw-r--r-- | src/ast/ast.hpp | 23 | ||||
-rw-r--r-- | src/ast/expr.cpp | 24 | ||||
-rw-r--r-- | src/ast/expr.hpp | 31 | ||||
-rw-r--r-- | src/ast/expr_ptr.hpp | 33 | ||||
-rw-r--r-- | src/ast/types.cpp | 3 |
6 files changed, 235 insertions, 67 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 4de02843..60c813d4 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -3,6 +3,7 @@ #include "ast.hpp"
#include "crate.hpp"
#include "types.hpp"
+#include "expr.hpp"
#include "../common.hpp"
#include <iostream>
#include "../parse/parseerror.hpp"
@@ -64,6 +65,125 @@ MetaItem MetaItem::clone() const throw ::std::runtime_error("MetaItem::clone - Fell off end");
}
+StructItem StructItem::clone() const
+{
+ return StructItem(m_attrs.clone(), m_is_public, m_name, m_type);
+}
+TupleItem TupleItem::clone() const
+{
+ return TupleItem(m_attrs.clone(), m_is_public, m_type);
+}
+
+
+TypeAlias TypeAlias::clone() const
+{
+ return TypeAlias( m_params, m_type );
+}
+Static Static::clone() const
+{
+ return Static( m_class, m_type, m_value.is_valid() ? AST::Expr( m_value.node().clone() ) : AST::Expr() );
+}
+
+Function::Function(Span sp, GenericParams params, TypeRef ret_type, Arglist args):
+ m_span(sp),
+ m_params( move(params) ),
+ m_rettype( move(ret_type) ),
+ m_args( move(args) )
+{
+}
+Function Function::clone() const
+{
+ decltype(m_args) new_args;
+ for(const auto& arg : m_args)
+ new_args.push_back( ::std::make_pair( arg.first.clone(), arg.second ) );
+
+ auto rv = Function( m_span, m_params, m_rettype, mv$(new_args) );
+ if( m_code.is_valid() )
+ {
+ rv.m_code = AST::Expr( m_code.node().clone() );
+ }
+ return rv;
+}
+
+void Trait::add_type(::std::string name, TypeRef type) {
+ m_items.push_back( Named<Item>(mv$(name), Item::make_Type({TypeAlias(GenericParams(), mv$(type))}), true) );
+}
+void Trait::add_function(::std::string name, Function fcn) {
+ DEBUG("trait fn " << name);
+ m_items.push_back( Named<Item>(mv$(name), Item::make_Function({mv$(fcn)}), true) );
+}
+void Trait::add_static(::std::string name, Static v) {
+ m_items.push_back( Named<Item>(mv$(name), Item::make_Static({mv$(v)}), true) );
+}
+void Trait::set_is_marker() {
+ m_is_marker = true;
+}
+bool Trait::is_marker() const {
+ return m_is_marker;
+}
+bool Trait::has_named_item(const ::std::string& name, bool& out_is_fcn) const
+{
+ for( const auto& i : m_items )
+ {
+ if( i.name == name ) {
+ out_is_fcn = i.data.is_Function();
+ return true;
+ }
+ }
+ return false;
+}
+
+Trait Trait::clone() const
+{
+ auto rv = Trait(m_params, m_supertraits);
+ for(const auto& item : m_items)
+ {
+ rv.m_items.push_back( Named<Item> { item.name, item.data.clone(), item.is_pub } );
+ }
+ return rv;
+}
+
+Enum Enum::clone() const
+{
+ decltype(m_variants) new_variants;
+ for(const auto& var : m_variants)
+ {
+ TU_MATCHA( (var.m_data), (e),
+ (Value,
+ new_variants.push_back( EnumVariant(var.m_attrs.clone(), var.m_name, e.m_value.clone()) );
+ ),
+ (Tuple,
+ new_variants.push_back( EnumVariant(var.m_attrs.clone(), var.m_name, e.m_sub_types) );
+ ),
+ (Struct,
+ decltype(e.m_fields) new_fields;
+ for(const auto& f : e.m_fields)
+ new_fields.push_back( f.clone() );
+ new_variants.push_back( EnumVariant(var.m_attrs.clone(), var.m_name, mv$(new_fields)) );
+ )
+ )
+ }
+ return Enum(m_params, mv$(new_variants));
+}
+Struct Struct::clone() const
+{
+ TU_MATCHA( (m_data), (e),
+ (Tuple,
+ decltype(e.ents) new_fields;
+ for(const auto& f : e.ents)
+ new_fields.push_back( f.clone() );
+ return Struct(m_params, mv$(new_fields));
+ ),
+ (Struct,
+ decltype(e.ents) new_fields;
+ for(const auto& f : e.ents)
+ new_fields.push_back( f.clone() );
+ return Struct(m_params, mv$(new_fields));
+ )
+ )
+ throw "";
+}
+
::std::ostream& operator<<(::std::ostream& os, const ImplDef& impl)
{
return os << "impl<" << impl.m_params << "> " << impl.m_trait.ent << " for " << impl.m_type << "";
@@ -282,42 +402,44 @@ Module::ItemRef Module::find_item(const ::std::string& needle, bool allow_leaves return Module::ItemRef();
}
-
-Function::Function(Span sp, GenericParams params, TypeRef ret_type, Arglist args):
- m_span(sp),
- m_params( move(params) ),
- m_rettype( move(ret_type) ),
- m_args( move(args) )
+Item Item::clone() const
{
+ TU_MATCHA( (*this), (e),
+ (None,
+ return AST::Item(e);
+ ),
+ (MacroInv,
+ TODO(Span(), "Clone on Item::MacroInv");
+ ),
+ (Module,
+ TODO(Span(), "Clone on Item::Module");
+ ),
+ (Crate,
+ return AST::Item(e);
+ ),
+ (Type,
+ return AST::Item(e.clone());
+ ),
+ (Struct,
+ return AST::Item(e.clone());
+ ),
+ (Enum,
+ return AST::Item(e.clone());
+ ),
+ (Trait,
+ return AST::Item(e.clone());
+ ),
+
+ (Function,
+ return AST::Item(e.clone());
+ ),
+ (Static,
+ return AST::Item(e.clone());
+ )
+ )
+ throw "";
}
-void Trait::add_type(::std::string name, TypeRef type) {
- m_items.push_back( Named<Item>(mv$(name), Item::make_Type({TypeAlias(GenericParams(), mv$(type))}), true) );
-}
-void Trait::add_function(::std::string name, Function fcn) {
- DEBUG("trait fn " << name);
- m_items.push_back( Named<Item>(mv$(name), Item::make_Function({mv$(fcn)}), true) );
-}
-void Trait::add_static(::std::string name, Static v) {
- m_items.push_back( Named<Item>(mv$(name), Item::make_Static({mv$(v)}), true) );
-}
-void Trait::set_is_marker() {
- m_is_marker = true;
-}
-bool Trait::is_marker() const {
- return m_is_marker;
-}
-bool Trait::has_named_item(const ::std::string& name, bool& out_is_fcn) const
-{
- for( const auto& i : m_items )
- {
- if( i.name == name ) {
- out_is_fcn = i.data.is_Function();
- return true;
- }
- }
- return false;
-}
::std::ostream& operator<<(::std::ostream& os, const TypeParam& tp)
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 8f9ff8f6..99359d6d 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -23,7 +23,7 @@ #include <ast/pattern.hpp>
#include <ast/attrs.hpp>
-#include <ast/expr.hpp>
+#include <ast/expr_ptr.hpp>
#include <ast/item.hpp>
#include <ast/macro.hpp>
@@ -70,6 +70,8 @@ struct StructItem friend ::std::ostream& operator<<(::std::ostream& os, const StructItem& x) {
return os << (x.m_is_public ? "pub " : "") << x.m_name << ": " << x.m_type;
}
+
+ StructItem clone() const;
};
struct TupleItem
@@ -92,6 +94,8 @@ struct TupleItem friend ::std::ostream& operator<<(::std::ostream& os, const TupleItem& x) {
return os << (x.m_is_public ? "pub " : "") << x.m_type;
}
+
+ TupleItem clone() const;
};
class TypeAlias
@@ -110,6 +114,8 @@ public: GenericParams& params() { return m_params; }
TypeRef& type() { return m_type; }
+
+ TypeAlias clone() const;
};
class Static
@@ -141,6 +147,8 @@ public: TypeRef& type() { return m_type; }
Expr& value() { return m_value; }
+
+ Static clone() const;
};
class Function
@@ -155,6 +163,7 @@ private: Expr m_code;
TypeRef m_rettype;
Arglist m_args;
+ // TODO: ABI, const, and unsafe
public:
Function()
{}
@@ -174,6 +183,8 @@ public: TypeRef& rettype() { return m_rettype; }
const Arglist& args() const { return m_args; }
Arglist& args() { return m_args; }
+
+ Function clone() const;
};
class Trait
@@ -210,6 +221,8 @@ public: bool is_marker() const;
bool has_named_item(const ::std::string& name, bool& out_is_fcn) const;
+
+ Trait clone() const;
};
TAGGED_UNION_EX(EnumVariantData, (), Value,
@@ -291,10 +304,11 @@ public: {}
const GenericParams& params() const { return m_params; }
+ GenericParams& params() { return m_params; }
const ::std::vector<EnumVariant>& variants() const { return m_variants; }
+ ::std::vector<EnumVariant>& variants() { return m_variants; }
- GenericParams& params() { return m_params; }
- ::std::vector<EnumVariant>& variants() { return m_variants; }
+ Enum clone() const;
};
TAGGED_UNION_EX(StructData, (), Struct,
@@ -333,6 +347,7 @@ public: TypeRef get_field_type(const char *name, const ::std::vector<TypeRef>& args);
+ Struct clone() const;
};
class ImplDef
@@ -634,6 +649,8 @@ TAGGED_UNION_EX(Item, (), None, public:
MetaItems attrs;
Span span;
+
+ Item clone() const;
)
);
diff --git a/src/ast/expr.cpp b/src/ast/expr.cpp index 780b480c..ecd60def 100644 --- a/src/ast/expr.cpp +++ b/src/ast/expr.cpp @@ -5,6 +5,19 @@ namespace AST { + +Expr::Expr(unique_ptr<ExprNode> node): + m_node(node.release()) +{ +} +Expr::Expr(ExprNode* node): + m_node(node) +{ +} +Expr::Expr(): + m_node(nullptr) +{ +} void Expr::visit_nodes(NodeVisitor& v) { if( m_node ) @@ -21,6 +34,17 @@ void Expr::visit_nodes(NodeVisitor& v) const m_node->visit(v); } } + +Expr Expr::clone() const +{ + if( m_node ) { + return Expr( m_node->clone() ); + } + else { + return Expr(); + } +} + ::std::ostream& operator<<(::std::ostream& os, const Expr& pat) { if( pat.m_node.get() ) diff --git a/src/ast/expr.hpp b/src/ast/expr.hpp index 0d503b81..00c1154b 100644 --- a/src/ast/expr.hpp +++ b/src/ast/expr.hpp @@ -40,11 +40,9 @@ public: MetaItems& attrs() { return m_attrs; } TypeRef& get_res_type() { return m_res_type; } - - friend ::std::ostream& operator<<(::std::ostream& os, const ExprNode& node); static ::std::unique_ptr<ExprNode> from_deserialiser(Deserialiser& d); }; -typedef ::std::unique_ptr<AST::ExprNode> ExprNodeP; +typedef ::std::unique_ptr<ExprNode> ExprNodeP; #define NODE_METHODS() \ void visit(NodeVisitor& nv) override;\ @@ -685,33 +683,6 @@ public: #undef NT }; -class Expr -{ - ::std::shared_ptr<ExprNode> m_node; -public: - Expr(unique_ptr<ExprNode> node): - m_node(node.release()) - { - } - Expr(ExprNode* node): - m_node(node) - { - } - Expr(): - m_node(nullptr) - { - } - - bool is_valid() const { return m_node.get() != nullptr; } - ExprNode& node() { assert(m_node.get()); return *m_node; } - const ExprNode& node() const { assert(m_node.get()); return *m_node; } - ::std::shared_ptr<ExprNode> take_node() { assert(m_node.get()); return ::std::move(m_node); } - void visit_nodes(NodeVisitor& v); - void visit_nodes(NodeVisitor& v) const; - - friend ::std::ostream& operator<<(::std::ostream& os, const Expr& pat); -}; - } #endif diff --git a/src/ast/expr_ptr.hpp b/src/ast/expr_ptr.hpp new file mode 100644 index 00000000..eb60c49f --- /dev/null +++ b/src/ast/expr_ptr.hpp @@ -0,0 +1,33 @@ +/* + */ +#include <memory> + +namespace AST { + +class ExprNode; +class NodeVisitor; + +typedef ::std::unique_ptr<AST::ExprNode> ExprNodeP; +extern ::std::ostream& operator<<(::std::ostream& os, const ExprNode& node); + +class Expr +{ + ::std::shared_ptr<ExprNode> m_node; +public: + Expr(unique_ptr<ExprNode> node); + Expr(ExprNode* node); + Expr(); + + bool is_valid() const { return m_node.get() != nullptr; } + const ExprNode& node() const { assert(m_node.get()); return *m_node; } + ExprNode& node() { assert(m_node.get()); return *m_node; } + ::std::shared_ptr<ExprNode> take_node() { assert(m_node.get()); return ::std::move(m_node); } + void visit_nodes(NodeVisitor& v); + void visit_nodes(NodeVisitor& v) const; + + Expr clone() const; + + friend ::std::ostream& operator<<(::std::ostream& os, const Expr& pat); +}; + +} diff --git a/src/ast/types.cpp b/src/ast/types.cpp index 293d9db0..1c6cc568 100644 --- a/src/ast/types.cpp +++ b/src/ast/types.cpp @@ -9,7 +9,8 @@ */ #include "types.hpp" #include "ast/ast.hpp" -#include "ast/crate.hpp" +#include <ast/crate.hpp> +#include <ast/expr.hpp> /// Mappings from internal type names to the core type enum static const struct { |