| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- (** Transform extern variables into getter/setter functions. *)
- (**
- In CiviC, a global variable defined in one compilation unit can be used in
- different compilation units. To do this, the variable definition needs to be
- marked with the [export] keyword in the first compilation units and other
- compilation unit need to contain a extern variable declaration.
- Unfortunately, the CiviC VM does not support exporting global variables.
- This phase solves this problem by replacing exported variables by getter and
- setter functions. This phase works in three steps.
- In the first step, getter and setter functions are added for all exported
- variables definitions and the export flag is removed from these variable
- definition. For example:
- {v export int foo;
- export int [n] bar; v}
- becomes:
- {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 void bar$set(int index, int new_value) \{
- bar[index] = new_value;
- \}
- export int bar$get(int index) \{
- return bar[index];
- \}
- export void bar$1$set(int new_value) \{
- bar$1 = new_value;
- \}
- export int bar$1$get() \{
- return bar$1;
- \} 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.
- In the second step, external variable declarations are replaced by function
- declarations for the corresponding getter and setter functions. For example:
- {v extern int foo;
- extern int[n] bar; v}
- 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}
- 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).
- In the third step, all occurrences of external variables are replaced by
- function call to a getter or setter function. For example:
- {v /* extern int foo; */
- /* extern int [n] bar; */
- export void main() \{
- bar[foo] = n;
- \} v}
- becomes:
- {v export void main() \{
- bar$set(foo$get(), bar$1$get());
- \} v}
- *)
- (** Main phase function, called by \{!Main\}. *)
- val phase : Main.phase_func
|