[vala/wip/code-transformer: 9/27] Move WhileStatement transformation into the CCodeTransformer
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/wip/code-transformer: 9/27] Move WhileStatement transformation into the CCodeTransformer
- Date: Fri, 19 Apr 2019 13:31:08 +0000 (UTC)
commit 33a08fb9e3e1ea5e2b0aaa45b2c700cea23f9a3b
Author: Luca Bruno <lucabru src gnome org>
Date: Tue Aug 30 12:43:41 2011 +0200
Move WhileStatement transformation into the CCodeTransformer
codegen/valaccodetransformer.vala | 20 +++++++++++++++
vala/valaflowanalyzer.vala | 51 +++++++++++++++++++++++++++++++++++++++
vala/valawhilestatement.vala | 43 ++++++++++++---------------------
3 files changed, 86 insertions(+), 28 deletions(-)
---
diff --git a/codegen/valaccodetransformer.vala b/codegen/valaccodetransformer.vala
index fa24ae7ab..0096dfb0b 100644
--- a/codegen/valaccodetransformer.vala
+++ b/codegen/valaccodetransformer.vala
@@ -61,6 +61,26 @@ public class Vala.CCodeTransformer : CodeTransformer {
local.accept_children (this);
}
+ public override void visit_while_statement (WhileStatement stmt) {
+ // convert to simple loop
+ begin_replace_statement (stmt);
+
+ if (!always_false (stmt.condition)) {
+ b.open_loop ();
+ if (!always_true (stmt.condition)) {
+ var cond = expression (@"!$(stmt.condition)");
+ b.open_if (cond);
+ b.add_break ();
+ b.close ();
+ }
+ b.add_statement (stmt.body);
+ b.close ();
+ }
+
+ stmt.body.checked = false;
+ end_replace_statement ();
+ }
+
public override void visit_expression (Expression expr) {
if (expr in context.analyzer.replaced_nodes) {
return;
diff --git a/vala/valaflowanalyzer.vala b/vala/valaflowanalyzer.vala
index 48b850045..b6a49d203 100644
--- a/vala/valaflowanalyzer.vala
+++ b/vala/valaflowanalyzer.vala
@@ -753,6 +753,57 @@ public class Vala.FlowAnalyzer : CodeVisitor {
jump_stack.remove_at (jump_stack.size - 1);
}
+ public override void visit_while_statement (WhileStatement stmt) {
+ if (unreachable (stmt)) {
+ return;
+ }
+
+ var loop_block = new BasicBlock ();
+ all_basic_blocks.add (loop_block);
+ jump_stack.add (new JumpTarget.continue_target (loop_block));
+ var after_loop_block = new BasicBlock ();
+ all_basic_blocks.add (after_loop_block);
+ jump_stack.add (new JumpTarget.break_target (after_loop_block));
+
+ current_block.connect (loop_block);
+ current_block = loop_block;
+
+ // condition
+ loop_block.add_node (stmt.condition);
+ handle_errors (stmt.condition);
+
+ if (always_false (stmt.condition)) {
+ mark_unreachable ();
+ } else {
+ current_block = new BasicBlock ();
+ all_basic_blocks.add (current_block);
+ loop_block.connect (current_block);
+ }
+
+ if (!always_true (stmt.condition)) {
+ loop_block.connect (after_loop_block);
+ }
+
+ // loop block
+ stmt.body.accept (this);
+ // end of loop block reachable?
+ if (current_block != null) {
+ current_block.connect (loop_block);
+ }
+
+ // after loop block reachable?
+ if (after_loop_block.get_predecessors ().size == 0) {
+ // after loop block not reachable
+ mark_unreachable ();
+ } else {
+ // after loop block reachable
+ current_block = after_loop_block;
+ }
+
+ jump_stack.remove_at (jump_stack.size - 1);
+ jump_stack.remove_at (jump_stack.size - 1);
+ }
+
public override void visit_foreach_statement (ForeachStatement stmt) {
if (unreachable (stmt)) {
return;
diff --git a/vala/valawhilestatement.vala b/vala/valawhilestatement.vala
index a15b1abe8..963764bb9 100644
--- a/vala/valawhilestatement.vala
+++ b/vala/valawhilestatement.vala
@@ -81,16 +81,6 @@ public class Vala.WhileStatement : CodeNode, Statement {
body.accept (visitor);
}
- bool always_true (Expression condition) {
- var literal = condition as BooleanLiteral;
- return (literal != null && literal.value);
- }
-
- bool always_false (Expression condition) {
- var literal = condition as BooleanLiteral;
- return (literal != null && !literal.value);
- }
-
public override void replace_expression (Expression old_node, Expression new_node) {
if (condition == old_node) {
condition = new_node;
@@ -104,28 +94,25 @@ public class Vala.WhileStatement : CodeNode, Statement {
checked = true;
- // convert to simple loop
-
- if (always_true (condition)) {
- // do not generate if block if condition is always true
- } else if (always_false (condition)) {
- // do not generate if block if condition is always false
- body.insert_statement (0, new BreakStatement (condition.source_reference));
- } else {
- var if_condition = new UnaryExpression (UnaryOperator.LOGICAL_NEGATION, condition,
condition.source_reference);
- var true_block = new Block (condition.source_reference);
- true_block.add_statement (new BreakStatement (condition.source_reference));
- var if_stmt = new IfStatement (if_condition, true_block, null,
condition.source_reference);
- body.insert_statement (0, if_stmt);
- }
+ condition.target_type = context.analyzer.bool_type.copy ();
- var loop = new Loop (body, source_reference);
+ condition.check (context);
- var parent_block = (Block) parent_node;
- parent_block.replace_statement (this, loop);
+ if (condition.error) {
+ /* if there was an error in the condition, skip this check */
+ error = true;
+ return false;
+ }
+
+ if (condition.value_type == null || !condition.value_type.compatible
(context.analyzer.bool_type)) {
+ error = true;
+ Report.error (condition.source_reference, "Condition must be boolean");
+ return false;
+ }
- if (!loop.check (context)) {
+ if (!body.check (context)) {
error = true;
+ return false;
}
return !error;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]