summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2019-03-04 10:38:43 +0800
committerJohn Hodge <tpg@ucc.asn.au>2019-03-04 10:38:43 +0800
commita473a4eddc80b54e3458739ef2c4b18c24d50f92 (patch)
treeba84734afc1ac0fb7278946519a86a80155ddf22 /src
parenta84d9310b5c838c0816c84ba96754906d4f5d667 (diff)
downloadmrust-a473a4eddc80b54e3458739ef2c4b18c24d50f92.tar.gz
Parse - Handle `do catch` (aka `try`)
Diffstat (limited to 'src')
-rw-r--r--src/ast/dump.cpp4
-rw-r--r--src/ast/expr.cpp9
-rw-r--r--src/ast/expr.hpp15
-rw-r--r--src/expand/mod.cpp3
-rw-r--r--src/expand/proc_macro.cpp3
-rw-r--r--src/hir/from_ast_expr.cpp3
-rw-r--r--src/parse/expr.cpp29
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: