diff options
| author | John Hodge <tpg@ucc.asn.au> | 2019-03-04 10:38:43 +0800 | 
|---|---|---|
| committer | John Hodge <tpg@ucc.asn.au> | 2019-03-04 10:38:43 +0800 | 
| commit | a473a4eddc80b54e3458739ef2c4b18c24d50f92 (patch) | |
| tree | ba84734afc1ac0fb7278946519a86a80155ddf22 | |
| parent | a84d9310b5c838c0816c84ba96754906d4f5d667 (diff) | |
| download | mrust-a473a4eddc80b54e3458739ef2c4b18c24d50f92.tar.gz | |
Parse - Handle `do catch` (aka `try`)
| -rw-r--r-- | src/ast/dump.cpp | 4 | ||||
| -rw-r--r-- | src/ast/expr.cpp | 9 | ||||
| -rw-r--r-- | src/ast/expr.hpp | 15 | ||||
| -rw-r--r-- | src/expand/mod.cpp | 3 | ||||
| -rw-r--r-- | src/expand/proc_macro.cpp | 3 | ||||
| -rw-r--r-- | src/hir/from_ast_expr.cpp | 3 | ||||
| -rw-r--r-- | src/parse/expr.cpp | 29 | 
7 files changed, 66 insertions, 0 deletions
| diff --git a/src/ast/dump.cpp b/src/ast/dump.cpp index 94ad6271..f0bdfa11 100644 --- a/src/ast/dump.cpp +++ b/src/ast/dump.cpp @@ -71,6 +71,10 @@ public:          dec_indent();          m_os << indent() << "}";      } +    virtual void visit(AST::ExprNode_Try& n) override { +        m_os << "try "; +        AST::NodeVisitor::visit(n.m_inner); +    }      virtual void visit(AST::ExprNode_Macro& n) override {          m_expr_root = false;          m_os << n.m_name << "!( /* TODO: Macro TT */ )"; diff --git a/src/ast/expr.cpp b/src/ast/expr.cpp index 5111bad6..dc006212 100644 --- a/src/ast/expr.cpp +++ b/src/ast/expr.cpp @@ -93,6 +93,12 @@ NODE(ExprNode_Block, {      return NEWNODE(ExprNode_Block, m_is_unsafe, m_yields_final_value, mv$(nodes), m_local_mod);  }) +NODE(ExprNode_Try, { +    os << "try " << *m_inner; +},{ +    return NEWNODE(ExprNode_Try, m_inner->clone()); +}) +  NODE(ExprNode_Macro, {      os << m_name << "!";      if( m_ident.size() > 0 ) @@ -471,6 +477,9 @@ NV(ExprNode_Block, {          visit(child);      //UNINDENT();  }) +NV(ExprNode_Try, { +    visit(node.m_inner); +})  NV(ExprNode_Macro,  {      BUG(node.span(), "Hit unexpanded macro in expression - " << node); diff --git a/src/ast/expr.hpp b/src/ast/expr.hpp index f3981db5..7675b29a 100644 --- a/src/ast/expr.hpp +++ b/src/ast/expr.hpp @@ -74,6 +74,19 @@ struct ExprNode_Block:      NODE_METHODS();  }; +struct ExprNode_Try: +    public ExprNode +{ +    ExprNodeP   m_inner; + +    ExprNode_Try(ExprNodeP inner): +        m_inner(mv$(inner)) +    { +    } + +    NODE_METHODS(); +}; +  struct ExprNode_Macro:      public ExprNode  { @@ -633,6 +646,7 @@ public:          virtual void visit(nt& node) = 0/*; \          virtual void visit(const nt& node) = 0*/      NT(ExprNode_Block); +    NT(ExprNode_Try);      NT(ExprNode_Macro);      NT(ExprNode_Asm);      NT(ExprNode_Flow); @@ -678,6 +692,7 @@ public:          virtual void visit(nt& node) override;/* \          virtual void visit(const nt& node) override*/      NT(ExprNode_Block); +    NT(ExprNode_Try);      NT(ExprNode_Macro);      NT(ExprNode_Asm);      NT(ExprNode_Flow); diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index 751b14eb..8e36bd95 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -547,6 +547,9 @@ struct CExpandExpr:          this->modstack = mv$(prev_modstack);      } +    void visit(::AST::ExprNode_Try& node) override { +        this->visit_nodelete(node, node.m_inner); +    }      void visit(::AST::ExprNode_Asm& node) override {          for(auto& v : node.m_output)              this->visit_nodelete(node, v.value); diff --git a/src/expand/proc_macro.cpp b/src/expand/proc_macro.cpp index 3f26c648..f0f28f5a 100644 --- a/src/expand/proc_macro.cpp +++ b/src/expand/proc_macro.cpp @@ -516,6 +516,9 @@ namespace {              TODO(sp, "");              m_pmi.send_symbol("}");          } +        void visit(::AST::ExprNode_Try& node) { +            TODO(sp, "ExprNode_Try"); +        }          void visit(::AST::ExprNode_Macro& node) {              TODO(sp, "ExprNode_Macro");          } diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp index 23797382..7d676bf8 100644 --- a/src/hir/from_ast_expr.cpp +++ b/src/hir/from_ast_expr.cpp @@ -47,6 +47,9 @@ struct LowerHIR_ExprNode_Visitor:          m_rv.reset( static_cast< ::HIR::ExprNode*>(rv) );      } +    virtual void visit(::AST::ExprNode_Try& v) override { +        TODO(v.span(), "Handle _Try"); +    }      virtual void visit(::AST::ExprNode_Macro& v) override {          BUG(v.span(), "Hit ExprNode_Macro");      } diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 6e18f0eb..6cc94d74 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -254,6 +254,7 @@ ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *add_silence)          case TOK_BRACE_OPEN:              { PUTBACK(tok, lex); ret = Parse_ExprBlockNode(lex); } +            // If the block is followed by `.` or `?`, it's actually an expression!              if( lex.lookahead(0) == TOK_DOT || lex.lookahead(0) == TOK_QMARK ) {                  lex.putback( Token(Token::TagTakeIP(), InterpolatedFragment(InterpolatedFragment::EXPR, ret.release())) );                  return Parse_ExprBlockLine_Stmt(lex, *add_silence); @@ -470,6 +471,17 @@ ExprNodeP Parse_Expr_Match(TokenStream& lex)      return NEWNODE( AST::ExprNode_Match, ::std::move(switch_val), ::std::move(arms) );  } +/// "do catch" block +ExprNodeP Parse_Expr_Try(TokenStream& lex) +{ +    TRACE_FUNCTION; +    //Token   tok; + +    auto inner = Parse_ExprBlockNode(lex); +    //TODO(lex.point_span(), "do catch"); +    return NEWNODE(AST::ExprNode_Try, ::std::move(inner)); +} +  /// Parses the 'stmt' fragment specifier  /// - Flow control  /// - Expressions @@ -1126,6 +1138,23 @@ ExprNodeP Parse_ExprVal(TokenStream& lex)          return Parse_WhileStmt(lex, "");      case TOK_RWORD_FOR:          return Parse_ForStmt(lex, ""); +    case TOK_RWORD_DO: +        if( TARGETVER_1_29 ) +        { +            // `do catch` - stabilised later as `try` +            if( GET_TOK(tok, lex) == TOK_IDENT && tok.str() == "catch" ) +            { +                return Parse_Expr_Try(lex); +            } +            else +            { +                throw ParseError::Unexpected(lex, tok); +            } +        } +        else +        { +            throw ParseError::Unexpected(lex, tok); +        }      case TOK_RWORD_MATCH:          return Parse_Expr_Match(lex);      case TOK_RWORD_IF: | 
