source: to-imperative/trunk/compiler/src/org/refal/plus/compiler/rfp_compile.rf @ 3589

Last change on this file since 3589 was 3589, checked in by yura, 13 years ago
  • Compiler files are moved into package org.refal.plus.compiler.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 48.4 KB
Line 
1$use Access Apply Arithm Box Class Compare Convert Dos List StdIO Table;
2
3$use "org.refal.plus.compiler.rfpc";
4$use "org.refal.plus.compiler.rfp_helper";
5$use "org.refal.plus.compiler.rfp_check";
6$use "org.refal.plus.compiler.rfp_as2as";
7$use "org.refal.plus.compiler.rfp_format";
8$use "org.refal.plus.compiler.rfp_vars";
9$use "org.refal.plus.compiler.rfp_const";
10$use "org.refal.plus.compiler.rfp_clashes";
11
12/*
13 * Table for storing object names.
14 */
15$table Objects;
16
17/*
18 * Table for storing parameters of referenced functions.
19 */
20$table Stub_Funcs;
21
22/*
23 * Box for storing function out format
24 */
25$box Out_Format;
26
27/*
28 * Box for storing names for function result variables
29 */
30$box Res_Vars;
31
32/*
33 * Following table is used by Gener-Label function for obtaining unical (for
34 * certain function) label name.
35 * e.Key ::= e.QualifiedName      (parameter given to Gener-Label)
36 * e.Val ::= [Int]          (last index used with such e.QualifiedName)
37 */
38$table Labels;
39
40/*
41 * Table for storing variables used in place of preprocessor-generated ones.
42 */
43$table Prep_Vars;
44
45
46$func Compile (e.targets) e.Items = e.Compiled_Items;
47
48$func Comp_Func_Stubs = e.asail_funcs;
49
50$func Comp_Func s.linkage s.tag t.name e.params_and_body = e.compiled_func;
51
52$func Comp_Sentence s.Istail (e.fails) (e.last_Re) e.Sentence = e.asail_sentence;
53
54$func Save_Snt_State = ;
55
56$func Recall_Snt_State = ;
57
58$func Pop_Snt_State = ;
59
60$func Extract_Calls e.Re = (e.last_Re) e.calls;
61
62$func Get_Clash_Sequence (e.last_Re) e.Snt = (e.clashes) e.rest_of_the_Sentence;
63
64$func? IsWithout_Calls e.Re = ;
65
66$func Comp_Clashes (e.clashes) s.Istail (v.fails) e.Sentence = e.asail_sentence;
67
68$func Gener_Label e.QualifiedName = t.label;
69
70$func Add_To_Label t.label e.name = t.label;
71
72$func Comp_Calls e.Re = e.calls;
73
74$func Prepare_Vars e.vars = e.vars;
75
76$func Prepare_Res e.Reult_exprs = e.Result_exprs;
77
78$func Prepare_Const e.const_expr = e.const_expr;
79
80$func Comp_Assigns e.assignments = e.asail_assignments;
81
82$func Comp_Format (e.last_Re) e.He = e.assignments;
83
84
85
86//*********** Get AS-Items and targets, and pass it to Compile ************
87
88/*
89 * О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.  О©╫О©╫О©╫ О©╫О©╫О©╫
90 * О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫.
91 */
92$box Declarations;
93
94$box Trace_Names;
95
96$box Module_Name;
97
98RFP_Compile (e.ModuleName) e.Items =
99  <Store &Module_Name e.ModuleName>,
100  { <Lookup &RFP_Options ITEMS>;; } :: e.targets,
101  <ClearTable &Stub_Funcs>,
102  <Store &Trace_Names /*empty*/>,
103  <Store &Declarations /*empty*/>,
104  <Init_Consts>,
105  <Compile (e.targets) e.Items> :: e.Items,
106  <Comp_Func_Stubs> :: e.stub_funcs,
107  (MODULE (e.ModuleName) <Get &Trace_Names> <Get &Declarations> <Comp_Consts>
108    e.Items e.stub_funcs);
109
110
111
112//***************** Choose needed items and compile them ******************
113
114Compile (e.targets) e.Items =
115  e.Items (/*e.asail*/) $iter {
116    e.Items : t.item e.rest,
117      {
118        e.targets : v =
119          e.targets : e t.name e,
120          t.item : (t t t.name e);;
121      },
122      t.item : {
123        (IMPORT s.tag t.name e) \?
124          {
125            s.tag : \{ CONST; FUNC; "FUNC?"; },
126              t.name : ("org" "refal" "plus" "wrappers" e) \! $fail;;
127          };
128        (TRACE t.name) =
129          <Put &Trace_Names (TRACE t.name)>;
130        (EXTERN t.name) =
131          <Put &Declarations (EXTERN t.name)>;
132        (NATIVE e) =
133          t.item;
134        (s.link s.tag t.name (e.in) (e.out) e.body), FUNC "FUNC?" TFUNC : e s.tag e =
135          {
136            e.body : (BRANCH e.branch) =
137              <Comp_Func s.link s.tag t.name (e.in) (e.out) e.branch>;
138            <Comp_Func s.link s.tag t.name (<Gener_Vars (e.in) "arg">) (e.out)>;
139          };
140        (s.link CONST t.name e.expr) =
141          <Put &Declarations (CONSTEXPR s.link t.name (e.expr) <Prepare_Const e.expr>)>;
142        (s.link s.tag t.name) =
143          <Put &Declarations (OBJ s.link s.tag t.name)>;
144      } :: e.item,
145      e.rest (e.asail e.item);
146  } :: e.Items (e.asail),
147  e.Items : /*empty*/ =
148  e.asail;
149
150
151$func Gener_Stub e = e;
152
153/*
154 * For each referenced function generate a stub one with format e = e.
155 */
156Comp_Func_Stubs = <Map &Gener_Stub (<Domain &Stub_Funcs>)>;
157
158Gener_Stub (t.name) =
159  <Lookup &Stub_Funcs t.name> : t.stub_name s.tag (e.Fin) (e.Fout),
160  <Gener_Vars (e.Fin) "stub"> :: e.He,
161  <Comp_Func LOCAL STUB t.stub_name ((EVAR ("arg" 1))) ((EVAR))
162    (LEFT e.He) (CUTALL) (RESULT (CALL t.name e.He))>;
163
164
165
166Comp_Func s.linkage s.tag t.name (e.in) (e.out) e.Sentence =
167  <ClearTable &Labels>,
168  <ClearTable &Prep_Vars>,
169  <Init_Vars>,
170  <Vars <Gener_Vars (<Format_Exp e.out>) "res">> :: e.res_vars,
171  <Vars_Decl Result e.res_vars> : e,
172  <Store &Res_Vars e.res_vars>,
173  <Store &Out_Format <Format_Exp e.out>>,
174  <Prepare_Res (e.in)> : (e.arg),
175  <Vars e.arg> :: e.arg_vars,
176  <Map &Set_Var ("Instantiated?" True) (e.arg_vars)> : e,
177  s.tag : {
178    FUNC = FUNC (FATAL);
179    "FUNC?" = "FUNC?" (RETFAIL);
180    TFUNC = TFUNC (FATAL);
181    STUB =
182      <Prepare_Res (Apply Apply "Unexpected fail")> : (e.message),
183      "FUNC?" (RETFAIL) ((ERROR e.message));
184  } :: s.tag e.fails,
185  (s.tag s.linkage t.name (<Vars_Print e.arg_vars>) (<Vars_Print e.res_vars>)
186    <Comp_Sentence Tail (e.fails) (e.arg) e.Sentence>
187  ) :: e.comp_func,
188  <Gener_Var_Names e.comp_func> :: e.comp_func,
189//! <Post-Comp (e.res-vars) e.comp-func> :: t e.result,
190//! e.result;
191  e.comp_func;
192//  :: (e.func-decl) e.func-body,
193//  () <Domain &Declarations> $iter {
194//    e.vars : (t.var) e.rest-vars,
195//      (e.var-decls (DECL t.var)) e.rest-vars;
196//  } :: (e.var-decls) e.vars,
197//  e.vars : /*empty*/,
198//  (e.func-decl e.var-decls e.func-body);
199
200Comp_Sentence s.Istail (v.fails) (e.last_Re) e.Sentence, e.Sentence : {
201  (LINENUMBER sN) e.Snt = (LINENUMBER sN) <Comp_Sentence s.Istail (v.fails) (e.last_Re) e.Snt>;
202
203  /*empty*/ = /*empty*/;
204
205  /*
206   * In case of Re look if we should do a tailcall.  If not, then compile
207   * function calls from the Re and assign results to the out parameters or
208   * use them in compilation of the rest of the sentence.
209   */
210  (RESULT e.Re) e.Snt =
211    {
212      /*
213       * If the Re is the last action in the sentence then we can do
214       * tailcall if one of the following is true:
215       *  - Re is a call of non-failable function;
216       *  - Re is a call of a failable function, current function is
217       *  failable, and the failures stack is empty.
218       * In both cases out format of the called function should coincide
219       * with those of compiled one.
220       * FIXME: really we can do tailcall if all the parameters of
221       * compiled function that won't get their values from the call can
222       * be assigned from other sources.  Some support from runtime is
223       * needed though.
224       */
225      e.Snt : /*empty*/, s.Istail : Tail, e.Re : (CALL t.name e.arg),
226        {
227          <IsInTable &IsFun t.name> =
228            v.fails : (RETFAIL),
229            "TAILCALL?";
230          TAILCALL;
231        } :: s.tailcall,
232        <Lookup_Func t.name> :: s.linkage s.tag (e.Fin) (e.Fout),
233        <IsSubformat (e.Fout) (<Get &Out_Format>)> =
234        <Extract_Calls e.arg> :: (e.last_Re) e.calls,
235        <Prepare_Res <Split_Re (e.Fin) e.last_Re>> :: e.splited_Re,
236        <Comp_Calls <R 0 v.fails> e.calls>
237        (s.tailcall t.name (e.splited_Re) (<Get &Res_Vars>));
238
239      <Extract_Calls e.Re> :: (e.last_Re) e.calls,
240        <Comp_Calls <R 0 v.fails> e.calls> :: e.comp_calls,
241        {
242          e.Snt : /*empty*/, Tail "Tail-in-Trap" : e s.Istail e =
243            <Split_Re (<Get &Out_Format>) e.last_Re> :: e.splited_Re,
244            <Prepare_Res e.splited_Re> :: e.splited_Re,
245            e.comp_calls <Comp_Assigns <Zip (<Get &Res_Vars>) (e.splited_Re)>>;
246
247          e.comp_calls <Comp_Sentence s.Istail (v.fails) (e.last_Re) e.Snt>;
248        };
249    };
250
251  /*
252   * In case of He compile assignments from last Re and then (with new state
253   * of variables) proceed with the rest of the sentence.
254   */
255  (FORMAT e.He) e.Snt =
256    <Comp_Format (e.last_Re) e.He>
257    <Comp_Sentence s.Istail (v.fails) () e.Snt>;
258
259  /*
260   * In case of Pe get from the begining of the sentence a maximum possible
261   * sequence of clashes and compile it.  New values of variables from the
262   * clashes use in the compilation of the rest of the sentence.
263   */
264  (s.dir e.Pattern) e.Snt, s.dir : \{ LEFT; RIGHT; } =
265    <Get_Clash_Sequence (e.last_Re) e.Sentence> :: (e.clashes) e.Sentence,
266    <Comp_Clashes (e.clashes) s.Istail (v.fails) e.Sentence>;
267
268  ("ALT?") e =
269    v.fails : e (e.last_fail),
270    e.last_fail;
271
272  (ALT) e =
273    FATAL;
274
275  /*
276   * In case of a block first see if its results are needed for something
277   * after the block and determine whether the block is a source.  Then
278   * compile each branch in turn.
279   */
280  (s.block e.branches) e.Snt,
281    s.block : \{
282      ALT = (FATAL);
283      "ALT?";
284    } :: e.Isfatal =
285    /*
286     * If the block initializes an $iter then extract from the $iter the He
287     * for placing it in the end of each branch.
288     * Then look if the block is used by a format expression.
289     * If so, we should declare variables from that expression before
290     * entering any branch -- those should be visible after the block.
291     * The format expression is placed in the end of each branch.
292     * But if a branch computes to $error, the expression shouldn't be
293     * used, so protect it with (Comp If-not-error).
294     * If next after the block is (Comp Error) then block results should be
295     * used as values for $error, so place (Comp Error) in the end of each
296     * branch.
297     * If next after the block is (Comp If-not-error) then our block is in
298     * the end of a branch of an outer block and has next pattern or format
299     * inherited from there.  In that case we should place all the sentence
300     * rest in the end of each branch because the block can be inside the
301     * $error already.
302     */
303    {
304      e.Snt : (ITER t.body t.format) e.rest =
305        t.format (Comp Iter t.body t.format) e.rest;
306      e.Snt;
307    } :: e.Snt,
308    e.Snt : {
309      (FORMAT e.format) e.rest =
310        <Prepare_Vars <Vars e.format>> :: e.vars,
311        (e.vars) ((Comp "If-not-error") (FORMAT e.format))
312        ((Comp Source)) e.rest;
313      (Comp Error) e.rest =
314        () ((Comp Error)) () /*empty*/;
315      (Comp "If-not-error") e.rest =
316        () (e.Snt) () /*empty*/;
317      e = () () () e.Snt;
318    } :: (e.out_vars) (e.next_terms) (e.Issource) e.Snt,
319    /*
320     * The block is a source if after it goes format expression
321     * (in that case e.source? isn't empty) or e.Snt isn't empty.
322     * Branches in the block are tail sentences if the current sentence is
323     * tail and the block isn't a source.
324     */
325    {
326      \{ e.Issource : v; e.Snt : v; } = ((Comp Source) <R 0 v.fails>) Notail;
327      () s.Istail;
328    } :: (e.Issource) s.Istail_branch,
329    /*
330     * In case our block is a source we should mark the position in the
331     * failures stack, so that we can jump to it after CUTALL.  And if our
332     * block isn't failable we should add (FATAL) to the end of the stack.
333     */
334    v.fails e.Issource e.Isfatal :: v.branch_fails,
335    /*
336     * Before compile the branches mark all out-vars as declared.
337     */
338    <Vars_Decl Expr e.out_vars> :: e.decls,
339    /*
340     * We put all compiled branches in a block, so positive return from a
341     * branch is a break from that block.
342     * Each branch in its turn is placed in its own block, so for a $fail
343     * to the next branch we should just break from that inner block.
344     * Each branch is compiled with the current sentence state and the
345     * state is recalled after that.  When all branches are compiled the
346     * state is popped out from the stack.
347     * If last branch fails then the whole block fails, and return from the
348     * last branch is return from the block.  So the last branch isn't
349     * placed in a block and is processed with the failures stack that was
350     * before entering the block.  Note: this trick helps us find more
351     * tailcalls.  If the call of a failable function is on the last branch
352     * of the block and the failures stack is empty we can do tailcall.
353     * When the last branch is compiled with the block's stack, all we
354     * should do is to check it.
355     */
356    <Gener_Label "block"> :: t.label,
357    <Save_Snt_State>,
358    (e.branches) /*e.comp-branches*/ $iter {
359      e.branches : (BRANCH e.branch) e.rest_br =
360        <Add_To_Label t.label "branch"> :: t.br_label,
361        <Comp_Sentence
362          s.Istail_branch
363          (v.branch_fails ((BREAK t.br_label)))
364          (e.last_Re)
365          e.branch e.next_terms
366        > :: e.comp_br,
367        <Recall_Snt_State>,
368        (e.rest_br) e.comp_branches (LABEL (t.br_label) e.comp_br (BREAK t.label));
369    } :: (e.branches) e.comp_branches,
370    e.branches : (BRANCH e.branch) =
371    <Comp_Sentence
372      s.Istail_branch (v.branch_fails) (e.last_Re) e.branch e.next_terms
373    > :: e.last_branch,
374    <Pop_Snt_State>,
375    <Vars_Reset e.out_vars>,
376    e.decls (LABEL (t.label) e.comp_branches e.last_branch)
377    <Comp_Sentence s.Istail (v.fails) () e.Snt>;
378
379  /*
380   * In case of $iter first of all compile initial assignment to the hard
381   * expression.
382   */
383  (ITER t.body t.format) e.Snt =
384    <Comp_Sentence s.Istail (v.fails) (e.last_Re)
385      t.format (Comp Iter t.body t.format) e.Snt
386    >;
387
388  /*
389   * Before compiling $iter condition or body we should forget available info
390   * about all format variables, because that info can be changed during
391   * cycle iterations.
392   * Then compile $iter condition and body both with the current state of the
393   * sentence.
394   * e.Snt can contain (Comp Error) and (protected from errors) pattern or
395   * format which comes from an outer block, so compile it together with the
396   * condition.
397   * If condition fails we should compute the body, so put the compiled
398   * condition in a block and place a break from it to the failures stack.
399   */
400  (Comp Iter (BRANCH e.body) t.format) e.Snt =
401    t.format : (FORMAT e.Fe),
402    <Vars_Reset <Prepare_Vars <Vars e.Fe>>>,
403    <Save_Snt_State>,
404    <Gener_Label "iter"> :: t.label,
405    <Gener_Label "exit_iter"> :: t.exit,
406    <Comp_Sentence s.Istail (v.fails ((BREAK t.label))) () e.Snt>
407      :: e.comp_condition,
408    <Pop_Snt_State>,
409    <Comp_Sentence Notail (v.fails) () e.body t.format> :: e.comp_body,
410    (FOR (/*cont-label*/) (t.exit) () ()
411      (LABEL (t.label) e.comp_condition (BREAK t.exit)) e.comp_body
412    );
413
414  /*
415   * In case of $trap/$with at first compile try-sentence.  All $fails from
416   * it should become errors.
417   * Then recall the state of the sentence and compile catching of an error
418   * with a variable err.
419   * e.Snt can contain (Comp Error) and (protected from errors) pattern or
420   * format which comes from an outer block, so compile it together with both
421   * sentences.
422   */
423  (TRY (BRANCH e.try) (BRANCH e.catch)) e.Snt =
424    <Save_Snt_State>,
425    {
426      s.Istail : Tail = "Tail-in-Trap";
427      s.Istail;
428    } :: s.Istail_in_trap,
429    <Comp_Sentence s.Istail_in_trap ((FATAL)) () e.try e.Snt> :: e.comp_try,
430    <Pop_Snt_State>,
431    <Gener_Err_Var> :: t.var,
432    <Set_Var ("Instantiated?" True) t.var>,
433    <Comp_Sentence s.Istail (v.fails) (t.var) e.catch e.Snt> :: e.comp_catch,
434    (TRY e.comp_try) ("CATCH-ERROR" e.comp_catch);
435
436  /*
437   * In case of \? add Stake to the failures stack.  Add last fail after it
438   * for <R 0 v.fails> continue to work.
439   */
440  (STAKE) e.Snt =
441    <Comp_Sentence s.Istail (v.fails (Comp Stake) <R 0 v.fails>) () e.Snt>;
442
443  /*
444   * In case of \! forget all failure catchers after last \?.
445   * If there is no Stake then we are inside negation or error (we assume the
446   * program is correct).  So the right failure catcher is in the bottom of
447   * the stack.
448   */
449  (CUT) e.Snt =
450    {
451      v.fails : $r v.earlier_fails (Comp Stake) e = v.earlier_fails;
452      <L 0 v.fails>;
453    } :: v.fails,
454    <Comp_Sentence s.Istail (v.fails) () e.Snt>;
455
456  /*
457   * In case of = clear the failures stack up to the closest source.
458   * Don't clear last fail after it for <R 0 v.fails> continue to work.
459   */
460  (CUTALL) e.Snt =
461    {
462      v.fails : $r v.earlier_fails (Comp Source) t.fail e =
463        v.earlier_fails (Comp Source) t.fail;
464      <L 0 v.fails>;
465    } :: v.fails,
466    <Comp_Sentence s.Istail (v.fails) () e.Snt>;
467
468  /*
469   * In case of = in the Refal-6 sense (non-transparent hedge for the fails),
470   * $fail(k) should become $error(Fname "Unexpected fail"), so clear the
471   * failures stack and put that value in it.
472   */
473  (NOFAIL) e.Snt =
474    <Comp_Sentence s.Istail ((FATAL)) (e.last_Re) e.Snt>;
475
476  /*
477   * In case of $fail return last failure catcher.
478   */
479  (FAIL) e.Snt =
480    v.fails : e (e.last_fail),
481    e.last_fail;
482
483  /*
484   * In case of # we should proceed with the rest if the source is computed
485   * to $fail.
486   * We could compile the rest of the sentence and place it in the
487   * failures stack.  But then the compiled sentence would be copied as many
488   * times as there are $fail's to the upper level in the source.  So we
489   * place compiled source in the block and put the break to exit from it in
490   * the stack.
491   * When compiling the source mark it as Notail as usual.
492   * If the source isn't computed to $fail we should proceed with the last
493   * failure catcher.
494   */
495  (NOT (BRANCH e.branch)) e.Snt =
496    <Gener_Label "negation"> :: t.label,
497    v.fails : e (e.last_fail),
498//    <Save-Snt-State>,
499    <Comp_Sentence Notail (((BREAK t.label))) () e.branch> e.last_fail
500      :: e.comp_negation,
501//    <Pop-Snt-State>,
502    (LABEL (t.label) e.comp_negation) <Comp_Sentence s.Istail (v.fails) () e.Snt>;
503
504  /*
505   * In case of $error all fails become $error(Fname "Unexpected fail").  So
506   * place that value in the failures stack and then compile the computation
507   * of the rest of the sentence and the last Re which should be the value of
508   * $error.
509   */
510  (ERROR (BRANCH e.branch)) e.Snt =
511    <Comp_Sentence Notail ((FATAL)) () e.branch e.Snt (Comp Error)>;
512
513  (Comp Error) e.Snt =
514    <Prepare_Res (e.last_Re)> : (e.Re),
515    (ERROR e.Re);
516
517  /*
518   * Protection mark to be used between source and tail.  If there is $error
519   * construction somewhere in the source then the tail shouldn't be
520   * computed, but instead the source value should be used for throwing.
521   */
522  (Comp "If-not-error") e.Snt =
523    {
524      e.Snt : e (Comp Error) =
525        <Comp_Sentence s.Istail (v.fails) (e.last_Re) (Comp Error)>;
526      <Comp_Sentence s.Istail (v.fails) (e.last_Re) e.Snt>;
527    };
528
529//  (Comp Fatal) = FATAL;
530
531//  (Comp Retfail) = RETFAIL;
532
533};
534
535
536
537//********* Sentence state stack and functions for work with it. **********
538
539$box Snt_State;
540
541/*
542 * Put current state in the stack.
543 */
544Save_Snt_State = <Put &Snt_State <Vars_Copy_State>>;
545
546/*
547 * Set current state to that at the top of the stack.
548 */
549Recall_Snt_State = <Vars_Set_State <R 0 <Get &Snt_State>>>;
550
551/*
552 * Pop the top from the stack and set current state to it.
553 */
554Pop_Snt_State =
555  <Recall_Snt_State>,
556  <Store &Snt_State <Middle 0 1 <Get &Snt_State>>>;
557
558
559
560//********************* Function calls compilation. ***********************
561
562/*
563 * $func Extract-Calls e.Re = (e.last-Re) e.calls;
564 *
565 *
566 *
567 */
568Extract_Calls {
569  (CALL t.name e.arg) e.rest =
570    <Lookup_Func t.name> :: s.linkage s.tag (e.Fin) (e.Fout),
571    <Extract_Calls e.arg> :: (e.last_Re) e.calls,
572    <Prepare_Res <Split_Re (e.Fin) e.last_Re>> :: e.splited_Re,
573    t.name : (e s.prefix),
574    <Gener_Subst_Vars (e.Fout) s.prefix> :: e.Re,
575    <Vars e.Re> :: e.vars,
576    <Map &Set_Var ("Instantiated?" True) (e.vars)> : e,
577    {
578      s.tag : "FUNC?" = (Failable (CALL t.name (e.splited_Re) (e.vars)));
579      (CALL t.name (e.splited_Re) (e.vars));
580    } :: t.call,
581    <Extract_Calls e.rest> :: (e.rest_Re) e.rest_calls,
582    (e.Re e.rest_Re) e.calls <Vars_Decl Result e.vars> t.call e.rest_calls;
583  (PAREN e.Re) e.rest =
584    <Extract_Calls e.Re> :: (e.last_Re) e.calls,
585    <Extract_Calls e.rest> :: (e.rest_Re) e.rest_calls,
586    ((PAREN e.last_Re) e.rest_Re) e.calls e.rest_calls;
587  t.Rt e.Re =
588    <Extract_Calls e.Re> :: (e.last_Re) e.calls,
589    (t.Rt e.last_Re) e.calls;
590  /*empty*/ = () /*empty*/;
591};
592
593
594Comp_Calls (e.fail) e.calls, e.calls : {
595  (Failable t.call) e.rest =
596    (IF ("CALL-FAILS" t.call) e.fail) <Comp_Calls (e.fail) e.rest>;
597  t.call e.rest =
598    t.call <Comp_Calls (e.fail) e.rest>;
599  /*empty*/ = /*empty*/;
600};
601
602
603
604//********* Preparation of vars and REs for following processing **********
605//********** Compilation of static parts of result expressions ************
606
607$func IsStatic_Expr s.Iscreate e.Re = sIstatic e.Re;
608
609$func IsRef_Func t = t;
610
611$func IsStatic_Term t.Rt = sIstatic e.Re;
612
613$func Stub_Name t.name = t.stub_name;
614
615
616/*
617 * Extract static parts from each Re.
618 * Also get the right names for variables generated during the preprocessing
619 * stage, if those are in the expr.
620 */
621Prepare_Res {
622  (e.Re) e.rest = <IsStatic_Expr Create e.Re> :: s e.Re, (e.Re) <Prepare_Res e.rest>;
623  /*empty*/     = /*empty*/;
624};
625
626/*
627 * Find all the longest static parts in the upper level of Re.  Create STATIC
628 * form in place of each one.
629 * Return a tag pointing whether the whole expression is static and expression
630 * with static parts replaced by STATIC forms.  Dynamic parts are returned
631 * unchanged.
632 */
633IsStatic_Expr s.Iscreate e.Re =
634  (/*e.static*/) e.Re $iter {
635    e.Re : t.Rt e.rest =
636      <IsStatic_Term t.Rt> : {
637        Static e.st_Re =
638          (e.static e.st_Re) e.rest;
639        Dynamic t.dyn_Rt =
640          <IsStatic_Expr Create e.rest> :: s e.rest,
641          (e.static) (Dynamic t.dyn_Rt e.rest);
642      };
643    (e.static);
644  } :: (e.static) e.Re,
645  e.Re : \{
646    /*empty*/, {
647      s.Iscreate : Create =
648        Static <Create_Static e.static>;
649      Static e.static;
650    };
651    (Dynamic e.dynamic) = Dynamic <Create_Static e.static> e.dynamic;
652  };
653
654/*
655 * The same as Static-Expr? but for terms.
656 */
657IsStatic_Term {
658  symbol       = Static symbol;
659  (PAREN e.Re) = <IsStatic_Expr "Not-Create" e.Re> :: sIstatic e.Re, sIstatic (PAREN e.Re);
660  (REF t.name) = Static <IsRef_Func (REF t.name)>;
661  (STATIC t.name) = Static <Get_Static (STATIC t.name)>;
662  t.var        = <Prepare_Vars t.var> : t.prep_var, Dynamic t.prep_var;
663};
664
665IsRef_Func {
666  (REF t.name) =
667    {
668      <Lookup_Func t.name> : {
669        s.linkage s.tag ((EVAR)) ((EVAR)) = (s.tag t.name);
670        s.linkage s.tag (e.Fin) (e.Fout) =
671          {
672            <Lookup &Stub_Funcs t.name> : t.stub_name e =
673              ("FUNC?" t.stub_name);
674            <Stub_Name t.name> :: t.stub_name,
675              <Bind &Stub_Funcs (t.name)
676                (t.stub_name s.tag (e.Fin) (e.Fout))>,
677              ("FUNC?" t.stub_name);
678          };
679      };
680      (REF t.name);
681    };
682  term = term;
683};
684
685/*
686 * О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ (О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫,
687 * О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫) О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ (О©╫О©╫
688 * О©╫чёО©╫ О©╫О©╫О©╫О©╫, О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ VAR).
689 */
690Prepare_Vars {
691//  (s.var-tag (e.prefix s.n)) e.rest, <Int? s.n> =
692//    {
693//      <Lookup &Prep-Vars (s.var-tag (e.prefix s.n))>;
694//      <Gener-Vars ((s.var-tag)) e.prefix> :: e.var,
695//        <Bind &Prep-Vars ((s.var-tag (e.prefix s.n))) (e.var)>,
696//        e.var;
697//    } :: e.var,
698//    e.var <Prepare-Vars e.rest>;
699  t.var e.rest = t.var <Prepare_Vars e.rest>;
700  /*empty*/ = /*empty*/;
701};
702
703/*
704 * О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫-О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.
705 */
706Stub_Name (e.qualifiers s.name) =
707  <ToChars s.name> : {
708    e1 '_' s.n, <IsInt s.n> = e1 '_' <Arithm.Add s.n 1>;
709    e1 = e1 '_' 0;
710  } :: e.name,
711//  (e.qualifiers <To-Word e.name>) :: t.name,
712  (<Get &Module_Name> <ToWord e.name>) :: t.name,
713  {
714    <Lookup_Func t.name> : e = <Stub_Name t.name>;
715    t.name;
716  };
717
718
719Prepare_Const {
720  (PAREN expr) e.rest = (PAREN <Prepare_Const expr>) <Prepare_Const e.rest>;
721  t1 e.rest = <IsRef_Func t1> <Prepare_Const e.rest>;
722  /*empty*/ = /*empty*/;
723};
724
725
726//**************** Compilation of assignment to variables *****************
727
728$func Comp_Assign_to_Var t.var e.Re (e.assigned_vars) = e.assign (e.used_vars);
729
730Comp_Assign_to_Var t.var e.Re (e.assigned_vars) =
731  {
732    t.var : e.Re = /*empty*/ ();
733    <Vars_Reset t.var>, $fail;
734    <IsSubstitutable_Var e.Re>, # \{ e.assigned_vars : e t.var e; } =
735      <Gener_Var_Assign t.var e.Re> ();
736    <Get_Var Decl t.var> : s = (ASSIGN <Vars_Print t.var> e.Re) (<Vars e.Re>);
737    <Vars_Decl Expr t.var> : e =
738      (DECL Expr <Vars_Print t.var> e.Re) (<Vars e.Re>);
739  };
740
741Comp_Assigns e.assigns =
742  e.assigns (/*e.assigned-vars*/) (/*e.comp-assigns*/) $iter {
743    e.assigns : (t.var (e.Re)) e.rest =
744      <Comp_Assign_to_Var t.var e.Re (e.assigned_vars)> :: e.c_as (e.a_vs),
745      e.rest (e.assigned_vars e.a_vs) (e.comp_assigns e.c_as);
746  } :: e.assigns (e.assigned_vars) (e.comp_assigns),
747  e.assigns : /*empty*/ =
748  e.comp_assigns;
749
750
751
752//************************* FORMAT compilation. ***************************
753
754$box Aux_Index;
755
756$func Gener_Aux_Var = t.new_aux_var;
757
758Gener_Aux_Var =
759  <Get &Aux_Index> : s.n,
760  <Store &Aux_Index <Arithm.Add s.n 1>>,
761  (VAR ("aux" s.n));
762
763
764$func Create_Aux_Vars (e.vars) e.splited_Re = e.assigns;
765
766
767Comp_Format (e.last_Re) e.He =
768  <Prepare_Vars <Vars e.He>> :: e.vars,
769  <Prepare_Res <Split_Re (<Format_Exp e.He>) e.last_Re>> :: e.splited_Re,
770  <Store &Aux_Index 1>,
771  <Create_Aux_Vars (e.vars) e.splited_Re> :: e.assigns,
772  <Comp_Assigns e.assigns>;
773
774/*
775 * О©╫О©╫О©╫О©╫, e.vars -- О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.  О©╫О©╫О©╫О©╫О©╫О©╫
776 * О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫О©╫О©╫
777 * О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫.
778 * e.splited-Re -- О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.  О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫
779 * e.vars О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.
780 *
781 * О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ t.var_i О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ e.Re_j, О©╫ i /= j, О©╫О©╫
782 * О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ t.var_j О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫ О©╫О©╫О©╫eО©╫О©╫О©╫О©╫О©╫О©╫
783 * t.var_i.  О©╫О©╫О©╫О©╫ О©╫О©╫, О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, t.var_i О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫
784 * О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ t.var_j, О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.
785 *
786 * О©╫О©╫О©╫О©╫О©╫О©╫:
787 *
788 * t1 (t1 t2) (t1 t3) :: t2 t1 t3
789 *
790 * t3 = (t1 + t3)();
791 * aux_1 = t1;
792 * t1 = (t1 + t2)()
793 * t2 = aux_1;
794 *
795 * О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫
796 * О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ (О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫ О©╫О©╫О©╫О©╫О©╫
797 * О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫).
798 *
799 * О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫
800 * О©╫О©╫О©╫О©╫О©╫О©╫ "О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫".  О©╫ О©╫О©╫О©╫О©╫О©╫О©╫:
801 *
802 *   - О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫
803 *     её О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫, О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫
804 *     О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫.
805 *
806 *   - О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫
807 *     О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.  О©╫О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫
808 *     О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.
809 *
810 *   - О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫
811 *     О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫.  О©╫.О©╫.
812 *     О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.
813 *
814 *   - О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.  О©╫О©╫О©╫О©╫О©╫О©╫О©╫
815 *     О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫, О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫,
816 *     О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ её О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.  О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫
817 *     О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫-О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫-О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫,
818 *     О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫
819 *     О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫-О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.
820 *     О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫, О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫
821 *     О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.
822 *
823 *   - О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫сё О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫, О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫
824 *     О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫её.
825 *
826 *
827 * О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫:
828 *
829 * t1 (t1 t2) (t1 t3) :: t2 t1 t3
830 *
831 * t1 -- (t2 t3) (t2)
832 * t2 -- (t1)    (t1)
833 * t3 -- ()      (t1)
834 *
835 *
836 * О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ var_i О©╫О©╫О©╫дёО©╫ О©╫О©╫О©╫ j /= i, О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫ Re_j О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫
837 * var_i -- provide[i], О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ j /= i, О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ var_j О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫
838 * О©╫О©╫О©╫О©╫чёО©╫О©╫ var_i, О©╫.О©╫. О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ Re_i.
839 *
840 * Res-vars <- <Map &Vars (Res)>
841 * for var_i in vars
842 *     provide[i] <-
843 *     for vars-Re_j in Res-vars, j /= i
844 *         vars-Re_j : e var_i e = j
845 *     require[i] <- <Res-vars[i] `*` vars[^i]> : e var_j e, j
846 *
847 * Res-vars = map Vars Res
848 * provide, require =
849 *   {   [ j | vars-Re_j <- Res-vars, j /= i, var_i `in` vars-Re_j ]
850 *     , [ j | var_j <- Res-vars[i] `*` vars, i /= j]
851 *     | var_i <- vars
852 *   }
853 *
854 */
855
856$func CAV e.vars (e.assigns) (e.delayed) = e.assigns;
857
858$func Get_Vars e = e;
859Get_Vars (e.Re) = (<Vars e.Re>);
860
861Create_Aux_Vars (e.vars) e.splited_Re =
862  <Zip (<Map &Get_Vars (e.splited_Re)>) (e.vars)> :: e.list,
863  <Box> :: s.box,
864  <Box> :: s.provide_i,
865  <Box> :: s.require_i,
866  {
867    e.vars : e1 t.var_i e2,
868      {
869        e.list : e ((e.vars_Re) t.var_j) e,
870          \{
871            t.var_i : t.var_j = <Put s.require_i <And (e1 e2) e.vars_Re>>;
872            e.vars_Re : e t.var_i e = <Put s.provide_i t.var_j>;
873          },
874          $fail;
875        <L <Length e1> e.splited_Re> :: t.Re_i,
876        <Put s.box (t.var_i t.Re_i (<Get s.provide_i>) (<Get s.require_i>))>,
877          <Store s.provide_i /*empty*/>,
878          <Store s.require_i /*empty*/>;
879      },
880      $fail;;
881  },
882  <CAV <Get s.box> (/*assigns*/) (/*delayed*/)>;
883
884
885/*
886 * О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ provide О©╫О©╫О©╫О©╫, её О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.
887 * О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫, О©╫О©╫О©╫ О©╫О©╫О©╫ (О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫) О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫
888 * О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ assigns, О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ vars, О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ provide
889 * О©╫ delayed.  О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ require её О©╫О©╫ О©╫О©╫О©╫О©╫.
890 *
891 * CAV Res vars provide require assigns delayed =
892 *   { i | var_i <- vars, provide_i == [] } ->     // О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫!  О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫
893 *                                                    О©╫О©╫ delayed О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.
894 *       vars    = vars - var_i
895 *       provide = [ provide_j - i | provide_j <- provide ]
896 *       assigns = assigns++[(var_i, Res[i])]
897 *       delayed = [ (var_j, provide_j - i) | (var_j, provide_j) <- delayed ]
898 *       CAV Res vars provide require assigns delayed
899 */
900
901$func Assign_Empty_Provides e.vars  = e.assigns (e.vars);
902
903Assign_Empty_Provides {
904  e1 (t.var_i t.Re_i (/*empty provide_i*/) (e.require_i)) e2 =
905    <Box> :: s.vars,
906    {
907      e1 e2 : e (t.var_j t.Re_j (e.provide_j) (e.require_j)) e,
908        <Put s.vars (t.var_j t.Re_j (<List.Sub (e.provide_j) t.var_i>) (e.require_j))>,
909        $fail;;
910    },
911    (t.var_i t.Re_i) <Assign_Empty_Provides <Get s.vars>>;
912  e.vars = /*empty*/ (e.vars);
913};
914
915
916/*
917 * О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ require О©╫О©╫О©╫О©╫, О©╫О©╫О©╫дёО©╫ её О©╫ delayed.
918 * О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫её О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ provide, О©╫.О©╫. О©╫О©╫О©╫О©╫О©╫ О©╫О©╫
919 * О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ require.
920 */
921$func Delay_Empty_Requires e.vars  = e.delayed (e.vars);
922
923Delay_Empty_Requires {
924  e1 t.var e2, t.var : (t.var_i t.Re_i (e.provide_i) (/*empty require_i*/)) =
925    <Delay_Empty_Requires e2> :: e.delayed (e.vars),
926    t.var e.delayed (e1 e.vars);
927  e.vars = /*empty*/ (e.vars);
928};
929
930
931/*
932 * О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ (О©╫О©╫ О©╫О©╫О©╫О©╫) О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.
933 */
934$func Max_Require e = e;
935
936Max_Require t.arg1 t.arg2 =
937  t.arg1 : (t.var1 t.Re1 t.provide1 (e.require1)),
938  t.arg2 : (t.var2 t.Re2 t.provide2 (e.require2)),
939  {
940    <Lt (<Length e.require1>) (<Length e.require2>)> = t.arg2;
941    t.arg1;
942  };
943
944
945/*
946 * О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.
947 * О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ (О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫).
948 * О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.
949 */
950$func Subst_Aux_Var e = e;
951
952Subst_Aux_Var t.var t.aux (t.v t.Re (e.provide) (e.require)), {
953  t.var : t.v = /*empty*/;
954  (
955    t.v
956    <Subst (t.var) ((t.aux)) t.Re>
957    (<List.Sub (e.provide) t.var>)
958    (<List.Sub (e.require) t.var>)
959  );
960};
961
962
963/*
964 * О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.
965 */
966$func Extract_Assigns e = e;
967Extract_Assigns (t.var t.Re e) = (t.var t.Re);
968
969
970/*
971 * О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.
972 *
973 * 1) О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ (О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫), О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫
974 *    О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.
975 * 2) О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.
976 * 3) О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫,
977 *    О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫
978 *    О©╫её О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ 1.
979 */
980CAV e.vars (e.assigns) (e.delayed) =
981  <Assign_Empty_Provides e.vars> :: e.new_assigns (e.vars),
982  e.assigns e.new_assigns <Assign_Empty_Provides e.delayed> :: e.assigns (e.delayed),
983  e.delayed <Delay_Empty_Requires e.vars> :: e.delayed (e.vars),
984  {
985    e.vars : t t e =
986      <Foldr1 &Max_Require (e.vars)> : (t.var t.Re e),
987      <Gener_Aux_Var> :: t.aux,
988      e.assigns (t.aux (t.var)) (t.var t.Re) :: e.assigns,
989      <Map &Subst_Aux_Var t.var t.aux (e.vars)> :: e.vars,
990      <Map &Subst_Aux_Var t.var t.aux (e.delayed)> :: e.delayed,
991      <CAV e.vars (e.assigns) (e.delayed)>;
992    e.assigns <Map &Extract_Assigns (e.vars e.delayed)>;
993  };
994
995
996
997
998//***************** О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ *******************
999
1000Get_Clash_Sequence (e.last_Re) t.Pattern e.Snt =
1001  (/*e.clashes*/) (RESULT e.last_Re) t.Pattern e.Snt $iter {
1002    e.Snt : (RESULT e.Re) (s.dir e.Pe) e.rest =
1003      /*
1004       * О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫
1005       * О©╫О©╫О©╫О©╫О©╫О©╫дёО©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.  О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫
1006       * О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫, О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.
1007       */
1008      <Prepare_Res (e.Re) (e.Pe)> : (e.R1) (e.P1),
1009      <Map &Set_Var (Clashes /*empty*/) (<Vars e.R1 e.P1>)> : e,
1010      (e.clashes (e.R1) (s.dir e.P1)) e.rest;
1011  } :: (e.clashes) e.Snt,
1012  # \{
1013    e.Snt : \{
1014      (RESULT e.Re) (LEFT e) e = e.Re;
1015      (RESULT e.Re) (RIGHT e) e = e.Re;
1016    } :: e.Re,
1017      <IsWithout_Calls e.Re>;
1018  } =
1019  (e.clashes) e.Snt;
1020
1021IsWithout_Calls e.Re =
1022  e.Re $iter {
1023    e.Re : t.Rt e.rest =
1024      t.Rt : {
1025        (CALL   e) = $fail;
1026        (ALT    e) = $fail;
1027        ("ALT?" e) = $fail;
1028        (PAREN e.Re1) = <IsWithout_Calls e.Re1>;
1029        t.symbol_or_var = /*empty*/;
1030      },
1031      e.rest;
1032  } :: e.Re,
1033  e.Re : /*empty*/;
1034
1035$func CC s.Istail (v.fails) t.end_cycle e.Snt = e.asail_Snt;
1036
1037Comp_Clashes (e.clashes) s.Istail (v.fails) e.Sentence =
1038  <Init_Clashes e.clashes>,
1039  <CC s.Istail (v.fails) <R 0 v.fails> e.Sentence>;
1040
1041$func CC_Known_Lengths t.fail e.idxs = e.conds;
1042
1043$func CC_Compute_Length t.fail t.end_cycle t.idx = e;
1044
1045$func CC_Unknown_Lengths t.fail e.idxs = e.conds;
1046
1047$func CC_Deref t.fail e.actions = e.actions;
1048
1049$func CC_Eqs t.fail (e.assigns) e.eqs = e.actions;
1050
1051CC s.Istail (v.fails) t.end_cycle e.Snt, {
1052  <Domain &Known_Lengths> : v.clashes =
1053    <CC_Known_Lengths t.end_cycle v.clashes>
1054    <CC s.Istail (v.fails) t.end_cycle e.Snt>;
1055  <Domain &Compute_Length> : (t.clash) e =
1056    <CC_Compute_Length <R 0 v.fails> t.end_cycle t.clash>
1057    <CC s.Istail (v.fails) t.end_cycle e.Snt>;
1058  <Domain &Unknown_Lengths> : e.clashes =
1059    <CC_Unknown_Lengths t.end_cycle e.clashes> :: e.conds,
1060    /*
1061     * О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫, О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫
1062     * О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.  О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ (О©╫О©╫
1063     * О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫) О©╫О©╫дёО©╫ О©╫О©╫ О©╫
1064     * О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫, О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.
1065     * О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ t.end-cycle О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫
1066     * О©╫О©╫О©╫О©╫О©╫.
1067     */
1068    <Update_Hard_Parts> : {
1069      v.actions =
1070        e.conds <CC_Deref <R 0 v.fails> v.actions>
1071        <CC s.Istail (v.fails) <R 0 v.fails> e.Snt>;
1072      /*empty*/ =
1073        e.conds <CC_Eqs <R 0 v.fails> () <Get &Eqs>> :: e.actions,
1074        <Store &Eqs /*empty*/>,
1075        {
1076          <Compose_Source> :: e.assign =
1077            e.actions <CC_Eqs <R 0 v.fails> () e.assign>
1078            <CC s.Istail (v.fails) <R 0 v.fails> e.Snt>;
1079          {
1080            <Get_Cycle> :: s.split (e.left) (e.right) (e.len)
1081                    t.var t.l_var t.r_var =
1082              {
1083                e.left : 0, e.right : 0 = /*empty*/ t.var;
1084                <Gener_Vars ((VAR)) "subexpr_" t.var> : t.sub_var,
1085                  (DECL Expr t.sub_var
1086                    (SUBEXPR t.var (e.left) ((INFIX "-" (e.len) (e.left e.right)))))
1087                  t.sub_var;
1088              } :: e.subexpr t.var,
1089              (<Get_Var_Min t.l_var>) :: t.min,
1090              {
1091                s.split : RSPLIT =
1092                  t.r_var t.l_var "DEC-ITER";
1093                t.l_var t.r_var "INC-ITER";
1094              } :: t.l_var t.r_var s.iter_op,
1095              <Gener_Label "continue"> :: t.cont_label,
1096              <Gener_Label "exit"> :: t.break_label,
1097              e.actions e.subexpr
1098              (s.split t.var t.min t.l_var t.r_var)
1099              (FOR (t.cont_label) (t.break_label) () ((s.iter_op t.var))
1100                (IF ("ITER-FAILS" t.var) <Concat <R 0 v.fails>>)
1101                <CC s.Istail (v.fails ((CONTINUE t.cont_label)))
1102                  <R 0 v.fails> e.Snt>
1103                (BREAK t.break_label)
1104              );
1105            e.actions <Comp_Sentence s.Istail (v.fails) () e.Snt>;
1106          };
1107        };
1108    };
1109};
1110
1111CC_Known_Lengths (e.fail) e.idxs, {
1112  e.idxs : (t.idx) e.rest =
1113    <Put &Checked_Lengths t.idx>,
1114    <Lookup &Known_Lengths t.idx> : (e.len_Re) (e.len_Pe),
1115    ("IF-INT-CMP" "!=" (e.len_Re) (e.len_Pe) e.fail)
1116    <CC_Known_Lengths (e.fail) e.rest>;
1117  <ClearTable &Known_Lengths>;
1118};
1119
1120CC_Compute_Length (e.fail) (e.end_cycle) t.idx =
1121  <Lookup &Compute_Length t.idx> : t.var s.mult (e.minuend) (e.subtrahend),
1122  <Get_Var_Min t.var> :: e.min,
1123  {
1124    t.var : ("Len-Var" e) =
1125      <Unbind &Compute_Length t.idx>,
1126      ("IF-INT-CMP" "<" (e.minuend)
1127          ((INFIX "+" (e.subtrahend)
1128            ((INFIX "*" (e.min) (s.mult)))
1129          ))
1130        e.end_cycle
1131      );
1132    <Create_Int_Var ("len") Aux e.minuend> :: t.m_var e.m_assign,
1133      <Create_Int_Var ("len") Aux e.subtrahend> :: t.s_var e.s_assign,
1134      ("IF-INT-CMP" "<" (t.m_var)
1135          ((INFIX "+" (t.s_var)
1136            ((INFIX "*" (e.min) (s.mult)))
1137          ))
1138        e.end_cycle
1139      ) :: e.min_cond,
1140      <Get_Var_Max t.var> : {
1141        /*empty*/;
1142        e.max,
1143          <Gt (<Add <TableSize &Compute_Length> <TableSize &Unknown_Lengths>>) (1)> =
1144          ("IF-INT-CMP" ">" (t.m_var)
1145              ((INFIX "+" (t.s_var)
1146                ((INFIX "*" (e.max) (s.mult)))
1147              ))
1148          e.end_cycle);
1149        e;
1150      } :: e.max_cond,
1151      (INFIX "%" ((INFIX "-" (t.m_var) (t.s_var))) (s.mult)) :: e.div_cond,
1152      <Create_Int_Var ("len_") t.var
1153        (INFIX "/" ((INFIX "-" (t.m_var) (t.s_var))) (s.mult))
1154      > :: t.len_var e.len_assign,
1155      <Set_Var (Length t.len_var) t.var>,
1156      <Unbind &Compute_Length t.idx>,
1157      <Put &Checked_Lengths t.idx>,
1158      <Get_Var Clashes t.var> :: e.clashes,
1159      <Map &Reclassify_Clash (<List.Sub (e.clashes) <Get &Checked_Lengths>>)> : e,
1160      e.m_assign e.s_assign
1161      e.min_cond e.max_cond
1162      ("IF-INT-CMP" "!=" (e.div_cond) (0) e.fail)
1163      e.len_assign;
1164  };
1165
1166$func  Get_Min e = e;
1167
1168$func? Get_Max e = e;
1169
1170CC_Unknown_Lengths (e.fail) e.idxs, {
1171  e.idxs : (t.idx) e.rest =
1172    <Lookup &Unknown_Lengths t.idx> : (e.len_Re) (e.len_Pe) (e.vars_Re) (e.vars_Pe),
1173    {
1174      <Get_Max e.vars_Re> :: e.max =
1175        <Get_Min e.vars_Pe> :: e.min,
1176        ("IF-INT-CMP" "<" (e.len_Re e.max) (e.len_Pe e.min) e.fail);
1177      /*empty*/;
1178    } :: e.cond1,
1179    {
1180      <Gt (<TableSize &Unknown_Lengths>) (1)>, <Get_Max e.vars_Pe> :: e.max =
1181        <Get_Min e.vars_Re> :: e.min,
1182        ("IF-INT-CMP" ">" (e.len_Re e.min) (e.len_Pe e.max) e.fail);
1183      /*empty*/;
1184    } :: e.cond2,
1185    e.cond1 e.cond2
1186    <CC_Unknown_Lengths (e.fail) e.rest>;
1187  <ClearTable &Unknown_Lengths>;
1188};
1189
1190Get_Min
1191{
1192  t.var e.vars = <Get_Var_Min t.var> <Get_Min e.vars>;
1193  /*empty*/ = /*empty*/;
1194};
1195
1196Get_Max
1197{
1198  t.var e.vars = <Get_Var_Max t.var> : v.max, v.max <Get_Max e.vars>;
1199  /*empty*/ = /*empty*/;
1200};
1201
1202$func Pos (e.Re) s.dir e.pos = e.pos;
1203
1204Pos {
1205  (e.Re) RIGHT e.pos = (INFIX "-" ((LENGTH e.Re)) (e.pos));
1206  (e.Re) LEFT  e.pos = e.pos;
1207};
1208
1209/*
1210 * О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫
1211 * О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ ASAIL.
1212 */
1213CC_Deref (e.fail) e.actions, e.actions : {
1214  ("SYMBOL?" e.Re (s.dir e.pos)) e.rest =
1215    (IF ("SYMBOL?" e.Re (<Pos (e.Re) s.dir e.pos>)) e.fail)
1216    <CC_Deref (e.fail) e.rest>;
1217  (DEREF t.var e.Re (s.dir e.pos)) e.rest =
1218    (DECL Expr t.var (DEREF e.Re (<Pos (e.Re) s.dir e.pos>)))
1219    <CC_Deref (e.fail) e.rest>;
1220  /*empty*/ = /*empty*/;
1221};
1222
1223CC_Eqs (e.fail) (e.assigns) e.eqs, {
1224  e.eqs : ((e.Re) (s.dir e.pos) t.Pt (e.len)) e.rest =
1225    {
1226      e.Re : t,
1227        <Get_Known_Length e.Re> : e.len (), // FIXME: Calculator must be used
1228        s.dir e.pos : \{
1229          LEFT 0;
1230          RIGHT e.len;
1231        } =
1232        e.Re;;
1233    } :: e.Re_term,
1234    {
1235      e.len : 1 = "TERM-EQ"; // FIXME: Calculator must be used
1236      EQ;
1237    } :: s.eq,
1238    <Pos (e.Re) s.dir e.pos> :: e.pos,
1239    {
1240      \{
1241        <Get_Var "Instantiated?" t.Pt> : True = t.Pt (e.Re);
1242        t.Pt : \{
1243          (REF e);
1244          (STATIC e);
1245        }, {
1246          <IsVar e.Re_term> = e.Re_term (t.Pt);
1247          t.Pt (e.Re);
1248        };
1249      } :: el (er),
1250        (IF (NOT (s.eq el (er) (e.pos))) e.fail) :: t.cond,
1251        {
1252          /*
1253           * О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ e.eqs О©╫О©╫О©╫ e.Re
1254           * О©╫О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫.
1255           */
1256          e.assigns : $r e1 (s.op t.Pt e.def) e2 =
1257            <CC_Eqs (e.fail) (e1 (s.op t.Pt e.def) t.cond e2) e.rest>;
1258          t.cond <CC_Eqs (e.fail) (e.assigns) e.rest>;
1259        };
1260      <Set_Var ("Instantiated?" True) t.Pt>,
1261        {
1262          t.Pt : (SVAR e) =
1263            (IF
1264              (NOT ("SYMBOL?" e.Re (e.pos)))
1265              e.fail
1266            );;
1267        } :: e.cond,
1268        {
1269          <Get_Var Decl t.Pt> : s =
1270            e.cond <CC_Eqs (e.fail) (e.assigns
1271              (ASSIGN t.Pt (SUBEXPR e.Re (e.pos) (e.len))))
1272              e.rest>;
1273          <Vars_Decl Expr t.Pt> : e,
1274            e.cond <CC_Eqs (e.fail) (e.assigns
1275              (DECL Expr t.Pt) (ASSIGN t.Pt (SUBEXPR e.Re (e.pos) (e.len)))) e.rest>;
1276        };
1277    };
1278  e.assigns e.eqs;
1279};
1280
1281
1282
1283
1284Gener_Label e.QualifiedName =
1285  {
1286    <Lookup &Labels e.QualifiedName> : s.num,
1287      <Arithm.Add s.num 1>;
1288    1;
1289  } :: s.num,
1290  <Bind &Labels (e.QualifiedName) (s.num)>,
1291  (e.QualifiedName s.num);
1292
1293Add_To_Label (e.label) e.name = <Gener_Label e.label "_" e.name>;
1294
1295
Note: See TracBrowser for help on using the repository browser.