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

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