diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-02-09 17:50:39 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2021-02-10 18:10:57 +0000 |
commit | 1a2c0911f0e818328a8909b1f5ba0685b6eca351 (patch) | |
tree | db3d500a783d5794a1a190f7172d6b8205b0db4e /gcc | |
parent | cb9998216d76ccc62b45fcf01b3a0928a026f7ed (diff) | |
download | gcc-1a2c0911f0e818328a8909b1f5ba0685b6eca351.zip gcc-1a2c0911f0e818328a8909b1f5ba0685b6eca351.tar.gz gcc-1a2c0911f0e818328a8909b1f5ba0685b6eca351.tar.bz2 |
Support Simple LoopExpr
This is the building block for the rest of loops where we have a basic
infinite loop. Break/Continue reliest on the resolution of labels and
breaks can also make a loop into a BlockExpr
Fixes #106
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.h | 19 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-block.h | 19 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-expr.h | 5 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-expr.h | 2 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-expr.h | 5 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.h | 5 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compilable/loop1.rs | 10 |
7 files changed, 65 insertions, 0 deletions
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h index 2dabe01..77b8888 100644 --- a/gcc/rust/backend/rust-compile-expr.h +++ b/gcc/rust/backend/rust-compile-expr.h @@ -580,6 +580,25 @@ public: translated = ResolvePathRef::Compile (&expr, ctx); } + void visit (HIR::LoopExpr &expr) + { + // loop_start: + // <loop_body> + // goto loop_start; + fncontext fnctx = ctx->peek_fn (); + Blabel *loop_start + = ctx->get_backend ()->label (fnctx.fndecl, "", expr.get_locus ()); + Bstatement *label_decl_stmt + = ctx->get_backend ()->label_definition_statement (loop_start); + ctx->add_statement (label_decl_stmt); + + translated = CompileExpr::Compile (expr.get_loop_block ().get (), ctx); + + Bstatement *goto_loop_start_stmt + = ctx->get_backend ()->goto_statement (loop_start, Location ()); + ctx->add_statement (goto_loop_start_stmt); + } + private: CompileExpr (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) {} diff --git a/gcc/rust/hir/rust-ast-lower-block.h b/gcc/rust/hir/rust-ast-lower-block.h index f81a242..d3c61df 100644 --- a/gcc/rust/hir/rust-ast-lower-block.h +++ b/gcc/rust/hir/rust-ast-lower-block.h @@ -134,6 +134,25 @@ public: translated = ASTLoweringBlock::translate (&expr, &terminated); } + void visit (AST::LoopExpr &expr) + { + std::vector<HIR::Attribute> outer_attribs; + HIR::BlockExpr *loop_block + = ASTLoweringBlock::translate (expr.get_loop_block ().get (), + &terminated); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated + = new HIR::LoopExpr (mapping, + std::unique_ptr<HIR::BlockExpr> (loop_block), + expr.get_locus (), HIR::LoopLabel::error (), + std::move (outer_attribs)); + } + private: ASTLoweringExprWithBlock () : ASTLoweringBase (), translated (nullptr), terminated (false) diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h index cd1863f..49ac7f1 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.h +++ b/gcc/rust/hir/rust-ast-lower-expr.h @@ -697,6 +697,11 @@ public: std::move (outer_attribs), expr.get_locus ()); } + void visit (AST::LoopExpr &expr) + { + translated = ASTLoweringExprWithBlock::translate (&expr, &terminated); + } + private: ASTLoweringExpr () : translated (nullptr), translated_array_elems (nullptr), terminated (false) diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index d4af3c2..14b223a 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -3334,6 +3334,8 @@ public: Location get_locus () const { return locus; } Location get_locus_slow () const override { return get_locus (); } + + std::unique_ptr<HIR::BlockExpr> &get_loop_block () { return loop_block; }; }; // 'Loop' expression (i.e. the infinite loop) HIR node diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h index d563f93..e8ee8b3 100644 --- a/gcc/rust/resolve/rust-ast-resolve-expr.h +++ b/gcc/rust/resolve/rust-ast-resolve-expr.h @@ -241,6 +241,11 @@ public: ResolveExpr::go (expr.get_receiver_expr ().get (), expr.get_node_id ()); } + void visit (AST::LoopExpr &expr) + { + ResolveExpr::go (expr.get_loop_block ().get (), expr.get_node_id ()); + } + private: ResolveExpr (NodeId parent) : ResolverBase (parent) {} }; diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index cb92332..17e79d4 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -741,6 +741,11 @@ public: } } + void visit (HIR::LoopExpr &expr) + { + infered = TypeCheckExpr::Resolve (expr.get_loop_block ().get ()); + } + private: TypeCheckExpr () : TypeCheckBase (), infered (nullptr), infered_array_elems (nullptr) diff --git a/gcc/testsuite/rust.test/compilable/loop1.rs b/gcc/testsuite/rust.test/compilable/loop1.rs new file mode 100644 index 0000000..a8ee2f5 --- /dev/null +++ b/gcc/testsuite/rust.test/compilable/loop1.rs @@ -0,0 +1,10 @@ +fn main() { + let mut a = 1; + let mut b = 1; + + loop { + let c = a + b; + a = b; + b = c; + } +} |