Просмотр исходного кода

Generated variable names now have leading underscores instead of dollar signs

Taddeus Kroes 12 лет назад
Родитель
Сommit
b530c36dde
12 измененных файлов с 170 добавлено и 138 удалено
  1. 4 7
      phases/constprop.ml
  2. 30 29
      phases/constprop.mli
  3. 1 3
      phases/context.ml
  4. 6 6
      phases/desug.ml
  5. 21 21
      phases/desug.mli
  6. 20 15
      phases/extern.ml
  7. 35 32
      phases/extern.mli
  8. 3 2
      phases/index.ml
  9. 1 3
      phases/unroll.ml
  10. 10 10
      phases/unroll.mli
  11. 23 4
      util.ml
  12. 16 6
      util.mli

+ 4 - 7
phases/constprop.ml

@@ -1,6 +1,6 @@
 (**
 (**
- * The compiler sometimes generates variables of the form foo$$1, to make sure
- * that expressions are only executed once. In many cases, this leads to
+ * The compiler sometimes generates variables of the form __foo_1__, to make
+ * sure that expressions are only executed once. In many cases, this leads to
  * over-complex constructions, for example when converting for-loops to
  * over-complex constructions, for example when converting for-loops to
  * while-loops. We use the knowledge of these variables being constant by
  * while-loops. We use the knowledge of these variables being constant by
  * propagation the constant values to their occurrences, and then apply
  * propagation the constant values to their occurrences, and then apply
@@ -18,9 +18,6 @@
 open Types
 open Types
 open Util
 open Util
 
 
-let is_const_name name =
-  Str.string_match (Str.regexp "^.+\\$\\$[0-9]+$") name 0
-
 let is_const = function
 let is_const = function
   | Const _
   | Const _
   | VarUse (_, None, _) -> true
   | VarUse (_, None, _) -> true
@@ -128,7 +125,7 @@ let rec propagate consts node =
   match node with
   match node with
 
 
   (* Constant assignments are added to constants table *)
   (* Constant assignments are added to constants table *)
-  | Assign (name, None, value, ann) when is_const_name name ->
+  | Assign (name, None, value, ann) when is_const_id name ->
     let value = propagate value in
     let value = propagate value in
     if is_const value then begin
     if is_const value then begin
       Hashtbl.add consts name value;
       Hashtbl.add consts name value;
@@ -136,7 +133,7 @@ let rec propagate consts node =
     end else
     end else
       Assign (name, None, value, ann)
       Assign (name, None, value, ann)
 
 
-  | VarLet (dec, None, value, ann) when is_const_name (nameof dec) ->
+  | VarLet (dec, None, value, ann) when is_const_id (nameof dec) ->
     let value = propagate value in
     let value = propagate value in
     if is_const value then begin
     if is_const value then begin
       Hashtbl.add consts (nameof dec) value;
       Hashtbl.add consts (nameof dec) value;

+ 30 - 29
phases/constprop.mli

@@ -1,7 +1,7 @@
 (** Rudimentary constant propagation and constant folding on generated
 (** Rudimentary constant propagation and constant folding on generated
     variables. *)
     variables. *)
 
 
-(** The compiler sometimes generates variables of the form [foo$$1], to make
+(** The compiler sometimes generates variables of the form [__foo_1__], to make
     sure that expressions are only executed once. In many cases, this leads to
     sure that expressions are only executed once. In many cases, this leads to
     over-complex constructions with more variable definitions den necessary, for
     over-complex constructions with more variable definitions den necessary, for
     example when converting for-loops to while-loops. We use the knowledge of
     example when converting for-loops to while-loops. We use the knowledge of
@@ -32,44 +32,45 @@
 After desugaring and array dimension reduction this becomes:
 After desugaring and array dimension reduction this becomes:
 
 
 {v void foo() \{
 {v void foo() \{
-    int i$4$5;
-    int stop$$6;
-    int step$$7;
-    int arr$dim$$1;
-    int arr$dim$$2;
-    int const$$1;
-    int const$$2;
-    int const$$3;
+    int ____i_6_7;
+    int __arr_1_2__;
+    int __arr_2_1__;
+    int __const_3__;
+    int __const_4__;
+    int __const_5__;
     int[] arr;
     int[] arr;
-    arr$dim$$1 = 2;
-    arr$dim$$2 = 2;
-    const$$1 = 1;
-    const$$2 = 2;
-    const$$3 = 3;
-    arr = __allocate((arr$dim$$1 * arr$dim$$2));
-    arr[((0 * arr$dim$$2) + 0)] = const$$1;
-    arr[((0 * arr$dim$$2) + 1)] = const$$2;
-    i$4$5 = 0;
-    stop$$6 = arr$dim$$2;
-    step$$7 = 1;
-    while (((step$$7 > 0) ? (i$4$5 < stop$$6) : (i$4$5 > stop$$6))) \{
-        arr[((1 * arr$dim$$2) + i$4$5)] = const$$3;
-        i$4$5 = (i$4$5 + step$$7);
+    int __stop_8__;
+    int __step_9__;
+    __arr_1_2__ = 2;
+    __arr_2_1__ = 2;
+    __const_3__ = 1;
+    __const_4__ = 2;
+    __const_5__ = 3;
+    arr := <allocate>((__arr_1_2__ * __arr_2_1__));
+    arr[((0 * __arr_2_1__) + 0)] = __const_3__;
+    arr[((0 * __arr_2_1__) + 1)] = __const_4__;
+    ____i_6_7 = 0;
+    __stop_8__ = __arr_2_1__;
+    __step_9__ = 1;
+    while (((__step_9__ > 0) ? (____i_6_7 < __stop_8__) : (____i_6_7 > __stop_8__))) \{
+        arr[((1 * __arr_2_1__) + ____i_6_7)] = __const_5__;
+        ____i_6_7 = (____i_6_7 + __step_9__);
     \}
     \}
+
 \} v}
 \} v}
 
 
 Constant propagation reduces this to:
 Constant propagation reduces this to:
 
 
 {v void foo() \{
 {v void foo() \{
-    int i$4$5;
+    int ____i_6_7;
     int[] arr;
     int[] arr;
-    arr = __allocate(4);
+    arr := <allocate>(4);
     arr[0] = 1;
     arr[0] = 1;
     arr[1] = 2;
     arr[1] = 2;
-    i$4$5 = 0;
-    while ((i$4$5 < 2)) \{
-        arr[(2 + i$4$5)] = 3;
-        i$4$5 = (i$4$5 + 1);
+    ____i_6_7 = 0;
+    while ((____i_6_7 < 2)) \{
+        arr[(2 + ____i_6_7)] = 3;
+        ____i_6_7 = (____i_6_7 + 1);
     \}
     \}
 \} v}
 \} v}
     *)
     *)

+ 1 - 3
phases/context.ml

@@ -9,8 +9,6 @@ let type2str = function Funcname _ -> "function" | Varname _ -> "variable"
 let mapfind name tbl =
 let mapfind name tbl =
   if Hashtbl.mem tbl name then Some (Hashtbl.find tbl name) else None
   if Hashtbl.mem tbl name then Some (Hashtbl.find tbl name) else None
 
 
-let is_generated name = String.contains name '$'
-
 let check_in_scope name errnode scope =
 let check_in_scope name errnode scope =
   let (vars, funs) = scope in
   let (vars, funs) = scope in
   let (name, tbl, other_map, desired_type) = match name with
   let (name, tbl, other_map, desired_type) = match name with
@@ -39,7 +37,7 @@ let add_to_scope name dec depth (vars, funs) =
     (* For generated variables, don't gove an error, since the error variable
     (* For generated variables, don't gove an error, since the error variable
      * is a derived array dimension of a redefined array, which will yield an
      * is a derived array dimension of a redefined array, which will yield an
      * error later on *)
      * error later on *)
-    if is_generated name then
+    if is_generated_id name then
       Hashtbl.replace tbl name (dec, depth, name_type)
       Hashtbl.replace tbl name (dec, depth, name_type)
     else
     else
       let msg = sprintf "Error: cannot redeclare %s \"%s\"" name_type name in
       let msg = sprintf "Error: cannot redeclare %s \"%s\"" name_type name in

+ 6 - 6
phases/desug.ml

@@ -57,7 +57,7 @@ let rec array_dims node =
     (* Names for VarDec dimensions must be unique to avoid weid errors when
     (* Names for VarDec dimensions must be unique to avoid weid errors when
      * during context analysis, when an array variable is redeclared within the
      * during context analysis, when an array variable is redeclared within the
      * same scope *)
      * same scope *)
-    let make_dimname i _ = fresh_const (name ^ "$" ^ string_of_int (i + 1)) in
+    let make_dimname i _ = fresh_const (name ^ "_" ^ string_of_int (i + 1)) in
 
 
     let make_dec value name = VarDec (Int, name, Some value, []) in
     let make_dec value name = VarDec (Int, name, Some value, []) in
     let (decs, dims) = make_dims make_dimname values make_dec in
     let (decs, dims) = make_dims make_dimname values make_dec in
@@ -65,9 +65,9 @@ let rec array_dims node =
 
 
   | GlobalDef (export, ArrayDims (ctype, values), name, init, ann) ->
   | GlobalDef (export, ArrayDims (ctype, values), name, init, ann) ->
     (* For global decs, the name must be derived from the array base name, but
     (* For global decs, the name must be derived from the array base name, but
-     * not constant (no $$in the name) since the variable must exist for
-     * exporting (and not pruned during constant propagation) *)
-    let make_dimname i _ = name ^ "$" ^ string_of_int (i + 1) in
+     * not constant (no trailing __) since the variable must exist for exporting
+     * (and not pruned during constant propagation) *)
+    let make_dimname i _ = generate_id name (i + 1) in
 
 
     let make_dec value name = GlobalDef (export, Int, name, Some value, []) in
     let make_dec value name = GlobalDef (export, Int, name, Some value, []) in
     let (decs, dims) = make_dims make_dimname values make_dec in
     let (decs, dims) = make_dims make_dimname values make_dec in
@@ -200,7 +200,7 @@ let for_to_while node =
 
 
     (* Transform for-loops to while-loops *)
     (* Transform for-loops to while-loops *)
     | For (counter, start, stop, step, body, ann) ->
     | For (counter, start, stop, step, body, ann) ->
-      let _i = fresh_var counter in
+      let _i = fresh_id counter in
       let _stop = fresh_const "stop" in
       let _stop = fresh_const "stop" in
       let _step = fresh_const "step" in
       let _step = fresh_const "step" in
       (*new_vars := !new_vars @ [_i; _stop; _step];*)
       (*new_vars := !new_vars @ [_i; _stop; _step];*)
@@ -284,7 +284,7 @@ let rec array_init = function
       | [] ->
       | [] ->
         array_init (Assign (name, Some indices, value, ann))
         array_init (Assign (name, Some indices, value, ann))
       | dim :: rest ->
       | dim :: rest ->
-        let counter = fresh_var "i" in
+        let counter = fresh_id "i" in
         let start = Const (IntVal 0, []) in
         let start = Const (IntVal 0, []) in
         let step = Const (IntVal 1, []) in
         let step = Const (IntVal 1, []) in
         let body = Block [add_loop (indices @ [Var (counter, None, [])]) rest] in
         let body = Block [add_loop (indices @ [Var (counter, None, [])]) rest] in

+ 21 - 21
phases/desug.mli

@@ -96,19 +96,19 @@ void foo() \{
     and constant propagation):
     and constant propagation):
 {v ...
 {v ...
 void foo() \{
 void foo() \{
-  int a$dim$$2;
-  int const$$1;
-  int const$$2;
-  int[2, a$dim$$2] a;
-  a$dim$$2 = two();
-  const$$1 = two();
-  const$$2 = two();
-  a = __allocate(2 * a$dim$$2);
-  a[0] = 1;
-  a[1] = const$$1;
-  a[a$dim$$2)] = 1;
-  a[a$dim$$2) + 1] = const$$2;
-  printInt(a[(1 * a$dim$$2) + 1]);
+    int _a_2_1_;
+    int _const_4_;
+    int _const_6_;
+    int[] a;
+    _a_2_1_ = two();
+    _const_4_ = two();
+    _const_6_ = two();
+    a := <allocate>((2 * _a_2_1_));
+    a[0] = 1;
+    a[1] = _const_4_;
+    a[_a_2_1_] = 1;
+    a[(_a_2_1_ + 1)] = _const_6_;
+    printInt(a[(_a_2_1_ + 1)]);
 \} v}
 \} v}
 
 
 
 
@@ -121,17 +121,17 @@ void foo() \{
 
 
     is transformed into:
     is transformed into:
 
 
-{v i$1 = <start>;
-step$2 = <step>;
-stop$3 = <stop>;
-while ((step$2 > 0) ? (i$1 < stop$3) : (i$1 > stop$3)) \{
+{v _i_1 = <start>;
+_step_2 = <step>;
+_stop_3 = <stop>;
+while ((_step_2 > 0) ? (_i_1 < _stop_3) : (_i_1 > _stop_3)) \{
     <body>
     <body>
-    i$1 = i$1 + step$2;
+    _i_1 = _i_1 + _step_2;
 \} v}
 \} v}
 
 
-    Here, [i$1], [step$2] and [stop$3] are fresh variables. Definitions of these
-    new variables are added to the scope of the current function. Every
-    occurrence of [i] in [<body>] is replaced with the fresh variable [i$1],
+    Here, [_i_1], [_step_2] and [_stop_3] are fresh variables. Definitions of
+    these new variables are added to the scope of the current function. Every
+    occurrence of [i] in [<body>] is replaced with the fresh variable [_i_1],
     this prevents problems with nested for-loops that use the same induction
     this prevents problems with nested for-loops that use the same induction
     variable.
     variable.
     *)
     *)

+ 20 - 15
phases/extern.ml

@@ -12,22 +12,27 @@ let call node args depth =
     FunUse (dec, args, [Type ctype; Depth depth])
     FunUse (dec, args, [Type ctype; Depth depth])
   | _ -> raise InvalidNode
   | _ -> raise InvalidNode
 
 
+let generate_name name postfix = "_" ^ name ^ "_" ^ postfix
+let getname name = generate_name name "get"
+let setname name = generate_name name "set"
+
 let create_getset globals = function
 let create_getset globals = function
   | GlobalDef (true, ArrayDims (ctype, _), name, None, ann) as dec ->
   | GlobalDef (true, ArrayDims (ctype, _), name, None, ann) as dec ->
     (* Getters for array variable: create getter for given index Note that
     (* Getters for array variable: create getter for given index Note that
      * getters and setters for dimensions are automatically generated,
      * getters and setters for dimensions are automatically generated,
      * because they have been put into new global variables during the
      * because they have been put into new global variables during the
      * desugaring phase *)
      * desugaring phase *)
-    let (param, index) = create_param Int (fresh_var "index") in
+    let (param, index) = create_param Int (fresh_id "index") in
     let var = VarUse (dec, Some [index], [Type ctype; Depth 1]) in
     let var = VarUse (dec, Some [index], [Type ctype; Depth 1]) in
     let body = Block [Return (var, [])] in
     let body = Block [Return (var, [])] in
-    let getter = FunDef (true, ctype, name ^ "$get", [param], body, []) in
+    let getter = FunDef (true, ctype, getname name, [param], body, []) in
 
 
     (* Setters for array variable: create setter for given index *)
     (* Setters for array variable: create setter for given index *)
-    let (param1, index) = create_param Int (fresh_var "index") in
-    let (param2, value) = create_param ctype (fresh_var "value") in
+    let (param1, index) = create_param Int (fresh_id "index") in
+    let (param2, value) = create_param ctype (fresh_id "value") in
+    let params = [param1; param2] in
     let body = Block [VarLet (dec, Some [index], value, [])] in
     let body = Block [VarLet (dec, Some [index], value, [])] in
-    let setter = FunDef (true, Void, name ^ "$set", [param1; param2], body, []) in
+    let setter = FunDef (true, Void, setname name, params, body, []) in
 
 
     [getter; setter]
     [getter; setter]
 
 
@@ -35,12 +40,12 @@ let create_getset globals = function
     (* Getter for basic variable type: return the variable *)
     (* Getter for basic variable type: return the variable *)
     let var = VarUse (dec, None, [Type ctype; Depth 1]) in
     let var = VarUse (dec, None, [Type ctype; Depth 1]) in
     let body = [Return (var, [])] in
     let body = [Return (var, [])] in
-    let getter = FunDef (true, ctype, name ^ "$get", [], Block body, []) in
+    let getter = FunDef (true, ctype, getname name, [], Block body, []) in
 
 
     (* Setter for basic variable type: assign the variable *)
     (* Setter for basic variable type: assign the variable *)
-    let (param, value) = create_param ctype (fresh_var "value") in
+    let (param, value) = create_param ctype (fresh_id "value") in
     let body = [VarLet (dec, None, value, [])] in
     let body = [VarLet (dec, None, value, [])] in
-    let setter = FunDef (true, Void, name ^ "$set", [param], Block body, []) in
+    let setter = FunDef (true, Void, setname name, [param], Block body, []) in
 
 
     [getter; setter]
     [getter; setter]
 
 
@@ -51,12 +56,12 @@ let create_getset globals = function
     let rec add_dims i = function
     let rec add_dims i = function
       | [] -> []
       | [] -> []
       | Dim (dimname, ann) :: tl ->
       | Dim (dimname, ann) :: tl ->
-        let newname = name ^ "$" ^ string_of_int i in
+        let newname = generate_id name i in
 
 
-        let getter = FunDec (ctype, newname ^ "$get", [], []) in
+        let getter = FunDec (ctype, getname newname, [], []) in
 
 
         let (param, _) = create_param ctype "value" in
         let (param, _) = create_param ctype "value" in
-        let setter = FunDec (Void, newname ^ "$set", [param], []) in
+        let setter = FunDec (Void, setname newname, [param], []) in
 
 
         Hashtbl.add globals dimname (call getter, call setter);
         Hashtbl.add globals dimname (call getter, call setter);
         getter :: setter :: (add_dims (i + 1) tl)
         getter :: setter :: (add_dims (i + 1) tl)
@@ -65,21 +70,21 @@ let create_getset globals = function
     let dimfuncs = add_dims 1 dims in
     let dimfuncs = add_dims 1 dims in
 
 
     let (param, _) = create_param Int "index" in
     let (param, _) = create_param Int "index" in
-    let getter = FunDec (ctype, name ^ "$get", [param], []) in
+    let getter = FunDec (ctype, getname name, [param], []) in
 
 
     let (param1, index) = create_param Int "index" in
     let (param1, index) = create_param Int "index" in
     let (param2, value) = create_param ctype "value" in
     let (param2, value) = create_param ctype "value" in
-    let setter = FunDec (Void, name ^ "$set", [param1; param2], []) in
+    let setter = FunDec (Void, setname name, [param1; param2], []) in
 
 
     Hashtbl.add globals name (call getter, call setter);
     Hashtbl.add globals name (call getter, call setter);
     getter :: setter :: dimfuncs
     getter :: setter :: dimfuncs
 
 
   (* Getter for basic variable type: return the variable *)
   (* Getter for basic variable type: return the variable *)
   | GlobalDec (ctype, name, ann) ->
   | GlobalDec (ctype, name, ann) ->
-    let getter = FunDec (ctype, name ^ "$get", [], []) in
+    let getter = FunDec (ctype, getname name, [], []) in
 
 
     let (param, _) = create_param ctype "value" in
     let (param, _) = create_param ctype "value" in
-    let setter = FunDec (Void, name ^ "$set", [param], []) in
+    let setter = FunDec (Void, setname name, [param], []) in
 
 
     Hashtbl.add globals name (call getter, call setter);
     Hashtbl.add globals name (call getter, call setter);
     [getter; setter]
     [getter; setter]

+ 35 - 32
phases/extern.mli

@@ -16,43 +16,44 @@
 
 
 
 
 {v export int foo;
 {v export int foo;
-export int [n] bar; v}
+export int[2] bar; v}
 
 
     becomes:
     becomes:
 
 
 {v int foo;
 {v int foo;
-int bar$1;
-int [bar$1] bar;
 
 
-export void foo$set(int new_value) \{
-    foo = new_value;
+export int _foo_get() \{
+    return foo;
 \}
 \}
 
 
-export int foo$get() \{
-    return foo;
+export void _foo_set(int _value_1) \{
+    foo = _value_1;
 \}
 \}
 
 
-export void bar$set(int index, int new_value) \{
-    bar[index] = new_value;
+int _bar_1 = 2;
+
+export int __bar_1_get() \{
+    return _bar_1;
 \}
 \}
 
 
-export int bar$get(int index) \{
-    return bar[index];
+export void __bar_1_set(int _value_2) \{
+    _bar_1 = _value_2;
 \}
 \}
 
 
-export void bar$1$set(int new_value) \{
-    bar$1 = new_value;
+int[_bar_1] bar;
+
+export int _bar_get(int _index_3) \{
+    return bar[_index_3];
 \}
 \}
 
 
-export int bar$1$get() \{
-    return bar$1;
+export void _bar_set(int _index_4, int _value_5) \{
+    bar[_index_4] = _value_5;
 \} v}
 \} v}
 
 
-
-Note that array dimensions are renamed during the desugaring phase, [n] is
-renamed to [bar$1] because it is the first dimension of bar. After that, it is
-handled as a regulary exported integer for which setter and getter functions are
-created.
+Note that array dimensions are renamed during the desugaring phase, [2] is
+moved to a variable [_bar_1] because it is the first dimension of [bar]. After
+that, it is handled as a regulary exported integer for which setter and getter
+functions are created implicitly.
 
 
 In the second step, external variable declarations are replaced by function
 In the second step, external variable declarations are replaced by function
 declarations for the corresponding getter and setter functions. For example:
 declarations for the corresponding getter and setter functions. For example:
@@ -63,16 +64,17 @@ extern int[n] bar; v}
 
 
     becomes:
     becomes:
 
 
-{v extern void foo$set(int new_value);
-extern int foo$get();
-extern void bar$set(int index, int new_value);
-extern int bar$get(int index);
-extern int bar$1$get(int new_value);
-extern int bar$1$set(int index, int new_value); v}
+{v extern int _foo_get();
+extern void _foo_set(int value);
+extern int _bar_get(int index);
+extern void _bar_set(int index, int value);
+extern int __bar_1_get();
+extern void __bar_1_set(int value); v}
 
 
-Again, note that [n] is renamed to [bar$1]. This is, however, not done during
-the desugaring phase, since the dimensions are not prevented from being
-evaluated more than once (See {!Desug} for an explanation about this).
+Again, note that [n] is renamed to [_bar_1]. Also note that this is not already
+done during the desugaring phase for external arrays, since the dimensions are
+not prevented from being evaluated more than once (See {!Desug} for an
+explanation about this).
 
 
 In the third step, all occurrences of external variables are replaced by
 In the third step, all occurrences of external variables are replaced by
 function call to a getter or setter function. For example:
 function call to a getter or setter function. For example:
@@ -85,10 +87,11 @@ export void main() \{
 
 
     becomes:
     becomes:
 
 
-{v export void main() \{
-    bar$set(foo$get(), bar$1$get());
+{v ...
+export void main() \{
+    _bar_set(_foo_get(), __bar_1_get());
 \} v}
 \} v}
 
 
     *)
     *)
-(** Main phase function, called by \{!Main\}. *)
+(** Main phase function, called by {!Main}. *)
 val phase : Main.phase_func
 val phase : Main.phase_func

+ 3 - 2
phases/index.ml

@@ -19,9 +19,10 @@ let tag_index program =
       annotate (Index index) (transform_children trav node)
       annotate (Index index) (transform_children trav node)
 
 
     | FunDef (export, rtype, name, params, body, ann) ->
     | FunDef (export, rtype, name, params, body, ann) ->
-      (* label name for local function is "<parent_label>$<name>" *)
+      (* label name for local function is "__<parent_label>_<name>" *)
       let callstack = name :: callstack in
       let callstack = name :: callstack in
-      let label = String.concat "$" (List.rev callstack) in
+      let prefix = if List.length callstack > 1 then "__" else "" in
+      let label = prefix ^ String.concat "_" (List.rev callstack) in
 
 
       let stacklen = ref 0 in
       let stacklen = ref 0 in
       let trav = tag stacklen callstack in
       let trav = tag stacklen callstack in

+ 1 - 3
phases/unroll.ml

@@ -5,8 +5,6 @@ open Util
 let may_be_unrolled i_values body =
 let may_be_unrolled i_values body =
   List.length i_values * List.length body <= 25
   List.length i_values * List.length body <= 25
 
 
-let is_generated s = Str.string_match (Str.regexp "^.+\\$[0-9]+$") s 0
-
 let rec range i j step =
 let rec range i j step =
   if i >= j then [] else i :: (range (i + step) j step)
   if i >= j then [] else i :: (range (i + step) j step)
 
 
@@ -56,7 +54,7 @@ let rec unroll_body counters = function
       _),
       _),
       Block body,
       Block body,
     _) as loop) :: tl
     _) as loop) :: tl
-    when is_generated i & comp = i ->
+    when is_generated_id i & comp = i ->
       begin
       begin
         match get_body_step i [] body with
         match get_body_step i [] body with
         | Some (step, rest) ->
         | Some (step, rest) ->

+ 10 - 10
phases/unroll.mli

@@ -20,23 +20,23 @@
     After desugaring and constant propagation, this has been transformed into:
     After desugaring and constant propagation, this has been transformed into:
 
 
 {v void foo() \{
 {v void foo() \{
-    int i$2$4;
-    int i$3$7;
+    int _i_6;
+    int _i_9;
     int[] arr;
     int[] arr;
     arr := <allocate>(6);
     arr := <allocate>(6);
-    i$2$4 = 0;
-    while ((i$2$4 < 2)) \{
-        i$3$7 = 0;
-        while ((i$3$7 < 3)) \{
-            arr[((i$2$4 * 3) + i$3$7)] = 1;
-            i$3$7 = (i$3$7 + 1);
+    _i_6 = 0;
+    while ((_i_6 < 2)) \{
+        _i_9 = 0;
+        while ((_i_9 < 3)) \{
+            arr[((_i_6 * 3) + _i_9)] = 1;
+            _i_9 = (_i_9 + 1);
         \}
         \}
-        i$2$4 = (i$2$4 + 1);
+        _i_6 = (_i_6 + 1);
     \}
     \}
 \} v}
 \} v}
 
 
     Now, the loops are unrolled (first the inner loop, then the outer loop) and
     Now, the loops are unrolled (first the inner loop, then the outer loop) and
-    constant folding is applied to [arr[((i$2$4 * 3) + i$3$7)]] in each
+    constant folding is applied to [arr[((_i_6 * 3) + _i_9)]] in each
     iteration:
     iteration:
 
 
 {v void foo() \{
 {v void foo() \{

+ 23 - 4
util.ml

@@ -25,14 +25,33 @@ let log_node verbosity node =
   if Globals.args.verbose >= verbosity then prt_node node
   if Globals.args.verbose >= verbosity then prt_node node
 
 
 (* Variable generation *)
 (* Variable generation *)
+
+let generate_id id num =
+  "_" ^ id ^ "_" ^ string_of_int num
+
 let var_counter = ref 0
 let var_counter = ref 0
-let fresh_var prefix =
+
+let fresh_id base =
+  (* For generated variables, just replace the counter *)
+  let base =
+    if string_match (regexp "^_\\(.+\\)_[0-9]+_?$") base 0 then
+      matched_group 1 base
+    else
+      base
+  in
   var_counter := !var_counter + 1;
   var_counter := !var_counter + 1;
-  prefix ^ "$" ^ string_of_int !var_counter
+  generate_id base !var_counter
 
 
-(* Constants are marked by a double $$ for recognition during constant
+(* Constants are marked by a leading _ for recognition during constant
  * propagation *)
  * propagation *)
-let fresh_const prefix = fresh_var (prefix ^ "$")
+let fresh_const id = fresh_id id ^ "_"
+
+let is_generated_id id = String.length id >= 1 & id.[0] = '_'
+
+let is_const_id id =
+  String.length id >= 2
+  & id.[0] = '_'
+  & id.[String.length id - 1] = '_'
 
 
 let loc_from_lexpos pstart pend =
 let loc_from_lexpos pstart pend =
   let (fname, ystart, yend, xstart, xend) = begin
   let (fname, ystart, yend, xstart, xend) = begin

+ 16 - 6
util.mli

@@ -2,16 +2,26 @@
 
 
 (** {2 Generating variables} *)
 (** {2 Generating variables} *)
 
 
-(** Generate a new variable from a given prefix, e.g. ["foo"] becomes ["foo$1"].
-    Uses an [int] reference defined in the implementation file as a counter to
-    assert uniqueness of the generated variable. *)
-val fresh_var : string -> string
+(** Generate a new identifier from a given base, e.g. ["foo"] becomes
+    ["_foo_1"]. Uses an [int] reference defined in the implementation file as a
+    counter to assert uniqueness of the generated variable. *)
+val fresh_id : string -> string
 
 
 (** Generate a new constant (a variable that is known to be assigned only once
 (** Generate a new constant (a variable that is known to be assigned only once
-    in total) from a given prefix, e.g. ["foo"] becomes ["foo$$1"]. Uses the
-    same counter as {!fresh_var}. *)
+    in total) from a given id, e.g. ["foo"] becomes ["_foo_1_"]. Uses the same
+    counter as {!fresh_id}. *)
 val fresh_const : string -> string
 val fresh_const : string -> string
 
 
+(** Check if an identifier is generated by the compiler. *)
+val is_generated_id : string -> bool
+
+(** Check if an identifier is a constant generated by the compiler. *)
+val is_const_id : string -> bool
+
+(** Generate an identifier from a base and a number. E.g., [generate_id "foo"
+    1] returns ["_foo_1"]*)
+val generate_id : string -> int -> string
+
 (** {2 AST traversal} *)
 (** {2 AST traversal} *)
 
 
 (** Default transformation traversal for AST nodes of arbitrary constructor.
 (** Default transformation traversal for AST nodes of arbitrary constructor.