summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast/pattern.cpp94
-rw-r--r--src/ast/pattern.hpp30
-rw-r--r--src/convert/ast_iterate.cpp14
-rw-r--r--src/convert/resolve.cpp2
-rw-r--r--src/dump_as_rust.cpp12
-rw-r--r--src/expand/mod.cpp4
-rw-r--r--src/parse/pattern.cpp43
-rw-r--r--src/resolve/absolute.cpp26
8 files changed, 162 insertions, 63 deletions
diff --git a/src/ast/pattern.cpp b/src/ast/pattern.cpp
index 35df2a1e..cf72d345 100644
--- a/src/ast/pattern.cpp
+++ b/src/ast/pattern.cpp
@@ -11,6 +11,36 @@
namespace AST {
+::std::ostream& operator<<(::std::ostream& os, const Pattern::Value& val)
+{
+ TU_MATCH(Pattern::Value, (val), (e),
+ (Invalid,
+ os << "/*BAD PAT VAL*/";
+ ),
+ (Integer,
+ switch(e.type)
+ {
+ case CORETYPE_BOOL:
+ os << (e.value ? "true" : "false");
+ break;
+ case CORETYPE_F32:
+ case CORETYPE_F64:
+ BUG(Span(), "Hit F32/f64 in printing pattern literal");
+ break;
+ default:
+ os << e.value;
+ break;
+ }
+ ),
+ (String,
+ os << "\"" << e << "\"";
+ ),
+ (Named,
+ os << e;
+ )
+ )
+ return os;
+}
::std::ostream& operator<<(::std::ostream& os, const Pattern& pat)
{
os << "Pattern(" << pat.m_binding << " @ ";
@@ -31,9 +61,9 @@ namespace AST {
os << "&" << (ent.mut ? "mut " : "") << *ent.sub;
),
(Value,
- os << *ent.start;
- if( ent.end.get() )
- os << " ... " << *ent.end;
+ os << ent.start;
+ if( ! ent.end.is_Invalid() )
+ os << " ... " << ent.end;
),
(Tuple,
os << "(" << ent.sub_patterns << ")";
@@ -72,6 +102,56 @@ namespace AST {
os << ")";
return os;
}
+void operator%(Serialiser& s, Pattern::Value::Tag c) {
+ s << Pattern::Value::tag_to_str(c);
+}
+void operator%(::Deserialiser& s, Pattern::Value::Tag& c) {
+ ::std::string n;
+ s.item(n);
+ c = Pattern::Value::tag_from_str(n);
+}
+void operator%(::Serialiser& s, const Pattern::Value& v) {
+ s % v.tag();
+ TU_MATCH(Pattern::Value, (v), (e),
+ (Invalid, ),
+ (Integer,
+ s % e.type;
+ s.item( e.value );
+ ),
+ (String,
+ s.item( e );
+ ),
+ (Named,
+ s.item(e);
+ )
+ )
+}
+void operator%(::Deserialiser& s, Pattern::Value& v) {
+ Pattern::Value::Tag tag;
+ s % tag;
+ switch(tag)
+ {
+ case Pattern::Value::TAG_Invalid:
+ v = Pattern::Value::make_Invalid({});
+ break;
+ case Pattern::Value::TAG_Integer: {
+ enum eCoreType ct; s % ct;
+ uint64_t val; s.item( val );
+ v = Pattern::Value::make_Integer({ct, val});
+ break; }
+ case Pattern::Value::TAG_String: {
+ ::std::string val;
+ s.item( val );
+ v = Pattern::Value::make_String(val);
+ break; }
+ case Pattern::Value::TAG_Named: {
+ ::AST::Path val;
+ s.item( val );
+ v = Pattern::Value::make_Named(val);
+ break; }
+ }
+}
+
void operator%(Serialiser& s, Pattern::Data::Tag c) {
s << Pattern::Data::tag_to_str(c);
}
@@ -100,8 +180,8 @@ SERIALISE_TYPE(Pattern::, "Pattern", {
s << e.sub;
),
(Value,
- s << e.start;
- s << e.end;
+ s % e.start;
+ s % e.end;
),
(Tuple,
s << e.sub_patterns;
@@ -140,8 +220,8 @@ SERIALISE_TYPE(Pattern::, "Pattern", {
s.item( ent.sub );
)
_D(Value,
- s.item( ent.start );
- s.item( ent.end );
+ s % ent.start;
+ s % ent.end;
)
_D(Tuple,
s.item( ent.sub_patterns );
diff --git a/src/ast/pattern.hpp b/src/ast/pattern.hpp
index b8e86b70..77e1142c 100644
--- a/src/ast/pattern.hpp
+++ b/src/ast/pattern.hpp
@@ -13,8 +13,6 @@ using ::std::unique_ptr;
using ::std::move;
class MacroInvocation;
-class ExprNode;
-
class Pattern:
public Serialisable
{
@@ -24,13 +22,23 @@ public:
BIND_REF,
BIND_MUTREF,
};
+ TAGGED_UNION(Value, Invalid,
+ (Invalid, struct {}),
+ (Integer, struct {
+ enum eCoreType type;
+ uint64_t value; // Signed numbers are encoded as 2's complement
+ }),
+ (String, ::std::string),
+ (Named, Path)
+ );
+
TAGGED_UNION(Data, Any,
(MaybeBind, struct { } ),
(Macro, struct { unique_ptr<::AST::MacroInvocation> inv; } ),
(Any, struct { } ),
(Box, struct { unique_ptr<Pattern> sub; } ),
(Ref, struct { bool mut; unique_ptr<Pattern> sub; } ),
- (Value, struct { unique_ptr<ExprNode> start; unique_ptr<ExprNode> end; } ),
+ (Value, struct { Value start; Value end; } ),
(Tuple, struct { ::std::vector<Pattern> sub_patterns; } ),
(StructTuple, struct { Path path; ::std::vector<Pattern> sub_patterns; } ),
(Struct, struct { Path path; ::std::vector< ::std::pair< ::std::string, Pattern> > sub_patterns; } ),
@@ -74,8 +82,8 @@ public:
{}
struct TagValue {};
- Pattern(TagValue, unique_ptr<ExprNode> node, unique_ptr<ExprNode> node2 = 0):
- m_data( Data::make_Value({ ::std::move(node), ::std::move(node2) }) )
+ Pattern(TagValue, Value val, Value end = Value()):
+ m_data( Data::make_Value({ ::std::move(val), ::std::move(end) }) )
{}
@@ -114,21 +122,11 @@ public:
m_binding_mut = is_mut;
}
- ::std::unique_ptr<ExprNode> take_node() {
- assert(m_data.is_Value());
- return ::std::move(m_data.unwrap_Value().start);
- }
// Accessors
const ::std::string& binding() const { return m_binding; }
Data& data() { return m_data; }
const Data& data() const { return m_data; }
- ExprNode& node() {
- return *m_data.as_Value().start;
- }
- const ExprNode& node() const {
- return *m_data.as_Value().start;
- }
Path& path() { return m_data.as_StructTuple().path; }
const Path& path() const { return m_data.as_StructTuple().path; }
@@ -142,6 +140,8 @@ public:
}
};
+::std::ostream& operator<<(::std::ostream& os, const Pattern::Value& val);
+
};
#endif
diff --git a/src/convert/ast_iterate.cpp b/src/convert/ast_iterate.cpp
index 5909d689..7e70f1f0 100644
--- a/src/convert/ast_iterate.cpp
+++ b/src/convert/ast_iterate.cpp
@@ -148,12 +148,14 @@ void CASTIterator::handle_pattern(AST::Pattern& pat, const TypeRef& type_hint)
(MaybeBind,
throw ::std::runtime_error("Calling CASTIterator::handle_pattern on MAYBE_BIND, not valid");
),
- (Value, {
- auto& v = pat.data().as_Value();
- handle_expr( *v.start );
- if( v.end.get() )
- handle_expr( *v.end );
- }),
+ (Value,
+ TU_IFLET(AST::Pattern::Value, v.start, Named, e,
+ handle_path(e, CASTIterator::MODE_TYPE);
+ )
+ TU_IFLET(AST::Pattern::Value, v.end, Named, e,
+ handle_path(e, CASTIterator::MODE_TYPE);
+ )
+ ),
(Tuple, {
auto& v = pat.data().as_Tuple();
// Tuple is handled by subpattern code
diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp
index ebfe2998..a240c6fc 100644
--- a/src/convert/resolve.cpp
+++ b/src/convert/resolve.cpp
@@ -1652,7 +1652,7 @@ void CPathResolver::handle_pattern(AST::Pattern& pat, const TypeRef& type_hint)
// It's a constant (enum variant usually)
pat = AST::Pattern(
AST::Pattern::TagValue(),
- ::std::unique_ptr<AST::ExprNode>( new AST::ExprNode_NamedValue( ::std::move(newpath) ) )
+ AST::Pattern::Value::make_Named( mv$(newpath) )
);
}
}
diff --git a/src/dump_as_rust.cpp b/src/dump_as_rust.cpp
index 357795c5..361bd245 100644
--- a/src/dump_as_rust.cpp
+++ b/src/dump_as_rust.cpp
@@ -801,14 +801,12 @@ void RustPrinter::print_pattern(const AST::Pattern& p, bool is_refutable)
m_os << "& ";
print_pattern(*v.sub, is_refutable);
}),
- (Value, {
- auto& v = p.data().as_Value();
- v.start->visit(*this);
- if( v.end.get() ) {
- m_os << " ... ";
- v.end->visit(*this);
+ (Value,
+ m_os << v.start;
+ if( ! v.end.is_Invalid() ) {
+ m_os << " ... " << v.end;
}
- }),
+ ),
(StructTuple, {
const auto& v = p.data().as_StructTuple();
m_os << v.path << "(";
diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp
index bbe4db85..2f4fe0be 100644
--- a/src/expand/mod.cpp
+++ b/src/expand/mod.cpp
@@ -150,8 +150,8 @@ void Expand_Pattern(bool is_early, ::AST::Crate& crate, LList<const AST::Module*
Expand_Pattern(is_early, crate, modstack, mod, *e.sub);
),
(Value,
- Expand_Expr(is_early, crate, modstack, e.start);
- Expand_Expr(is_early, crate, modstack, e.end);
+ //Expand_Expr(is_early, crate, modstack, e.start);
+ //Expand_Expr(is_early, crate, modstack, e.end);
),
(Tuple,
for(auto& sp : e.sub_patterns)
diff --git a/src/parse/pattern.cpp b/src/parse/pattern.cpp
index dcbc8c5d..bb697618 100644
--- a/src/parse/pattern.cpp
+++ b/src/parse/pattern.cpp
@@ -140,13 +140,15 @@ AST::Pattern Parse_PatternReal(TokenStream& lex, bool is_refutable)
{
if( !ret.data().is_Value() )
throw ParseError::Generic(lex, "Using '...' with a non-value on left");
- auto leftval = ret.take_node();
+ auto& ret_v = ret.data().as_Value();
+
auto right_pat = Parse_PatternReal1(lex, is_refutable);
if( !right_pat.data().is_Value() )
throw ParseError::Generic(lex, "Using '...' with a non-value on right");
- auto rightval = right_pat.take_node();
+ auto rightval = mv$( right_pat.data().as_Value().start );
+ ret_v.end = mv$(rightval);
- return AST::Pattern(AST::Pattern::TagValue(), ::std::move(leftval), ::std::move(rightval));
+ return ret;
}
else
{
@@ -193,31 +195,32 @@ AST::Pattern Parse_PatternReal1(TokenStream& lex, bool is_refutable)
auto dt = tok.datatype();
if(dt == CORETYPE_ANY)
dt = CORETYPE_I32;
- return AST::Pattern( AST::Pattern::TagValue(), NEWNODE(AST::ExprNode_Integer, -tok.intval(), dt) );
- }
- else if( tok.type() == TOK_FLOAT )
- {
- auto dt = tok.datatype();
- if(dt == CORETYPE_ANY)
- dt = CORETYPE_F32;
- return AST::Pattern( AST::Pattern::TagValue(), NEWNODE(AST::ExprNode_Float, -tok.floatval(), dt) );
+ return AST::Pattern( AST::Pattern::TagValue(), AST::Pattern::Value::make_Integer({dt, -tok.intval()}) );
}
+ //else if( tok.type() == TOK_FLOAT )
+ //{
+ // auto dt = tok.datatype();
+ // if(dt == CORETYPE_ANY)
+ // dt = CORETYPE_F32;
+ // return AST::Pattern( AST::Pattern::TagValue(), AST::Pattern::Value::make_Integer({dt, reinterpret_cast<uint64_t>(-tok.floatval()), dt}) );
+ //}
else
{
throw ParseError::Unexpected(lex, tok, {TOK_INTEGER, TOK_FLOAT});
}
- case TOK_FLOAT:
- return AST::Pattern( AST::Pattern::TagValue(), NEWNODE(AST::ExprNode_Float, tok.floatval(), tok.datatype()) );
+ //case TOK_FLOAT:
+ // return AST::Pattern( AST::Pattern::TagValue(), AST::Pattern::Value::make_Integer({tok.datatype(), reinterpret_cast<uint64_t>(tok.floatval())}) );
case TOK_INTEGER:
- return AST::Pattern( AST::Pattern::TagValue(), NEWNODE(AST::ExprNode_Integer, tok.intval(), tok.datatype()) );
+ return AST::Pattern( AST::Pattern::TagValue(), AST::Pattern::Value::make_Integer({tok.datatype(), tok.intval()}) );
case TOK_RWORD_TRUE:
- return AST::Pattern( AST::Pattern::TagValue(), NEWNODE( AST::ExprNode_Bool, true ) );
+ return AST::Pattern( AST::Pattern::TagValue(), AST::Pattern::Value::make_Integer({CORETYPE_BOOL, 1}) );
case TOK_RWORD_FALSE:
- return AST::Pattern( AST::Pattern::TagValue(), NEWNODE( AST::ExprNode_Bool, false ) );
+ return AST::Pattern( AST::Pattern::TagValue(), AST::Pattern::Value::make_Integer({CORETYPE_BOOL, 0}) );
case TOK_STRING:
- return AST::Pattern( AST::Pattern::TagValue(), NEWNODE(AST::ExprNode_String, tok.str()) );
+ return AST::Pattern( AST::Pattern::TagValue(), AST::Pattern::Value::make_String( mv$(tok.str()) ) );
case TOK_BYTESTRING:
- return AST::Pattern( AST::Pattern::TagValue(), NEWNODE(AST::ExprNode_String, tok.str()) );
+ // TODO: Differentiate byte and UTF-8 strings
+ return AST::Pattern( AST::Pattern::TagValue(), AST::Pattern::Value::make_String( mv$(tok.str()) ) );
case TOK_PAREN_OPEN:
return AST::Pattern( AST::Pattern::TagTuple(), Parse_PatternList(lex, is_refutable) );
case TOK_SQUARE_OPEN:
@@ -233,12 +236,12 @@ AST::Pattern Parse_PatternReal_Path(TokenStream& lex, AST::Path path, bool is_re
switch( GET_TOK(tok, lex) )
{
case TOK_PAREN_OPEN:
- return AST::Pattern(AST::Pattern::TagEnumVariant(), ::std::move(path), Parse_PatternList(lex, is_refutable));
+ return AST::Pattern( AST::Pattern::TagEnumVariant(), ::std::move(path), Parse_PatternList(lex, is_refutable) );
case TOK_BRACE_OPEN:
return Parse_PatternStruct(lex, ::std::move(path), is_refutable);
default:
lex.putback(tok);
- return AST::Pattern(AST::Pattern::TagValue(), NEWNODE(AST::ExprNode_NamedValue, ::std::move(path)));
+ return AST::Pattern( AST::Pattern::TagValue(), AST::Pattern::Value::make_Named(mv$(path)) );
}
}
diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp
index de555c37..7d521686 100644
--- a/src/resolve/absolute.cpp
+++ b/src/resolve/absolute.cpp
@@ -351,6 +351,19 @@ void Resolve_Absolute_Generic(const Context& context, ::AST::GenericParams& para
}
}
+// Locals shouldn't be possible, as they'd end up as MaybeBind. Will assert the path class.
+void Resolve_Absolute_PatternValue(const Context& context, ::AST::Pattern::Value& val)
+{
+ TU_MATCH(::AST::Pattern::Value, (val), (e),
+ (Invalid, ),
+ (Integer, ),
+ (String, ),
+ (Named,
+ assert( ! e.is_trivial() );
+ Resolve_Absolute_Path(context, Span(), true, e);
+ )
+ )
+}
void Resolve_Absolute_Pattern(Context& context, bool allow_refutable, ::AST::Pattern& pat)
{
if( pat.binding() != "" ) {
@@ -361,7 +374,12 @@ void Resolve_Absolute_Pattern(Context& context, bool allow_refutable, ::AST::Pa
TU_MATCH( ::AST::Pattern::Data, (pat.data()), (e),
(MaybeBind,
- BUG(Span(), "Resolve_Absolute_Pattern - Encountered MaybeBind");
+ if( allow_refutable ) {
+ TODO(Span(), "Resolve_Absolute_Pattern - Encountered MaybeBind in refutable context");
+ }
+ else {
+ TODO(Span(), "Resolve_Absolute_Pattern - Encountered MaybeBind in irrefutable context - replace with binding");
+ }
),
(Macro,
BUG(Span(), "Resolve_Absolute_Pattern - Encountered Macro");
@@ -378,10 +396,8 @@ void Resolve_Absolute_Pattern(Context& context, bool allow_refutable, ::AST::Pa
(Value,
if( ! allow_refutable )
BUG(Span(), "Resolve_Absolute_Pattern - Enountered refutable pattern where only irrefutable allowed");
- // TODO: Value patterns should be resolved with a different context (disallowing locals)
- Resolve_Absolute_Expr(context, *e.start);
- if( e.end )
- Resolve_Absolute_Expr(context, *e.end);
+ Resolve_Absolute_PatternValue(context, e.start);
+ Resolve_Absolute_PatternValue(context, e.end);
),
(Tuple,
for(auto& sp : e.sub_patterns)