diff options
author | John Hodge <tpg@mutabah.net> | 2016-06-12 14:00:32 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-06-12 14:00:32 +0800 |
commit | d7cff94061f2c42095e91ca5c30cffde03974cdc (patch) | |
tree | 4a560f568f7833588793d347bbd6a188230c49a5 /src | |
parent | 1c75ff6ca74ca61049b29c5b9ce6f916752c87c7 (diff) | |
download | mrust-d7cff94061f2c42095e91ca5c30cffde03974cdc.tar.gz |
Parse - Fix incorrect handling of trailing semicolons
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/ast.cpp | 3 | ||||
-rw-r--r-- | src/parse/expr.cpp | 59 | ||||
-rw-r--r-- | src/parse/root.cpp | 1 |
3 files changed, 21 insertions, 42 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 77981a4d..8af991c0 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -105,6 +105,7 @@ SERIALISE_TYPE(ImplDef::, "AST_ImplDef", { void Impl::add_function(bool is_public, ::std::string name, Function fcn)
{
+ DEBUG("impl fn " << name);
m_items.push_back( Named<Item>( mv$(name), Item::make_Function({::std::move(fcn)}), is_public ) );
}
void Impl::add_type(bool is_public, ::std::string name, TypeRef type)
@@ -247,6 +248,7 @@ void Module::add_enum(bool is_public, ::std::string name, Enum item, MetaItems a this->add_item( is_public, name, Item::make_Enum({mv$(item)}), mv$(attrs) );
}
void Module::add_function(bool is_public, ::std::string name, Function item, MetaItems attrs) {
+ DEBUG("mod fn " << name);
this->add_item( is_public, name, Item::make_Function({mv$(item)}), mv$(attrs) );
}
void Module::add_submod(bool is_public, ::std::string name, Module mod, MetaItems attrs) {
@@ -452,6 +454,7 @@ void Trait::add_type(::std::string name, TypeRef type) { m_items.push_back( Named<Item>(mv$(name), Item::make_Type({TypeAlias(GenericParams(), mv$(type))}), true) );
}
void Trait::add_function(::std::string name, Function fcn) {
+ DEBUG("trait fn " << name);
m_items.push_back( Named<Item>(mv$(name), Item::make_Function({mv$(fcn)}), true) );
}
void Trait::add_static(::std::string name, Static v) {
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 3dbdd1d3..f01272f6 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -22,7 +22,7 @@ static inline ExprNodeP mk_exprnodep(const TokenStream& lex, AST::ExprNode* en){ #define NEWNODE(type, ...) mk_exprnodep(lex, new type(__VA_ARGS__))
ExprNodeP Parse_ExprBlockNode(TokenStream& lex);
-ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *expect_end);
+ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *add_silence);
ExprNodeP Parse_Stmt(TokenStream& lex);
ExprNodeP Parse_Expr0(TokenStream& lex);
ExprNodeP Parse_IfStmt(TokenStream& lex);
@@ -105,8 +105,8 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex) // fall
default: {
PUTBACK(tok, lex);
- bool expect_end = false;
- nodes.push_back(Parse_ExprBlockLine(lex, &expect_end));
+ bool add_silence_if_end = false;
+ nodes.push_back(Parse_ExprBlockLine(lex, &add_silence_if_end));
if( nodes.back() ) {
nodes.back()->set_attrs( mv$(item_attrs) );
}
@@ -114,14 +114,11 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex) // TODO: Error if attribute on void expression?
}
// Set to TRUE if there was no semicolon after a statement
- if( expect_end )
+ if( LOOK_AHEAD(lex) == TOK_BRACE_CLOSE && add_silence_if_end )
{
- DEBUG("expect_end == true");
- if( GET_TOK(tok, lex) != TOK_BRACE_CLOSE )
- {
- throw ParseError::Unexpected(lex, tok, Token(TOK_BRACE_CLOSE));
- }
- PUTBACK(tok, lex);
+ DEBUG("expect_end == false, end of block");
+ nodes.push_back( NEWNODE(AST::ExprNode_Tuple, ::std::vector<ExprNodeP>()) );
+ // NOTE: Would break, but we're in a switch
}
break;
}
@@ -136,7 +133,7 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex) /// Handles:
/// - Block-level constructs (with lifetime annotations)
/// - use/extern/const/let
-ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *expect_end)
+ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *add_silence)
{
Token tok;
@@ -171,7 +168,7 @@ ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *expect_end) switch( tok.type() )
{
case TOK_SEMICOLON:
- return 0;
+ return NEWNODE(AST::ExprNode_Tuple, ::std::vector<AST::ExprNodeP>());
case TOK_BRACE_OPEN:
PUTBACK(tok, lex);
return Parse_ExprBlockNode(lex);
@@ -217,13 +214,16 @@ ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *expect_end) default: {
PUTBACK(tok, lex);
auto ret = Parse_Stmt(lex);
- if( GET_TOK(tok, lex) != TOK_SEMICOLON )
- {
+ // If this expression statement wasn't followed by a semicolon, then it's yielding its value out of the block.
+ // - I.e. The block should be ending
+ if( GET_TOK(tok, lex) != TOK_SEMICOLON ) {
+ CHECK_TOK(tok, TOK_BRACE_CLOSE);
PUTBACK(tok, lex);
- *expect_end = true;
}
- return ::std::move(ret);
- break;
+ else {
+ *add_silence = true;
+ }
+ return ret;
}
}
}
@@ -911,31 +911,6 @@ ExprNodeP Parse_ExprVal_Closure(TokenStream& lex, bool is_move) return NEWNODE( AST::ExprNode_Closure, ::std::move(args), ::std::move(rt), ::std::move(code) );
}
-ExprNodeP Parse_FormatArgs(TokenStream& lex)
-{
- TRACE_FUNCTION;
-
- Token tok;
-
- GET_CHECK_TOK(tok, lex, TOK_STRING);
- ::std::string fmt = tok.str();
-
- ::std::vector<ExprNodeP> nodes;
-
- while( GET_TOK(tok, lex) == TOK_COMMA )
- {
- // TODO: Support named
- auto exp = NEWNODE( AST::ExprNode_UniOp, AST::ExprNode_UniOp::REF, Parse_Expr1(lex) );
-
- // ( &arg as *const _, &<arg as Trait>::fmt as fn(*const (), &mut Formatter) )
- //nodes.push_back( NEWNODE( AST::ExprNode_Cast, TypeRef
- }
-
- //return NEWNODE( AST::ExprNode_ArrayLiteral, ::std::move(nodes) );
- DEBUG("TODO: Proper support for format_args!");
- return NEWNODE( AST::ExprNode_Tuple, ::std::vector<ExprNodeP>() );
-}
-
ExprNodeP Parse_ExprVal(TokenStream& lex)
{
TRACE_FUNCTION;
diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 1e57227e..7dfb6f2c 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -1040,6 +1040,7 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl) case TOK_RWORD_FN: {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
::std::string name = tok.str();
+ DEBUG("Function " << name);
// - Self allowed, can't be prototype-form
auto fcn = Parse_FunctionDefWithCode(lex, abi, item_attrs, true);
impl.add_function(is_public, ::std::move(name), mv$(fcn));
|