diff options
author | John Hodge <tpg@mutabah.net> | 2016-05-18 20:42:08 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-05-18 20:42:08 +0800 |
commit | 921db4d1205948cbf684bf7e1d3894bdb7c2b4d5 (patch) | |
tree | e0e1c5bf9a341dc12165d19e879362f065d2ac69 /src | |
parent | c9284d392f89c0108785189ff986efbece5c9b65 (diff) | |
download | mrust-921db4d1205948cbf684bf7e1d3894bdb7c2b4d5.tar.gz |
Tagged union cleanup hacks
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/ast.cpp | 2 | ||||
-rw-r--r-- | src/ast/path.cpp | 1 | ||||
-rw-r--r-- | src/ast/pattern.cpp | 2 | ||||
-rw-r--r-- | src/hir/expr.cpp | 4 | ||||
-rw-r--r-- | src/hir/expr.hpp | 41 | ||||
-rw-r--r-- | src/hir/from_ast_expr.cpp | 28 | ||||
-rw-r--r-- | src/hir/type_ptr.cpp | 5 | ||||
-rw-r--r-- | src/hir/type_ptr.hpp | 1 | ||||
-rw-r--r-- | src/include/tagged_union.hpp | 10 | ||||
-rw-r--r-- | src/types.cpp | 6 |
10 files changed, 96 insertions, 4 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 850c1dc3..23e9bfea 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -671,7 +671,7 @@ SERIALISE_TYPE(TypeParam::, "AST_TypeParam", { SERIALISE_TYPE(PATH::, TAG, {\
s % this->tag(); TU_MATCH(PATH, ((*this)), (NAME), __VA_ARGS__)\
}, {\
- PATH::Tag tag; s % tag; switch(tag) { SERIALISE_TU_ARMS(PATH, NAME, __VA_ARGS__) } \
+ PATH::Tag tag; s % tag; switch(tag) { case PATH::TAGDEAD: throw ""; SERIALISE_TU_ARMS(PATH, NAME, __VA_ARGS__) } \
})
SERIALISE_TU(GenericBound, "GenericBound", ent,
diff --git a/src/ast/path.cpp b/src/ast/path.cpp index 9cdf0317..9ff9fe0d 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -577,6 +577,7 @@ SERIALISE_TYPE(Path::, "AST_Path", { s % tag; switch(tag) { + case Class::TAGDEAD: throw ""; _D(Invalid) _D(Local , s.item( ent.name ); ) diff --git a/src/ast/pattern.cpp b/src/ast/pattern.cpp index d7168bc9..c3373206 100644 --- a/src/ast/pattern.cpp +++ b/src/ast/pattern.cpp @@ -133,6 +133,7 @@ void operator%(::Deserialiser& s, Pattern::Value& v) { s % tag; switch(tag) { + case Pattern::Value::TAGDEAD: throw ""; case Pattern::Value::TAG_Invalid: v = Pattern::Value::make_Invalid({}); break; @@ -208,6 +209,7 @@ SERIALISE_TYPE(Pattern::, "Pattern", { s % tag; switch(tag) { + case Pattern::Data::TAGDEAD: throw ""; _D(Any, ) _D(MaybeBind, ) diff --git a/src/hir/expr.cpp b/src/hir/expr.cpp index bcc42c11..9029833b 100644 --- a/src/hir/expr.cpp +++ b/src/hir/expr.cpp @@ -13,17 +13,21 @@ DEF_VISIT(ExprNode_Return) DEF_VISIT(ExprNode_Let) DEF_VISIT(ExprNode_Loop) DEF_VISIT(ExprNode_LoopControl) +DEF_VISIT(ExprNode_Match) + DEF_VISIT(ExprNode_Assign) DEF_VISIT(ExprNode_BinOp) DEF_VISIT(ExprNode_UniOp) DEF_VISIT(ExprNode_Cast) + DEF_VISIT(ExprNode_CallPath) DEF_VISIT(ExprNode_CallMethod) DEF_VISIT(ExprNode_Literal) DEF_VISIT(ExprNode_PathValue); DEF_VISIT(ExprNode_Variable); +DEF_VISIT(ExprNode_StructLiteral); #undef DEF_VISIT diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp index c47131b4..eb321bec 100644 --- a/src/hir/expr.hpp +++ b/src/hir/expr.hpp @@ -79,6 +79,27 @@ struct ExprNode_Let: NODE_METHODS(); }; +struct ExprNode_Match: + public ExprNode +{ + struct Arm + { + ::std::vector< ::HIR::Pattern> m_patterns; + ::HIR::ExprNodeP m_cond; + ::HIR::ExprNodeP m_code; + }; + + ::HIR::ExprNodeP m_value; + ::std::vector<Arm> m_arms; + + ExprNode_Match(::HIR::ExprNodeP val, ::std::vector<Arm> arms): + m_value( mv$(val) ), + m_arms( mv$(arms) ) + {} + + NODE_METHODS(); +}; + struct ExprNode_Assign: public ExprNode { @@ -251,6 +272,24 @@ struct ExprNode_Variable: NODE_METHODS(); }; +struct ExprNode_StructLiteral: + public ExprNode +{ + typedef ::std::vector< ::std::pair< ::std::string, ExprNodeP > > t_values; + + ::HIR::GenericPath m_path; + ::HIR::ExprNodeP m_base_value; + t_values m_values; + + ExprNode_StructLiteral(::HIR::GenericPath path, ::HIR::ExprNodeP base_value, t_values values): + m_path( mv$(path) ), + m_base_value( mv$(base_value) ), + m_values( mv$(values) ) + {} + + NODE_METHODS(); +}; + #undef NODE_METHODS class ExprVisitor @@ -263,6 +302,7 @@ public: NV(ExprNode_Let) NV(ExprNode_Loop) NV(ExprNode_LoopControl) + NV(ExprNode_Match) NV(ExprNode_Assign) NV(ExprNode_BinOp) @@ -275,6 +315,7 @@ public: NV(ExprNode_Literal); NV(ExprNode_PathValue); NV(ExprNode_Variable); + NV(ExprNode_StructLiteral); }; } diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp index 4a801361..e90d0b99 100644 --- a/src/hir/from_ast_expr.cpp +++ b/src/hir/from_ast_expr.cpp @@ -186,6 +186,26 @@ struct LowerHIR_ExprNode_Visitor: virtual void visit(::AST::ExprNode_Loop& v) override { } virtual void visit(::AST::ExprNode_Match& v) override { + ::std::vector< ::HIR::ExprNode_Match::Arm> arms; + + for(const auto& arm : v.m_arms) + { + ::HIR::ExprNode_Match::Arm new_arm { + {}, + LowerHIR_ExprNode_Inner_Opt(arm.m_cond.get()), + LowerHIR_ExprNode_Inner(*arm.m_code) + }; + + for(const auto& pat : arm.m_patterns) + new_arm.m_patterns.push_back( LowerHIR_Pattern(pat) ); + + arms.push_back( mv$(new_arm) ); + } + + m_rv.reset( new ::HIR::ExprNode_Match( + LowerHIR_ExprNode_Inner(*v.m_val), + mv$(arms) + )); } virtual void visit(::AST::ExprNode_If& v) override { } @@ -245,6 +265,14 @@ struct LowerHIR_ExprNode_Visitor: virtual void visit(::AST::ExprNode_Closure& v) override { } virtual void visit(::AST::ExprNode_StructLiteral& v) override { + ::HIR::ExprNode_StructLiteral::t_values values; + for(const auto& val : v.m_values) + values.push_back( ::std::make_pair(val.first, LowerHIR_ExprNode_Inner(*val.second)) ); + m_rv.reset( new ::HIR::ExprNode_StructLiteral( + LowerHIR_GenericPath(v.m_path), + LowerHIR_ExprNode_Inner_Opt(v.m_base_value.get()), + mv$(values) + ) ); } virtual void visit(::AST::ExprNode_Array& v) override { } diff --git a/src/hir/type_ptr.cpp b/src/hir/type_ptr.cpp index b9faf847..b4814e41 100644 --- a/src/hir/type_ptr.cpp +++ b/src/hir/type_ptr.cpp @@ -6,6 +6,11 @@ m_ptr( new TypeRef(mv$(tr)) ) { } +::HIR::TypeRefPtr::TypeRefPtr(TypeRefPtr&& other): + m_ptr( other.m_ptr ) +{ + other.m_ptr = nullptr; +} ::HIR::TypeRefPtr::~TypeRefPtr() { delete m_ptr, m_ptr = nullptr; diff --git a/src/hir/type_ptr.hpp b/src/hir/type_ptr.hpp index 05987da1..b3e1bcc7 100644 --- a/src/hir/type_ptr.hpp +++ b/src/hir/type_ptr.hpp @@ -9,6 +9,7 @@ class TypeRefPtr { TypeRef* m_ptr; public: TypeRefPtr(TypeRef _); + TypeRefPtr(TypeRefPtr&& _); ~TypeRefPtr(); }; diff --git a/src/include/tagged_union.hpp b/src/include/tagged_union.hpp index 67e5643e..9f1becc5 100644 --- a/src/include/tagged_union.hpp +++ b/src/include/tagged_union.hpp @@ -98,9 +98,11 @@ // "match"-like statement // TU_MATCH(Class, m_data, ent, (Variant, CODE), (Variant2, CODE)) #define TU_MATCH(CLASS, VAR, NAME, ...) switch( (TU_FIRST VAR).tag()) {/* +*/ case CLASS::TAGDEAD: throw "ERROR: destructed tagged union used";/* */ TU_MATCH_ARMS(CLASS, VAR, NAME, __VA_ARGS__)/* */} #define TU_MATCH_DEF(CLASS, VAR, NAME, DEF, ...) switch( (TU_FIRST VAR).tag()) {/* +*/ case CLASS::TAGDEAD: throw "ERROR: destructed tagged union used";/* */ TU_MATCH_ARMS(CLASS, VAR, NAME, __VA_ARGS__)/* */ default: {TU_EXP DEF;} break;/* */} @@ -188,6 +190,7 @@ class _name TU_EXP _inherit { \ */public:\ TU_TYPEDEFS _variants/* */ enum Tag { \ + TAGDEAD, \ TU_TAGS _variants\ };/* */ private:\ @@ -198,15 +201,16 @@ class _name TU_EXP _inherit { \ */ public:\ _name(): m_tag(TAG_##_def) { new((void*)m_data) TU_DATANAME(_def); }/* */ _name(const _name&) = delete;/* -*/ _name(_name&& x) noexcept: m_tag(x.m_tag) TU_EXP _extra_move { switch(m_tag) { TU_MOVE_CASES _variants } }/* -*/ _name& operator =(_name&& x) { switch(m_tag) { TU_DEST_CASES _variants } m_tag = x.m_tag; TU_EXP _extra_assign switch(m_tag) { TU_MOVE_CASES _variants }; return *this; }/* -*/ ~_name() { switch(m_tag) { TU_DEST_CASES _variants } m_tag = TAG_##_def; new((void*)m_data) TU_DATANAME(_def); } \ +*/ _name(_name&& x) noexcept: m_tag(x.m_tag) TU_EXP _extra_move { switch(m_tag) { case TAGDEAD: break; TU_MOVE_CASES _variants } x.m_tag = TAGDEAD; }/* +*/ _name& operator =(_name&& x) { switch(m_tag) { case TAGDEAD: break; TU_DEST_CASES _variants } m_tag = x.m_tag; TU_EXP _extra_assign switch(m_tag) { case TAGDEAD: break; TU_MOVE_CASES _variants }; return *this; }/* +*/ ~_name() { switch(m_tag) { case TAGDEAD: break; TU_DEST_CASES _variants } m_tag = TAGDEAD; } \ \ Tag tag() const { return m_tag; }\ TU_CONSS(_name, TU_EXP _variants) \ /* */ static const char *tag_to_str(Tag tag) { \ switch(tag) {/* +*/ case TAGDEAD: return "";/* */ TU_TOSTR_CASES _variants/* */ } return ""; \ }/* diff --git a/src/types.cpp b/src/types.cpp index f3777666..ffa4db42 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -99,6 +99,7 @@ TypeRef::TypeRef(const TypeRef& other) { switch( other.m_data.tag() ) { + case TypeData::TAGDEAD: throw ""; #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) @@ -125,6 +126,7 @@ bool TypeRef::deref(bool is_implicit) #define _(VAR, ...) case TypeData::TAG_##VAR: { auto &ent = m_data.as_##VAR(); (void)&ent; __VA_ARGS__ } break; switch(m_data.tag()) { + case TypeData::TAGDEAD: throw ""; case TypeData::TAG_None: throw ::std::runtime_error("Dereferencing ! - bugcheck"); case TypeData::TAG_Macro: throw ::std::runtime_error("Dereferencing unexpanded macro - bugcheck"); case TypeData::TAG_Any: throw ::std::runtime_error("Dereferencing _"); @@ -259,6 +261,7 @@ void TypeRef::resolve_args(::std::function<TypeRef(const char*)> fcn) #define _(VAR, ...) case TypeData::TAG_##VAR: { auto &ent = m_data.as_##VAR(); (void)&ent; __VA_ARGS__ } break; switch(m_data.tag()) { + case TypeData::TAGDEAD: throw ""; _(None, throw ::std::runtime_error("TypeRef::resolve_args on !"); ) @@ -692,6 +695,7 @@ Ordering TypeRef::ord(const TypeRef& x) const #define _(VAR, ...) case TypeData::TAG_##VAR: { const auto &ent = tr.m_data.as_##VAR(); (void)&ent; __VA_ARGS__ } break; switch(tr.m_data.tag()) { + case TypeData::TAGDEAD: throw ""; _(None, os << "!"; ) @@ -803,6 +807,7 @@ SERIALISE_TYPE(TypeRef::, "TypeRef", { s % m_data.tag(); switch(m_data.tag()) { + case TypeData::TAGDEAD: throw ""; _S(None) _S(Macro, s.item( ent.inv ); @@ -850,6 +855,7 @@ SERIALISE_TYPE(TypeRef::, "TypeRef", { s % tag; switch(tag) { + case TypeData::TAGDEAD: throw ""; _D(None) _D(Any) _D(Unit) |