diff options
author | John Hodge (sonata) <tpg@mutabah.net> | 2015-01-22 18:54:56 +0800 |
---|---|---|
committer | John Hodge (sonata) <tpg@mutabah.net> | 2015-01-22 18:54:56 +0800 |
commit | 450d55d26e0265858f60f5a118aac72cf392495f (patch) | |
tree | e7d03a68e827636173cc96c06452e291fd0ed351 /src | |
parent | feca7097047ef4821c6684f741cb8305567834c8 (diff) | |
download | mrust-450d55d26e0265858f60f5a118aac72cf392495f.tar.gz |
Corrected pattern handling (a bit)
Diffstat (limited to 'src')
-rw-r--r-- | src/parse/expr.cpp | 96 | ||||
-rw-r--r-- | src/parse/lex.cpp | 1 | ||||
-rw-r--r-- | src/parse/lex.hpp | 1 |
3 files changed, 83 insertions, 15 deletions
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index d9d42460..e91a8b26 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -28,6 +28,8 @@ AST::Expr Parse_ExprBlock(TokenStream& lex) return AST::Expr(Parse_ExprBlockNode(lex));
}
+::std::vector<AST::Pattern> Parse_PatternList(TokenStream& lex);
+
/// Parse a pattern
///
/// Examples:
@@ -44,36 +46,86 @@ AST::Pattern Parse_Pattern(TokenStream& lex) AST::Path path;
Token tok;
tok = lex.getToken();
- // 1. Bind mutability
+
+ bool expect_bind = false;
+ bool is_mut = false;
+ bool is_ref = false;
+ // 1. Mutablity + Reference
+ if( tok.type() == TOK_RWORD_REF )
+ {
+ throw ParseError::Todo("ref bindings");
+ is_ref = true;
+ expect_bind = true;
+ tok = lex.getToken();
+ }
if( tok.type() == TOK_RWORD_MUT )
{
throw ParseError::Todo("mut bindings");
+ is_mut = true;
+ expect_bind = true;
tok = lex.getToken();
}
- if( tok.type() == TOK_RWORD_REF )
+
+ ::std::string bind_name;
+ if( expect_bind )
{
- throw ParseError::Todo("ref bindings");
- tok = lex.getToken();
+ CHECK_TOK(tok, TOK_IDENT);
+ bind_name = tok.str();
+ if( GET_TOK(tok, lex) != TOK_AT )
+ {
+ lex.putback(tok);
+ return AST::Pattern(AST::Pattern::TagBind(), bind_name);
+ }
}
- switch( tok.type() )
+
+ // TODO: If the next token is an ident, parse as a path
+ if( !expect_bind && tok.type() == TOK_IDENT )
{
- case TOK_IDENT:
- // 1. Identifiers could be either a bind or a value
- // - If the path resolves to a single node, either a local enum value, or a binding
lex.putback(tok);
path = Parse_Path(lex, false, PATH_GENERIC_EXPR);
+ // - If the path is trivial
if( path.size() == 1 && path[0].args().size() == 0 )
{
- // Could be a name binding, check the next token
- GET_TOK(tok, lex);
- if(tok.type() != TOK_PAREN_OPEN) {
+ switch( GET_TOK(tok, lex) )
+ {
+ // - If the next token after that is '@', use as bind name and expect an actual pattern
+ case TOK_AT:
+ bind_name = path[0].name();
+ GET_TOK(tok, 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));
+ // - Else, treat as a MaybeBind
+ default:
lex.putback(tok);
return AST::Pattern(AST::Pattern::TagMaybeBind(), path[0].name());
}
- lex.putback(tok);
}
- // otherwise, it's a value check
- if(0)
+ 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());
+ }
+ }
+ }
+
+
+ switch( tok.type() )
+ {
+ case TOK_IDENT:
+ lex.putback(tok);
+ path = Parse_Path(lex, false, PATH_GENERIC_EXPR);
+ if( 0 )
case TOK_DOUBLE_COLON:
// 2. Paths are enum/struct names
{
@@ -97,12 +149,26 @@ AST::Pattern Parse_Pattern(TokenStream& lex) break;
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");
default:
throw ParseError::Unexpected(tok);
}
- throw ParseError::BugCheck("Parse_TT_Stmt should early return");
+ throw ParseError::BugCheck("Parse_Pattern should early return");
+}
+
+::std::vector<AST::Pattern> Parse_PatternList(TokenStream& lex)
+{
+ Token tok;
+ ::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 child_pats;
}
ExprNodeP Parse_ExprBlockNode(TokenStream& lex)
diff --git a/src/parse/lex.cpp b/src/parse/lex.cpp index 9655df0a..7dd8eb3c 100644 --- a/src/parse/lex.cpp +++ b/src/parse/lex.cpp @@ -458,6 +458,7 @@ const char* Token::typestr(enum eTokenType type) case TOK_INTEGER: return "TOK_INTEGER";
case TOK_CHAR: return "TOK_CHAR";
case TOK_FLOAT: return "TOK_FLOAT";
+ case TOK_STRING: return "TOK_STRING";
case TOK_CATTR_OPEN: return "TOK_CATTR_OPEN";
case TOK_ATTR_OPEN: return "TOK_ATTR_OPEN";
diff --git a/src/parse/lex.hpp b/src/parse/lex.hpp index 6a798909..710f3a6c 100644 --- a/src/parse/lex.hpp +++ b/src/parse/lex.hpp @@ -20,6 +20,7 @@ enum eTokenType TOK_INTEGER,
TOK_CHAR,
TOK_FLOAT,
+ TOK_STRING, TOK_CATTR_OPEN,
TOK_ATTR_OPEN,
|