Browse Source

Added template for bool_op phase

Taddeus Kroes 12 years ago
parent
commit
88a4200db8
4 changed files with 55 additions and 9 deletions
  1. 1 1
      Makefile
  2. 7 8
      main.ml
  3. 29 0
      phases/bool_op.ml
  4. 18 0
      test/bool_op.cvc

+ 1 - 1
Makefile

@@ -1,6 +1,6 @@
 RESULT := civicc
 PHASES := load parse print desug context_analysis expand_dims typecheck \
-	dim_reduce
+	dim_reduce bool_op
 SOURCES := ast.ml util.mli util.ml lexer.mll parser.mly stringify.mli \
 	stringify.ml $(patsubst %,phases/%.ml,$(PHASES)) main.ml
 PRE_TARGETS := ast.cmi ast.o util.cmi util.o

+ 7 - 8
main.ml

@@ -14,23 +14,22 @@ let compile args =
         Load.phase;
         (*Print.phase;*)
         Parse.phase;
-        Print.phase;
+        (*Print.phase*)
         Desug.phase;
-        Print.phase;
+        (*Print.phase*)
         Context_analysis.phase;
-        Print.phase;
+        (*Print.phase*)
         Typecheck.phase;
-        Print.phase;
+        (*Print.phase*)
         Expand_dims.phase;
+        (*Print.phase*)
+        Bool_op.phase;
         Print.phase;
+        (*
         Dim_reduce.phase;
         Print.phase;
-        (*
         Extern_vars.phase;
         Print.phase;
-        Print.phase;
-        Bool_op.phase;
-        Print.phase;
         Assemble.phase;
         Print.phase;
         Peephole.phase;

+ 29 - 0
phases/bool_op.ml

@@ -0,0 +1,29 @@
+(**
+ * The phase applies the transformations shown below. These transformations are
+ * required because the CiviC VM does not offer instructions that perform these
+ * operations. Another reason is that conjunction and disjunction require
+ * short-circuit evaluation. In the examples below, `b1` and `b2` are
+ * expressions of type boolean, `i` is of type int and `f` is of type float.
+ *
+ * > b1 == b2   ==>   (int)b1 == (int)b2
+ * > b1 != b2   ==>   (int)b1 != (int)b2
+ * > b1 && b2   ==>   b1 ? b2 : false
+ * > b1 || b2   ==>   b1 ? true : b2
+ * > b1 + b2    ==>   (bool)((int)b1 + (int)b2)
+ * > b1 * b2    ==>   (bool)((int)b1 * (int)b2)
+ * > (bool)i    ==>   i != 0
+ * > (bool)f    ==>   f != 0.0
+ * > (int)b1    ==>   b1 ? 1 : 0
+ * > (float)b1  ==>   b1 ? 1.0 : 0.0
+ *)
+open Ast
+open Util
+
+let rec bool_op = function
+    | node -> transform_children bool_op node
+
+let rec phase input =
+    prerr_endline "- Convert bool operations";
+    match input with
+    | Ast (node, args) -> Ast (bool_op node, args)
+    | _ -> raise (InvalidInput "bool operations")

+ 18 - 0
test/bool_op.cvc

@@ -0,0 +1,18 @@
+extern void printBool(bool val);
+
+void foo() {
+    bool b1;
+    bool b2;
+    int i;
+    float f;
+    printBool(b1 == b2);   // (int)b1 == (int)b2
+    printBool(b1 != b2);   // (int)b1 != (int)b2
+    printBool(b1 && b2);   // b1 ? b2 : false
+    printBool(b1 || b2);   // b1 ? true : b2
+    printBool(b1 + b2);    // (bool)((int)b1 + (int)b2)
+    printBool(b1 * b2);    // (bool)((int)b1 * (int)b2)
+    printBool((bool)i);    // i != 0
+    printBool((bool)f);    // f != 0.0
+    printBool((int)b1);    // b1 ? 1 : 0
+    printBool((float)b1);  // b1 ? 1.0 : 0.0
+}