diff options
author | John Hodge <tpg@mutabah.net> | 2015-03-08 23:58:56 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2015-03-08 23:58:56 +0800 |
commit | b082aab8d49e3b5a2e1eeee97fd9330f782b7381 (patch) | |
tree | 5eb644019f9b1eca222258453bcc54ff266e40fe | |
parent | 54ab187e82a41f7221660c7b1dc7777ce8a17228 (diff) | |
download | mrust-b082aab8d49e3b5a2e1eeee97fd9330f782b7381.tar.gz |
Cleanup to pattern handling
-rw-r--r-- | src/ast/expr.cpp | 4 | ||||
-rw-r--r-- | src/ast/expr.hpp | 2 | ||||
-rw-r--r-- | src/ast/pattern.hpp | 9 | ||||
-rw-r--r-- | src/convert/resolve.cpp | 2 | ||||
-rw-r--r-- | src/dump_as_rust.cpp | 2 | ||||
-rw-r--r-- | src/parse/eTokenType.enum.h | 2 | ||||
-rw-r--r-- | src/parse/expr.cpp | 99 | ||||
-rw-r--r-- | src/parse/lex.cpp | 1 | ||||
-rw-r--r-- | src/parse/root.cpp | 2 |
9 files changed, 75 insertions, 48 deletions
diff --git a/src/ast/expr.cpp b/src/ast/expr.cpp index 8c239092..e29b3068 100644 --- a/src/ast/expr.cpp +++ b/src/ast/expr.cpp @@ -236,6 +236,8 @@ void operator%(::Serialiser& s, const ExprNode_BinOp::Type t) { #define _(v) case ExprNode_BinOp::v: s << #v; return _(CMPEQU); _(CMPNEQU); + _(BOOLAND); + _(BOOLOR); _(BITAND); _(BITOR); _(BITXOR); @@ -267,6 +269,8 @@ NODE(ExprNode_BinOp, { { case CMPEQU: os << "=="; break; case CMPNEQU: os << "!="; break; + case BOOLAND: os << "&&"; break; + case BOOLOR: os << "||"; break; case BITAND: os << "&"; break; case BITOR: os << "|"; break; case BITXOR: os << "^"; break; diff --git a/src/ast/expr.hpp b/src/ast/expr.hpp index 9ae6540e..b9ab5d05 100644 --- a/src/ast/expr.hpp +++ b/src/ast/expr.hpp @@ -320,6 +320,8 @@ struct ExprNode_BinOp: CMPLTE, CMPGT, CMPGTE, + BOOLAND, + BOOLOR, BITAND, BITOR, diff --git a/src/ast/pattern.hpp b/src/ast/pattern.hpp index 82db2b7c..deda0b97 100644 --- a/src/ast/pattern.hpp +++ b/src/ast/pattern.hpp @@ -20,6 +20,7 @@ public: enum BindType { MAYBE_BIND, ANY, + REF, VALUE, TUPLE, TUPLE_STRUCT, @@ -83,6 +84,12 @@ public: m_class(VALUE), m_node( ::std::move(node) ) {} + + struct TagReference {}; + Pattern(TagReference, Pattern sub_pattern): + m_class(REF), + m_sub_patterns( { ::std::move(sub_pattern) } ) + {} struct TagTuple {}; Pattern(TagTuple, ::std::vector<Pattern> sub_patterns): @@ -98,7 +105,7 @@ public: {} // Mutators - void set_bind(::std::string name) { + void set_bind(::std::string name, bool is_ref, bool is_mut) { m_binding = name; } diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp index cba7d375..9a1033c9 100644 --- a/src/convert/resolve.cpp +++ b/src/convert/resolve.cpp @@ -354,7 +354,7 @@ void CPathResolver::handle_pattern(AST::Pattern& pat, const TypeRef& type_hint) {
// It's a name binding (desugar to 'name @ _')
pat = AST::Pattern();
- pat.set_bind(name);
+ pat.set_bind(name, false, false);
}
else
{
diff --git a/src/dump_as_rust.cpp b/src/dump_as_rust.cpp index 1a7737ba..ae6a6337 100644 --- a/src/dump_as_rust.cpp +++ b/src/dump_as_rust.cpp @@ -278,6 +278,8 @@ public: case AST::ExprNode_BinOp::CMPLTE: m_os << "<="; break; case AST::ExprNode_BinOp::CMPGT: m_os << ">"; break; case AST::ExprNode_BinOp::CMPGTE: m_os << ">="; break; + case AST::ExprNode_BinOp::BOOLAND:m_os << "&&"; break; + case AST::ExprNode_BinOp::BOOLOR: m_os << "||"; break; case AST::ExprNode_BinOp::BITAND: m_os << "&"; break; case AST::ExprNode_BinOp::BITOR: m_os << "|"; break; case AST::ExprNode_BinOp::BITXOR: m_os << "^"; break; diff --git a/src/parse/eTokenType.enum.h b/src/parse/eTokenType.enum.h index d3f294b5..4209c94a 100644 --- a/src/parse/eTokenType.enum.h +++ b/src/parse/eTokenType.enum.h @@ -17,6 +17,8 @@ _(TOK_STRING) _(TOK_CATTR_OPEN) _(TOK_ATTR_OPEN) +_(TOK_UNDERSCORE) + // Symbols _(TOK_PAREN_OPEN) _(TOK_PAREN_CLOSE) _(TOK_BRACE_OPEN) _(TOK_BRACE_CLOSE) diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index c7cceee0..3d812fb8 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -30,6 +30,10 @@ AST::Expr Parse_ExprBlock(TokenStream& lex) ::std::vector<AST::Pattern> Parse_PatternList(TokenStream& lex);
+AST::Pattern Parse_PatternReal_Path(TokenStream& lex, AST::Path path);
+AST::Pattern Parse_PatternReal(TokenStream& lex);
+
+
/// Parse a pattern
///
/// Examples:
@@ -73,12 +77,14 @@ AST::Pattern Parse_Pattern(TokenStream& lex) bind_name = tok.str();
if( GET_TOK(tok, lex) != TOK_AT )
{
+ // No '@', it's a name binding
lex.putback(tok);
return AST::Pattern(AST::Pattern::TagBind(), bind_name);
}
+
+ tok = lex.getToken();
}
- // TODO: If the next token is an ident, parse as a path
if( !expect_bind && tok.type() == TOK_IDENT )
{
lex.putback(tok);
@@ -95,9 +101,9 @@ AST::Pattern Parse_Pattern(TokenStream& lex) break;
// - Else, if the next token is a '(' or '{', treat as a struct/enum
case TOK_BRACE_OPEN:
- throw ParseError::Todo("Parse_Pattern - Structure patterns");
case TOK_PAREN_OPEN:
- return AST::Pattern(AST::Pattern::TagEnumVariant(), ::std::move(path), Parse_PatternList(lex));
+ lex.putback(tok);
+ return Parse_PatternReal_Path(lex, path);
// - Else, treat as a MaybeBind
default:
lex.putback(tok);
@@ -106,62 +112,62 @@ AST::Pattern Parse_Pattern(TokenStream& lex) }
else
{
- switch(GET_TOK(tok, lex))
- {
- case TOK_BRACE_OPEN:
- throw ParseError::Todo("Parse_Pattern - Structure patterns");
- case TOK_PAREN_OPEN:
- return AST::Pattern(AST::Pattern::TagEnumVariant(), ::std::move(path), Parse_PatternList(lex));
- default:
- lex.putback(tok);
- return AST::Pattern(AST::Pattern::TagMaybeBind(), path[0].name());
- }
+ // non-trivial path, has to be a pattern (not a bind)
+ return Parse_PatternReal_Path(lex, path);
}
}
+ lex.putback(tok);
+ AST::Pattern pat = Parse_PatternReal(lex);
+ pat.set_bind(bind_name, is_ref, is_mut);
+ return pat;
+}
+AST::Pattern Parse_PatternReal(TokenStream& lex)
+{
+ Token tok;
+ AST::Path path;
- switch( tok.type() )
+ switch( GET_TOK(tok, lex) )
{
+ case TOK_UNDERSCORE:
+ return AST::Pattern( );
+ case TOK_AMP:
+ return AST::Pattern( AST::Pattern::TagReference(), Parse_PatternReal(lex) );
case TOK_IDENT:
lex.putback(tok);
- path = Parse_Path(lex, false, PATH_GENERIC_EXPR);
- if( 0 )
+ return Parse_PatternReal_Path( lex, Parse_Path(lex, false, PATH_GENERIC_EXPR) );
case TOK_DOUBLE_COLON:
// 2. Paths are enum/struct names
- {
- path = Parse_Path(lex, true, PATH_GENERIC_EXPR);
- }
- switch( GET_TOK(tok, lex) )
- {
- case TOK_PAREN_OPEN: {
- // A list of internal patterns
- ::std::vector<AST::Pattern> child_pats;
- do {
- child_pats.push_back( Parse_Pattern(lex) );
- } while( GET_TOK(tok, lex) == TOK_COMMA );
- CHECK_TOK(tok, TOK_PAREN_CLOSE);
- return AST::Pattern(AST::Pattern::TagEnumVariant(), ::std::move(path), ::std::move(child_pats));
- }
- default:
- lex.putback(tok);
- return AST::Pattern(AST::Pattern::TagValue(), NEWNODE(AST::ExprNode_NamedValue, ::std::move(path)));
- }
- break;
+ return Parse_PatternReal_Path( lex, Parse_Path(lex, true, PATH_GENERIC_EXPR) );
case TOK_INTEGER:
return AST::Pattern( AST::Pattern::TagValue(), NEWNODE(AST::ExprNode_Integer, tok.intval(), tok.datatype()) );
case TOK_STRING:
throw ParseError::Todo("string patterns");
case TOK_PAREN_OPEN:
- // This may also have to handle range expressions? (and other complexities)
- throw ParseError::Todo("tuple patterns");
+ return AST::Pattern(AST::Pattern::TagTuple(), Parse_PatternList(lex));
+ case TOK_SQUARE_OPEN:
+ throw ParseError::Todo("array patterns");
default:
throw ParseError::Unexpected(lex, tok);
}
- throw ParseError::BugCheck("Parse_Pattern should early return");
+}
+AST::Pattern Parse_PatternReal_Path(TokenStream& lex, AST::Path path)
+{
+ Token tok;
+
+ switch( GET_TOK(tok, lex) )
+ {
+ case TOK_PAREN_OPEN:
+ return AST::Pattern(AST::Pattern::TagEnumVariant(), ::std::move(path), Parse_PatternList(lex));
+ default:
+ lex.putback(tok);
+ return AST::Pattern(AST::Pattern::TagValue(), NEWNODE(AST::ExprNode_NamedValue, ::std::move(path)));
+ }
}
::std::vector<AST::Pattern> Parse_PatternList(TokenStream& lex)
{
+ TRACE_FUNCTION;
Token tok;
::std::vector<AST::Pattern> child_pats;
do {
@@ -237,18 +243,14 @@ ExprNodeP Parse_Stmt(TokenStream& lex, bool& opt_semicolon) return NEWNODE( AST::ExprNode_Return, Parse_Expr1(lex) );
case TOK_RWORD_LOOP:
throw ParseError::Todo("loop");
- break;
case TOK_RWORD_FOR:
throw ParseError::Todo("for");
- break;
case TOK_RWORD_WHILE:
throw ParseError::Todo("while");
- break;
default:
lex.putback(tok);
return Parse_Expr0(lex);
}
-
}
::std::vector<ExprNodeP> Parse_ParenList(TokenStream& lex)
@@ -351,7 +353,12 @@ ExprNodeP Parse_Expr_Match(TokenStream& lex) ExprNodeP val = Parse_Stmt(lex, opt_semicolon);
arms.push_back( ::std::make_pair( ::std::move(pat), ::std::move(val) ) );
- } while( GET_TOK(tok, lex) == TOK_COMMA );
+
+ if( GET_TOK(tok, lex) == TOK_COMMA )
+ continue;
+ lex.putback(tok);
+
+ } while( 1 );
CHECK_TOK(tok, TOK_BRACE_CLOSE);
return NEWNODE( AST::ExprNode_Match, ::std::move(switch_val), ::std::move(arms) );
@@ -405,12 +412,14 @@ ExprNodeP cur(TokenStream& lex) \ // 1: Bool OR
LEFTASSOC(Parse_Expr1, Parse_Expr2,
case TOK_DOUBLE_PIPE:
- throw ParseError::Todo("expr - boolean OR");
+ rv = NEWNODE( AST::ExprNode_BinOp, AST::ExprNode_BinOp::BOOLOR, ::std::move(rv), next(lex));
+ break;
)
// 2: Bool AND
LEFTASSOC(Parse_Expr2, Parse_Expr3,
case TOK_DOUBLE_AMP:
- throw ParseError::Todo("expr - boolean AND");
+ rv = NEWNODE( AST::ExprNode_BinOp, AST::ExprNode_BinOp::BOOLAND, ::std::move(rv), next(lex));
+ break;
)
// 3: (In)Equality
LEFTASSOC(Parse_Expr3, Parse_Expr4,
diff --git a/src/parse/lex.cpp b/src/parse/lex.cpp index a81086ce..678da4d0 100644 --- a/src/parse/lex.cpp +++ b/src/parse/lex.cpp @@ -100,6 +100,7 @@ static const struct { const char* chars; signed int type; } RWORDS[] = { + TOKENT("_", TOK_UNDERSCORE), TOKENT("abstract",TOK_RWORD_ABSTRACT), TOKENT("alignof", TOK_RWORD_ALIGNOF), TOKENT("as", TOK_RWORD_AS), diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 7484609b..f5f48132 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -319,7 +319,6 @@ AST::Function Parse_FunctionDef(TokenStream& lex, bool allow_no_code=false) // By-value method
fcn_class = AST::Function::CLASS_VALMETHOD;
GET_TOK(tok, lex);
- throw ParseError::Todo("By-value methods");
}
else
{
@@ -821,6 +820,7 @@ MacroRule Parse_MacroRules_Var(Preproc& lex) auto rep = Parse_TT(lex, true); // - don't care about the enclosing brackets
TTStream slex(rep);
+ // parse token tree into a flattend replacement, handling expansions
while(GET_TOK(tok, slex) != TOK_EOF)
{
if( tok.type() == TOK_DOLLAR )
|