diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/pattern.cpp | 11 | ||||
-rw-r--r-- | src/ast/pattern.hpp | 62 | ||||
-rw-r--r-- | src/dump_as_rust.cpp | 4 | ||||
-rw-r--r-- | src/expand/file_line.cpp | 2 | ||||
-rw-r--r-- | src/hir/expr.hpp | 10 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 12 | ||||
-rw-r--r-- | src/hir/pattern.cpp | 2 | ||||
-rw-r--r-- | src/hir/pattern.hpp | 2 | ||||
-rw-r--r-- | src/hir_conv/bind.cpp | 2 | ||||
-rw-r--r-- | src/hir_conv/constant_evaluation.cpp | 4 | ||||
-rw-r--r-- | src/hir_conv/expand_type.cpp | 2 | ||||
-rw-r--r-- | src/hir_conv/resolve_ufcs.cpp | 2 | ||||
-rw-r--r-- | src/hir_typeck/expr.cpp | 158 | ||||
-rw-r--r-- | src/main.cpp | 4 | ||||
-rw-r--r-- | src/parse/pattern.cpp | 33 | ||||
-rw-r--r-- | src/resolve/absolute.cpp | 14 |
16 files changed, 247 insertions, 77 deletions
diff --git a/src/ast/pattern.cpp b/src/ast/pattern.cpp index 9e17abcf..68d5d627 100644 --- a/src/ast/pattern.cpp +++ b/src/ast/pattern.cpp @@ -44,8 +44,9 @@ namespace AST { ::std::ostream& operator<<(::std::ostream& os, const Pattern& pat) { os << "Pattern("; - if(pat.m_binding != "") - os << pat.m_binding << " @ "; + if( pat.m_binding.is_valid() ) { + os << pat.m_binding.m_name << " @ "; + } TU_MATCH(Pattern::Data, (pat.m_data), (ent), (MaybeBind, os << ent.name << "?"; @@ -176,8 +177,6 @@ AST::Pattern AST::Pattern::clone() const AST::Pattern rv; rv.m_span = m_span; rv.m_binding = m_binding; - rv.m_binding_type = m_binding_type; - rv.m_binding_mut = m_binding_mut; struct H { static ::std::unique_ptr<Pattern> clone_sp(const ::std::unique_ptr<Pattern>& p) { @@ -245,7 +244,7 @@ AST::Pattern AST::Pattern::clone() const #define _D(VAR, ...) case Pattern::Data::TAG_##VAR: { m_data = Pattern::Data::make_##VAR({}); auto& ent = m_data.as_##VAR(); (void)&ent; __VA_ARGS__ } break; SERIALISE_TYPE(Pattern::, "Pattern", { - s.item(m_binding); + //s.item(m_binding); s % m_data.tag(); TU_MATCH(Pattern::Data, (m_data), (e), (Any, @@ -287,7 +286,7 @@ SERIALISE_TYPE(Pattern::, "Pattern", { ) ) },{ - s.item(m_binding); + //s.item(m_binding); Pattern::Data::Tag tag; s % tag; switch(tag) diff --git a/src/ast/pattern.hpp b/src/ast/pattern.hpp index 699ed466..fbdaa79e 100644 --- a/src/ast/pattern.hpp +++ b/src/ast/pattern.hpp @@ -13,15 +13,39 @@ using ::std::unique_ptr; using ::std::move; class MacroInvocation; +class PatternBinding +{ +public: + enum class Type { + MOVE, + REF, + MUTREF, + }; + ::std::string m_name; + Type m_type; + bool m_mutable; + unsigned int m_slot; + + PatternBinding(): + m_name(""), + m_type(Type::MOVE), + m_mutable(false), + m_slot( ~0u ) + {} + PatternBinding(::std::string name, Type ty, bool ismut): + m_name(name), + m_type(ty), + m_mutable(ismut), + m_slot( ~0u ) + {} + + bool is_valid() const { return m_name != ""; } +}; + class Pattern: public Serialisable { public: - enum BindType { - BIND_MOVE, - BIND_REF, - BIND_MUTREF, - }; TAGGED_UNION(Value, Invalid, (Invalid, struct {}), (Integer, struct { @@ -47,24 +71,20 @@ public: ); private: Span m_span; - ::std::string m_binding; - BindType m_binding_type; - bool m_binding_mut; + PatternBinding m_binding; Data m_data; public: virtual ~Pattern(); - Pattern(): - m_binding_type(BIND_MOVE) + Pattern() {} Pattern(Pattern&&) = default; Pattern& operator=(Pattern&&) = default; struct TagMaybeBind {}; Pattern(TagMaybeBind, ::std::string name): - m_binding(""), - m_binding_type(BIND_MOVE), + m_binding(), m_data( Data::make_MaybeBind({name}) ) {} @@ -80,10 +100,8 @@ public: {} struct TagBind {}; - Pattern(TagBind, ::std::string name): - m_binding(name), - m_binding_type( BIND_MOVE ), - m_binding_mut(false) + Pattern(TagBind, ::std::string name, PatternBinding::Type ty = PatternBinding::Type::MOVE, bool is_mut=false): + m_binding( PatternBinding(name, ty, is_mut) ) {} struct TagBox {}; @@ -129,10 +147,8 @@ public: {} // Mutators - void set_bind(::std::string name, BindType type, bool is_mut) { - m_binding = name; - m_binding_type = type; - m_binding_mut = is_mut; + void set_bind(::std::string name, PatternBinding::Type type, bool is_mut) { + m_binding = PatternBinding(name, type, is_mut); } @@ -142,10 +158,8 @@ public: Pattern clone() const; // Accessors - const ::std::string& binding() const { return m_binding; } - const BindType& binding_type() const { assert(m_binding != ""); return m_binding_type; } - bool binding_mut() const { assert(m_binding != ""); return m_binding_mut; } - + PatternBinding& binding() { return m_binding; } + const PatternBinding& binding() const { return m_binding; } Data& data() { return m_data; } const Data& data() const { return m_data; } Path& path() { return m_data.as_StructTuple().path; } diff --git a/src/dump_as_rust.cpp b/src/dump_as_rust.cpp index 536af263..abad2938 100644 --- a/src/dump_as_rust.cpp +++ b/src/dump_as_rust.cpp @@ -774,8 +774,8 @@ void RustPrinter::print_bounds(const AST::GenericParams& params) void RustPrinter::print_pattern(const AST::Pattern& p, bool is_refutable) { - if( p.binding() != "" ) { - m_os << p.binding(); + if( p.binding().is_valid() ) { + m_os << p.binding().m_name; // If binding is irrefutable, and would be binding against a wildcard, just emit the name if( !is_refutable && p.data().is_Any() ) { diff --git a/src/expand/file_line.cpp b/src/expand/file_line.cpp index 75ce5679..c3bfc2de 100644 --- a/src/expand/file_line.cpp +++ b/src/expand/file_line.cpp @@ -21,7 +21,7 @@ class CExpanderLine: ::std::unique_ptr<TokenStream> expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override { - return box$( TTStreamO(TokenTree(Token((uint64_t)sp.start_line, CORETYPE_I32))) ); + return box$( TTStreamO(TokenTree(Token((uint64_t)sp.start_line, CORETYPE_U32))) ); } }; diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp index 037a848c..72bc2070 100644 --- a/src/hir/expr.hpp +++ b/src/hir/expr.hpp @@ -238,11 +238,10 @@ struct ExprNode_Cast: public ExprNode { ::HIR::ExprNodeP m_value; - ::HIR::TypeRef m_type; ExprNode_Cast(::HIR::ExprNodeP value, ::HIR::TypeRef dst_type): - m_value( mv$(value) ), - m_type( mv$(dst_type) ) + ExprNode( mv$(dst_type) ), + m_value( mv$(value) ) {} NODE_METHODS(); @@ -251,11 +250,10 @@ struct ExprNode_Unsize: public ExprNode { ::HIR::ExprNodeP m_value; - ::HIR::TypeRef m_type; ExprNode_Unsize(::HIR::ExprNodeP value, ::HIR::TypeRef dst_type): - m_value( mv$(value) ), - m_type( mv$(dst_type) ) + ExprNode( mv$(dst_type) ), + m_value( mv$(value) ) {} NODE_METHODS(); diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index d2aba4a9..7d755d63 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -91,17 +91,17 @@ TRACE_FUNCTION_F("@" << pat.span().filename << ":" << pat.span().start_line << " pat = " << pat); ::HIR::PatternBinding binding; - if( pat.binding() != "" ) + if( pat.binding().is_valid() ) { ::HIR::PatternBinding::Type bt = ::HIR::PatternBinding::Type::Move; - switch(pat.binding_type()) + switch(pat.binding().m_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; + case ::AST::PatternBinding::Type::MOVE: bt = ::HIR::PatternBinding::Type::Move; break; + case ::AST::PatternBinding::Type::REF: bt = ::HIR::PatternBinding::Type::Ref; break; + case ::AST::PatternBinding::Type::MUTREF: bt = ::HIR::PatternBinding::Type::MutRef; break; } // TODO: Get bound slot - binding = ::HIR::PatternBinding(pat.binding_mut(), bt, pat.binding(), 0); + binding = ::HIR::PatternBinding(pat.binding().m_mutable, bt, pat.binding().m_name, pat.binding().m_slot); } TU_MATCH(::AST::Pattern::Data, (pat.data()), (e), (MaybeBind, diff --git a/src/hir/pattern.cpp b/src/hir/pattern.cpp index 64b132a3..ba688f1f 100644 --- a/src/hir/pattern.cpp +++ b/src/hir/pattern.cpp @@ -27,7 +27,7 @@ namespace HIR { case PatternBinding::Type::Ref: os << "ref "; break; case PatternBinding::Type::MutRef: os << "ref mut "; break; } - os << x.m_binding.m_name << " @ "; + os << x.m_binding.m_name << "/*"<<x.m_binding.m_slot<<"*/" << " @ "; } TU_MATCH(Pattern::Data, (x.m_data), (e), (Any, diff --git a/src/hir/pattern.hpp b/src/hir/pattern.hpp index 4eefa181..8b67b599 100644 --- a/src/hir/pattern.hpp +++ b/src/hir/pattern.hpp @@ -26,7 +26,7 @@ struct PatternBinding ::std::string m_name; unsigned int m_slot; - bool is_valid() const { return m_name == ""; } + bool is_valid() const { return m_name != ""; } PatternBinding(): m_mutable(false), diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp index c96fc348..6608f230 100644 --- a/src/hir_conv/bind.cpp +++ b/src/hir_conv/bind.cpp @@ -254,7 +254,7 @@ namespace { } void visit(::HIR::ExprNode_Cast& node) override { - upper_visitor.visit_type(node.m_type); + upper_visitor.visit_type(node.m_res_type); ::HIR::ExprVisitorDef::visit(node); } diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index e7b5f2bb..3ec3d4f2 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -569,12 +569,12 @@ namespace { } void visit(::HIR::ExprNode_Cast& node) override { ::HIR::ExprVisitorDef::visit(node); - m_exp.visit_type(node.m_type); + m_exp.visit_type(node.m_res_type); } // TODO: This shouldn't exist yet? void visit(::HIR::ExprNode_Unsize& node) override { ::HIR::ExprVisitorDef::visit(node); - m_exp.visit_type(node.m_type); + m_exp.visit_type(node.m_res_type); } void visit(::HIR::ExprNode_Closure& node) override { ::HIR::ExprVisitorDef::visit(node); diff --git a/src/hir_conv/expand_type.cpp b/src/hir_conv/expand_type.cpp index c29b7d71..f084da74 100644 --- a/src/hir_conv/expand_type.cpp +++ b/src/hir_conv/expand_type.cpp @@ -99,7 +99,7 @@ public: } void visit(::HIR::ExprNode_Cast& node) override { - upper_visitor.visit_type(node.m_type); + upper_visitor.visit_type(node.m_res_type); ::HIR::ExprVisitorDef::visit(node); } diff --git a/src/hir_conv/resolve_ufcs.cpp b/src/hir_conv/resolve_ufcs.cpp index be23be21..14b0233a 100644 --- a/src/hir_conv/resolve_ufcs.cpp +++ b/src/hir_conv/resolve_ufcs.cpp @@ -49,7 +49,7 @@ namespace { } void visit(::HIR::ExprNode_Cast& node) override { - upper_visitor.visit_type(node.m_type); + upper_visitor.visit_type(node.m_res_type); ::HIR::ExprVisitorDef::visit(node); } diff --git a/src/hir_typeck/expr.cpp b/src/hir_typeck/expr.cpp index eafa7078..7b22f9d3 100644 --- a/src/hir_typeck/expr.cpp +++ b/src/hir_typeck/expr.cpp @@ -136,10 +136,12 @@ namespace { struct IVar { + bool deleted; unsigned int alias; ::std::unique_ptr< ::HIR::TypeRef> type; IVar(): + deleted(false), alias(~0u), type(new ::HIR::TypeRef()) {} @@ -148,6 +150,7 @@ namespace { class TypecheckContext { + ::std::vector< ::HIR::TypeRef> m_locals; ::std::vector< IVar > m_ivars; bool m_has_changed; public: @@ -159,7 +162,7 @@ namespace { void dump() const { - DEBUG("TypecheckContext - " << m_ivars.size() << " ivars"); + DEBUG("TypecheckContext - " << m_ivars.size() << " ivars, " << m_locals.size() << " locals"); unsigned int i = 0; for(const auto& v : m_ivars) { if(v.is_alias()) { @@ -170,6 +173,11 @@ namespace { } i ++ ; } + i = 0; + for(const auto& v : m_locals) { + DEBUG("VAR " << i << " = " << v); + i ++; + } } bool take_changed() { @@ -184,8 +192,20 @@ namespace { /// Adds a local variable binding (type is mutable so it can be inferred if required) void add_local(unsigned int index, ::HIR::TypeRef type) { - // TODO: Add local of this name (with ivar) + if( m_locals.size() <= index ) + m_locals.resize(index+1); + m_locals[index] = mv$(type); + } + + const ::HIR::TypeRef& get_var_type(unsigned int index) + { + if( index >= m_locals.size() ) { + this->dump(); + BUG(Span(), "Local index out of range " << index << " >= " << m_locals.size()); + } + return m_locals.at(index); } + /// Add (and bind) all '_' types in `type` void add_ivars(::HIR::TypeRef& type) { @@ -255,6 +275,7 @@ namespace { void add_binding(::HIR::Pattern& pat, ::HIR::TypeRef& type) { + TRACE_FUNCTION_F("pat = " << pat << ", type = " << type); static Span _sp; const Span& sp = _sp; @@ -919,6 +940,17 @@ namespace { m_ivars.back().type->m_data.as_Infer().index = m_ivars.size() - 1; return m_ivars.size() - 1; } + void del_ivar(unsigned int index) + { + DEBUG("Deleting ivar " << index << " of " << m_ivars.size()); + if( index == m_ivars.size() - 1 ) { + m_ivars.pop_back(); + } + else { + assert(!"Can't delete an ivar after it's been used"); + m_ivars[index].deleted = true; + } + } ::HIR::TypeRef new_ivar_tr() { ::HIR::TypeRef rv; rv.m_data.as_Infer().index = this->new_ivar(); @@ -931,6 +963,7 @@ namespace { unsigned int count = 0; assert(index < m_ivars.size()); while( m_ivars.at(index).is_alias() ) { + assert( m_ivars.at(index).deleted == false ); index = m_ivars.at(index).alias; if( count >= m_ivars.size() ) { @@ -939,6 +972,7 @@ namespace { } count ++; } + assert( m_ivars.at(index).deleted == false ); return m_ivars.at(index); } ::HIR::TypeRef& get_type(::HIR::TypeRef& type) @@ -995,9 +1029,11 @@ namespace { public ::HIR::ExprVisitorDef { TypecheckContext& context; + const ::HIR::TypeRef& ret_type; public: - ExprVisitor_Enum(TypecheckContext& context): - context(context) + ExprVisitor_Enum(TypecheckContext& context, const ::HIR::TypeRef& ret_type): + context(context), + ret_type(ret_type) { } @@ -1007,13 +1043,18 @@ namespace { } void visit(::HIR::ExprNode_Block& node) override { + ::HIR::ExprVisitorDef::visit(node); if( node.m_nodes.size() > 0 ) { node.m_nodes.back()->m_res_type = node.m_res_type.clone(); } else { node.m_res_type = ::HIR::TypeRef::new_unit(); } + } + void visit(::HIR::ExprNode_Return& node) override + { ::HIR::ExprVisitorDef::visit(node); + this->context.apply_equality(node.span(), this->ret_type, node.m_value->m_res_type, &node.m_value); } void visit(::HIR::ExprNode_Let& node) override @@ -1040,6 +1081,30 @@ namespace { } } } + void visit(::HIR::ExprNode_Tuple& node) override + { + // - Remove the ivar created by the generic visitor + this->context.dump(); + this->context.del_ivar( node.m_res_type.m_data.as_Infer().index ); + + ::HIR::ExprVisitorDef::visit(node); + + ::std::vector< ::HIR::TypeRef> types; + for( const auto& sn : node.m_vals ) + types.push_back( sn->m_res_type.clone() ); + node.m_res_type = ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Tuple(mv$(types)) ); + } + void visit(::HIR::ExprNode_Closure& node) override + { + for(auto& a : node.m_args) { + this->context.add_ivars(a.second); + this->context.add_binding(a.first, a.second); + } + this->context.add_ivars(node.m_return); + node.m_code->m_res_type = node.m_return.clone(); + + ::HIR::ExprVisitorDef::visit(node); + } }; class ExprVisitor_Run: @@ -1052,6 +1117,7 @@ namespace { { } + // - Block: Ignore all return values except the last one (which is yeilded) void visit(::HIR::ExprNode_Block& node) override { TRACE_FUNCTION_F("{ }"); @@ -1064,6 +1130,7 @@ namespace { } ::HIR::ExprVisitorDef::visit(node); } + // - Let: Equates inner to outer void visit(::HIR::ExprNode_Let& node) override { TRACE_FUNCTION_F("let " << node.m_pattern << " : " << node.m_type); @@ -1074,6 +1141,7 @@ namespace { ::HIR::ExprVisitorDef::visit(node); } + // - If: Both branches have to agree void visit(::HIR::ExprNode_If& node) override { TRACE_FUNCTION_F("if ..."); @@ -1083,6 +1151,7 @@ namespace { } ::HIR::ExprVisitorDef::visit(node); } + // - Match: all branches match void visit(::HIR::ExprNode_Match& node) override { TRACE_FUNCTION_F("match ..."); @@ -1095,6 +1164,85 @@ namespace { } ::HIR::ExprVisitorDef::visit(node); } + // - Assign: both sides equal + void visit(::HIR::ExprNode_Assign& node) override + { + if( node.m_op == ::HIR::ExprNode_Assign::Op::None ) { + this->context.apply_equality(node.span(), + node.m_slot->m_res_type, node.m_value->m_res_type, + &node.m_value + ); + } + else { + // TODO: Look for overload + } + ::HIR::ExprVisitorDef::visit(node); + } + // - BinOp: Look for overload or primitive + void visit(::HIR::ExprNode_BinOp& node) override + { + ::HIR::ExprVisitorDef::visit(node); + } + // - UniOp: Look for overload or primitive + void visit(::HIR::ExprNode_UniOp& node) override + { + ::HIR::ExprVisitorDef::visit(node); + } + // - Cast: Nothing needs to happen + void visit(::HIR::ExprNode_Cast& node) override + { + ::HIR::ExprVisitorDef::visit(node); + } + // - Index: Look for implementation of the Index trait + void visit(::HIR::ExprNode_Index& node) override + { + ::HIR::ExprVisitorDef::visit(node); + } + // - Deref: Look for impl of Deref + void visit(::HIR::ExprNode_Deref& node) override + { + ::HIR::ExprVisitorDef::visit(node); + } + // - Call Path: Locate path and build return + void visit(::HIR::ExprNode_CallPath& node) override + { + ::HIR::ExprVisitorDef::visit(node); + } + // - Call Value: If type is known, locate impl of Fn/FnMut/FnOnce + void visit(::HIR::ExprNode_CallValue& node) override + { + ::HIR::ExprVisitorDef::visit(node); + } + // - Call Method: Locate method on type + void visit(::HIR::ExprNode_CallMethod& node) override + { + ::HIR::ExprVisitorDef::visit(node); + } + // - Field: Locate field on type + void visit(::HIR::ExprNode_Field& node) override + { + ::HIR::ExprVisitorDef::visit(node); + } + // - PathValue: Insert type from path + void visit(::HIR::ExprNode_PathValue& node) override + { + ::HIR::ExprVisitorDef::visit(node); + } + // - Variable: Bind to same ivar + void visit(::HIR::ExprNode_Variable& node) override + { + this->context.apply_equality(node.span(), + node.m_res_type, this->context.get_var_type(node.m_slot) + ); + } + // - Struct literal: Semi-known types + void visit(::HIR::ExprNode_StructLiteral& node) override + { + } + // - Tuple literal: + void visit(::HIR::ExprNode_Tuple& node) override + { + } // TODO: Other nodes (propagate/equalize types down) }; }; @@ -1109,7 +1257,7 @@ void Typecheck_Code(TypecheckContext context, const ::HIR::TypeRef& result_type, // 1. Enumerate inferrence variables and assign indexes to them { - ExprVisitor_Enum visitor { context }; + ExprVisitor_Enum visitor { context, result_type }; expr->visit( visitor ); } // - Apply equality between the node result and the expected type diff --git a/src/main.cpp b/src/main.cpp index f5dd63a3..90358661 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,9 +25,9 @@ int g_debug_indent_level = 0; bool debug_enabled()
{
- return true;
+ //return true;
//return g_cur_phase != "Parse";
- //return g_cur_phase != "Parse" && g_cur_phase != "Expand";
+ return g_cur_phase != "Parse" && g_cur_phase != "Expand";
//return g_cur_phase != "Parse" && g_cur_phase != "Expand" && g_cur_phase != "Resolve";
}
::std::ostream& debug_output(int indent, const char* function)
diff --git a/src/parse/pattern.cpp b/src/parse/pattern.cpp index 5d13cba6..424099ff 100644 --- a/src/parse/pattern.cpp +++ b/src/parse/pattern.cpp @@ -52,7 +52,7 @@ AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable) } bool expect_bind = false; - ::AST::Pattern::BindType bind_type = AST::Pattern::BIND_MOVE; + auto bind_type = AST::PatternBinding::Type::MOVE; bool is_mut = false; // 1. Mutablity + Reference if( tok.type() == TOK_RWORD_REF ) @@ -61,19 +61,19 @@ AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable) tok = lex.getToken(); if( tok.type() == TOK_RWORD_MUT ) { - bind_type = AST::Pattern::BIND_MUTREF; + bind_type = AST::PatternBinding::Type::MUTREF; GET_TOK(tok, lex); } else { - bind_type = AST::Pattern::BIND_REF; + bind_type = AST::PatternBinding::Type::REF; } } else if( tok.type() == TOK_RWORD_MUT ) { is_mut = true; expect_bind = true; - tok = lex.getToken(); + GET_TOK(tok, lex); } else { @@ -90,10 +90,11 @@ AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable) if( GET_TOK(tok, lex) != TOK_AT ) { PUTBACK(tok, lex); - return AST::Pattern(AST::Pattern::TagBind(), bind_name); + return AST::Pattern(AST::Pattern::TagBind(), bind_name, bind_type, is_mut); } - tok = lex.getToken(); + // '@' consumed, move on to next token + GET_TOK(tok, lex); } // Otherwise, handle MaybeBind else if( tok.type() == TOK_IDENT ) @@ -118,11 +119,15 @@ AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable) break; default: // Maybe bind // if the pattern can be refuted (i.e this could be an enum variant), return MaybeBind - if( is_refutable ) + if( is_refutable ) { + assert(bind_type == ::AST::PatternBinding::Type::MOVE); + assert(is_mut == false); return AST::Pattern(AST::Pattern::TagMaybeBind(), mv$(tok.str())); + } // Otherwise, it IS a binding - else - return AST::Pattern(AST::Pattern::TagBind(), mv$(tok.str())); + else { + return AST::Pattern(AST::Pattern::TagBind(), mv$(tok.str()), bind_type, is_mut); + } } } else @@ -131,9 +136,9 @@ AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable) } PUTBACK(tok, lex); - AST::Pattern pat = Parse_PatternReal(lex, is_refutable); + auto pat = Parse_PatternReal(lex, is_refutable); pat.set_bind(bind_name, bind_type, is_mut); - return ::std::move(pat); + return mv$(pat); } AST::Pattern Parse_PatternReal(TokenStream& lex, bool is_refutable) @@ -351,7 +356,7 @@ AST::Pattern Parse_PatternStruct(TokenStream& lex, AST::Path path, bool is_refut bool is_short_bind = false; bool is_box = false; - AST::Pattern::BindType bind_type = AST::Pattern::BIND_MOVE; + auto bind_type = AST::PatternBinding::Type::MOVE; bool is_mut = false; if( tok.type() == TOK_RWORD_BOX ) { is_box = true; @@ -362,11 +367,11 @@ AST::Pattern Parse_PatternStruct(TokenStream& lex, AST::Path path, bool is_refut is_short_bind = true; GET_TOK(tok, lex); if( tok.type() == TOK_RWORD_MUT ) { - bind_type = AST::Pattern::BIND_MUTREF; + bind_type = AST::PatternBinding::Type::MUTREF; GET_TOK(tok, lex); } else { - bind_type = AST::Pattern::BIND_REF; + bind_type = AST::PatternBinding::Type::REF; } } else if( tok.type() == TOK_RWORD_MUT ) { diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index 05fa7523..180cab0f 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -842,7 +842,10 @@ void Resolve_Absolute_Expr(Context& context, ::AST::Expr& expr) { if( expr.is_valid() ) { + auto ov = context.m_var_count; + context.m_var_count = 0; Resolve_Absolute_Expr(context, expr.node()); + context.m_var_count = ov; } } void Resolve_Absolute_Expr(Context& context, ::AST::ExprNode& node) @@ -1033,27 +1036,30 @@ void Resolve_Absolute_PatternValue(/*const*/ Context& context, const Span& sp, : void Resolve_Absolute_Pattern(Context& context, bool allow_refutable, ::AST::Pattern& pat) { TRACE_FUNCTION_F("allow_refutable = " << allow_refutable << ", pat = " << pat); - if( pat.binding() != "" ) { + if( pat.binding().is_valid() ) { if( !pat.data().is_Any() && ! allow_refutable ) TODO(pat.span(), "Resolve_Absolute_Pattern - Encountered bound destructuring pattern"); // TODO: Record the local variable number in the binding - context.push_var( pat.span(), pat.binding() ); + pat.binding().m_slot = context.push_var( pat.span(), pat.binding().m_name ); + DEBUG("- Binding #" << pat.binding().m_slot << " '" << pat.binding().m_name << "'"); } TU_MATCH( ::AST::Pattern::Data, (pat.data()), (e), (MaybeBind, - assert( pat.binding() == "" ); + assert( pat.binding().is_valid() == false ); if( allow_refutable ) { auto name = mv$( e.name ); // Attempt to resolve the name in the current namespace, and if it fails, it's a binding auto p = context.lookup_opt( name, Context::LookupMode::Constant ); if( p.is_valid() ) { pat = ::AST::Pattern(::AST::Pattern::TagValue(), ::AST::Pattern::Value::make_Named(mv$(p))); + DEBUG("MaybeBind resolved to " << pat); } else { pat = ::AST::Pattern(::AST::Pattern::TagBind(), mv$(name)); // TODO: Record the local variable number in the binding - context.push_var( pat.span(), pat.binding() ); + pat.binding().m_slot = context.push_var( pat.span(), pat.binding().m_name ); + DEBUG("- Binding #" << pat.binding().m_slot << " '" << pat.binding().m_name << "' (was MaybeBind)"); } } else { |