aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2020-05-30 18:41:40 +0100
committerPhilip Herron <philip.herron@embecosm.com>2020-11-28 21:13:15 +0000
commitf230adf6179df01a709bacc8e7e83a160d04aeb2 (patch)
tree6652a869e12bb2f6934b7674fe90a3ea317071d8 /gcc
parent6a9ddc71985f33dbe9e22a3dff99533f881f5ba1 (diff)
downloadgcc-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.cc2
-rw-r--r--gcc/rust/ast/rust-expr.h23
-rw-r--r--gcc/rust/backend/rust-compile.cc108
-rw-r--r--gcc/rust/backend/rust-compile.h1
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;