guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: unification


From: stefan
Subject: Re: unification
Date: Sat, 15 May 2010 01:06:31 +0200
User-agent: KMail/1.12.4 (Linux/2.6.31.12-0.2-desktop; KDE/4.3.5; x86_64; ; )

Hi,

This will give some ideas of how I prefere to handle
unification. I add a few extra instructions. And I do not
expect you to swallow that. But at least it is a beutiful 
idea.

Consider an example of a unifing matcher e.g.

(def f ((a _) a) 
       ((c b) b))

currently this compiles to

,x f

Disassembly of #<procedure f (arg121)>:

   0    (assert-nargs-ee/locals 25)
   2    (unify-init)
   3    (br :L142)                      ;; -> 19
   7    (local-ref 0)                   ;; `arg121'
   9    (unify-cons)
  10    (local-set 1)                   ;; `a'
  12    (unify-cons)
  13    (drop)
  14    (make-eol)                      ;; ()
  15    (unify-eq)
  16    (local-ref 1)                   ;; `a'
  18    (return)
  19    (br :L143)                      ;; -> 36
  23    (local-ref 0)                   ;; `arg121'
  25    (unify-cons)
  26    (local-set 3)                   ;; `c'
  28    (unify-cons)
  29    (local-set 2)                   ;; `b'
  31    (make-eol)                      ;; ()
  32    (unify-eq)
  33    (local-ref 2)                   ;; `b'
  35    (return)
  36    (toplevel-ref 1)                ;; `error'
  38    (object-ref 2)                  ;; "no match in f"
  40    (tail-call 1)

2 initiates and stors the (br :L142) location if we need to jump to the 
next match, then executes 7  (this can be made better)

7.  pushes argument
9.  do a unifying cons. essentially (push cdr) (push car)
    but the unifying flavor. if not a cons go to L142 and initiate
10. set a to the pushed car and pop the car
12. do another cons sequence
13. pop
14. push '() and then check if eq? with the cdr
then the resulting code is executed.

if there is a failure we jump to 19, initiates the new next jump as :L143
and continue as before.

here is the code for unify-cons in c.


#define UNIFY_MODDED                            \
  {                                             \
  if(!unify_modded)                             \
    unify_modded = (int) SCM_UNPACK(gp_newframe());     \
  }

#define UNIFY_FAIL                              \
  {                                             \
    if(!unify_modded)                           \
      gp_unwind(FI_TO_SCM(unify_modded));       \
    ip = match_next;                            \
    sp = stack_next;                            \
    NEXT;                                       \
  }

VM_DEFINE_INSTRUCTION(123, unify_cons, "unify-cons",0,0,0)
{
  gp_lookup(GP_GETREF(*sp));
  sp--;
  if(GP_CONS(gp_ret.ref))
    {
      PUSH(GP_UNREF(gp_ret.id + 3));
      PUSH(GP_UNREF(gp_ret.id + 1));
      NEXT;
    }     
  if(gp_ret.val == 0) //variable
    {
      SCM *ref;
      UNIFY_MODDED;
      ref = GP_GETREF(gp_mk_cons());
      gp_set_ref(gp_ret.id,GP_UNREF(ref));
      PUSH(GP_UNREF(ref + 3));
      PUSH(GP_UNREF(ref + 1));      
      NEXT;
    }
  
  UNIFY_FAIL;
}

Have fun
/Stefan






reply via email to

[Prev in Thread] Current Thread [Next in Thread]