summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ast/pattern.cpp11
-rw-r--r--src/ast/pattern.hpp62
-rw-r--r--src/dump_as_rust.cpp4
-rw-r--r--src/expand/file_line.cpp2
-rw-r--r--src/hir/expr.hpp10
-rw-r--r--src/hir/from_ast.cpp12
-rw-r--r--src/hir/pattern.cpp2
-rw-r--r--src/hir/pattern.hpp2
-rw-r--r--src/hir_conv/bind.cpp2
-rw-r--r--src/hir_conv/constant_evaluation.cpp4
-rw-r--r--src/hir_conv/expand_type.cpp2
-rw-r--r--src/hir_conv/resolve_ufcs.cpp2
-rw-r--r--src/hir_typeck/expr.cpp158
-rw-r--r--src/main.cpp4
-rw-r--r--src/parse/pattern.cpp33
-rw-r--r--src/resolve/absolute.cpp14
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 {