]> git.jsancho.org Git - gacela.git/commitdiff
Functions for playing with arguments when apply to procedures.
authorJavier Sancho <jsf@jsancho.org>
Tue, 14 Aug 2012 15:25:13 +0000 (17:25 +0200)
committerJavier Sancho <jsf@jsancho.org>
Tue, 14 Aug 2012 15:25:13 +0000 (17:25 +0200)
src/utils.scm
src/views.scm

index 4a27f88706c30e146dd7397c842699784b930601..28cc16346524e78c189e7ef194906a37e6c9dad0 100644 (file)
 
 
 (define-module (gacela utils)
-  #:use-module (ice-9 session)
-  #:export (use-cache-with))
+  #:export (use-cache-with
+           arguments-calling
+           arguments-apply))
 
 
 ;;; Cache for procedures
+
 (define (use-cache-with proc)
+  "Cache for procedures"
   (let ((cache (make-weak-value-hash-table)))
     (lambda (. param)
       (let* ((key param)
               (set! res (apply proc param))
               (hash-set! cache key res)
               res))))))
+
+
+;;; Playing with procedures arguments
+
+(define undefined)
+(define (bound? var) (not (eq? var undefined)))
+
+(define (required-arguments args values)
+  "Return an alist with required arguments and their values"
+  (define (f vars values)
+    (cond ((or (null? vars) (null? values)) '())
+         (else (assoc-set! (f (cdr vars) (cdr values))
+                           (car vars)
+                           (car values)))))
+  (f (assoc-ref args 'required) values))
+
+(define (optional-arguments args values)
+  "Return an alist with optional arguments and their values"
+  (define (f vars values)
+    (cond ((null? vars) '())
+         ((null? values) (assoc-set! (f (cdr vars) '())
+                                     (car vars)
+                                     undefined))
+         (else (assoc-set! (f (cdr vars) (cdr values))
+                           (car vars)
+                           (car values)))))
+  (f (assoc-ref args 'optional)
+     (list-tail values
+               (min (length (assoc-ref args 'required))
+                    (length values)))))
+
+(define (keyword-arguments args values)
+  "Return an alist with keyword arguments and their values"
+  (define (f vars values)
+    (cond ((null? vars) '())
+         (else
+          (let ((val (member (car vars) values)))
+            (assoc-set! (f (cdr vars) values)
+                           (keyword->symbol (car vars))
+                           (if val (cadr val) undefined))))))
+  (f (map (lambda (x) (car x)) (assoc-ref args 'keyword)) values))
+
+(define (rest-arguments args values)
+  "Return an alist with rest arguments"
+  (let ((rest (assoc-ref args 'rest)))
+    (cond (rest (assoc-set! '()
+                           rest
+                           (list-tail values
+                                      (min (+ (length (assoc-ref args 'required))
+                                              (length (assoc-ref args 'optional)))
+                                           (length values)))))
+         (else '()))))
+
+(define (arguments-calling proc values)
+  "Return an alist with procedure arguments and their values"
+  (let ((args ((@ (ice-9 session) procedure-arguments) proc)))
+    (append (required-arguments args values)
+           (optional-arguments args values)
+           (keyword-arguments args values)
+           (rest-arguments args values))))
+
+(define (required-arguments-apply args values)
+  "Return a list with required arguments for use with apply"
+  (define (f vars values)
+    (cond ((null? vars) '())
+         (else 
+          (cons (assoc-ref values (car vars))
+                (f (cdr vars) values)))))
+  (f (assoc-ref args 'required) values))
+
+(define (optional-arguments-apply args values)
+  "Return a list with optional arguments for use with apply"
+  (define (f vars values)
+    (cond ((null? vars) '())
+         (else (let ((a (f (cdr vars) values))
+                     (val (assoc (car vars) values)))
+                 (cond ((and val (bound? (cdr val)))
+                        (cons (cdr val) a))
+                       (else a))))))
+  (f (assoc-ref args 'optional) values))
+
+(define (keyword-arguments-apply args values)
+  "Return a list with keyword arguments for use with apply"
+  (define (f vars values)
+    (cond ((null? vars) '())
+         (else (let ((a (f (cdr vars) values))
+                     (val (assoc (keyword->symbol (car vars)) values)))
+                 (cond ((and val (bound? (cdr val)))
+                        (cons (car vars) (cons (cdr val) a)))
+                       (else a))))))
+  (f (map (lambda (x) (car x)) (assoc-ref args 'keyword)) values))
+
+(define (rest-arguments-apply args values)
+  "Return a list with rest arguments for use with apply"
+  (let ((rest (assoc-ref args 'rest)))
+    (cond (rest (assoc-ref values rest))
+         (else '()))))
+  
+(define (arguments-apply proc values)
+  "Return a list for use with apply"
+  (let ((args ((@ (ice-9 session) procedure-arguments) proc)))
+    (append (required-arguments-apply args values)
+           (optional-arguments-apply args values)
+           (keyword-arguments-apply args values)
+           (rest-arguments-apply args values))))
index 805a47d13f3a278945df9b8feca14c1ba39058d8..c19bf338100064fbf0eda3d5f842f18c2adeeac0 100644 (file)
@@ -42,7 +42,7 @@
            (video:rotate ax ay az)
            (video:translate x y z)
            (video:rotate rx ry rz)
-           (primitive)))
+           (primitive (assoc-ref properties 'args))))
          ((translate)
           (set! x (+ x (car params)))
           (set! y (+ y (cadr params)))
 
 ;;; Primitives
 
-(define (basic proc)
-  ((@ (system vm program) program-lambda-list) proc))
+(define-macro (primitive proc)
+  `(lambda (. params)
+     (let ((m (mesh (lambda (args) (apply ,proc args)))))
+       (m 'property-set! 'args params)
+       m)))
 
 (define-macro (define-primitives . symbols)
   (cond ((null? symbols)