summaryrefslogtreecommitdiff
path: root/src/ast
diff options
context:
space:
mode:
Diffstat (limited to 'src/ast')
-rw-r--r--src/ast/ast.cpp188
-rw-r--r--src/ast/ast.hpp23
-rw-r--r--src/ast/expr.cpp24
-rw-r--r--src/ast/expr.hpp31
-rw-r--r--src/ast/expr_ptr.hpp33
-rw-r--r--src/ast/types.cpp3
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 {