ast_binary->right_first and an execution order check
authorWolfgang Bumiller <wry.git@bumiller.com>
Tue, 27 Aug 2013 08:42:09 +0000 (10:42 +0200)
committerWolfgang Bumiller <wry.git@bumiller.com>
Tue, 27 Aug 2013 08:42:13 +0000 (10:42 +0200)
ast.c
ast.h
tests/order.qc [new file with mode: 0644]
tests/order.tmpl [new file with mode: 0644]

diff --git a/ast.c b/ast.c
index 2a8caf2..099f7b8 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -443,6 +443,7 @@ ast_binary* ast_binary_new(lex_ctx_t ctx, int op,
     self->op = op;
     self->left = left;
     self->right = right;
+    self->right_first = false;
 
     ast_propagate_effects(self, left);
     ast_propagate_effects(self, right);
@@ -2037,6 +2038,8 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va
     if ((OPTS_FLAG(SHORT_LOGIC) || OPTS_FLAG(PERL_LOGIC)) &&
         (self->op == INSTR_AND || self->op == INSTR_OR))
     {
+        /* NOTE: The short-logic path will ignore right_first */
+
         /* short circuit evaluation */
         ir_block *other, *merge;
         ir_block *from_left, *from_right;
@@ -2134,13 +2137,21 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va
         return true;
     }
 
-    cgen = self->left->codegen;
-    if (!(*cgen)((ast_expression*)(self->left), func, false, &left))
-        return false;
-
-    cgen = self->right->codegen;
-    if (!(*cgen)((ast_expression*)(self->right), func, false, &right))
-        return false;
+    if (self->right_first) {
+        cgen = self->right->codegen;
+        if (!(*cgen)((ast_expression*)(self->right), func, false, &right))
+            return false;
+        cgen = self->left->codegen;
+        if (!(*cgen)((ast_expression*)(self->left), func, false, &left))
+            return false;
+    } else {
+        cgen = self->left->codegen;
+        if (!(*cgen)((ast_expression*)(self->left), func, false, &left))
+            return false;
+        cgen = self->right->codegen;
+        if (!(*cgen)((ast_expression*)(self->right), func, false, &right))
+            return false;
+    }
 
     *out = ir_block_create_binop(func->curblock, ast_ctx(self), ast_function_label(func, "bin"),
                                  self->op, left, right);
diff --git a/ast.h b/ast.h
index bb7a317..9b7e558 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -251,7 +251,7 @@ struct ast_binary_s
     ast_expression *left;
     ast_expression *right;
     ast_binary_ref  refs;
-
+    bool            right_first;
 };
 ast_binary* ast_binary_new(lex_ctx_t    ctx,
                            int        op,
diff --git a/tests/order.qc b/tests/order.qc
new file mode 100644 (file)
index 0000000..979d137
--- /dev/null
@@ -0,0 +1,8 @@
+float go(string x) {
+    print(x, "\n");
+    return 1;
+}
+
+void main() {
+    float x = go("A") + go("B");
+}
diff --git a/tests/order.tmpl b/tests/order.tmpl
new file mode 100644 (file)
index 0000000..7a4089f
--- /dev/null
@@ -0,0 +1,6 @@
+I: order.qc
+D: execution order check
+T: -execute
+C: -std=gmqcc
+M: A
+M: B