guile-devel
[Top][All Lists]
Advanced

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

Poor man's constant folding


From: Ludovic Courtès
Subject: Poor man's constant folding
Date: Wed, 16 Jun 2010 00:27:12 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux)

Hello!

Here’s an experiment to implement constant folding using plain macros
(while waiting for an implementation of Wadell’s inlining algorithm ;-)):

--8<---------------cut here---------------start------------->8---
(use-modules (srfi srfi-1))

(define-syntax define-nary-constructor
  (lambda (s)
    (syntax-case s ()
      ((_ name pred)
       (identifier? #'name)
       (let ((p (symbol-append '% (syntax->datum #'name) '-proc)))
         (with-syntax ((proc-name (datum->syntax #'name p)))
           #'(begin
               (eval-when (expand)
                 (define proc-name name))
               (define-syntax name
                 (lambda (x)
                   (syntax-case x ()
                     ((_ . args)
                      (every pred (syntax->datum #'args))
                      (apply proc-name (syntax->datum #'args)))
                     ((_ . args)
                      #'(proc-name . args))
                     (_ #'proc-name)))))))))))

(define-nary-constructor + number?)
(define-nary-constructor - number?)
(define-nary-constructor / number?)
(define-nary-constructor * number?)
--8<---------------cut here---------------end--------------->8---

It works transparently in all the cases I could think of:

   scheme@(guile-user)> (+ 2 3)
   5
   scheme@(guile-user)> +
   #<procedure + (#:optional _ _ . _)>
   scheme@(guile-user)> %+-proc
   #<procedure + (#:optional _ _ . _)>
   scheme@(guile-user)> ,c (+ "a" "b")
   Disassembly of #<objcode 16f08c8>:

      0    (assert-nargs-ee/locals 0)      
      2    (load-symbol "%+-proc")         ;; %+-proc
     13    (link-now)                      
     14    (variable-ref)                  
     15    (load-string "a")               ;; "a"
     20    (load-string "b")               ;; "b"
     25    (tail-call 2)                   
  
   scheme@(guile-user)> (use-modules (oop goops))
   scheme@(guile-user)> (define-method (+ (a <string>) (b <string>))
                          (string-append a b))
   scheme@(guile-user)> (+ "a" "b")
   "ab"

The main shortcoming is that it doesn’t work recursively:

  scheme@(guile-user)> ,c (+ 1 (+ 2 (+ 3 4)))
  Disassembly of #<objcode 1c1df88>:

     0    (assert-nargs-ee/locals 0)      
     2    (load-symbol "%+-proc")         ;; %+-proc
    13    (link-now)                      
    14    (variable-ref)                  
    15    (make-int8:1)                   ;; 1
    16    (new-frame)                     
    17    (load-symbol "%+-proc")         ;; %+-proc
    28    (link-now)                      
    29    (variable-ref)                  
    30    (make-int8 2)                   ;; 2
    32    (make-int8 7)                   ;; 7
    34    (call 2)                        
    36    (tail-call 2)                   

I’m not sure this can be worked around reasonably.

Comments?

Thanks,
Ludo’.




reply via email to

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