diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/pattern.hpp | 11 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 212 | ||||
-rw-r--r-- | src/hir/from_ast.hpp | 1 | ||||
-rw-r--r-- | src/hir/from_ast_expr.cpp | 6 | ||||
-rw-r--r-- | src/hir/pattern.hpp | 33 | ||||
-rw-r--r-- | src/parse/pattern.cpp | 2 |
6 files changed, 255 insertions, 10 deletions
diff --git a/src/ast/pattern.hpp b/src/ast/pattern.hpp index 05a1d3bb..a115eaf9 100644 --- a/src/ast/pattern.hpp +++ b/src/ast/pattern.hpp @@ -73,7 +73,9 @@ public: struct TagBind {}; Pattern(TagBind, ::std::string name): - m_binding(name) + m_binding(name), + m_binding_type( BIND_MOVE ), + m_binding_mut(false) {} struct TagBox {}; @@ -125,9 +127,12 @@ public: // Accessors const ::std::string& binding() const { return m_binding; } - Data& data() { return m_data; } + const BindType& binding_type() const { assert(m_binding != ""); return m_binding_type; } + bool binding_mut() const { assert(m_binding != ""); return m_binding_mut; } + + Data& data() { return m_data; } const Data& data() const { return m_data; } - Path& path() { return m_data.as_StructTuple().path; } + 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); diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 82b7e489..b857ad67 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -58,6 +58,218 @@ ::HIR::Pattern LowerHIR_Pattern(const ::AST::Pattern& pat) { + ::HIR::PatternBinding binding; + if( pat.binding() != "" ) + { + ::HIR::PatternBinding::Type bt; + switch(pat.binding_type()) + { + case ::AST::Pattern::BIND_MOVE: bt = ::HIR::PatternBinding::Type::Move; break; + case ::AST::Pattern::BIND_REF: bt = ::HIR::PatternBinding::Type::Ref; break; + case ::AST::Pattern::BIND_MUTREF: bt = ::HIR::PatternBinding::Type::MutRef; break; + } + // TODO: Get bound slot + binding = ::HIR::PatternBinding(pat.binding_mut(), bt, pat.binding(), 0); + } + TU_MATCH(::AST::Pattern::Data, (pat.data()), (e), + (MaybeBind, + BUG(Span(), "Encountered MaybeBind pattern"); + ), + (Macro, + BUG(Span(), "Encountered Macro pattern"); + ), + (Any, + return ::HIR::Pattern { + mv$(binding), + ::HIR::Pattern::Data::make_Any({}) + }; + ), + (Box, + return ::HIR::Pattern { + mv$(binding), + ::HIR::Pattern::Data::make_Box({ + box$(LowerHIR_Pattern( *e.sub )) + }) + }; + ), + (Ref, + return ::HIR::Pattern { + mv$(binding), + ::HIR::Pattern::Data::make_Ref({ + (e.mut ? ::HIR::BorrowType::Unique : ::HIR::BorrowType::Shared), + box$(LowerHIR_Pattern( *e.sub )) + }) + }; + ), + (Tuple, + ::std::vector< ::HIR::Pattern> sub_patterns; + for(const auto& sp : e.sub_patterns) + sub_patterns.push_back( LowerHIR_Pattern(sp) ); + + return ::HIR::Pattern { + mv$(binding), + ::HIR::Pattern::Data::make_Tuple({ + mv$(sub_patterns) + }) + }; + ), + + (StructTuple, + ::std::vector< ::HIR::Pattern> sub_patterns; + for(const auto& sp : e.sub_patterns) + sub_patterns.push_back( LowerHIR_Pattern(sp) ); + + TU_MATCH_DEF(::AST::PathBinding, (e.path.binding()), (pb), + ( + BUG(Span(), "Encountered StructTuple pattern not pointing to a enum variant or a struct"); + ), + (EnumVar, + return ::HIR::Pattern { + mv$(binding), + ::HIR::Pattern::Data::make_EnumTuple({ + LowerHIR_GenericPath(e.path), + mv$(sub_patterns) + }) + }; + ), + (Struct, + return ::HIR::Pattern { + mv$(binding), + ::HIR::Pattern::Data::make_StructTuple({ + LowerHIR_GenericPath(e.path), + mv$(sub_patterns) + }) + }; + ) + ) + ), + (Struct, + ::std::vector< ::std::pair< ::std::string, ::HIR::Pattern> > sub_patterns; + for(const auto& sp : e.sub_patterns) + sub_patterns.push_back( ::std::make_pair(sp.first, LowerHIR_Pattern(sp.second)) ); + + + TU_MATCH_DEF(::AST::PathBinding, (e.path.binding()), (pb), + ( + BUG(Span(), "Encountered Struct pattern not pointing to a enum variant or a struct"); + ), + (EnumVar, + return ::HIR::Pattern { + mv$(binding), + ::HIR::Pattern::Data::make_EnumStruct({ + LowerHIR_GenericPath(e.path), + mv$(sub_patterns) + }) + }; + ), + (Struct, + return ::HIR::Pattern { + mv$(binding), + ::HIR::Pattern::Data::make_Struct({ + LowerHIR_GenericPath(e.path), + mv$(sub_patterns) + }) + }; + ) + ) + ), + + (Value, + struct H { + static ::HIR::CoreType get_int_type(const ::eCoreType ct) { + switch(ct) + { + case CORETYPE_ANY: return ::HIR::CoreType::Str; + + case CORETYPE_I8 : return ::HIR::CoreType::I8; + case CORETYPE_U8 : return ::HIR::CoreType::U8; + case CORETYPE_I16: return ::HIR::CoreType::I16; + case CORETYPE_U16: return ::HIR::CoreType::U16; + case CORETYPE_I32: return ::HIR::CoreType::I32; + case CORETYPE_U32: return ::HIR::CoreType::U32; + case CORETYPE_I64: return ::HIR::CoreType::I64; + case CORETYPE_U64: return ::HIR::CoreType::U64; + + case CORETYPE_INT: return ::HIR::CoreType::Isize; + case CORETYPE_UINT: return ::HIR::CoreType::Usize; + default: + BUG(Span(), "Unknown type for integer literal"); + } + } + static ::HIR::Pattern::Value lowerhir_pattern_value(const ::AST::Pattern::Value& v) { + TU_MATCH(::AST::Pattern::Value, (v), (e), + (Invalid, + BUG(Span(), "Encountered Invalid value in Pattern"); + ), + (Integer, + return ::HIR::Pattern::Value::make_Integer({ + H::get_int_type(e.type), + e.value + }); + ), + (String, + return ::HIR::Pattern::Value::make_String(e); + ), + (Named, + return ::HIR::Pattern::Value::make_Named( LowerHIR_Path(e) ); + ) + ) + throw "BUGCHECK: Reached end of LowerHIR_Pattern::H::lowerhir_pattern_value"; + } + }; + if( e.end.is_Invalid() ) { + return ::HIR::Pattern { + mv$(binding), + ::HIR::Pattern::Data::make_Value({ + H::lowerhir_pattern_value(e.start) + }) + }; + } + else { + return ::HIR::Pattern { + mv$(binding), + ::HIR::Pattern::Data::make_Range({ + H::lowerhir_pattern_value(e.start), + H::lowerhir_pattern_value(e.end) + }) + }; + } + ), + (Slice, + ::std::vector< ::HIR::Pattern> leading; + for(const auto& sp : e.leading) + leading.push_back( LowerHIR_Pattern(sp) ); + + if( e.extra_bind != "" || e.trailing.size() > 0 ) { + ::std::vector< ::HIR::Pattern> trailing; + for(const auto& sp : e.trailing) + trailing.push_back( LowerHIR_Pattern(sp) ); + + auto extra_bind = (e.extra_bind == "_" || e.extra_bind == "") + ? ::HIR::PatternBinding() + // TODO: Get slot name for `extra_bind` + : ::HIR::PatternBinding(false, ::HIR::PatternBinding::Type::Ref, e.extra_bind, 0) + ; + + return ::HIR::Pattern { + mv$(binding), + ::HIR::Pattern::Data::make_SplitSlice({ + mv$(leading), + mv$(extra_bind), + mv$(trailing) + }) + }; + } + else { + return ::HIR::Pattern { + mv$(binding), + ::HIR::Pattern::Data::make_Slice({ + mv$(leading) + }) + }; + } + ) + ) throw ::std::runtime_error("TODO: LowerHIR_Pattern"); } diff --git a/src/hir/from_ast.hpp b/src/hir/from_ast.hpp index 0dde55b0..ef55d3a5 100644 --- a/src/hir/from_ast.hpp +++ b/src/hir/from_ast.hpp @@ -4,6 +4,7 @@ extern ::HIR::ExprPtr LowerHIR_ExprNode(const ::AST::ExprNode& e); extern ::HIR::Path LowerHIR_Path(const ::AST::Path& path); +extern ::HIR::GenericPath LowerHIR_GenericPath(const ::AST::Path& path); extern ::HIR::TypeRef LowerHIR_Type(const ::TypeRef& ty); extern ::HIR::Pattern LowerHIR_Pattern(const ::AST::Pattern& pat); diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp index 2ab1507a..4a801361 100644 --- a/src/hir/from_ast_expr.cpp +++ b/src/hir/from_ast_expr.cpp @@ -251,10 +251,10 @@ struct LowerHIR_ExprNode_Visitor: virtual void visit(::AST::ExprNode_Tuple& v) override { } virtual void visit(::AST::ExprNode_NamedValue& v) override { - if( v.m_path.is_trivial() ) { + TU_IFLET(::AST::Path::Class, v.m_path.m_class, Local, e, auto slot = v.m_path.binding().as_Variable().slot; - m_rv.reset( new ::HIR::ExprNode_Variable( v.m_path.nodes()[0].name(), slot ) ); - } + m_rv.reset( new ::HIR::ExprNode_Variable( e.name, slot ) ); + ) else { m_rv.reset( new ::HIR::ExprNode_PathValue( LowerHIR_Path(v.m_path) ) ); } diff --git a/src/hir/pattern.hpp b/src/hir/pattern.hpp index 2ff0a0d2..4d7668f6 100644 --- a/src/hir/pattern.hpp +++ b/src/hir/pattern.hpp @@ -12,10 +12,31 @@ namespace HIR { struct PatternBinding { + enum class Type { + Move, + Ref, + MutRef, + }; + + bool m_mutable; + Type m_type; ::std::string m_name; unsigned int m_slot; bool is_valid() const { return m_name == ""; } + + PatternBinding(): + m_mutable(false), + m_type(Type::Move), + m_name(""), + m_slot(0) + {} + PatternBinding(bool mut, Type type, ::std::string name, unsigned int slot): + m_mutable(mut), + m_type(type), + m_name( mv$(name) ), + m_slot( slot ) + {} }; struct Pattern @@ -30,16 +51,20 @@ struct Pattern ); TAGGED_UNION(Data, Any, + // Irrefutable / destructuring (Any, struct { } ), (Box, struct { ::std::unique_ptr<Pattern> sub; }), - (Ref, struct { bool mut; ::std::unique_ptr<Pattern> sub; } ), - (Value, struct { Value val; } ), - (Range, struct { Value start; Value end; } ), + (Ref, struct { ::HIR::BorrowType type; ::std::unique_ptr<Pattern> sub; } ), (Tuple, struct { ::std::vector<Pattern> sub_patterns; } ), (StructTuple, struct { GenericPath path; ::std::vector<Pattern> sub_patterns; } ), (Struct, struct { GenericPath path; ::std::vector< ::std::pair< ::std::string, Pattern> > sub_patterns; } ), + // Refutable + (Value, struct { Value val; } ), + (Range, struct { Value start; Value end; } ), + (EnumTuple, struct { GenericPath path; ::std::vector<Pattern> sub_patterns; } ), + (EnumStruct, struct { GenericPath path; ::std::vector< ::std::pair< ::std::string, Pattern> > sub_patterns; } ), (Slice, struct { - ::std::vector<Pattern> leading; + ::std::vector<Pattern> sub_patterns; } ), (SplitSlice, struct { ::std::vector<Pattern> leading; diff --git a/src/parse/pattern.cpp b/src/parse/pattern.cpp index bb697618..085df108 100644 --- a/src/parse/pattern.cpp +++ b/src/parse/pattern.cpp @@ -259,9 +259,11 @@ AST::Pattern Parse_PatternReal_Slice(TokenStream& lex, bool is_refutable) ::std::string binding_name; if( tok.type() == TOK_RWORD_REF && lex.lookahead(0) == TOK_IDENT && lex.lookahead(1) == TOK_DOUBLE_DOT ) { GET_TOK(tok, lex); + // TODO: Bind type binding_name = tok.str(); } else if( tok.type() == TOK_IDENT && lex.lookahead(0) == TOK_DOUBLE_DOT) { + // TODO: Bind type binding_name = tok.str(); } else if( tok.type() == TOK_UNDERSCORE && lex.lookahead(0) == TOK_DOUBLE_DOT) { |