summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast/pattern.hpp11
-rw-r--r--src/hir/from_ast.cpp212
-rw-r--r--src/hir/from_ast.hpp1
-rw-r--r--src/hir/from_ast_expr.cpp6
-rw-r--r--src/hir/pattern.hpp33
-rw-r--r--src/parse/pattern.cpp2
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) {