next up previous contents index
Next: コード説明 Up: KLICの基本的な動作 Previous: 定数構造体のコンパイル

  

以下のようなKL1プログラム``naive reverse''を例として説明をする。

 

:- module main.

main :-
       nrev([1,2,3], X),
       klicio:klicio([stdout(normal([putt(X),nl]))]).

nrev([], Y) :- Y=[].
nrev([A|X], Y) :- nrev(X, X1), append(X1, [A], Y).

append([], Y, Z) :- Y=Z.
append([A|X], Y, Z) :- Z=[A|Z1], append(X, Y, Z1).

このコードをKLICコンパイラでコンパイルすると以下のようなCコードになる。  

     1  /* Compiled by KLIC compiler version 3.002 (Wed Sep 17 15:37:13 JST 1997) */
     2  #include <klic/klichdr.h>
     3  #include "atom.h"
     4  #include "funct.h"
     5  
     6  module module_main();
     7  Const struct predicate predicate_main_xmain_0 =
     8     { module_main, 0, 0 };
     9  Const struct predicate predicate_main_xnrev_2 =
    10     { module_main, 1, 2 };
    11  Const struct predicate predicate_main_xappend_3 =
    12     { module_main, 2, 3 };
    13  extern Const struct predicate predicate_klicio_xklicio_1;
    14  
    15  module module_main(glbl, qp, allocp, toppred)
    16    struct global_variables *glbl;
    17    struct goalrec *qp;
    18    register q *allocp;
    19    Const struct predicate *toppred;
    20  {
    21    static Const q cons_const_0[] = {
    22      NILATOM,
    23      makeint(3),
    24    };
    25    static Const q cons_const_1[] = {
    26      makecons(cons_const_0),
    27      makeint(2),
    28    };
    29    static Const q cons_const_2[] = {
    30      makecons(cons_const_1),
    31      makeint(1),
    32    };
    33    static Const q cons_const_3[] = {
    34      NILATOM,
    35      makesym(atom_nl),
    36    };
    37    q a0, a1, a2;
    38  
    39    q *reasonp;
    40   module_top:
    41    switch_on_pred() {
    42      case_pred(0, main_0_top);
    43      case_pred(1, nrev_2_top);
    44      last_case_pred(2, append_3_top);
    45    }
    46  
    47   main_0_top: {
    48    q x0, x1, x2, x3, x4, x5;
    49    qp = qp->next;
    50   main_0_clear_reason:
    51    reasonp = reasons;
    52   main_0_0:
    53    allocp[0] = (q)qp;
    54    allocp[1] = (q)(&predicate_main_xnrev_2);
    55    allocp[2] = makecons(cons_const_2);
    56    allocp[3] = x0 = makeref(&allocp[3]);
    57    allocp[4] = makesym(functor_putt_1);
    58    allocp[5] = x0;
    59    x1 = makefunctor(&allocp[4]);
    60    allocp[6] = makecons(cons_const_3);
    61    allocp[7] = x1;
    62    x2 = makecons(&allocp[6]);
    63    allocp[8] = makesym(functor_normal_1);
    64    allocp[9] = x2;
    65    x3 = makefunctor(&allocp[8]);
    66    allocp[10] = makesym(functor_stdout_1);
    67    allocp[11] = x3;
    68    x4 = makefunctor(&allocp[10]);
    69    allocp[12] = NILATOM;
    70    allocp[13] = x4;
    71    x5 = makecons(&allocp[12]);
    72    allocp[14] = (q)(struct goalrec*)&allocp[0];
    73    allocp[15] = (q)(&predicate_klicio_xklicio_1);
    74    allocp[16] = x5;
    75    qp = (struct goalrec*)&allocp[14];
    76    allocp += 17;
    77    proceed();
    78   main_0_ext_interrupt:
    79    reasonp = 0l;
    80   main_0_interrupt:
    81    goto interrupt_0;
    82   }
    83  
    84   nrev_2_top: {
    85    q x0, x1, x2;
    86    a0 = qp->args[0];
    87    a1 = qp->args[1];
    88    qp = qp->next;
    89   nrev_2_clear_reason:
    90    reasonp = reasons;
    91   nrev_2_0:
    92   nrev_2_1:
    93    switch (ptagof(a0)) {
    94   case CONS:
    95    allocp[0] = NILATOM;
    96    x1 = car_of(a0);
    97    allocp[1] = x1;
    98    x0 = makecons(&allocp[0]);
    99    allocp[2] = (q)qp;
   100    allocp[3] = (q)(&predicate_main_xappend_3);
   101    allocp[4] = x2 = makeref(&allocp[4]);
   102    allocp[5] = x0;
   103    allocp[6] = a1;
   104    a0 = cdr_of(a0);
   105    a1 = x2;
   106    qp = (struct goalrec*)&allocp[2];
   107    allocp += 7;
   108    execute(nrev_2_0);
   109    goto nrev_2_ext_interrupt;
   110   case ATOMIC:
   111    if (a0 != NILATOM) goto nrev_2_interrupt;
   112    x0 = NILATOM;
   113    unify_value(a1, x0);
   114    proceed();
   115   case VARREF:
   116    deref_and_jump(a0,nrev_2_1);
   117    *reasonp++ =  a0;
   118    goto nrev_2_interrupt;
   119    };
   120    goto nrev_2_interrupt;
   121   nrev_2_ext_interrupt:
   122    reasonp = 0l;
   123   nrev_2_interrupt:
   124    goto interrupt_2;
   125   }
   126  
   127   append_3_top: {
   128    q x0, x1, x2;
   129    a0 = qp->args[0];
   130    a1 = qp->args[1];
   131    a2 = qp->args[2];
   132    qp = qp->next;
   133   append_3_clear_reason:
   134    reasonp = reasons;
   135   append_3_0:
   136   append_3_1:
   137    switch (ptagof(a0)) {
   138   case CONS:
   139    allocp[0] = x1 = makeref(&allocp[0]);
   140    x2 = car_of(a0);
   141    allocp[1] = x2;
   142    x0 = makecons(&allocp[0]);
   143    allocp += 2;
   144    unify_value(a2, x0);
   145    a0 = cdr_of(a0);
   146    a2 = x1;
   147    execute(append_3_0);
   148    goto append_3_ext_interrupt;
   149   case ATOMIC:
   150    if (a0 != NILATOM) goto append_3_interrupt;
   151    unify(a1, a2);
   152    proceed();
   153   case VARREF:
   154    deref_and_jump(a0,append_3_1);
   155    *reasonp++ =  a0;
   156    goto append_3_interrupt;
   157    };
   158    goto append_3_interrupt;
   159   append_3_ext_interrupt:
   160    reasonp = 0l;
   161   append_3_interrupt:
   162    goto interrupt_3;
   163   }
   164   interrupt_3:
   165    allocp[4] = a2;
   166   interrupt_2:
   167    allocp[3] = a1;
   168   interrupt_1:
   169    allocp[2] = a0;
   170   interrupt_0:
   171    allocp = interrupt_goal(allocp, toppred, reasonp);
   172   proceed_label:
   173    loop_within_module(module_main);
   174  }



 

Sekita Daigo
1998-05-18