diff options
author | John Hodge <tpg@mutabah.net> | 2015-03-18 12:09:29 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2015-03-18 12:09:29 +0800 |
commit | d967bbb657fce4f2bea01ba646ae28463fd27fb7 (patch) | |
tree | 48aa0129ad1006897fddb9ddbcc3af58cc59cf42 /src/parse | |
parent | 993f20b4cd3cc4692817ded4f632efcff6d7b72f (diff) | |
download | mrust-d967bbb657fce4f2bea01ba646ae28463fd27fb7.tar.gz |
Array literals, op-equals parsing, super in path, blocks
Diffstat (limited to 'src/parse')
-rw-r--r-- | src/parse/eTokenType.enum.h | 3 | ||||
-rw-r--r-- | src/parse/expr.cpp | 267 | ||||
-rw-r--r-- | src/parse/lex.cpp | 3 | ||||
-rw-r--r-- | src/parse/root.cpp | 11 |
4 files changed, 146 insertions, 138 deletions
diff --git a/src/parse/eTokenType.enum.h b/src/parse/eTokenType.enum.h index 4209c94a..69f00f02 100644 --- a/src/parse/eTokenType.enum.h +++ b/src/parse/eTokenType.enum.h @@ -61,6 +61,8 @@ _(TOK_DOUBLE_AMP) _(TOK_DOUBLE_PIPE) _(TOK_DOUBLE_LT) _(TOK_DOUBLE_GT) +_(TOK_DOUBLE_LT_EQUAL) +_(TOK_DOUBLE_GT_EQUAL) _(TOK_DOLLAR) @@ -69,6 +71,7 @@ _(TOK_AT) _(TOK_TILDE) _(TOK_BACKSLASH) _(TOK_CARET) +_(TOK_CARET_EQUAL) _(TOK_BACKTICK) // Reserved Words diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 01ecc2cb..88bb021f 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -14,7 +14,6 @@ using AST::ExprNode; ExprNodeP Parse_ExprBlockNode(TokenStream& lex);
ExprNodeP Parse_Stmt(TokenStream& lex);
ExprNodeP Parse_Expr0(TokenStream& lex);
-ExprNodeP Parse_ExprBlocks(TokenStream& lex);
ExprNodeP Parse_IfStmt(TokenStream& lex);
ExprNodeP Parse_WhileStmt(TokenStream& lex, ::std::string lifetime);
ExprNodeP Parse_ForStmt(TokenStream& lex, ::std::string lifetime);
@@ -378,7 +377,7 @@ ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *expect_end) else {
CHECK_TOK(tok, TOK_EQUAL);
}
- ExprNodeP val = Parse_ExprBlocks(lex);
+ ExprNodeP val = Parse_Expr0(lex);
return NEWNODE( AST::ExprNode_LetBinding, ::std::move(pat), ::std::move(type), ::std::move(val) );
}
@@ -393,6 +392,11 @@ ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *expect_end) return Parse_IfStmt(lex);
case TOK_RWORD_MATCH:
return Parse_Expr_Match(lex);
+ case TOK_RWORD_UNSAFE: {
+ auto rv = Parse_ExprBlockNode(lex);
+ dynamic_cast<AST::ExprNode_Block&>(*rv).set_unsafe();
+ return rv;
+ }
// Fall through to the statement code
default: {
@@ -503,108 +507,6 @@ ExprNodeP Parse_ForStmt(TokenStream& lex, ::std::string lifetime) return NEWNODE( AST::ExprNode_Loop, lifetime, AST::ExprNode_Loop::FOR,
::std::move(pat), ::std::move(val), Parse_ExprBlockNode(lex) );
}
-
-/// Parses the 'stmt' fragment specifier
-/// - Flow control
-/// - Expressions
-ExprNodeP Parse_Stmt(TokenStream& lex)
-{
- TRACE_FUNCTION;
- Token tok;
-
- switch(GET_TOK(tok, lex))
- {
- case TOK_RWORD_RETURN: {
- ExprNodeP val;
- if( GET_TOK(tok, lex) != TOK_SEMICOLON ) {
- lex.putback(tok);
- val = Parse_Expr1(lex);
- }
- else
- lex.putback(tok);
- return NEWNODE( AST::ExprNode_Flow, AST::ExprNode_Flow::RETURN, "", ::std::move(val) );
- }
- case TOK_RWORD_CONTINUE:
- case TOK_RWORD_BREAK:
- {
- AST::ExprNode_Flow::Type type;
- switch(tok.type())
- {
- case TOK_RWORD_CONTINUE: type = AST::ExprNode_Flow::CONTINUE; break;
- case TOK_RWORD_BREAK: type = AST::ExprNode_Flow::BREAK; break;
- default: throw ParseError::BugCheck(/*lex,*/ "continue/break");
- }
- ::std::string lifetime;
- if( GET_TOK(tok, lex) == TOK_LIFETIME )
- {
- lifetime = tok.str();
- GET_TOK(tok, lex);
- }
- ExprNodeP val;
- if( tok.type() != TOK_SEMICOLON && tok.type() != TOK_COMMA && tok.type() != TOK_BRACE_CLOSE ) {
- lex.putback(tok);
- val = Parse_Expr1(lex);
- }
- else
- lex.putback(tok);
- return NEWNODE( AST::ExprNode_Flow, type, lifetime, ::std::move(val) );
- }
- default:
- lex.putback(tok);
- return Parse_Expr0(lex);
- }
-}
-
-::std::vector<ExprNodeP> Parse_ParenList(TokenStream& lex)
-{
- TRACE_FUNCTION;
- Token tok;
-
- ::std::vector<ExprNodeP> rv;
- GET_CHECK_TOK(tok, lex, TOK_PAREN_OPEN);
- if( GET_TOK(tok, lex) != TOK_PAREN_CLOSE )
- {
- lex.putback(tok);
- do {
- rv.push_back( Parse_Expr0(lex) );
- } while( GET_TOK(tok, lex) == TOK_COMMA );
- CHECK_TOK(tok, TOK_PAREN_CLOSE);
- }
- return rv;
-}
-
-// 0: Assign
-ExprNodeP Parse_Expr0(TokenStream& lex)
-{
- TRACE_FUNCTION;
- Token tok;
-
- ExprNodeP rv = Parse_ExprBlocks(lex);
- auto op = AST::ExprNode_Assign::NONE;
- switch( GET_TOK(tok, lex) )
- {
- case TOK_PLUS_EQUAL:
- op = AST::ExprNode_Assign::ADD;
- if(0)
- case TOK_DASH_EQUAL:
- op = AST::ExprNode_Assign::SUB;
- if(0)
- case TOK_SLASH_EQUAL:
- op = AST::ExprNode_Assign::DIV;
- if(0)
- case TOK_STAR_EQUAL:
- op = AST::ExprNode_Assign::MUL;
- if(0)
- case TOK_EQUAL:
- op = AST::ExprNode_Assign::NONE;
- return NEWNODE( AST::ExprNode_Assign, op, ::std::move(rv), Parse_ExprBlocks(lex) );
-
- default:
- lex.putback(tok);
- return rv;
- }
-}
-
/// Parse an 'if' statement
// Note: TOK_RWORD_IF has already been eaten
ExprNodeP Parse_IfStmt(TokenStream& lex)
@@ -657,7 +559,7 @@ ExprNodeP Parse_IfStmt(TokenStream& lex) else
return NEWNODE( AST::ExprNode_If, ::std::move(cond), ::std::move(code), ::std::move(altcode) );
}
-
+/// "match" block
ExprNodeP Parse_Expr_Match(TokenStream& lex)
{
TRACE_FUNCTION;
@@ -703,34 +605,113 @@ ExprNodeP Parse_Expr_Match(TokenStream& lex) return NEWNODE( AST::ExprNode_Match, ::std::move(switch_val), ::std::move(arms) );
}
-// 0.5: Blocks
-ExprNodeP Parse_ExprBlocks(TokenStream& lex)
+/// Parses the 'stmt' fragment specifier
+/// - Flow control
+/// - Expressions
+ExprNodeP Parse_Stmt(TokenStream& lex)
+{
+ TRACE_FUNCTION;
+ Token tok;
+
+ switch(GET_TOK(tok, lex))
+ {
+ case TOK_RWORD_RETURN: {
+ ExprNodeP val;
+ if( GET_TOK(tok, lex) != TOK_SEMICOLON ) {
+ lex.putback(tok);
+ val = Parse_Expr1(lex);
+ }
+ else
+ lex.putback(tok);
+ return NEWNODE( AST::ExprNode_Flow, AST::ExprNode_Flow::RETURN, "", ::std::move(val) );
+ }
+ case TOK_RWORD_CONTINUE:
+ case TOK_RWORD_BREAK:
+ {
+ AST::ExprNode_Flow::Type type;
+ switch(tok.type())
+ {
+ case TOK_RWORD_CONTINUE: type = AST::ExprNode_Flow::CONTINUE; break;
+ case TOK_RWORD_BREAK: type = AST::ExprNode_Flow::BREAK; break;
+ default: throw ParseError::BugCheck(/*lex,*/ "continue/break");
+ }
+ ::std::string lifetime;
+ if( GET_TOK(tok, lex) == TOK_LIFETIME )
+ {
+ lifetime = tok.str();
+ GET_TOK(tok, lex);
+ }
+ ExprNodeP val;
+ if( tok.type() != TOK_SEMICOLON && tok.type() != TOK_COMMA && tok.type() != TOK_BRACE_CLOSE ) {
+ lex.putback(tok);
+ val = Parse_Expr1(lex);
+ }
+ else
+ lex.putback(tok);
+ return NEWNODE( AST::ExprNode_Flow, type, lifetime, ::std::move(val) );
+ }
+ default:
+ lex.putback(tok);
+ return Parse_Expr0(lex);
+ }
+}
+
+::std::vector<ExprNodeP> Parse_ParenList(TokenStream& lex)
+{
+ TRACE_FUNCTION;
+ Token tok;
+
+ ::std::vector<ExprNodeP> rv;
+ GET_CHECK_TOK(tok, lex, TOK_PAREN_OPEN);
+ if( GET_TOK(tok, lex) != TOK_PAREN_CLOSE )
+ {
+ lex.putback(tok);
+ do {
+ rv.push_back( Parse_Expr0(lex) );
+ } while( GET_TOK(tok, lex) == TOK_COMMA );
+ CHECK_TOK(tok, TOK_PAREN_CLOSE);
+ }
+ return rv;
+}
+
+// 0: Assign
+ExprNodeP Parse_Expr0(TokenStream& lex)
{
TRACE_FUNCTION;
Token tok;
+
+ ExprNodeP rv = Parse_Expr1(lex);
+ auto op = AST::ExprNode_Assign::NONE;
switch( GET_TOK(tok, lex) )
{
- case TOK_BRACE_OPEN:
- lex.putback(tok);
- return Parse_ExprBlockNode(lex);
- case TOK_RWORD_LOOP:
- return NEWNODE( AST::ExprNode_Loop, "", Parse_ExprBlockNode(lex) );
- case TOK_RWORD_WHILE:
- return Parse_WhileStmt(lex, "");
- case TOK_RWORD_FOR:
- return Parse_ForStmt(lex, "");
- case TOK_RWORD_MATCH:
- return Parse_Expr_Match(lex);
- case TOK_RWORD_IF:
- return Parse_IfStmt(lex);
- case TOK_RWORD_UNSAFE: {
- auto rv = Parse_ExprBlockNode(lex);
- dynamic_cast<AST::ExprNode_Block&>(*rv).set_unsafe();
- return rv;
- }
+ case TOK_PLUS_EQUAL:
+ op = AST::ExprNode_Assign::ADD; if(0)
+ case TOK_DASH_EQUAL:
+ op = AST::ExprNode_Assign::SUB; if(0)
+ case TOK_STAR_EQUAL:
+ op = AST::ExprNode_Assign::MUL; if(0)
+ case TOK_SLASH_EQUAL:
+ op = AST::ExprNode_Assign::DIV; if(0)
+
+ case TOK_AMP_EQUAL:
+ op = AST::ExprNode_Assign::AND; if(0)
+ case TOK_PIPE_EQUAL:
+ op = AST::ExprNode_Assign::OR ; if(0)
+ case TOK_CARET_EQUAL:
+ op = AST::ExprNode_Assign::XOR; if(0)
+
+ case TOK_DOUBLE_GT_EQUAL:
+ op = AST::ExprNode_Assign::SHR; if(0)
+ case TOK_DOUBLE_LT_EQUAL:
+ op = AST::ExprNode_Assign::SHL; if(0)
+
+ case TOK_EQUAL:
+ op = AST::ExprNode_Assign::NONE;
+ return NEWNODE( AST::ExprNode_Assign, op, ::std::move(rv), Parse_Expr1(lex) );
+
default:
lex.putback(tok);
- return Parse_Expr1(lex);
+ return rv;
}
}
@@ -765,6 +746,7 @@ bool Parse_IsTokValue(eTokenType tok_type) case TOK_STRING:
case TOK_RWORD_TRUE:
case TOK_RWORD_FALSE:
+ case TOK_RWORD_SELF:
case TOK_RWORD_BOX:
case TOK_PAREN_OPEN:
return true;
@@ -937,11 +919,9 @@ ExprNodeP Parse_ExprFC(TokenStream& lex) lex.putback(tok);
val = NEWNODE( AST::ExprNode_CallObject, ::std::move(val), Parse_ParenList(lex) );
break;
- case TOK_SQUARE_OPEN: {
- ExprNodeP idx = Parse_Expr0(lex);
- val = NEWNODE( AST::ExprNode_Index, ::std::move(val), ::std::move(idx) );
+ case TOK_SQUARE_OPEN:
+ val = NEWNODE( AST::ExprNode_Index, ::std::move(val), Parse_Expr0(lex) );
GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
- }
break;
case TOK_DOT:
// Field access / method call
@@ -1081,6 +1061,25 @@ ExprNodeP Parse_ExprVal(TokenStream& lex) AST::Path path;
switch( GET_TOK(tok, lex) )
{
+ case TOK_BRACE_OPEN:
+ lex.putback(tok);
+ return Parse_ExprBlockNode(lex);
+ case TOK_RWORD_LOOP:
+ return NEWNODE( AST::ExprNode_Loop, "", Parse_ExprBlockNode(lex) );
+ case TOK_RWORD_WHILE:
+ return Parse_WhileStmt(lex, "");
+ case TOK_RWORD_FOR:
+ return Parse_ForStmt(lex, "");
+ case TOK_RWORD_MATCH:
+ return Parse_Expr_Match(lex);
+ case TOK_RWORD_IF:
+ return Parse_IfStmt(lex);
+ case TOK_RWORD_UNSAFE: {
+ auto rv = Parse_ExprBlockNode(lex);
+ dynamic_cast<AST::ExprNode_Block&>(*rv).set_unsafe();
+ return rv;
+ }
+
case TOK_IDENT:
// Get path
lex.putback(tok);
@@ -1150,7 +1149,7 @@ ExprNodeP Parse_ExprVal(TokenStream& lex) if( GET_TOK(tok, lex) == TOK_SQUARE_CLOSE )
{
// Empty literal
- //return NEWNODE( AST::ExprNode_Array, ::std::vector<ExprNodeP>() );
+ return NEWNODE( AST::ExprNode_Array, ::std::vector<ExprNodeP>() );
}
else
{
@@ -1161,7 +1160,7 @@ ExprNodeP Parse_ExprVal(TokenStream& lex) // Repetiion
auto count = Parse_Expr0(lex);
GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
- //return NEWNODE( AST::ExprNode_Array, ::std::move(first), ::std::move(count); );
+ return NEWNODE( AST::ExprNode_Array, ::std::move(first), ::std::move(count) );
}
else
{
@@ -1173,10 +1172,10 @@ ExprNodeP Parse_ExprVal(TokenStream& lex) GET_TOK(tok, lex);
}
CHECK_TOK(tok, TOK_SQUARE_CLOSE);
- //return NEWNODE( AST::ExprNode_Array, ::std::move(items) );
+ return NEWNODE( AST::ExprNode_Array, ::std::move(items) );
}
}
- throw ParseError::Todo(lex, "Array literals");
+ throw ParseError::BugCheck(lex, "Array literal fell");
case TOK_MACRO:
{
TokenTree tt = Parse_TT(lex, true);
diff --git a/src/parse/lex.cpp b/src/parse/lex.cpp index a2459e14..1e5fb1cf 100644 --- a/src/parse/lex.cpp +++ b/src/parse/lex.cpp @@ -74,6 +74,7 @@ static const struct { TOKENT(";", TOK_SEMICOLON), TOKENT("<", TOK_LT), TOKENT("<<", TOK_DOUBLE_LT), + TOKENT("<<=",TOK_DOUBLE_LT_EQUAL), TOKENT("<=", TOK_LTE), TOKENT("=" , TOK_EQUAL), TOKENT("==", TOK_DOUBLE_EQUAL), @@ -81,6 +82,7 @@ static const struct { TOKENT(">", TOK_GT), TOKENT(">=", TOK_GTE), TOKENT(">>", TOK_DOUBLE_GT), + TOKENT(">>=",TOK_DOUBLE_GT_EQUAL), TOKENT("?", TOK_QMARK), TOKENT("@", TOK_AT), // A-Z :: Elsewhere @@ -88,6 +90,7 @@ static const struct { TOKENT("\\", TOK_BACKSLASH), TOKENT("]", TOK_SQUARE_CLOSE), TOKENT("^", TOK_CARET), + TOKENT("^=", TOK_CARET_EQUAL), TOKENT("`", TOK_BACKTICK), TOKENT("{", TOK_BRACE_OPEN), diff --git a/src/parse/root.cpp b/src/parse/root.cpp index cd197292..acd0e9e9 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -251,6 +251,9 @@ TypeRef Parse_Type(TokenStream& lex) case TOK_DOUBLE_COLON:
// Path with generics
return TypeRef(TypeRef::TagPath(), Parse_Path(lex, true, PATH_GENERIC_TYPE));
+ case TOK_RWORD_SUPER:
+ GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON);
+ return TypeRef(TypeRef::TagPath(), Parse_PathFrom(lex, AST::Path(AST::Path::TagSuper()), PATH_GENERIC_TYPE));
// HACK! Convert && into & &
case TOK_DOUBLE_AMP:
@@ -446,12 +449,12 @@ void Parse_WhereClause(TokenStream& lex, AST::TypeParams& params) // Parse a single function argument
::std::pair< AST::Pattern, TypeRef> Parse_Function_Arg(TokenStream& lex, bool expect_named)
{
- TRACE_FUNCTION;
+ TRACE_FUNCTION_F("expect_named = " << expect_named);
Token tok;
AST::Pattern pat;
- if( expect_named || (LOOK_AHEAD(lex) == TOK_IDENT && lex.lookahead(1) == TOK_COLON) )
+ if( expect_named || LOOK_AHEAD(lex) == TOK_UNDERSCORE || LOOK_AHEAD(lex) == TOK_RWORD_MUT || (LOOK_AHEAD(lex) == TOK_IDENT && lex.lookahead(1) == TOK_COLON) )
{
pat = Parse_Pattern(lex);
GET_CHECK_TOK(tok, lex, TOK_COLON);
@@ -566,7 +569,7 @@ AST::Function Parse_FunctionDef(TokenStream& lex, ::std::string abi, AST::MetaIt // Argument list
do {
- args.push_back( Parse_Function_Arg(lex, true) );
+ args.push_back( Parse_Function_Arg(lex, !can_be_prototype) );
} while( GET_TOK(tok, lex) == TOK_COMMA );
CHECK_TOK(tok, TOK_PAREN_CLOSE);
}
@@ -599,7 +602,7 @@ AST::Function Parse_FunctionDef(TokenStream& lex, ::std::string abi, AST::MetaIt lex.putback(tok);
}
- return AST::Function(params, fcn_class, ret_type, args);
+ return AST::Function(::std::move(params), fcn_class, ::std::move(ret_type), ::std::move(args));
}
AST::Function Parse_FunctionDefWithCode(TokenStream& lex, ::std::string abi, AST::MetaItems attrs, bool allow_self)
|