diff options
author | Philip Herron <herron.philip@googlemail.com> | 2020-05-30 18:41:40 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2020-11-28 21:13:15 +0000 |
commit | f230adf6179df01a709bacc8e7e83a160d04aeb2 (patch) | |
tree | 6652a869e12bb2f6934b7674fe90a3ea317071d8 /gcc | |
parent | 6a9ddc71985f33dbe9e22a3dff99533f881f5ba1 (diff) | |
download | gcc-f230adf6179df01a709bacc8e7e83a160d04aeb2.zip gcc-f230adf6179df01a709bacc8e7e83a160d04aeb2.tar.gz gcc-f230adf6179df01a709bacc8e7e83a160d04aeb2.tar.bz2 |
Compile conditional expressions if/if-else/if-elif-else
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/ast/rust-ast-full-test.cc | 2 | ||||
-rw-r--r-- | gcc/rust/ast/rust-expr.h | 23 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 108 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.h | 1 |
4 files changed, 122 insertions, 12 deletions
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc index 550b7e0..3eb2f5d 100644 --- a/gcc/rust/ast/rust-ast-full-test.cc +++ b/gcc/rust/ast/rust-ast-full-test.cc @@ -1970,7 +1970,7 @@ IfExprConseqIf::as_string () const { ::std::string str = IfExpr::as_string (); - str += "\n Else if expr: \n " + if_expr->as_string (); + str += "\n Else if expr: \n " + conseq_if_expr->as_string (); return str; } diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index ee4368f..ea66884 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -4195,6 +4195,14 @@ public: virtual void accept_vis (ASTVisitor &vis) OVERRIDE; + void vis_if_condition (ASTVisitor &vis) { condition->accept_vis (vis); } + + void vis_if_block (ASTVisitor &vis) { if_block->accept_vis (vis); } + + Expr *get_if_condition () { return condition.get (); } + + BlockExpr *get_if_block () { return if_block.get (); } + protected: // Use covariance to implement clone function as returning this object rather // than base @@ -4259,6 +4267,8 @@ public: virtual void accept_vis (ASTVisitor &vis) OVERRIDE; + void vis_else_block (ASTVisitor &vis) { else_block->accept_vis (vis); } + protected: // Use covariance to implement clone function as returning this object rather // than base @@ -4286,7 +4296,7 @@ protected: class IfExprConseqIf : public IfExpr { // IfExpr* if_expr; - ::std::unique_ptr<IfExpr> if_expr; + ::std::unique_ptr<IfExpr> conseq_if_expr; public: /*~IfExprConseqIf() { @@ -4299,13 +4309,13 @@ public: ::std::unique_ptr<BlockExpr> if_block, ::std::unique_ptr<IfExpr> conseq_if_expr, Location locus) : IfExpr (::std::move (condition), ::std::move (if_block), locus), - if_expr (::std::move (conseq_if_expr)) + conseq_if_expr (::std::move (conseq_if_expr)) {} // outer attributes not allowed // Copy constructor with clone IfExprConseqIf (IfExprConseqIf const &other) - : IfExpr (other), if_expr (other.if_expr->clone_if_expr ()) + : IfExpr (other), conseq_if_expr (other.conseq_if_expr->clone_if_expr ()) {} // Destructor - define here if required @@ -4316,7 +4326,7 @@ public: IfExpr::operator= (other); // condition = other.condition->clone_expr(); // if_block = other.if_block->clone_block_expr(); - if_expr = other.if_expr->clone_if_expr (); + conseq_if_expr = other.conseq_if_expr->clone_if_expr (); return *this; } @@ -4327,6 +4337,11 @@ public: virtual void accept_vis (ASTVisitor &vis) OVERRIDE; + void vis_conseq_if_expr (ASTVisitor &vis) + { + conseq_if_expr->accept_vis (vis); + } + protected: // Use covariance to implement clone function as returning this object rather // than base diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc index 13d6b80..69245dc 100644 --- a/gcc/rust/backend/rust-compile.cc +++ b/gcc/rust/backend/rust-compile.cc @@ -170,7 +170,6 @@ Compilation::visit (AST::AttrInputMetaItemContainer &input) void Compilation::visit (AST::IdentifierExpr &ident_expr) { - printf ("IdentifierExpr: %s\n", ident_expr.as_string ().c_str ()); Bvariable *var = NULL; if (!scope.LookupVar (ident_expr.as_string (), &var)) { @@ -581,9 +580,27 @@ Compilation::visit (AST::FieldAccessExpr &expr) void Compilation::visit (AST::ClosureExprInner &expr) {} + void Compilation::visit (AST::BlockExpr &expr) -{} +{ + Bblock *enclosingScope = NULL; + Location start_location; /* = stmt.locus; FIXME */ + Location end_location; // FIXME + + std::vector<Bvariable *> vars; + auto code_block + = backend->block (scope.GetCurrentFndecl (), scope.CurBlock (), vars, + start_location, end_location); + + scope.PushBlock (code_block); + for (auto &stmt : expr.statements) + { + stmt->accept_vis (*this); + } + // dont pop +} + void Compilation::visit (AST::ClosureExprInnerTyped &expr) {} @@ -653,18 +670,89 @@ Compilation::visit (AST::ForLoopExpr &expr) void Compilation::visit (AST::IfExpr &expr) { - printf ("IfExpr %s\n", expr.as_string ().c_str ()); + Bexpression *cond = NULL; + VISIT_POP (expr.get_if_condition ()->get_locus_slow (), + expr.get_if_condition (), cond, exprs); + if (cond == NULL) + { + rust_error_at (expr.get_if_condition ()->get_locus_slow (), + "failed to compile"); + return; + } + + expr.vis_if_block (*this); + Bblock *then_block = scope.PopBlock (); + + auto stmt = backend->if_statement (scope.GetCurrentFndecl (), cond, + then_block, NULL, expr.get_locus_slow ()); + stmts.push_back (stmt); } + void Compilation::visit (AST::IfExprConseqElse &expr) { - printf ("IfExprConseqElse %s\n", expr.as_string ().c_str ()); + Bexpression *cond = NULL; + VISIT_POP (expr.get_if_condition ()->get_locus_slow (), + expr.get_if_condition (), cond, exprs); + if (cond == NULL) + { + rust_error_at (expr.get_if_condition ()->get_locus_slow (), + "failed to compile"); + return; + } + + expr.vis_if_block (*this); + Bblock *then_block = scope.PopBlock (); + + expr.vis_else_block (*this); + Bblock *else_block = scope.PopBlock (); + + auto stmt + = backend->if_statement (scope.GetCurrentFndecl (), cond, then_block, + else_block, expr.get_locus_slow ()); + stmts.push_back (stmt); } + void Compilation::visit (AST::IfExprConseqIf &expr) { - printf ("IfExprConseqIf %s\n", expr.as_string ().c_str ()); + Bexpression *cond = NULL; + VISIT_POP (expr.get_if_condition ()->get_locus_slow (), + expr.get_if_condition (), cond, exprs); + if (cond == NULL) + { + rust_error_at (expr.get_if_condition ()->get_locus_slow (), + "failed to compile"); + return; + } + + expr.vis_if_block (*this); + Bblock *then_block = scope.PopBlock (); + + // setup else block + Bblock *enclosingScope = NULL; + Location start_location; /* = stmt.locus; FIXME */ + Location end_location; // FIXME + + std::vector<Bvariable *> vars; + auto else_block + = backend->block (scope.GetCurrentFndecl (), scope.CurBlock (), vars, + start_location, end_location); + + scope.PushBlock (else_block); + expr.vis_conseq_if_expr (*this); + // get trailing if required + for (auto &s : stmts) + scope.AddStatement (s); + stmts.clear (); + scope.PopBlock (); + + auto stmt + = backend->if_statement (scope.GetCurrentFndecl (), cond, then_block, + else_block, expr.get_locus_slow ()); + stmts.push_back (stmt); } + void Compilation::visit (AST::IfExprConseqIfLet &expr) { @@ -1104,8 +1192,6 @@ Compilation::visit (AST::ExprStmtWithoutBlock &stmt) void Compilation::visit (AST::ExprStmtWithBlock &stmt) { - printf ("ExprStmtWithBlock: %s\n", stmt.as_string ().c_str ()); - Bblock *enclosingScope = NULL; Location start_location; /* = stmt.locus; FIXME */ Location end_location; // FIXME @@ -1117,6 +1203,14 @@ Compilation::visit (AST::ExprStmtWithBlock &stmt) scope.PushBlock (code_block); stmt.expr->accept_vis (*this); + + // get trailing if required + for (auto &s : stmts) + { + scope.AddStatement (s); + } + stmts.clear (); + scope.PopBlock (); auto body = backend->block_statement (code_block); diff --git a/gcc/rust/backend/rust-compile.h b/gcc/rust/backend/rust-compile.h index 045afbf..ec39236 100644 --- a/gcc/rust/backend/rust-compile.h +++ b/gcc/rust/backend/rust-compile.h @@ -241,6 +241,7 @@ private: ::Btype *translatedType; std::vector<AST::IdentifierPattern> patternBuffer; std::vector< ::Bexpression *> exprs; + std::vector< ::Bstatement *> stmts; // careful these are the vectors we pass into the GCC middle-end std::vector< ::Btype *> type_decls; |