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

Last change on this file since 963 was 963, checked in by orlov, 18 years ago
  • Improved generation of names for auxiliary variables.
  • Print-Error function is moved from rfp_compile to rfp_check.
  • A bug in Split-Re function which caused $const'ants to be disclosed too early

in some cases is fixed.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.3 KB
Line 
1// $Source$
2// $Revision: 963 $
3// $Date: 2003-07-06 03:03:26 +0000 (Sun, 06 Jul 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$func Print-Var e = e;
147
148Vars-Print e.vars = <Map &Print-Var (e.vars)>;
149
150Print-Var {
151  (s.tag (e.name)) = (s.tag (<To-Word e.name>));
152  (s.tag s.box)    = (s.tag s.box);
153};
154
155
156
157$func Decl-Var e = e;
158
159Vars-Decl e.vars = <Map &Decl-Var (e.vars)>;
160
161
162Decl-Var t.var, {
163  <Get-Var Decl t.var> : s.box;
164  <Box (DECL "Expr" <Print-Var t.var>)> :: s.decl,
165    <Set-Var (Decl s.decl) t.var>,
166    (Declare s.decl);
167
168//!     <? &State> : $r e1 (t.var tag t.min t.max s.decl e.rest) e2 =
169//!             {
170//!                     <Box? s.decl> = s.decl;
171//!                     <Box (DECL "Expr" <Print-Var t.var>)> :: s.decl,
172//!                             <Store &State e1 (t.var tag t.min t.max s.decl e.rest) e2>,
173//!                             s.decl;
174//!             } :: s.decl,
175//!             (Declare s.decl);
176//!
177//!     <Create-Var t.var> : e, <Decl-Var t.var>;
178};
179
180
181
182Create-Int-Var (e.prefix) t.var e.expr, {
183  t.var : Aux = (VAR <Box 0 e.prefix>);
184  (VAR <Box 1 e.prefix t.var>);
185} :: t.int-var =
186  t.int-var (INT t.int-var e.expr);
187
188
189
190//!Declared? t.var =
191//!     <? &State> : $r e (t.var tag t.min t.max s.decl e.rest) e = <Box? s.decl>;
192
193
194//!$func? Decl-Box t.var = s.box;
195
196//!Decl-Box t.var =
197//!     <? &State> : $r e (t.var tag t.min t.max s.decl e.rest) e = <Box? s.decl>, s.decl;
198
199
200//!Instantiated? t.var =
201//! <Var? t.var>,
202//! <? &State> : $r e (t.var tag t.min t.max s.decl s.inst) e = s.inst : Instantiated;
203
204
205/*
206 */
207Gener-Vars (e.format) e.prefix =
208  {
209    e.format : (s.tag) e.Fe, {
210      s.tag : \{ EVAR; VVAR; TVAR; SVAR; } =
211        (s.tag <Box 0 e.prefix>) <Gener-Vars (e.Fe) e.prefix>;
212      (s.tag <Box 1 e.prefix>) <Gener-Vars (e.Fe) e.prefix>;
213    };
214    e.format : (PAREN v1) e2 =
215      (PAREN <Gener-Vars (v1) e.prefix>) <Gener-Vars (e2) e.prefix>;
216    e.format : t.Ft e.Fe =
217      t.Ft <Gener-Vars (e.Fe) e.prefix>;
218    /*empty*/;
219  };
220
221Gener-Err-Var = (EVAR <Box 2>);
222
223
224Generated-Var? (s.tag s.box), s.tag : \{ EVAR; VVAR; TVAR; SVAR; };
225
226
227/*
228 * (s.tag s.box) -- сгенерированная ранее переменная.
229 * Вместо того, чтобы присвоить её значение переменной t.var, мы подставляем
230 * t.var во все места, гда была использована (s.tag s.box).  Таким образом,
231 * t.var получит нужное значение в тот момент, когда выполняется присваивание в
232 * (s.tag s.box).
233 * Если переменная t.var уже была ранее декларирована, чтобы избежать повторной
234 * декларации, делаем декларацию для (s.tag s.box) пустой.
235 * Если же переменная t.var -- новая, то её декларацией становится декларация
236 * (s.tag s.box).
237 */
238Gener-Var-Assign t.var (s.tag s.box) =
239  <Store s.box <Print-Var t.var>>,
240  {
241    <Get-Var Decl t.var> : s =
242      <Get-Var Decl (s.tag s.box)> : s.decl-box,
243      <Store s.decl-box /*empty*/>;
244    <Set-Var (Decl <Get-Var Decl (s.tag s.box)>) t.var>;
245  };
246
247
248$box Var-Names;
249
250$table Var-Indices;
251
252$func Boxes-To-Vars e.expr-with-boxes = e.expr-with-var-names;
253
254$func Gener-Name s.form-one? s.name = s.unique-name;
255
256
257Gener-Var-Names expr =
258  <Store &Var-Names /*empty*/>,
259  <RFP-Clear-Table &Var-Indices>,
260  <Boxes-To-Vars expr>;
261
262
263Boxes-To-Vars {
264  (s.tag s.box) expr, s.tag : \{ EVAR; VVAR; TVAR; SVAR; VAR; } =
265    <? s.box> : {
266      0 e.name =
267        (VAR (<Gener-Name From-One <To-Word e.name>>)) :: t.var,
268        <Store s.box t.var>,
269        t.var <Boxes-To-Vars expr>;
270      1 e.prefix t.var =
271        <Boxes-To-Vars t.var> : (s (e.name)),
272        (VAR (<Gener-Name From-Two <To-Word e.prefix e.name>>)) :: t.var,
273        <Store s.box t.var>,
274        t.var <Boxes-To-Vars expr>;
275      2 =
276        ERROR-EXPR <Boxes-To-Vars expr>;
277      t.var = <Boxes-To-Vars t.var expr>;
278    };
279  (Declare s.decl) expr = <Boxes-To-Vars <? s.decl> expr>;
280  (e1) e2   = (<Boxes-To-Vars e1>) <Boxes-To-Vars e2>;
281  term expr = term <Boxes-To-Vars expr>;
282  /*empty*/ = /*empty*/;
283};
284
285
286Gener-Name s.form-one? s.name =
287  {
288    <Lookup &Var-Indices s.name>;
289    0;
290  } : s.idx,
291  <"+" s.idx 1> :: s.idx,
292  <Bind &Var-Indices (s.name) (s.idx)>,
293  {
294    # \{ s.form-one? : From-One; }, s.idx : 1 = /*empty*/;
295    s.idx;
296  } :: e.idx,
297  <To-Word s.name e.idx> :: s.n,
298  {
299    <? &Var-Names> : $r e s.n e = <Gener-Name s.form-one? s.name>;
300    <Put &Var-Names s.n>, s.n;
301  };
302
303
304
305/*
306 * Generates indexes for all variables in e.Format and returns e.Format with all
307 * (?VAR) changed to (?VAR (e.Name)) and s.max.
308 * e.Name is all words from e.prefix plus unical number. Numbers are generated
309 * sequentially starting with s.num.
310 * s.max is the maximum of all generated numbers plus one.
311 * All normal variables from e.Format are returned as they are.
312 */
313Gener-Var-Indices s.num (e.Format) e.prefix, {
314  e.Format : t.Ft e.rest, t.Ft : {
315    s.ObjectSymbol = t.Ft <Gener-Var-Indices s.num (e.rest) e.prefix>;
316    (REF e) = t.Ft <Gener-Var-Indices s.num (e.rest) e.prefix>;
317    (PAREN e.Fe) =
318      <Gener-Var-Indices s.num (e.Fe) e.prefix> :: expr s.num,
319      (PAREN expr) <Gener-Var-Indices s.num (e.rest) e.prefix>;
320    (s.VariableTag) =
321      (s.VariableTag (PRAGMA) (e.prefix s.num)) :: t.var,
322      <"+" s.num 1> :: s.num,
323      t.var <Gener-Var-Indices s.num (e.rest) e.prefix>;
324    (s.VariableTag e.Name) = t.Ft <Gener-Var-Indices s.num (e.rest) e.prefix>;
325  };
326  /*
327   * e.Format is empty, so return s.num -- the last term in the answer.
328   */
329  s.num;
330};
331
332
333
334Strip-STVE expr = <Subst (SVAR TVAR VVAR EVAR) ((VAR) (VAR) (VAR) (VAR)) expr>;
335
336Vars e.expr =
337  e.expr () $iter {
338    e.expr : t.first e.rest,
339      t.first : {
340        s.ObjectSymbol = /*empty*/;
341        (REF t.Name) = /*empty*/;
342        (STATIC t.Name) = /*empty*/;
343        (PAREN e.ResultExpression) = <Vars e.ResultExpression>;
344        (CALL (PRAGMA (e) e) t.Fname e.ResultExpression) =
345          <Vars e.ResultExpression>;
346        (CALL t.Fname e.ResultExpression) = <Vars e.ResultExpression>;
347        t.var = t.var;  // t.var ::= (EVAR t.Name) | (VVAR t.Name)
348                //         | (TVAR t.Name) | (SVAR t.Name)
349      } :: e.var =
350      e.rest (e.vars e.var);
351  } :: e.expr (e.vars),
352  e.expr : /*empty*/ =
353  e.vars;
354
355Norm-Vars (e.vars) e.Snt =
356  /*
357   * Store all new variables in the &Vars-Tab table and return the list with
358   * all variables in the (VAR t.name) form.
359   */
360  <Store-Vars e.vars> :: e.new-vars,
361  /*
362   * Rename all new variables in e.Snt. Never mind multiple occurences.
363   */
364  (e.vars) (e.new-vars) e.Snt $iter {
365    e.vars : t.var e.rest, e.tmp-vars : t.new-var e.new-rest, {
366      t.var : t.new-var =
367        (e.rest) (e.new-rest) e.Snt;
368      t.var : (s.tag e) =
369        (e.rest) (e.new-rest) <Subst (t.var) ((t.new-var)) e.Snt>;
370    };
371  } :: (e.vars) (e.tmp-vars) e.Snt,
372  e.vars : /*empty*/ =
373  (e.new-vars) e.Snt;
374
375
376$table Vars-Tab;
377
378Store-Vars e.vars =
379//  <WriteLN Store-Vars e.vars>,
380  e.vars () $iter {
381    e.vars : (s.var-tag (e.QualifiedName s.last)) e.rest,
382      {
383        s.last : 0 = (e.QualifiedName);
384        <Int? s.last> = (e.QualifiedName s.last);
385        /*empty*/ =
386          s.var-tag : {
387            SVAR = "s";
388            TVAR = "t";
389            VVAR = "v";
390            EVAR = "e";
391            VAR = /*empty*/;
392          } :: e.var-sym,
393          (e.var-sym e.QualifiedName s.last);
394      } :: t.name,
395      {
396        <In-Table? &Vars-Tab t.name>; // do nothing
397        <Table> :: s.tab, <Bind &Vars-Tab (t.name) (s.tab)>,
398          s.var-tag : {
399            SVAR =
400              <Set-Var t.name (Min) (1)>,
401              <Set-Var t.name (Max) (1)>,
402              <Set-Var t.name (Length) (1)>,
403              <Set-Var t.name (Flat) (True)>;
404            TVAR =
405              <Set-Var t.name (Min) (1)>,
406              <Set-Var t.name (Max) (1)>,
407              <Set-Var t.name (Length) (1)>;
408            VVAR =
409              <Set-Var t.name (Min) (1)>;
410//              <Set-Var t.name (Max) ()>;
411            EVAR =
412              <Set-Var t.name (Min) (0)>;
413//              <Set-Var t.name (Max) ()>;
414            e = <WriteLN !-!-!-! t.name>,
415              <Exit -1>;
416          },
417          <Set-Var t.name (Left-compare) ()>,
418          <Set-Var t.name (Right-compare) ()>,
419          <Set-Var t.name (Left-checks) ()>,
420          <Set-Var t.name (Right-checks) ()>,
421          <Set-Var t.name (Format) ((s.var-tag))>;
422      },
423      e.rest (e.new-vars (VAR t.name));
424  } :: e.vars (e.new-vars),
425  e.vars : /*empty*/ =
426  e.new-vars;
427
428Declare-Vars s.type e.vars =
429  e.vars () $iter {
430    e.vars : (VAR t.name) e.rest, {
431      <?? t.name Declared> : True;  // do nothing
432      {
433        <In-Table? &Vars-Tab t.name>; // do nothing
434        { s.type : Expr = <WriteLN Decl-Format t.name>;; },
435        <Table> :: s.tab, <Bind &Vars-Tab (t.name) (s.tab)>,
436          <Set-Var t.name (Left-compare) ()>,
437          <Set-Var t.name (Right-compare) ()>,
438          <Set-Var t.name (Left-checks) ()>,
439          <Set-Var t.name (Right-checks) ()>,
440//          <Set-Var t.name (Format) ((VAR t.name))>,
441          <Set-Var t.name (Format) ((EVAR))>,
442          <Set-Var t.name (Min) (0)>;
443      },
444        <Set-Var t.name (Declared) (True)>,
445        (DECL s.type (VAR t.name));
446    } :: e.new-decl,
447    e.rest (e.decls e.new-decl);
448  } :: e.vars (e.decls),
449  e.vars : /*empty*/ =
450  e.decls;
451
452Instantiate-Vars e.vars =
453  e.vars $iter {
454    e.vars : (VAR t.name) e.rest,
455      <Set-Var t.name (Instantiated) (True)>,
456      e.rest;
457  } :: e.vars,
458  e.vars : /*empty*/;
459
460?? t.name e.key =
461  <Lookup &Vars-Tab t.name> : s.tab,
462  <Lookup s.tab e.key>;
463
464//!Set-Var t.name (e.key) (e.val) =
465//  <WriteLN Set-Var t.name (e.key)>,
466//!     <Lookup &Vars-Tab t.name> : s.tab,
467//!     <Bind s.tab (e.key) (e.val)>;
468
469
Note: See TracBrowser for help on using the repository browser.