| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- (** 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[2] bar; v}
- becomes:
- {v int foo;
- export int _foo_get() \{
- return foo;
- \}
- export void _foo_set(int _value_1) \{
- foo = _value_1;
- \}
- int _bar_1 = 2;
- export int __bar_1_get() \{
- return _bar_1;
- \}
- export void __bar_1_set(int _value_2) \{
- _bar_1 = _value_2;
- \}
- int[_bar_1] bar;
- export int _bar_get(int _index_3) \{
- return bar[_index_3];
- \}
- export void _bar_set(int _index_4, int _value_5) \{
- bar[_index_4] = _value_5;
- \} v}
- 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
- declarations for the corresponding getter and setter functions. For example:
- {v extern int foo;
- extern int[n] bar; v}
- becomes:
- {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]. 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
- 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
|