From 5bb8ec98e80b6dedfb38b9c12e571fd4d81a7bb2 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 25 Oct 2016 16:13:50 +0800 Subject: AST - Encode unit variants with a NULL value instead of an empty set --- src/expand/derive.cpp | 345 ++++++++++++++++++-------------------------------- src/hir/from_ast.cpp | 28 ++-- src/parse/root.cpp | 2 +- 3 files changed, 142 insertions(+), 233 deletions(-) (limited to 'src') diff --git a/src/expand/derive.cpp b/src/expand/derive.cpp index 4c4b6e10..91b6c7d5 100644 --- a/src/expand/derive.cpp +++ b/src/expand/derive.cpp @@ -374,37 +374,25 @@ public: pat_a = AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(base_path + v.m_name)); ), (Tuple, - if( e.m_sub_types.size() == 0 ) - { - code = NEWNODE(CallMethod, - NEWNODE(NamedValue, AST::Path("f")), - AST::PathNode("write_str",{}), - vec$( NEWNODE(String, v.m_name + "()") ) - ); - pat_a = AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(base_path + v.m_name)); - } - else + // TODO: Complete this. + ::std::vector pats_a; + //::std::vector nodes; + + for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) { - // TODO: Complete this. - ::std::vector pats_a; - //::std::vector nodes; - - for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) - { - auto name_a = FMT("a" << idx); - pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_a, ::AST::PatternBinding::Type::REF) ); - //nodes.push_back( this->assert_is_eq(assert_method_path, NEWNODE(NamedValue, AST::Path(name_a))) ); - } - - //code = NEWNODE(Block, mv$(nodes)); - code = NEWNODE(CallMethod, - NEWNODE(NamedValue, AST::Path("f")), - AST::PathNode("write_str",{}), - vec$( NEWNODE(String, v.m_name + "(...)") ) - ); - - pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_a)); + auto name_a = FMT("a" << idx); + pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_a, ::AST::PatternBinding::Type::REF) ); + //nodes.push_back( this->assert_is_eq(assert_method_path, NEWNODE(NamedValue, AST::Path(name_a))) ); } + + //code = NEWNODE(Block, mv$(nodes)); + code = NEWNODE(CallMethod, + NEWNODE(NamedValue, AST::Path("f")), + AST::PathNode("write_str",{}), + vec$( NEWNODE(String, v.m_name + "(...)") ) + ); + + pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_a)); ), (Struct, ::std::vector< ::std::pair > pats_a; @@ -529,35 +517,26 @@ public: pat_b = AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(base_path + v.m_name)); ), (Tuple, - if( e.m_sub_types.size() == 0 ) - { - code = NEWNODE(Bool, true); - pat_a = AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(base_path + v.m_name)); - pat_b = AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(base_path + v.m_name)); - } - else + ::std::vector pats_a; + ::std::vector pats_b; + ::std::vector nodes; + + for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) { - ::std::vector pats_a; - ::std::vector pats_b; - ::std::vector nodes; - - for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) - { - auto name_a = FMT("a" << idx); - auto name_b = FMT("b" << idx); - pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_a, ::AST::PatternBinding::Type::REF) ); - pats_b.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_b, ::AST::PatternBinding::Type::REF) ); - nodes.push_back(this->compare_and_ret(sp, core_name, - NEWNODE(NamedValue, AST::Path(name_a)), - NEWNODE(NamedValue, AST::Path(name_b)) - )); - } - - nodes.push_back( NEWNODE(Bool, true) ); - pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_a)); - pat_b = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_b)); - code = NEWNODE(Block, mv$(nodes)); + auto name_a = FMT("a" << idx); + auto name_b = FMT("b" << idx); + pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_a, ::AST::PatternBinding::Type::REF) ); + pats_b.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_b, ::AST::PatternBinding::Type::REF) ); + nodes.push_back(this->compare_and_ret(sp, core_name, + NEWNODE(NamedValue, AST::Path(name_a)), + NEWNODE(NamedValue, AST::Path(name_b)) + )); } + + nodes.push_back( NEWNODE(Bool, true) ); + pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_a)); + pat_b = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_b)); + code = NEWNODE(Block, mv$(nodes)); ), (Struct, ::std::vector< ::std::pair > pats_a; @@ -744,36 +723,27 @@ public: pat_b = AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(base_path + v.m_name)); ), (Tuple, - if( e.m_sub_types.size() == 0 ) - { - code = this->make_ret_equal(core_name); - pat_a = AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(base_path + v.m_name)); - pat_b = AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(base_path + v.m_name)); - } - else + ::std::vector pats_a; + ::std::vector pats_b; + ::std::vector nodes; + + for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) { - ::std::vector pats_a; - ::std::vector pats_b; - ::std::vector nodes; - - for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) - { - auto name_a = FMT("a" << idx); - auto name_b = FMT("b" << idx); - pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_a, ::AST::PatternBinding::Type::REF) ); - pats_b.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_b, ::AST::PatternBinding::Type::REF) ); - - nodes.push_back(this->make_compare_and_ret( sp, core_name, - NEWNODE(NamedValue, AST::Path(name_a)), - NEWNODE(NamedValue, AST::Path(name_b)) - )); - } + auto name_a = FMT("a" << idx); + auto name_b = FMT("b" << idx); + pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_a, ::AST::PatternBinding::Type::REF) ); + pats_b.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_b, ::AST::PatternBinding::Type::REF) ); - nodes.push_back( this->make_ret_equal(core_name) ); - pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_a)); - pat_b = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_b)); - code = NEWNODE(Block, mv$(nodes)); + nodes.push_back(this->make_compare_and_ret( sp, core_name, + NEWNODE(NamedValue, AST::Path(name_a)), + NEWNODE(NamedValue, AST::Path(name_b)) + )); } + + nodes.push_back( this->make_ret_equal(core_name) ); + pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_a)); + pat_b = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_b)); + code = NEWNODE(Block, mv$(nodes)); ), (Struct, ::std::vector< ::std::pair > pats_a; @@ -831,14 +801,7 @@ public: return AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(var_path)); ), (Tuple, - if( e.m_sub_types.size() == 0 ) - { - return AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(var_path)); - } - else - { - return AST::Pattern(AST::Pattern::TagNamedTuple(), var_path, AST::Pattern::TuplePat { {}, true, {} }); - } + return AST::Pattern(AST::Pattern::TagNamedTuple(), var_path, AST::Pattern::TuplePat { {}, true, {} }); ), (Struct, return AST::Pattern(AST::Pattern::TagStruct(), var_path, {}, false); @@ -963,26 +926,18 @@ public: pat_a = AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(base_path + v.m_name)); ), (Tuple, - if( e.m_sub_types.size() == 0 ) - { - code = NEWNODE(Block); - pat_a = AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(base_path + v.m_name)); - } - else + ::std::vector pats_a; + ::std::vector nodes; + + for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) { - ::std::vector pats_a; - ::std::vector nodes; - - for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) - { - auto name_a = FMT("a" << idx); - pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_a, ::AST::PatternBinding::Type::REF) ); - nodes.push_back( this->assert_is_eq(assert_method_path, NEWNODE(NamedValue, AST::Path(name_a))) ); - } - - pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_a)); - code = NEWNODE(Block, mv$(nodes)); + auto name_a = FMT("a" << idx); + pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_a, ::AST::PatternBinding::Type::REF) ); + nodes.push_back( this->assert_is_eq(assert_method_path, NEWNODE(NamedValue, AST::Path(name_a))) ); } + + pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_a)); + code = NEWNODE(Block, mv$(nodes)); ), (Struct, ::std::vector< ::std::pair > pats_a; @@ -1132,36 +1087,27 @@ public: pat_b = AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(base_path + v.m_name)); ), (Tuple, - if( e.m_sub_types.size() == 0 ) - { - code = this->make_ret_equal(core_name); - pat_a = AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(base_path + v.m_name)); - pat_b = AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(base_path + v.m_name)); - } - else + ::std::vector pats_a; + ::std::vector pats_b; + ::std::vector nodes; + + for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) { - ::std::vector pats_a; - ::std::vector pats_b; - ::std::vector nodes; - - for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) - { - auto name_a = FMT("a" << idx); - auto name_b = FMT("b" << idx); - pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_a, ::AST::PatternBinding::Type::REF) ); - pats_b.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_b, ::AST::PatternBinding::Type::REF) ); - - nodes.push_back(this->make_compare_and_ret( sp, core_name, - NEWNODE(NamedValue, AST::Path(name_a)), - NEWNODE(NamedValue, AST::Path(name_b)) - )); - } + auto name_a = FMT("a" << idx); + auto name_b = FMT("b" << idx); + pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_a, ::AST::PatternBinding::Type::REF) ); + pats_b.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_b, ::AST::PatternBinding::Type::REF) ); - nodes.push_back( this->make_ret_equal(core_name) ); - pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_a)); - pat_b = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_b)); - code = NEWNODE(Block, mv$(nodes)); + nodes.push_back(this->make_compare_and_ret( sp, core_name, + NEWNODE(NamedValue, AST::Path(name_a)), + NEWNODE(NamedValue, AST::Path(name_b)) + )); } + + nodes.push_back( this->make_ret_equal(core_name) ); + pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_a)); + pat_b = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_b)); + code = NEWNODE(Block, mv$(nodes)); ), (Struct, ::std::vector< ::std::pair > pats_a; @@ -1219,14 +1165,7 @@ public: return AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(var_path)); ), (Tuple, - if( e.m_sub_types.size() == 0 ) - { - return AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(var_path)); - } - else - { - return AST::Pattern(AST::Pattern::TagNamedTuple(), var_path, AST::Pattern::TuplePat { {}, true, {} }); - } + return AST::Pattern(AST::Pattern::TagNamedTuple(), var_path, AST::Pattern::TuplePat { {}, true, {} }); ), (Struct, return AST::Pattern(AST::Pattern::TagStruct(), var_path, {}, false); @@ -1365,26 +1304,18 @@ public: pat_a = AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(base_path + v.m_name)); ), (Tuple, - if( e.m_sub_types.size() == 0 ) - { - code = NEWNODE(NamedValue, base_path + v.m_name); - pat_a = AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(base_path + v.m_name)); - } - else + ::std::vector pats_a; + ::std::vector nodes; + + for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) { - ::std::vector pats_a; - ::std::vector nodes; - - for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) - { - auto name_a = FMT("a" << idx); - pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_a, ::AST::PatternBinding::Type::REF) ); - nodes.push_back( this->clone_val_direct(core_name, NEWNODE(NamedValue, AST::Path(name_a))) ); - } - - pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_a)); - code = NEWNODE(CallPath, base_path + v.m_name, mv$(nodes)); + auto name_a = FMT("a" << idx); + pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_a, ::AST::PatternBinding::Type::REF) ); + nodes.push_back( this->clone_val_direct(core_name, NEWNODE(NamedValue, AST::Path(name_a))) ); } + + pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_a)); + code = NEWNODE(CallPath, base_path + v.m_name, mv$(nodes)); ), (Struct, ::std::vector< ::std::pair > pats_a; @@ -1622,27 +1553,19 @@ public: pat_a = AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(base_path + v.m_name)); ), (Tuple, - if( e.m_sub_types.size() == 0 ) - { - code = mv$(var_idx_hash); - pat_a = AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(base_path + v.m_name)); - } - else + ::std::vector pats_a; + ::std::vector nodes; + nodes.push_back( mv$(var_idx_hash) ); + + for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) { - ::std::vector pats_a; - ::std::vector nodes; - nodes.push_back( mv$(var_idx_hash) ); - - for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) - { - auto name_a = FMT("a" << idx); - pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_a, ::AST::PatternBinding::Type::REF) ); - nodes.push_back( this->hash_val_direct(core_name, NEWNODE(NamedValue, AST::Path(name_a))) ); - } - - pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_a)); - code = NEWNODE(Block, mv$(nodes)); + auto name_a = FMT("a" << idx); + pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_a, ::AST::PatternBinding::Type::REF) ); + nodes.push_back( this->hash_val_direct(core_name, NEWNODE(NamedValue, AST::Path(name_a))) ); } + + pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_a)); + code = NEWNODE(Block, mv$(nodes)); ), (Struct, ::std::vector< ::std::pair > pats_a; @@ -1818,49 +1741,33 @@ public: pat_a = AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(base_path + v.m_name)); ), (Tuple, - if( e.m_sub_types.size() == 0 ) + ::std::vector pats_a; + ::std::vector nodes; + + for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) { - code = NEWNODE(CallPath, this->get_trait_path_Encoder() + "emit_enum_variant", + auto name_a = FMT("a" << idx); + pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_a, ::AST::PatternBinding::Type::REF) ); + nodes.push_back( NEWNODE(CallPath, this->get_trait_path_Encoder() + "emit_enum_variant_arg", vec$( NEWNODE(NamedValue, AST::Path("s")), - NEWNODE(String, v.m_name), - NEWNODE(Integer, var_idx, CORETYPE_UINT), - NEWNODE(Integer, 0, CORETYPE_UINT), - this->enc_closure(sp, this->get_val_ok(core_name)) - ) - ); - pat_a = AST::Pattern(AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(base_path + v.m_name)); - } - else - { - ::std::vector pats_a; - ::std::vector nodes; - - for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) - { - auto name_a = FMT("a" << idx); - pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), name_a, ::AST::PatternBinding::Type::REF) ); - nodes.push_back( NEWNODE(CallPath, this->get_trait_path_Encoder() + "emit_enum_variant_arg", - vec$( - NEWNODE(NamedValue, AST::Path("s")), - NEWNODE(Integer, idx, CORETYPE_UINT), - this->enc_closure(sp, this->enc_val_direct(NEWNODE(NamedValue, AST::Path(name_a)))) - ) - ) ); - } - nodes.push_back( this->get_val_ok(core_name) ); - - code = NEWNODE(CallPath, this->get_trait_path_Encoder() + "emit_enum_variant", - vec$( - NEWNODE(NamedValue, AST::Path("s")), - NEWNODE(String, v.m_name), - NEWNODE(Integer, var_idx, CORETYPE_UINT), - NEWNODE(Integer, e.m_sub_types.size(), CORETYPE_UINT), - this->enc_closure(sp, NEWNODE(Block, mv$(nodes))) + NEWNODE(Integer, idx, CORETYPE_UINT), + this->enc_closure(sp, this->enc_val_direct(NEWNODE(NamedValue, AST::Path(name_a)))) ) - ); - pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_a)); + ) ); } + nodes.push_back( this->get_val_ok(core_name) ); + + code = NEWNODE(CallPath, this->get_trait_path_Encoder() + "emit_enum_variant", + vec$( + NEWNODE(NamedValue, AST::Path("s")), + NEWNODE(String, v.m_name), + NEWNODE(Integer, var_idx, CORETYPE_UINT), + NEWNODE(Integer, e.m_sub_types.size(), CORETYPE_UINT), + this->enc_closure(sp, NEWNODE(Block, mv$(nodes))) + ) + ); + pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), base_path + v.m_name, mv$(pats_a)); ), (Struct, ::std::vector< ::std::pair > pats_a; diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 1abd7771..b8445020 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -827,22 +827,24 @@ namespace { { TU_MATCH(::AST::EnumVariantData, (var.m_data), (e), (Value, - variants.push_back( ::std::make_pair(var.m_name, ::HIR::Enum::Variant::make_Value({ - LowerHIR_Expr(e.m_value), - ::HIR::Literal {} - }) ) ); - ), - (Tuple, - if( e.m_sub_types.size() == 0 ) { - variants.push_back( ::std::make_pair(var.m_name, ::HIR::Enum::Variant::make_Unit({})) ); + if( e.m_value.is_valid() ) + { + variants.push_back( ::std::make_pair(var.m_name, ::HIR::Enum::Variant::make_Value({ + LowerHIR_Expr(e.m_value), + ::HIR::Literal {} + }) ) ); } - else { - ::HIR::Enum::Variant::Data_Tuple types; - for(const auto& st : e.m_sub_types) - types.push_back( new_visent(true, LowerHIR_Type(st)) ); - variants.push_back( ::std::make_pair(var.m_name, ::HIR::Enum::Variant::make_Tuple(mv$(types))) ); + else + { + variants.push_back( ::std::make_pair(var.m_name, ::HIR::Enum::Variant::make_Unit({})) ); } ), + (Tuple, + ::HIR::Enum::Variant::Data_Tuple types; + for(const auto& st : e.m_sub_types) + types.push_back( new_visent(true, LowerHIR_Type(st)) ); + variants.push_back( ::std::make_pair(var.m_name, ::HIR::Enum::Variant::make_Tuple(mv$(types))) ); + ), (Struct, ::HIR::Enum::Variant::Data_Struct ents; for( const auto& ent : e.m_fields ) diff --git a/src/parse/root.cpp b/src/parse/root.cpp index eca14572..4da47cbe 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -824,7 +824,7 @@ AST::Enum Parse_EnumDef(TokenStream& lex, const AST::MetaItems& meta_items) } else { - variants.push_back( AST::EnumVariant(mv$(item_attrs), mv$(name), ::std::vector()) ); + variants.push_back( AST::EnumVariant(mv$(item_attrs), mv$(name), ::AST::Expr()) ); } if( tok.type() != TOK_COMMA ) -- cgit v1.2.3