diff options
author | John Hodge <tpg@mutabah.net> | 2015-03-19 14:40:41 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2015-03-19 14:40:41 +0800 |
commit | 01b1749e3b008e0f11219c842da1492f1e42aba1 (patch) | |
tree | 7038a1e757371f503c875f6b1a7e556f8662e44c | |
parent | a1e8e5a056ec064177cf5f67766450175e435639 (diff) | |
download | mrust-01b1749e3b008e0f11219c842da1492f1e42aba1.tar.gz |
Convert patterns over to tagged unions
-rw-r--r-- | src/ast/ast.cpp | 130 | ||||
-rw-r--r-- | src/ast/pattern.hpp | 62 | ||||
-rw-r--r-- | src/convert/ast_iterate.cpp | 70 | ||||
-rw-r--r-- | src/convert/resolve.cpp | 2 | ||||
-rw-r--r-- | src/dump_as_rust.cpp | 61 | ||||
-rw-r--r-- | src/include/tagged_enum.hpp | 51 | ||||
-rw-r--r-- | src/parse/expr.cpp | 4 |
7 files changed, 244 insertions, 136 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 48517095..37cb17b6 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -40,62 +40,110 @@ SERIALISE_TYPE(MetaItem::, "AST_MetaItem", { ::std::ostream& operator<<(::std::ostream& os, const Pattern& pat)
{
- switch(pat.m_class)
+ os << "Pattern(" << pat.m_binding << " @ ";
+ switch(pat.m_data.tag())
{
- case Pattern::ANY:
- os << "Pattern(TagWildcard, '" << pat.m_binding << "' @ _)";
+ case Pattern::Data::Any:
+ os << "_";
break;
- case Pattern::MAYBE_BIND:
- os << "Pattern(TagMaybeBind, '" << pat.m_binding << "')";
+ case Pattern::Data::MaybeBind:
+ os << "?";
break;
- case Pattern::REF:
- os << "Pattern(TagReference, '" << pat.m_binding << "' @ " << pat.m_sub_patterns[0] << ")";
+ case Pattern::Data::Ref:
+ os << "&" << (pat.m_data.as_Ref().mut ? "mut " : "") << *pat.m_data.as_Ref().sub;
break;
- case Pattern::VALUE:
- os << "Pattern(TagValue, '" << pat.m_binding << "' @ TODO:ExprNode)";
+ case Pattern::Data::Value:
+ os << *pat.m_data.as_Value().start;
+ if( pat.m_data.as_Value().end.get() )
+ os << " ... " << *pat.m_data.as_Value().end;
break;
- case Pattern::TUPLE:
- os << "Pattern(TagTuple, '" << pat.m_binding << "' @ [" << pat.m_sub_patterns << "])";
+ case Pattern::Data::Tuple:
+ os << "(" << pat.m_data.as_Tuple().sub_patterns << ")";
break;
- case Pattern::TUPLE_STRUCT:
- os << "Pattern(TagEnumVariant, '" << pat.m_binding << "' @ " << pat.m_path << ", [" << pat.m_sub_patterns << "])";
+ case Pattern::Data::StructTuple:
+ os << pat.m_data.as_StructTuple().path << " (" << pat.m_data.as_StructTuple().sub_patterns << ")";
+ break;
+ case Pattern::Data::Struct:
+ os << pat.m_data.as_Struct().path << " {" << pat.m_data.as_Struct().sub_patterns << "}";
break;
}
+ os << ")";
return os;
}
-void operator%(Serialiser& s, Pattern::BindType c) {
- switch(c)
- {
- #define _(v) case Pattern::v: s << #v; return;
- _(ANY)
- _(MAYBE_BIND)
- _(REF)
- _(VALUE)
- _(TUPLE)
- _(TUPLE_STRUCT)
- #undef _
- }
+void operator%(Serialiser& s, Pattern::Data::Tag c) {
+ s << Pattern::Data::tag_to_str(c);
}
-void operator%(::Deserialiser& s, Pattern::BindType& c) {
+void operator%(::Deserialiser& s, Pattern::Data::Tag& c) {
::std::string n;
s.item(n);
- if(1) ;
- #define _(v) else if(n == #v) c = Pattern::v;
- _(ANY)
- _(MAYBE_BIND)
- _(REF)
- _(VALUE)
- _(TUPLE)
- _(TUPLE_STRUCT)
- #undef _
- else
- throw ::std::runtime_error("");
+ c = Pattern::Data::tag_from_str(n);
}
-SERIALISE_TYPE_S(Pattern, {
- s % m_class;
+SERIALISE_TYPE(Pattern::, "Pattern", {
+ s.item(m_binding);
+ s % m_data.tag();
+ switch(m_data.tag())
+ {
+ case Pattern::Data::Any:
+ break;
+ case Pattern::Data::MaybeBind:
+ break;
+ case Pattern::Data::Ref:
+ s << m_data.as_Ref().mut;
+ s << m_data.as_Ref().sub;
+ break;
+ case Pattern::Data::Value:
+ s << m_data.as_Value().start;
+ s << m_data.as_Value().end;
+ break;
+ case Pattern::Data::Tuple:
+ s << m_data.as_Tuple().sub_patterns;
+ break;
+ case Pattern::Data::StructTuple:
+ s << m_data.as_StructTuple().path;
+ s << m_data.as_StructTuple().sub_patterns;
+ break;
+ case Pattern::Data::Struct:
+ s << m_data.as_Struct().path;
+ s << m_data.as_Struct().sub_patterns;
+ break;
+ }
+},{
s.item(m_binding);
- s.item(m_sub_patterns);
- s.item(m_path);
+ Pattern::Data::Tag tag;
+ s % tag;
+ switch(tag)
+ {
+ case Pattern::Data::Any:
+ m_data = Pattern::Data::make_null_Any();
+ break;
+ case Pattern::Data::MaybeBind:
+ m_data = Pattern::Data::make_null_MaybeBind();
+ break;
+ case Pattern::Data::Ref:
+ m_data = Pattern::Data::make_null_Ref();
+ s.item( m_data.as_Ref().mut );
+ s.item( m_data.as_Ref().sub );
+ break;
+ case Pattern::Data::Value:
+ m_data = Pattern::Data::make_null_Value();
+ s.item( m_data.as_Value().start );
+ s.item( m_data.as_Value().end );
+ break;
+ case Pattern::Data::Tuple:
+ m_data = Pattern::Data::make_null_Tuple();
+ s.item( m_data.as_Tuple().sub_patterns );
+ break;
+ case Pattern::Data::StructTuple:
+ m_data = Pattern::Data::make_null_StructTuple();
+ s.item( m_data.as_StructTuple().path );
+ s.item( m_data.as_StructTuple().sub_patterns );
+ break;
+ case Pattern::Data::Struct:
+ m_data = Pattern::Data::make_null_Struct();
+ s.item( m_data.as_Struct().path );
+ s.item( m_data.as_Struct().sub_patterns );
+ break;
+ }
});
Impl Impl::make_concrete(const ::std::vector<TypeRef>& types) const
diff --git a/src/ast/pattern.hpp b/src/ast/pattern.hpp index fde31201..355b5c2a 100644 --- a/src/ast/pattern.hpp +++ b/src/ast/pattern.hpp @@ -18,80 +18,62 @@ class Pattern: public Serialisable { public: - enum BindType { - MAYBE_BIND, - ANY, - REF, - VALUE, - TUPLE, - TUPLE_STRUCT, - }; -private: - BindType m_class; - ::std::string m_binding; - Path m_path; - ::std::vector<Pattern> m_sub_patterns; - TAGGED_ENUM(Data, Any, (Any, () ), (MaybeBind, () ), - (Ref, (bool mut; unique_ptr<ExprNode> sub;) ), + (Ref, (bool mut; unique_ptr<Pattern> sub;) ), (Value, (unique_ptr<ExprNode> start; unique_ptr<ExprNode> end;) ), (Tuple, (::std::vector<Pattern> sub_patterns;) ), (StructTuple, (Path path; ::std::vector<Pattern> sub_patterns;) ), (Struct, (Path path; ::std::vector< ::std::pair< ::std::string,Pattern> > sub_patterns;) ) - ) m_data; + ); +private: + ::std::string m_binding; + Data m_data; public: - Pattern(): - m_class(ANY) + Pattern() {} // Wildcard = '..', distinct from '_' // TODO: Store wildcard as a different pattern type struct TagWildcard {}; - Pattern(TagWildcard): - m_class(ANY) + Pattern(TagWildcard) {} struct TagBind {}; Pattern(TagBind, ::std::string name): - m_class(ANY), m_binding(name) {} struct TagMaybeBind {}; Pattern(TagMaybeBind, ::std::string name): - m_class(MAYBE_BIND), - m_binding(name) + m_binding(name), + m_data( Data::make_MaybeBind({}) ) {} struct TagValue {}; Pattern(TagValue, unique_ptr<ExprNode> node, unique_ptr<ExprNode> node2 = 0): - m_class(VALUE), m_data( Data::make_Value({ ::std::move(node), ::std::move(node2) }) ) {} struct TagReference {}; Pattern(TagReference, Pattern sub_pattern): - m_class(REF), - m_sub_patterns() + m_data( Data::make_Ref( /*Data::Data_Ref */ { + false, unique_ptr<Pattern>(new Pattern(::std::move(sub_pattern))) + }) ) { - m_sub_patterns.push_back( ::std::move(sub_pattern) ); } struct TagTuple {}; Pattern(TagTuple, ::std::vector<Pattern> sub_patterns): - m_class(TUPLE), - m_sub_patterns( ::std::move(sub_patterns) ) + m_data( Data::make_Tuple( { ::std::move(sub_patterns) } ) ) {} struct TagEnumVariant {}; Pattern(TagEnumVariant, Path path, ::std::vector<Pattern> sub_patterns): - m_class(TUPLE_STRUCT), - m_path( ::std::move(path) ), - m_sub_patterns( ::std::move(sub_patterns) ) + m_data( Data::make_StructTuple( { ::std::move(path), ::std::move(sub_patterns) } ) ) {} // Mutators @@ -100,29 +82,31 @@ public: } ::std::unique_ptr<ExprNode> take_node() { - assert(m_class == VALUE); - m_class = ANY; assert(m_data.is_Value()); return ::std::move(m_data.unwrap_Value().start); } // Accessors const ::std::string& binding() const { return m_binding; } - BindType type() const { return m_class; } + Data& data() { return m_data; } + const Data& data() const { return m_data; } ExprNode& node() { return *m_data.as_Value().start; } const ExprNode& node() const { return *m_data.as_Value().start; } - Path& path() { return m_path; } - const Path& path() const { return m_path; } - ::std::vector<Pattern>& sub_patterns() { return m_sub_patterns; } - const ::std::vector<Pattern>& sub_patterns() const { return m_sub_patterns; } + Path& path() { return m_data.as_StructTuple().path; } + const Path& path() const { return m_data.as_StructTuple().path; } friend ::std::ostream& operator<<(::std::ostream& os, const Pattern& pat); SERIALISABLE_PROTOTYPES(); + static ::std::unique_ptr<Pattern> from_deserialiser(Deserialiser& s) { + ::std::unique_ptr<Pattern> ret(new Pattern); + s.item(*ret); + return ::std::move(ret); + } }; }; diff --git a/src/convert/ast_iterate.cpp b/src/convert/ast_iterate.cpp index e53e1ba8..02914c49 100644 --- a/src/convert/ast_iterate.cpp +++ b/src/convert/ast_iterate.cpp @@ -62,29 +62,34 @@ void CASTIterator::handle_pattern(AST::Pattern& pat, const TypeRef& type_hint) { //DEBUG("pat = " << pat); // Resolve names - switch(pat.type()) + switch(pat.data().tag()) { - case AST::Pattern::ANY: + case AST::Pattern::Data::Any: // Wildcard, nothing to do break; - case AST::Pattern::REF: + case AST::Pattern::Data::Ref: { + auto& v = pat.data().as_Ref(); if( type_hint.is_wildcard() ) - handle_pattern(pat.sub_patterns()[0], (const TypeRef&)TypeRef()); + handle_pattern(*v.sub, (const TypeRef&)TypeRef()); else if( type_hint.is_reference() ) throw ::std::runtime_error("Ref pattern on non-ref value"); else - handle_pattern(pat.sub_patterns()[0], type_hint.sub_types()[0]); - break; - case AST::Pattern::MAYBE_BIND: + handle_pattern(*v.sub, type_hint.sub_types()[0]); + break; } + case AST::Pattern::Data::MaybeBind: throw ::std::runtime_error("Calling CASTIterator::handle_pattern on MAYBE_BIND, not valid"); - case AST::Pattern::VALUE: - handle_expr( pat.node() ); - break; - case AST::Pattern::TUPLE: + case AST::Pattern::Data::Value: { + auto& v = pat.data().as_Value(); + handle_expr( *v.start ); + if( v.end.get() ) + handle_expr( *v.end ); + break; } + case AST::Pattern::Data::Tuple: { + auto& v = pat.data().as_Tuple(); // Tuple is handled by subpattern code if( type_hint.is_wildcard() ) { - for( auto& sp : pat.sub_patterns() ) + for( auto& sp : v.sub_patterns ) handle_pattern(sp, (const TypeRef&)TypeRef()); } else if( !type_hint.is_tuple() ) @@ -93,24 +98,41 @@ void CASTIterator::handle_pattern(AST::Pattern& pat, const TypeRef& type_hint) } else { - if( type_hint.sub_types().size() != pat.sub_patterns().size() ) + if( type_hint.sub_types().size() != v.sub_patterns.size() ) { throw ::std::runtime_error("Tuple pattern count doesn't match"); } - for( unsigned int i = 0; i < pat.sub_patterns().size(); i ++ ) + for( unsigned int i = 0; i < v.sub_patterns.size(); i ++ ) { - handle_pattern(pat.sub_patterns()[i], type_hint.sub_types()[i]); + handle_pattern(v.sub_patterns[i], type_hint.sub_types()[i]); } } - break; - case AST::Pattern::TUPLE_STRUCT: + break; } + case AST::Pattern::Data::Struct: { + auto& v = pat.data().as_Struct(); + handle_path( v.path, CASTIterator::MODE_TYPE ); + if( type_hint.is_wildcard() ) + { + for( auto& sp : v.sub_patterns ) + handle_pattern(sp.second, (const TypeRef&)TypeRef()); + } + else if( !type_hint.is_path() ) + { + throw ::std::runtime_error("Tuple struct pattern on non-tuple value"); + } + else + { + throw ::std::runtime_error("TODO: Struct typecheck/iterate"); + } + break; } + case AST::Pattern::Data::StructTuple: { + auto& v = pat.data().as_StructTuple(); // Resolve the path! - // - TODO: Restrict to types and enum variants - handle_path( pat.path(), CASTIterator::MODE_TYPE ); + handle_path( v.path, CASTIterator::MODE_TYPE ); // Handle sub-patterns if( type_hint.is_wildcard() ) { - for( auto& sp : pat.sub_patterns() ) + for( auto& sp : v.sub_patterns ) handle_pattern(sp, (const TypeRef&)TypeRef()); } else if( !type_hint.is_path() ) @@ -120,8 +142,8 @@ void CASTIterator::handle_pattern(AST::Pattern& pat, const TypeRef& type_hint) else { auto& hint_path = type_hint.path(); - auto& pat_path = pat.path(); - DEBUG("Pat: " << pat.path() << ", Type: " << type_hint.path()); + auto& pat_path = v.path; + DEBUG("Pat: " << pat_path << ", Type: " << type_hint.path()); switch( hint_path.binding_type() ) { case AST::Path::UNBOUND: @@ -136,13 +158,13 @@ void CASTIterator::handle_pattern(AST::Pattern& pat, const TypeRef& type_hint) auto& enm = pat_path.bound_enum(); auto idx = pat_path.bound_idx(); auto& var = enm.variants().at(idx); - handle_pattern_enum(pat_path[-2].args(), hint_path[-1].args(), enm.params(), var, pat.sub_patterns()); + handle_pattern_enum(pat_path[-2].args(), hint_path[-1].args(), enm.params(), var, v.sub_patterns); break; } default: throw ::std::runtime_error(FMT("Bad type in tuple struct pattern : " << type_hint.path())); } } - break; + break; } } // Extract bindings and add to namespace if( pat.binding().size() > 0 ) diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp index 9aae9847..49c2e2a9 100644 --- a/src/convert/resolve.cpp +++ b/src/convert/resolve.cpp @@ -344,7 +344,7 @@ void CPathResolver::handle_pattern(AST::Pattern& pat, const TypeRef& type_hint) {
DEBUG("pat = " << pat);
// Resolve "Maybe Bind" entries
- if( pat.type() == AST::Pattern::MAYBE_BIND )
+ if( pat.data().tag() == AST::Pattern::Data::MaybeBind )
{
::std::string name = pat.binding();
// Locate a _constant_ within the current namespace which matches this name
diff --git a/src/dump_as_rust.cpp b/src/dump_as_rust.cpp index 1d3fa300..e1c32a69 100644 --- a/src/dump_as_rust.cpp +++ b/src/dump_as_rust.cpp @@ -661,36 +661,55 @@ void RustPrinter::print_bounds(const AST::TypeParams& params) void RustPrinter::print_pattern(const AST::Pattern& p) { - if( p.binding() != "" && p.type() == AST::Pattern::ANY ) { - m_os << p.binding(); - return; - } - if( p.binding() != "" ) m_os << p.binding() << " @ "; - switch(p.type()) + switch(p.data().tag()) { - case AST::Pattern::ANY: + case AST::Pattern::Data::Any: m_os << "_"; break; - case AST::Pattern::REF: - m_os << "& "; - print_pattern(p.sub_patterns()[0]); - break; - case AST::Pattern::VALUE: - m_os << p.node(); + case AST::Pattern::Data::MaybeBind: + m_os << "_ /*?*/"; break; - case AST::Pattern::MAYBE_BIND: - m_os << "/*?*/" << p.path(); - break; - case AST::Pattern::TUPLE_STRUCT: - m_os << p.path(); - case AST::Pattern::TUPLE: + case AST::Pattern::Data::Ref: { + const auto& v = p.data().as_Ref(); + m_os << "& "; + print_pattern(*v.sub); + break; } + case AST::Pattern::Data::Value: { + auto& v = p.data().as_Value(); + m_os << *v.start; + if( v.end.get() ) + m_os << " ... " << *v.end; + break; } + case AST::Pattern::Data::StructTuple: { + const auto& v = p.data().as_StructTuple(); + m_os << v.path << "("; + for(const auto& sp : v.sub_patterns) { + print_pattern(sp); + m_os << ","; + } + m_os << ")"; + break; } + case AST::Pattern::Data::Struct: { + const auto& v = p.data().as_Struct(); + m_os << v.path << "("; + for(const auto& sp : v.sub_patterns) { + m_os << sp.first << ": "; + print_pattern(sp.second); + m_os << ","; + } + m_os << ")"; + break; } + case AST::Pattern::Data::Tuple: { + const auto& v = p.data().as_Tuple(); m_os << "("; - for(const auto& sp : p.sub_patterns()) + for(const auto& sp : v.sub_patterns) { print_pattern(sp); + m_os << ","; + } m_os << ")"; - break; + break; } } } diff --git a/src/include/tagged_enum.hpp b/src/include/tagged_enum.hpp index 2ef1b034..08168fe5 100644 --- a/src/include/tagged_enum.hpp +++ b/src/include/tagged_enum.hpp @@ -1,6 +1,7 @@ #define TE_DATANAME(name) Data_##name #define ENUM_CONS(__tag, __type) \ + static self_t make_null_##__tag() { self_t ret; ret.m_tag = __tag; new (ret.m_data) __type; return ::std::move(ret); } \ static self_t make_##__tag(__type v) \ {\ self_t ret;\ @@ -65,23 +66,46 @@ #define TE_MOVE_CASE6(_1, ...) TE_MOVE_CASE _1 TE_MOVE_CASE5(__VA_ARGS__) #define TE_MOVE_CASE7(_1, ...) TE_MOVE_CASE _1 TE_MOVE_CASE6(__VA_ARGS__) +// "tag_to_str" internals +#define TE_TOSTR_CASE(tag,_) case tag: return #tag; +#define TE_TOSTR_CASE2(a,b) TE_TOSTR_CASE a TE_TOSTR_CASE b +#define TE_TOSTR_CASE3(a,...) TE_TOSTR_CASE a TE_TOSTR_CASE2(__VA_ARGS__) +#define TE_TOSTR_CASE4(a,...) TE_TOSTR_CASE a TE_TOSTR_CASE3(__VA_ARGS__) +#define TE_TOSTR_CASE5(a,...) TE_TOSTR_CASE a TE_TOSTR_CASE4(__VA_ARGS__) +#define TE_TOSTR_CASE6(a,...) TE_TOSTR_CASE a TE_TOSTR_CASE5(__VA_ARGS__) +#define TE_TOSTR_CASE7(a,...) TE_TOSTR_CASE a TE_TOSTR_CASE6(__VA_ARGS__) +// "tag_from_str" internals +#define TE_FROMSTR_CASE(tag,_) else if(str == #tag) return tag; +#define TE_FROMSTR_CASE2(a,b) TE_FROMSTR_CASE a TE_FROMSTR_CASE b +#define TE_FROMSTR_CASE3(a,...) TE_FROMSTR_CASE a TE_FROMSTR_CASE2(__VA_ARGS__) +#define TE_FROMSTR_CASE4(a,...) TE_FROMSTR_CASE a TE_FROMSTR_CASE3(__VA_ARGS__) +#define TE_FROMSTR_CASE5(a,...) TE_FROMSTR_CASE a TE_FROMSTR_CASE4(__VA_ARGS__) +#define TE_FROMSTR_CASE6(a,...) TE_FROMSTR_CASE a TE_FROMSTR_CASE5(__VA_ARGS__) +#define TE_FROMSTR_CASE7(a,...) TE_FROMSTR_CASE a TE_FROMSTR_CASE6(__VA_ARGS__) + // Macro to obtain a numbered macro for argument counts -#define TE_GM(SUF,_1,_2,_3,_4,_5,_6,_7,COUNT,...) SUF##COUNT +#define TE_GM_I(SUF,_1,_2,_3,_4,_5,_6,_7,COUNT,...) SUF##COUNT +#define TE_GM(SUF,...) TE_GM_I(SUF,__VA_ARGS__,7,6,5,4,3,2) -#define MAXS(...) TE_GM(MAXS ,__VA_ARGS__,7,6,5,4,3,2)(__VA_ARGS__) -#define TE_TYPEDEFS(...) TE_GM(TE_TYPEDEF ,__VA_ARGS__,7,6,5,4,3,2)(__VA_ARGS__) -#define TE_TAGS(...) TE_GM(TE_TAG ,__VA_ARGS__,7,6,5,4,3,2)(__VA_ARGS__) -#define TE_DEST_CASES(...) TE_GM(TE_DEST_CASE,__VA_ARGS__,7,6,5,4,3,2)(__VA_ARGS__) -#define TE_MOVE_CASES(...) TE_GM(TE_MOVE_CASE,__VA_ARGS__,7,6,5,4,3,2)(__VA_ARGS__) -#define TE_CONSS(...) TE_GM(TE_CONS ,__VA_ARGS__,7,6,5,4,3,2)(__VA_ARGS__) +#define MAXS(...) TE_GM(MAXS ,__VA_ARGS__)(__VA_ARGS__) +#define TE_TYPEDEFS(...) TE_GM(TE_TYPEDEF ,__VA_ARGS__)(__VA_ARGS__) +#define TE_TAGS(...) TE_GM(TE_TAG ,__VA_ARGS__)(__VA_ARGS__) +#define TE_DEST_CASES(...) TE_GM(TE_DEST_CASE,__VA_ARGS__)(__VA_ARGS__) +#define TE_MOVE_CASES(...) TE_GM(TE_MOVE_CASE,__VA_ARGS__)(__VA_ARGS__) +#define TE_TOSTR_CASES(...) TE_GM(TE_TOSTR_CASE ,__VA_ARGS__)(__VA_ARGS__) +#define TE_FROMSTR_CASES(...) TE_GM(TE_FROMSTR_CASE,__VA_ARGS__)(__VA_ARGS__) +#define TE_CONSS(...) TE_GM(TE_CONS ,__VA_ARGS__)(__VA_ARGS__) #define TAGGED_ENUM(_name, _def, ...) \ class _name { \ typedef _name self_t; \ TE_TYPEDEFS(__VA_ARGS__) \ +public:\ enum Tag { \ TE_TAGS(__VA_ARGS__)\ - } m_tag; \ + }; \ +private:\ + Tag m_tag; \ char m_data[MAXS(__VA_ARGS__)]; \ public:\ _name(): m_tag(_def) {}\ @@ -89,7 +113,18 @@ public:\ _name(_name&& x): m_tag(x.m_tag) { x.m_tag = _def; switch(m_tag) { TE_MOVE_CASES(__VA_ARGS__) } } \ _name& operator =(_name&& x) { this->~_name(); m_tag = x.m_tag; x.m_tag = _def; switch(m_tag) { TE_MOVE_CASES(__VA_ARGS__) }; return *this; } \ ~_name() { switch(m_tag) { TE_DEST_CASES(__VA_ARGS__) } } \ + \ + Tag tag() const { return m_tag; }\ TE_CONSS(__VA_ARGS__) \ +/* +*/ static const char *tag_to_str(Tag tag) { \ + switch(tag) { TE_TOSTR_CASES(__VA_ARGS__) } return ""; \ + }/* +*/ static Tag tag_from_str(const ::std::string& str) { \ + if(0); \ + TE_FROMSTR_CASES(__VA_ARGS__)\ + else throw ::std::runtime_error("enum "#_name" No conversion"); \ + }\ } #define ENUM3(_name, _def, _t1, _v1, _t2, _v2, _t3, _v3)\ diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index e217974a..af044ab3 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -134,11 +134,11 @@ AST::Pattern Parse_PatternReal(TokenStream& lex) AST::Pattern ret = Parse_PatternReal1(lex);
if( GET_TOK(tok, lex) == TOK_TRIPLE_DOT )
{
- if( ret.type() != AST::Pattern::VALUE )
+ if( !ret.data().is_Value() )
throw ParseError::Generic(lex, "Using '...' with a non-value on left");
auto leftval = ret.take_node();
auto right_pat = Parse_PatternReal1(lex);
- if( right_pat.type() != AST::Pattern::VALUE )
+ if( !right_pat.data().is_Value() )
throw ParseError::Generic(lex, "Using '...' with a non-value on right");
auto rightval = right_pat.take_node();
|