source: to-imperative/trunk/compiler/rfp_vars.rf @ 1231

Last change on this file since 1231 was 1231, checked in by orlov, 17 years ago
  • Fixed $iter compilation.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.9 KB
Line 
1// $Source$
2// $Revision: 1231 $
3// $Date: 2003-08-15 13:30:23 +0000 (Fri, 15 Aug 2003) $
4
5$use Arithm Box Class Convert Dos StdIO Table;
6
7$use "rfp_helper";
8$use "rfp_list";
9$use "rfpc";
10
11
12
13Var? (s.tag t.name), s.tag : \{ SVAR; TVAR; VVAR; EVAR; VAR; };
14
15
16//***************************** Free indices. ******************************
17//
18//$table Free-Indices;
19//
20//
21//$func Free-Index e.key = s.idx;
22//
23//Free-Index e.key, {
24//  <Lookup &Free-Indices e.key> : s.idx = s.idx;
25//  1;
26//};
27//
28//
29//$func Set-Index (e.key) s.idx = ;
30//
31//Set-Index (e.key) s.idx = <Bind &Free-Indices (e.key) (s.idx)>;
32
33
34*************** Functions to deal with sets of variables. ****************
35
36$box State;
37
38Vars-Copy-State = <Box <? &State>>;
39
40Vars-Set-State s.state = <Store &State <? s.state>>;
41
42
43Init-Vars =
44  <Store &State /*empty*/>;
45//  <RFP-Clear-Table &Free-Indices>;
46
47
48
49$func Normalize-Info e.info t.var = ;
50
51Normalize-Info e.info t.var =
52  /*
53   * Если дана длина, приравнять к ней минимум и максимум.
54   */
55  {
56    e.info : e (Length e.len) e =
57      {
58        e.info : e1 (Min e.min) e2 =
59          {
60            e.min : e.len = e.info;
61            (Min e.len) e1 e2;
62          };
63        (Min e.len) e.info;
64      } :: e.info,
65      {
66        e.info : e1 (Max e.max) e2 =
67          {
68            e.max : e.len = e.info;
69            e1 e2 (Max e.len);
70          };
71        e.info (Max e.len);
72      };
73    e.info;
74  } :: e.info,
75  /*
76   * Если минимум не установлен, установить его, исходя из типа переменной.
77   */
78  {
79    e.info : e (Min e) e = e.info;
80    t.var : {
81      (SVAR e) = 1;
82      (TVAR e) = 1;
83      (VVAR e) = 1;
84      (EVAR e) = 0;
85      ( VAR e) = 0;
86    } :: s.min =
87      e.info (Min s.min);
88  } :: e.info,
89  /*
90   * Для s- и t-переменных установить максимум, если не установлен.
91   */
92  {
93    t.var : \{ (SVAR e); (TVAR e); } =
94      {
95        e.info : e (Max e) e = e.info;
96        e.info (Max 1);
97      };
98    e.info;
99  } :: e.info,
100  /*
101   * Если минимум совпадает с максимумом, то установить длину.
102   * FIXME: не нужно ли здесь упрощать выражения для минимума и максимума?
103   */
104  {
105    e.info : e (Length e) e = e.info;
106    e.info : e (Max s.max) e, e.info : e (Min s.max) e = e.info (Length s.max);
107    e.info;
108  } :: e.info,
109  /*
110   * Если переменная получила значение, а длина её не была известна, значит
111   * она будет считаться функцией LENGTH в ран-тайм.
112   */
113  {
114    e.info : e (Length e) e = e.info;
115    e.info : e (Instantiated? True) e = e.info (Length (LENGTH t.var));
116    e.info;
117  } :: e.info,
118  <Put &State (t.var e.info)>;
119
120Set-Var e.info t.var, {
121  <? &State> : $r e1 (t.var e.old-info) e2 =
122    e.old-info (e.info) (/*e.new-info*/) $iter {
123      e.old-info : (t.key e.val) e.rest, {
124        e.info : e3 (t.key e.new-val) e4 = e3 e4 (t.key e.new-val);
125        e.info (t.key e.val);
126      } :: e.info t.item =
127        e.rest (e.info) (e.new-info t.item);
128    } :: e.old-info (e.info) (e.new-info),
129    e.old-info : /*empty*/ =
130    <Store &State e1 e2>,
131    e.info e.new-info t.var;
132  e.info t.var;
133} :: e.info t.var =
134  <Normalize-Info e.info t.var>;
135
136Get-Var t.key t.var,
137  <? &State> : $r e1 (t.var e.info) e2 =
138  {
139    e.info : e (t.key e.val) e = e.val;
140    /*empty*/;
141  };
142
143Set-Var- e.info t.var = <Set-Var e.info t.var>;
144
145
146
147$func Reset-Var e = e;
148
149Vars-Reset e.vars = <Map &Reset-Var (e.vars)> : e;
150
151
152Reset-Var t.var =
153  <? &State> : $r e1 (t.var e (Decl s.decl) e) e2,
154  <Store &State e1 e2>,
155  <Normalize-Info (Instantiated? True) (Decl s.decl) t.var>;
156
157
158
159$func Print-Var e = e;
160
161Vars-Print e.vars = <Map &Print-Var (e.vars)>;
162
163Print-Var {
164  (s.tag (e.name)) = (s.tag (<To-Word e.name>));
165  (s.tag s.box)    = (s.tag s.box);
166};
167
168
169
170$func Decl-Var e = e;
171
172Vars-Decl e.vars = <Map &Decl-Var (e.vars)>;
173
174
175Decl-Var t.var, {
176  <Get-Var Decl t.var> : s.box;
177  <Box (DECL "Expr" <Print-Var t.var>)> :: s.decl,
178    <Set-Var (Decl s.decl) t.var>,
179    (Declare s.decl);
180
181//!     <? &State> : $r e1 (t.var tag t.min t.max s.decl e.rest) e2 =
182//!             {
183//!                     <Box? s.decl> = s.decl;
184//!                     <Box (DECL "Expr" <Print-Var t.var>)> :: s.decl,
185//!                             <Store &State e1 (t.var tag t.min t.max s.decl e.rest) e2>,
186//!                             s.decl;
187//!             } :: s.decl,
188//!             (Declare s.decl);
189//!
190//!     <Create-Var t.var> : e, <Decl-Var t.var>;
191};
192
193
194
195Create-Int-Var (e.prefix) t.var e.expr, {
196  t.var : Aux = (VAR <Box 0 e.prefix>);
197  (VAR <Box 1 e.prefix t.var>);
198} :: t.int-var =
199  t.int-var (INT t.int-var e.expr);
200
201
202
203
204/*
205 */
206Gener-Vars (e.format) e.prefix =
207  {
208    e.format : (s.tag) e.Fe, {
209      s.tag : \{ EVAR; VVAR; TVAR; SVAR; } =
210        (s.tag <Box 0 e.prefix>) <Gener-Vars (e.Fe) e.prefix>;
211      (s.tag <Box 1 e.prefix>) <Gener-Vars (e.Fe) e.prefix>;
212    };
213    e.format : (PAREN v1) e2 =
214      (PAREN <Gener-Vars (v1) e.prefix>) <Gener-Vars (e2) e.prefix>;
215    e.format : t.Ft e.Fe =
216      t.Ft <Gener-Vars (e.Fe) e.prefix>;
217    /*empty*/;
218  };
219
220Gener-Err-Var = (EVAR <Box 2>);
221
222
223Gener-Subst-Vars (e.format) e.prefix = <Gener-Vars (e.format) (Subst) e.prefix>;
224
225
226Substitutable-Var? (s.tag s.box) =
227  s.tag : \{ EVAR; VVAR; TVAR; SVAR; },
228  <? s.box> : 0 (Subst) e;
229
230
231/*
232 * (s.tag s.box) -- сгенерированная ранее переменная.
233 * Вместо того, чтобы присвоить её значение переменной t.var, мы подставляем
234 * t.var во все места, гда была использована (s.tag s.box).  Таким образом,
235 * t.var получит нужное значение в тот момент, когда выполняется присваивание в
236 * (s.tag s.box).
237 * Если переменная t.var уже была ранее декларирована, чтобы избежать повторной
238 * декларации, делаем декларацию для (s.tag s.box) пустой.
239 * Если же переменная t.var -- новая, то её декларацией становится декларация
240 * (s.tag s.box).
241 */
242Gener-Var-Assign t.var (s.tag s.box) =
243  <Store s.box <Print-Var t.var>>,
244  {
245    <Get-Var Decl t.var> : s =
246      <Get-Var Decl (s.tag s.box)> : s.decl-box,
247      <Store s.decl-box /*empty*/>;
248    <Set-Var (Decl <Get-Var Decl (s.tag s.box)>) t.var>;
249  };
250
251
252$box Var-Names;
253
254$table Var-Indices;
255
256$func Boxes-To-Vars e.expr-with-boxes = e.expr-with-var-names;
257
258$func Gener-Name s.form-one? s.name = s.unique-name;
259
260
261Gener-Var-Names expr =
262  <Store &Var-Names /*empty*/>,
263  <RFP-Clear-Table &Var-Indices>,
264  <Boxes-To-Vars expr>;
265
266
267Boxes-To-Vars {
268  (s.tag s.box) expr, s.tag : \{ EVAR; VVAR; TVAR; SVAR; VAR; } =
269    <? s.box> : {
270      0 e.name =
271        { e.name : (Subst) e.n = e.n; e.name; } :: e.name,
272        (VAR (<Gener-Name From-One <To-Word e.name>>)) :: t.var,
273        <Store s.box t.var>,
274        t.var <Boxes-To-Vars expr>;
275      1 e.prefix t.var =
276        <Boxes-To-Vars t.var> : {
277          (REF (e s.name)) = s.name;
278          (s (e.name)) = e.name;
279        } :: e.name,
280        (VAR (<Gener-Name From-Two <To-Word e.prefix e.name>>)) :: t.var,
281        <Store s.box t.var>,
282        t.var <Boxes-To-Vars expr>;
283      2 =
284        ERROR-EXPR <Boxes-To-Vars expr>;
285      t.var = <Boxes-To-Vars t.var expr>;
286    };
287  (Declare s.decl) expr = <Boxes-To-Vars <? s.decl> expr>;
288  (e1) e2   = (<Boxes-To-Vars e1>) <Boxes-To-Vars e2>;
289  term expr = term <Boxes-To-Vars expr>;
290  /*empty*/ = /*empty*/;
291};
292
293
294Gener-Name s.form-one? s.name =
295  {
296    <Lookup &Var-Indices s.name>;
297    0;
298  } : s.idx,
299  <"+" s.idx 1> :: s.idx,
300  <Bind &Var-Indices (s.name) (s.idx)>,
301  {
302    # \{ s.form-one? : From-One; }, s.idx : 1 = /*empty*/;
303    s.idx;
304  } :: e.idx,
305  <To-Word s.name e.idx> :: s.n,
306  {
307    <? &Var-Names> : $r e s.n e = <Gener-Name s.form-one? s.name>;
308    <Put &Var-Names s.n>, s.n;
309  };
310
311
312
313/*
314 * Generates indexes for all variables in e.Format and returns e.Format with all
315 * (?VAR) changed to (?VAR (e.Name)) and s.max.
316 * e.Name is all words from e.prefix plus unical number. Numbers are generated
317 * sequentially starting with s.num.
318 * s.max is the maximum of all generated numbers plus one.
319 * All normal variables from e.Format are returned as they are.
320 */
321Gener-Var-Indices s.num (e.Format) e.prefix, {
322  e.Format : t.Ft e.rest, t.Ft : {
323    s.ObjectSymbol = t.Ft <Gener-Var-Indices s.num (e.rest) e.prefix>;
324    (REF e) = t.Ft <Gener-Var-Indices s.num (e.rest) e.prefix>;
325    (PAREN e.Fe) =
326      <Gener-Var-Indices s.num (e.Fe) e.prefix> :: expr s.num,
327      (PAREN expr) <Gener-Var-Indices s.num (e.rest) e.prefix>;
328    (s.VariableTag) =
329      (s.VariableTag (PRAGMA) (e.prefix s.num)) :: t.var,
330      <"+" s.num 1> :: s.num,
331      t.var <Gener-Var-Indices s.num (e.rest) e.prefix>;
332    (s.VariableTag e.Name) = t.Ft <Gener-Var-Indices s.num (e.rest) e.prefix>;
333  };
334  /*
335   * e.Format is empty, so return s.num -- the last term in the answer.
336   */
337  s.num;
338};
339
340
341
342Vars e.expr =
343  e.expr () $iter {
344    e.expr : t.first e.rest,
345      t.first : {
346        s.ObjectSymbol = /*empty*/;
347        (REF t.Name) = /*empty*/;
348        (STATIC t.Name) = /*empty*/;
349        (PAREN e.ResultExpression) = <Vars e.ResultExpression>;
350        (CALL (PRAGMA (e) e) t.Fname e.ResultExpression) =
351          <Vars e.ResultExpression>;
352        (CALL t.Fname e.ResultExpression) = <Vars e.ResultExpression>;
353        t.var = t.var;  // t.var ::= (EVAR t.Name) | (VVAR t.Name)
354                //         | (TVAR t.Name) | (SVAR t.Name)
355      } :: e.var =
356      e.rest (e.vars e.var);
357  } :: e.expr (e.vars),
358  e.expr : /*empty*/ =
359  e.vars;
360
Note: See TracBrowser for help on using the repository browser.