summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/macro_rules/mod.cpp21
-rw-r--r--src/parse/expr.cpp42
2 files changed, 47 insertions, 16 deletions
diff --git a/src/macro_rules/mod.cpp b/src/macro_rules/mod.cpp
index effa03cb..095763a8 100644
--- a/src/macro_rules/mod.cpp
+++ b/src/macro_rules/mod.cpp
@@ -68,14 +68,28 @@ bool is_token_expr(eTokenType tt) {
return true;
switch( tt )
{
+ // Leading unary operators
case TOK_AMP: // Borrow
case TOK_STAR: // Deref
- case TOK_PAREN_OPEN: // Parenthesised
- case TOK_SQUARE_OPEN: // Array
- case TOK_MACRO:
case TOK_DASH: // Negate
case TOK_EXCLAM: // Invert
case TOK_RWORD_BOX: // Box
+ // Composite values
+ case TOK_MACRO:
+ case TOK_PAREN_OPEN: // Parenthesised
+ case TOK_SQUARE_OPEN: // Array
+
+ // Flow
+ case TOK_RWORD_RETURN:
+ case TOK_RWORD_BREAK:
+ case TOK_RWORD_CONTINUE:
+
+ // Blocks
+ case TOK_RWORD_IF:
+ case TOK_RWORD_FOR:
+ case TOK_RWORD_WHILE:
+ case TOK_RWORD_LOOP:
+ case TOK_RWORD_UNSAFE:
// Closures
case TOK_RWORD_MOVE:
@@ -88,6 +102,7 @@ bool is_token_expr(eTokenType tt) {
case TOK_STRING:
case TOK_RWORD_TRUE:
case TOK_RWORD_FALSE:
+
case TOK_INTERPOLATED_EXPR:
return true;
default:
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp
index c632ed55..9d7748eb 100644
--- a/src/parse/expr.cpp
+++ b/src/parse/expr.cpp
@@ -27,6 +27,7 @@ static inline ExprNodeP mk_exprnodep(const TokenStream& lex, AST::ExprNode* en){
//ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *add_silence);
ExprNodeP Parse_ExprBlockLine_Stmt(TokenStream& lex, bool *add_silence);
//ExprNodeP Parse_Stmt(TokenStream& lex); // common.hpp
+ExprNodeP Parse_Stmt_Let(TokenStream& lex);
ExprNodeP Parse_Expr0(TokenStream& lex);
ExprNodeP Parse_IfStmt(TokenStream& lex);
ExprNodeP Parse_WhileStmt(TokenStream& lex, ::std::string lifetime);
@@ -177,19 +178,10 @@ ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *add_silence)
return NEWNODE(AST::ExprNode_Tuple, ::std::vector<AST::ExprNodeP>());
// let binding
- case TOK_RWORD_LET: {
- AST::Pattern pat = Parse_Pattern(lex, false); // irrefutable
- TypeRef type;
- if( GET_TOK(tok, lex) == TOK_COLON ) {
- type = Parse_Type(lex);
- GET_TOK(tok, lex);
- }
- ExprNodeP val;
- if( tok.type() == TOK_EQUAL ) {
- val = Parse_Expr0(lex);
- }
- return NEWNODE( AST::ExprNode_LetBinding, ::std::move(pat), ::std::move(type), ::std::move(val) );
- }
+ case TOK_RWORD_LET:
+ ret = Parse_Stmt_Let(lex);
+ GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
+ return ret;
// Blocks that don't need semicolons
// NOTE: If these are followed by a small set of tokens (`.` and `?`) then they are actually the start of an expression
@@ -432,6 +424,11 @@ ExprNodeP Parse_Stmt(TokenStream& lex)
switch(GET_TOK(tok, lex))
{
+ case TOK_INTERPOLATED_STMT:
+ return tok.take_frag_node();
+ // Duplicated here for the :stmt pattern fragment.
+ case TOK_RWORD_LET:
+ return Parse_Stmt_Let(lex);
case TOK_RWORD_RETURN: {
ExprNodeP val;
switch(LOOK_AHEAD(lex))
@@ -491,6 +488,25 @@ ExprNodeP Parse_Stmt(TokenStream& lex)
}
}
+ExprNodeP Parse_Stmt_Let(TokenStream& lex)
+{
+ Token tok;
+ AST::Pattern pat = Parse_Pattern(lex, false); // irrefutable
+ TypeRef type;
+ if( GET_TOK(tok, lex) == TOK_COLON ) {
+ type = Parse_Type(lex);
+ GET_TOK(tok, lex);
+ }
+ ExprNodeP val;
+ if( tok.type() == TOK_EQUAL ) {
+ val = Parse_Expr0(lex);
+ }
+ else {
+ PUTBACK(tok, lex);
+ }
+ return NEWNODE( AST::ExprNode_LetBinding, ::std::move(pat), ::std::move(type), ::std::move(val) );
+}
+
::std::vector<ExprNodeP> Parse_ParenList(TokenStream& lex)
{
TRACE_FUNCTION;