home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / lifeos2.zip / LIFE-1.02 / TOOLS / STD_EXPA.LF < prev    next >
Text File  |  1996-06-04  |  11KB  |  410 lines

  1. %    $Id: std_expander.lf,v 1.2 1994/12/08 23:54:02 duchier Exp $    
  2. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3. %                   STANDARD EXPANDER 
  4. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5.  
  6. module("std_expander") ?
  7.  
  8.  
  9. import("acc_declarations") ?
  10.  
  11. public(std_expander,comma,
  12.        clauses,context,code,define,macro) ?
  13.  
  14. associate_expanders(std_expander,make_expander) ?
  15. op(1000,xfy,comma)?
  16.  
  17. global(init_method,head_method,traverse_method,leaf_method,
  18.        split_method,save_method,restore_method,merge_method,
  19.        terminate_method) ?
  20.  
  21. X:std_expander :-
  22.     make_expander(X,in_clauses => In,out_clauses => []),
  23.     maprel(assert,In),
  24.     fail.
  25.  
  26. make_expander(S:std_expander(Name,
  27.                  init => init_method,
  28.                  head => head_method,
  29.                  leaf => leaf_method,
  30.                  split => split_method,
  31.                  save => save_method,
  32.                  restore => restore_method,
  33.                  merge => merge_method,
  34.                  terminate   => terminate_method),
  35.           in_clauses => In,out_clauses => Out) :-
  36.     ( head_method = std,!
  37.     ;
  38.       pred_info(head_method,[context,clauses,code])
  39.     ),
  40.     ( save_method = std,!
  41.     ;
  42.       pred_info(save_method,[context,code])
  43.     ),      
  44.     ( restore_method = std,!
  45.     ;
  46.       pred_info(restore_method,[context,code])
  47.     ),
  48.     ( leaf_method = std,!
  49.     ;
  50.       pred_info(leaf_method,[clauses,context,code])
  51.     ),
  52.     ( init_method = std,!
  53.     ;
  54.       pred_info(init_method,[clauses])
  55.     ),
  56.     ( terminate_method = std,!
  57.     ;
  58.       pred_info(terminate_method,[code,clauses])
  59.     ),
  60.     split_method = {std;@},!, 
  61.     merge_method = {std;@},!,
  62.     
  63.     traverse_method = str2psi(strcon(psi2str(Name),"_traverse"),
  64.                   current_module),
  65.     
  66.     pred_info(Name,clauses),
  67.     pred_info(traverse_method,[context,clauses,code]),
  68.     
  69.     first_clause(Name,First),
  70.     conj_clause(Conj),
  71.     disj_clause(Disj), 
  72.     cond_clause(Cond),
  73.     macro_clause(Macro),
  74.     leaf_clause(Leaf),
  75.     In = [First,Conj,Disj,Cond,Macro,Leaf|Out].
  76.  
  77. first_clause(Name,First) :-
  78.     First =
  79.     (Name & @(Head :- Body,
  80.           in_clauses => Cl1,out_clauses => Cl6,
  81.           file => File, line => Line) :-
  82.        initialize(context => Co1,
  83.               in_clauses => Cl1,out_clauses => Cl2,
  84.               file => File,line => Line) comma
  85.        head(Head,NewHead,
  86.         in_code => Code1,out_code => Code2,
  87.         in_context => Co1,out_context => Co2,
  88.         in_clauses => Cl2,out_clauses => Cl3) comma
  89.        traverse(Body,
  90.             in_code => Code2,out_code => Code3,
  91.             in_context => Co1,out_context => Co2,
  92.             in_clauses => Cl3,out_clauses => Cl4) comma
  93.        terminate(in_code => Code3,out_code => succeed,
  94.              context => Co2,
  95.              in_clauses => Cl4,out_clauses => Cl5),
  96.      Cl5 = [`(NewHead :- Code1)|Cl6]
  97.     ).
  98.  
  99.  
  100. conj_clause(Conj) :-
  101.     Conj = 
  102.     (traverse(S1:@(A,B),
  103.           in_code => Code1,out_code => Code3,
  104.           in_context => Co1,out_context => Co3,
  105.           in_clauses => Cl1,out_clauses => Cl3):-
  106.      `(S1 :== ,),
  107.      !,
  108.      traverse(A,
  109.           in_code => Code1,out_code => Code2, 
  110.           in_context => Co1,out_context => Co2,
  111.           in_clauses => Cl1,out_clauses => Cl2),
  112.      traverse(B,
  113.           in_code => Code2,out_code => Code3,
  114.           in_context => Co2,out_context => Co3,
  115.           in_clauses => Cl2,out_clauses => Cl3)
  116.     ).
  117.  
  118.  
  119. disj_clause(Disj) :- 
  120.       Disj = 
  121.     (traverse(S2:@(A,B),
  122.           in_code => Code1,out_code => Code4,
  123.           in_context => Co1,out_context => Co2,
  124.           in_clauses => Cl1,out_clauses => Cl3) :-
  125.      `(S2 :== ;),
  126.      !,
  127.      split(in_code => Code1,out_code => Code2,
  128.            in => Co1,out1 => Co1A,out2 => Co1B) comma
  129.      (
  130.          save(in_code => CodeA,out_code => CodeA2,
  131.           in_context => Co1A,out_context => Co2A) comma
  132.          traverse(A,
  133.               in_code => CodeA2,out_code => CodeA3,
  134.               in_context => Co2A,out_context => Co3A,
  135.               in_clauses => Cl1,out_clauses => Cl2) comma
  136.          restore(in_code => CodeA3,out_code => succeed,
  137.              in_context => Co3A,out_context => Co4A)                  
  138.      ),
  139.          
  140.      (
  141.          save(in_code => CodeB,out_code => CodeB2,
  142.           in_context => Co1B,out_context => Co2B) comma
  143.          traverse(B,
  144.               in_code => CodeB2,out_code => CodeB3,
  145.               in_context => Co2B,out_context => Co3B,
  146.               in_clauses => Cl2,out_clauses => Cl3) comma
  147.          restore(in_code => CodeB3,out_code => succeed,
  148.              in_context => Co3B,out_context => Co4B)
  149.      ),
  150.      merge(in_code => Code3,out_code => Code4,
  151.            in1 => Co4A,in2 => Co4B,out => Co2),
  152.      Code2 = `((CodeA;CodeB) comma Code3)
  153.     ).
  154.  
  155. cond_clause(Cond) :-
  156.     Cond =
  157.     (traverse(S3,
  158.           in_code => Code1,out_code => Code4,
  159.           in_context => Co1,out_context => Co2,
  160.           in_clauses => Cl1,out_clauses => Cl3) :-
  161.      `(S3 :== `cond),
  162.      !,
  163.      (
  164.          `has_feature(1,S3,Condition),!
  165.      ;
  166.          Condition = "missing condition in the code!"  %% should not 
  167.                                %  be silent !!
  168.      ),
  169.      split(in_code => Code1,out_code => Code2,
  170.            in => Co1,out1 => Co1A,out2 => Co1B) comma
  171.      (
  172.          `has_feature(2,S3,Alt1),!,
  173.          save(in_code => CodeA,out_code => CodeA2,
  174.           in_context => Co1A,out_context => Co2A) comma
  175.          traverse(Alt1,
  176.               in_code => CodeA2,out_code => CodeA3,
  177.               in_context => Co2A,out_context => Co3A,
  178.               in_clauses => Cl1,out_clauses => Cl2) comma 
  179.          restore(in_code => CodeA3,out_code => succeed,
  180.              in_context => Co3A,out_context => Co4A)
  181.      ;
  182.          save(in_code => CodeA6,out_code => CodeA5,
  183.           in_context => Co1A,out_context => Co5A) comma
  184.          restore(in_code => CodeA5,out_code => succeed,
  185.              in_context => Co5A,out_context => Co4A) comma
  186.          Cl1 = Cl2,
  187.          CodeA = CodeA6
  188.      ),
  189.      (
  190.          `has_feature(3,S3,Alt2),!,
  191.          save(in_code => CodeB,out_code => CodeB2,
  192.           in_context => Co1B,out_context => Co2B) comma 
  193.          traverse(Alt2,
  194.               in_code => CodeB2,out_code => CodeB3,
  195.               in_context => Co2B,out_context => Co3B,
  196.               in_clauses => Cl2,out_clauses => Cl3) comma
  197.          restore(in_code => CodeB3,out_code => succeed,
  198.              in_context => Co3B,out_context => Co4B)
  199.          
  200.      ;
  201.          save(in_code => CodeB6,out_code => CodeB5,
  202.           in_context => Co1B,out_context => Co5B) comma
  203.          restore(in_code => CodeB5,out_code => succeed,
  204.              in_context => Co5B,out_context => Co4B) comma
  205.          Cl2 = Cl3,
  206.          CodeB = CodeB6
  207.      ),
  208.      merge(in_code => Code3,out_code => Code4,
  209.            in1 => Co4A,in2 => Co4B,out => Co2),
  210.      Code2 = `(`cond(Condition,
  211.              CodeA,
  212.              CodeB
  213.             ) comma Code3)
  214.     ).
  215.  
  216.  
  217. macro_clause(MacroClause) :-
  218.     MacroClause = 
  219.     (traverse(Leaf,
  220.           in_code => Code1,out_code => Code2,
  221.           in_context => Co1,out_context => Co2,
  222.           in_clauses => Cl1,out_clauses => Cl2) :-
  223.      `macro(Leaf,Def),!,
  224.      traverse(Def,
  225.           in_code => Code1,out_code => Code2,
  226.           in_context => Co1,out_context => Co2,
  227.           in_clauses => Cl1,out_clauses => Cl2)
  228.     ).
  229.  
  230.  
  231. leaf_clause(LeafClause) :-
  232.     LeafClause = 
  233.     (traverse(Leaf,
  234.           in_code => Code1,out_code => Code2,
  235.           in_context => Co1,out_context => Co2,
  236.           in_clauses => Cl1,out_clauses => Cl2) :-
  237.      leaf(Leaf,
  238.           in_code => Code1,out_code => Code2,
  239.           in_context => Co1,out_context => Co2,
  240.           in_clauses => Cl1,out_clauses => Cl2)
  241.     ).
  242.  
  243.  
  244. initialize(context => Co1,
  245.        in_clauses => Cl1,out_clauses => Cl2,
  246.        file => File,line => Line) ->    
  247.     cond( init_method :== std,
  248.           ( succeed | Cl1 = Cl2),
  249.           root_sort(init_method)
  250.           & @(context => Co1,
  251.           in_clauses => Cl1,out_clauses => Cl2,
  252.           file => File,line => Line)
  253.         ).
  254.  
  255. terminate(context => Co1,
  256.       in_code => Code1,out_code => Code2,
  257.       in_clauses => Cl1,out_clauses => Cl2) ->    
  258.     cond( terminate_method :== std,
  259.           ( succeed | Cl1 = Cl2, Code1 = Code2),
  260.           root_sort(terminate_method)
  261.         & @(context => Co1,
  262.             in_code => Code1,out_code => Code2,
  263.             in_clauses => Cl1,out_clauses => Cl2)
  264.         ).
  265.  
  266.  
  267. head(Head,NewHead,
  268.      in_code => Code1,out_code => Code2,
  269.      in_context => Co1,out_context => Co2,
  270.      in_clauses => Cl1,out_clauses => Cl2) ->
  271.     cond( head_method :== std,
  272.           ( succeed | Cl1 = Cl2, NewHead = Head, Code1 = Code2),
  273.           root_sort(head_method)
  274.           & @(Head,NewHead,
  275.           in_code => Code1,out_code => Code2,
  276.           in_context => Co1,out_context => Co2,
  277.           in_clauses => Cl1,out_clauses => Cl2)
  278.         ).
  279.           
  280.  
  281. traverse(Body,
  282.      in_code => Code1,out_code => Code2,
  283.      in_context => Co1,out_context => Co2,
  284.      in_clauses => Cl3,out_clauses => Cl4) ->
  285.     root_sort(traverse_method)
  286.     & @(Body,
  287.         in_code => Code1,out_code => Code2,
  288.         in_context => Co1,out_context => Co2,
  289.         in_clauses => Cl3,out_clauses => Cl4).
  290.  
  291.  
  292. split(in_code => Code1,out_code => Code2,
  293.       in => Co,out1 => Co1,out2 => Co2) ->
  294.     cond( split_method :== std,
  295.           (succeed | Co = Co1, Co1 = Co2, Code1 = Code2),
  296.           root_sort(split_method)
  297.           & @(in_code => Code1,out_code => Code2,
  298.           in => Co,out1 => Co1,out2 => Co2)
  299.         ).
  300. save(in_code => Code1,out_code => Code2,
  301.      in_context => Co1,out_context => Co2) ->
  302.     cond( save_method :== std,
  303.           (succeed | Co1 = Co2, Code1 = Code2),
  304.           root_sort(save_method)
  305.           & @(in_code => Code1,out_code => Code2,
  306.           in_context => Co1,out_context => Co2)
  307.         ).
  308.  
  309. restore(in_code => Code1,out_code => Code2,
  310.     in_context => Co1,out_context => Co2) ->
  311.     cond( restore_method :== std,
  312.           (succeed | Co1 = Co2, Code1 = Code2),
  313.           root_sort(restore_method)
  314.           & @(in_code => Code1,out_code => Code2,
  315.           in_context => Co1,out_context => Co2)
  316.         ).
  317.  
  318. merge(in_code => Code1,out_code => Code2,
  319.       in1 => Co1,in2 => Co2,out => Co) ->
  320.     cond( merge_method :== std,
  321.           (succeed | Co = Co1, Co1 = Co2, Code1 = Code2),
  322.           root_sort(merge_method)
  323.           & @(in_code => Code1,out_code => Code2,
  324.           in1 => Co1,in2 => Co2,out => Co)
  325.         ).
  326.     
  327. leaf(Leaf,
  328.      in_code => Code1,out_code => Code2,
  329.      in_context => Co1,out_context => Co2,
  330.      in_clauses => Cl1,out_clauses => Cl2) ->
  331.     cond( leaf_method :== std,
  332.           (succeed | Co1 = Co2, Cl1 = Cl2, Code1 = (Leaf comma Code2)),
  333.           root_sort(leaf_method)
  334.           & @(Leaf,
  335.           in_code => Code1,out_code => Code2,
  336.           in_context => Co1,out_context => Co2,
  337.           in_clauses => Cl1,out_clauses => Cl2)
  338.         ).
  339.  
  340.  
  341. X comma Y -> cond( X :== succeed,
  342.            Y,
  343.            cond( Y :== succeed,
  344.              X,
  345.              (X,Y))).
  346.  
  347.  
  348. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  349. %
  350. % Macros
  351. %
  352. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  353.  
  354. %%% macro definition
  355.  
  356. persistent(macros_table) ?
  357.  
  358. non_strict(define) ?
  359.  
  360. define(A,B) :-
  361.     macros_table.current_module.A <<- @(A,B).
  362.  
  363.  
  364. associate_expanders(define,define_expander) ?
  365. define_expander(define(A,B),in_clauses => In,out_clauses => In) :-
  366.     define(A,B).
  367.  
  368. macro(X,Def) ->
  369.     cond( X :< string,
  370.           submacro(features(macros_table.current_module),
  371.                X,Def),
  372.           macro2(X,Def)
  373.         ).
  374.  
  375.  
  376. macro2(X,Def) ->
  377.     cond( has_feature(X,macros_table.current_module,Def1),
  378.           ( true |
  379.         @(X,Def) = copy_term(Def1)
  380.           ),
  381.           cond( is_sort(X),
  382.             submacro(features(macros_table,current_module),
  383.                  X,Def),
  384.             false
  385.           )
  386.         ).
  387.  
  388. submacro([A|B],X,Def) ->
  389.     cond( X :< A,
  390.           ( true |
  391.         @(X,Def) = copy_term(macros_table.current_module.A)
  392.           ),
  393.           submacro(B,X,Def)
  394.         ).
  395. submacro([],_,_) -> false.
  396.  
  397.  
  398. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  399. %
  400. % Info for accumulation
  401. %
  402. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  403.  
  404. acc_info(clauses,X,In,Out,acc_pred => In = [X|Out]).
  405. acc_info(context).
  406. acc_info(code,X,In,Out,acc_pred => In = (X comma Out)).
  407.  
  408.