guile-commits
[Top][All Lists]
Advanced

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

[Guile-commits] GNU Guile branch, stable-2.0, updated. v2.0.3-10-gee15aa


From: Andy Wingo
Subject: [Guile-commits] GNU Guile branch, stable-2.0, updated. v2.0.3-10-gee15aa4
Date: Tue, 15 Nov 2011 23:01:41 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Guile".

http://git.savannah.gnu.org/cgit/guile.git/commit/?id=ee15aa46e3fb29e609bd7c431e8f2676f6573d57

The branch, stable-2.0 has been updated
       via  ee15aa46e3fb29e609bd7c431e8f2676f6573d57 (commit)
       via  f3cf9421cb319e2cb9ffde4ec41cad7fdcafcebc (commit)
      from  020602791b3f929e2d65ffdd8d67977763d6883e (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit ee15aa46e3fb29e609bd7c431e8f2676f6573d57
Author: Andy Wingo <address@hidden>
Date:   Tue Nov 15 23:38:40 2011 +0100

    set names of functions defined at the toplevel from `eval'
    
    * module/ice-9/eval.scm (primitive-eval): Set the name of
      toplevel-defined functions.

commit f3cf9421cb319e2cb9ffde4ec41cad7fdcafcebc
Author: Andy Wingo <address@hidden>
Date:   Tue Nov 15 23:36:07 2011 +0100

    better debuggability for interpreted procedures
    
    * libguile/procprop.c (scm_set_procedure_minimum_arity_x): New
      function, allows a user to override a function's arity.
      (scm_i_procedure_arity): Look up in the overrides table first.
    
    * libguile/procprop.h: Add scm_set_procedure_minimum_arity_x.
    
    * module/ice-9/eval.scm (primitive-eval): Override arity of "general
      closures".
    
    * test-suite/tests/procprop.test ("procedure-arity"): Add tests.
    
    Based on a patch from Stefan Israelsson Tampe.  Test based on work by
    Patrick Bernaud.

-----------------------------------------------------------------------

Summary of changes:
 libguile/procprop.c            |   37 +++++++
 libguile/procprop.h            |    2 +
 module/ice-9/eval.scm          |  229 ++++++++++++++++++++++------------------
 test-suite/tests/procprop.test |   26 ++++-
 4 files changed, 187 insertions(+), 107 deletions(-)

diff --git a/libguile/procprop.c b/libguile/procprop.c
index c3fb90e..8e2cd6a 100644
--- a/libguile/procprop.c
+++ b/libguile/procprop.c
@@ -51,9 +51,25 @@ SCM_GLOBAL_SYMBOL (scm_sym_name, "name");
 static SCM overrides;
 static scm_i_pthread_mutex_t overrides_lock = SCM_I_PTHREAD_MUTEX_INITIALIZER;
 
+static SCM arity_overrides;
+
 int
 scm_i_procedure_arity (SCM proc, int *req, int *opt, int *rest)
 {
+  SCM o;
+
+  scm_i_pthread_mutex_lock (&overrides_lock);
+  o = scm_hashq_ref (arity_overrides, proc, SCM_BOOL_F);
+  scm_i_pthread_mutex_unlock (&overrides_lock);
+
+  if (scm_is_true (o))
+    {
+      *req = scm_to_int (scm_car (o));
+      *opt = scm_to_int (scm_cadr (o));
+      *rest = scm_is_true (scm_caddr (o));
+      return 1;
+    }
+
   while (!SCM_PROGRAM_P (proc))
     {
       if (SCM_IMP (proc))
@@ -74,9 +90,29 @@ scm_i_procedure_arity (SCM proc, int *req, int *opt, int 
*rest)
           return 0;
         }
     }
+
   return scm_i_program_arity (proc, req, opt, rest);
 }
 
+SCM_DEFINE (scm_set_procedure_minimum_arity_x, "set-procedure-minimum-arity!",
+            4, 0, 0, (SCM proc, SCM req, SCM opt, SCM rest),
+            "")
+#define FUNC_NAME s_scm_set_procedure_minimum_arity_x
+{
+  int t SCM_UNUSED;
+
+  SCM_VALIDATE_PROC (1, proc);
+  SCM_VALIDATE_INT_COPY (2, req, t);
+  SCM_VALIDATE_INT_COPY (3, opt, t);
+  SCM_VALIDATE_BOOL (4, rest);
+
+  scm_i_pthread_mutex_lock (&overrides_lock);
+  scm_hashq_set_x (arity_overrides, proc, scm_list_3 (req, opt, rest));
+  scm_i_pthread_mutex_unlock (&overrides_lock);
+  return SCM_UNDEFINED;
+}
+#undef FUNC_NAME
+
 SCM_DEFINE (scm_procedure_minimum_arity, "procedure-minimum-arity", 1, 0, 0, 
            (SCM proc),
            "Return the \"minimum arity\" of a procedure.\n\n"
@@ -207,6 +243,7 @@ void
 scm_init_procprop ()
 {
   overrides = scm_make_weak_key_hash_table (SCM_UNDEFINED);
+  arity_overrides = scm_make_weak_key_hash_table (SCM_UNDEFINED);
 #include "libguile/procprop.x"
 }
 
diff --git a/libguile/procprop.h b/libguile/procprop.h
index c8c156a..919fa4d 100644
--- a/libguile/procprop.h
+++ b/libguile/procprop.h
@@ -36,6 +36,8 @@ SCM_API SCM scm_sym_system_procedure;
 
 
 SCM_INTERNAL int scm_i_procedure_arity (SCM proc, int *req, int *opt, int 
*rest);
+SCM_API SCM scm_set_procedure_minimum_arity_x (SCM proc, SCM req, SCM opt,
+                                               SCM rest);
 SCM_API SCM scm_procedure_minimum_arity (SCM proc);
 SCM_API SCM scm_procedure_properties (SCM proc);
 SCM_API SCM scm_set_procedure_properties_x (SCM proc, SCM alist);
diff --git a/module/ice-9/eval.scm b/module/ice-9/eval.scm
index 30a373a..c0fa64c 100644
--- a/module/ice-9/eval.scm
+++ b/module/ice-9/eval.scm
@@ -235,109 +235,127 @@
                     (inits (if tail (caddr tail) '()))
                     (alt (and tail (cadddr tail))))
                (make-general-closure env body nreq rest nopt kw inits alt))))
-      (lambda %args
-        (let lp ((env env)
-                 (nreq* nreq)
-                 (args %args))
-          (if (> nreq* 0)
-              ;; First, bind required arguments.
-              (if (null? args)
-                  (if alt
-                      (apply alt-proc %args)
-                      (scm-error 'wrong-number-of-args
-                                 "eval" "Wrong number of arguments"
-                                 '() #f))
-                  (lp (cons (car args) env)
-                      (1- nreq*)
-                      (cdr args)))
-              ;; Move on to optional arguments.
-              (if (not kw)
-                  ;; Without keywords, bind optionals from arguments.
-                  (let lp ((env env)
-                           (nopt nopt)
-                           (args args)
-                           (inits inits))
-                    (if (zero? nopt)
-                        (if rest?
-                            (eval body (cons args env))
-                            (if (null? args)
-                                (eval body env)
-                                (if alt
-                                    (apply alt-proc %args)
-                                    (scm-error 'wrong-number-of-args
-                                               "eval" "Wrong number of 
arguments"
-                                               '() #f))))
-                        (if (null? args)
-                            (lp (cons (eval (car inits) env) env)
-                                (1- nopt) args (cdr inits))
-                            (lp (cons (car args) env)
-                                (1- nopt) (cdr args) (cdr inits)))))
-                  ;; With keywords, we stop binding optionals at the first
-                  ;; keyword.
-                  (let lp ((env env)
-                           (nopt* nopt)
-                           (args args)
-                           (inits inits))
-                    (if (> nopt* 0)
-                        (if (or (null? args) (keyword? (car args)))
-                            (lp (cons (eval (car inits) env) env)
-                                (1- nopt*) args (cdr inits))
-                            (lp (cons (car args) env)
-                                (1- nopt*) (cdr args) (cdr inits)))
-                        ;; Finished with optionals.
-                        (let* ((aok (car kw))
-                               (kw (cdr kw))
-                               (kw-base (+ nopt nreq (if rest? 1 0)))
-                               (imax (let lp ((imax (1- kw-base)) (kw kw))
-                                       (if (null? kw)
-                                           imax
-                                           (lp (max (cdar kw) imax)
-                                               (cdr kw)))))
-                               ;; Fill in kwargs  with "undefined" vals.
-                               (env (let lp ((i kw-base)
-                                             ;; Also, here we bind the rest
-                                             ;; arg, if any.
-                                             (env (if rest? (cons args env) 
env)))
-                                      (if (<= i imax)
-                                          (lp (1+ i) (cons unbound-arg env))
-                                          env))))
-                          ;; Now scan args for keywords.
-                          (let lp ((args args))
-                            (if (and (pair? args) (pair? (cdr args))
-                                     (keyword? (car args)))
-                                (let ((kw-pair (assq (car args) kw))
-                                      (v (cadr args)))
-                                  (if kw-pair
-                                      ;; Found a known keyword; set its value.
-                                      (list-set! env (- imax (cdr kw-pair)) v)
-                                      ;; Unknown keyword.
-                                      (if (not aok)
-                                          (scm-error 'keyword-argument-error
-                                                     "eval" "Unrecognized 
keyword"
-                                                     '() #f)))
-                                  (lp (cddr args)))
-                                (if (pair? args)
-                                    (if rest?
-                                        ;; Be lenient parsing rest args.
-                                        (lp (cdr args))
-                                        (scm-error 'keyword-argument-error
-                                                   "eval" "Invalid keyword"
-                                                   '() #f))
-                                    ;; Finished parsing keywords. Fill in
-                                    ;; uninitialized kwargs by evalling init
-                                    ;; expressions in their appropriate
-                                    ;; environment.
-                                    (let lp ((i (- imax kw-base))
-                                             (inits inits))
-                                      (if (pair? inits)
-                                          (let ((tail (list-tail env i)))
-                                            (if (eq? (car tail) unbound-arg)
-                                                (set-car! tail
-                                                          (eval (car inits)
-                                                                (cdr tail))))
-                                            (lp (1- i) (cdr inits)))
-                                          ;; Finally, eval the body.
-                                          (eval body env))))))))))))))
+      (define (set-procedure-arity! proc)
+        (let lp ((alt alt) (nreq nreq) (nopt nopt) (rest? rest?))
+          (if (not alt)
+              (set-procedure-minimum-arity! proc nreq nopt rest?)
+              (let* ((nreq* (cadr alt))
+                     (rest?* (if (null? (cddr alt)) #f (caddr alt)))
+                     (tail (and (pair? (cddr alt)) (pair? (cdddr alt)) (cdddr 
alt)))
+                     (nopt* (if tail (car tail) 0))
+                     (alt* (and tail (cadddr tail))))
+                (if (or (< nreq* nreq)
+                        (and (= nreq* nreq)
+                             (if rest?
+                                 (and rest?* (> nopt* nopt))
+                                 (or rest?* (> nopt* nopt)))))
+                    (lp alt* nreq* nopt* rest?*)
+                    (lp alt* nreq nopt rest?)))))
+        proc)
+      (set-procedure-arity!
+       (lambda %args
+         (let lp ((env env)
+                  (nreq* nreq)
+                  (args %args))
+           (if (> nreq* 0)
+               ;; First, bind required arguments.
+               (if (null? args)
+                   (if alt
+                       (apply alt-proc %args)
+                       (scm-error 'wrong-number-of-args
+                                  "eval" "Wrong number of arguments"
+                                  '() #f))
+                   (lp (cons (car args) env)
+                       (1- nreq*)
+                       (cdr args)))
+               ;; Move on to optional arguments.
+               (if (not kw)
+                   ;; Without keywords, bind optionals from arguments.
+                   (let lp ((env env)
+                            (nopt nopt)
+                            (args args)
+                            (inits inits))
+                     (if (zero? nopt)
+                         (if rest?
+                             (eval body (cons args env))
+                             (if (null? args)
+                                 (eval body env)
+                                 (if alt
+                                     (apply alt-proc %args)
+                                     (scm-error 'wrong-number-of-args
+                                                "eval" "Wrong number of 
arguments"
+                                                '() #f))))
+                         (if (null? args)
+                             (lp (cons (eval (car inits) env) env)
+                                 (1- nopt) args (cdr inits))
+                             (lp (cons (car args) env)
+                                 (1- nopt) (cdr args) (cdr inits)))))
+                   ;; With keywords, we stop binding optionals at the first
+                   ;; keyword.
+                   (let lp ((env env)
+                            (nopt* nopt)
+                            (args args)
+                            (inits inits))
+                     (if (> nopt* 0)
+                         (if (or (null? args) (keyword? (car args)))
+                             (lp (cons (eval (car inits) env) env)
+                                 (1- nopt*) args (cdr inits))
+                             (lp (cons (car args) env)
+                                 (1- nopt*) (cdr args) (cdr inits)))
+                         ;; Finished with optionals.
+                         (let* ((aok (car kw))
+                                (kw (cdr kw))
+                                (kw-base (+ nopt nreq (if rest? 1 0)))
+                                (imax (let lp ((imax (1- kw-base)) (kw kw))
+                                        (if (null? kw)
+                                            imax
+                                            (lp (max (cdar kw) imax)
+                                                (cdr kw)))))
+                                ;; Fill in kwargs  with "undefined" vals.
+                                (env (let lp ((i kw-base)
+                                              ;; Also, here we bind the rest
+                                              ;; arg, if any.
+                                              (env (if rest? (cons args env) 
env)))
+                                       (if (<= i imax)
+                                           (lp (1+ i) (cons unbound-arg env))
+                                           env))))
+                           ;; Now scan args for keywords.
+                           (let lp ((args args))
+                             (if (and (pair? args) (pair? (cdr args))
+                                      (keyword? (car args)))
+                                 (let ((kw-pair (assq (car args) kw))
+                                       (v (cadr args)))
+                                   (if kw-pair
+                                       ;; Found a known keyword; set its value.
+                                       (list-set! env (- imax (cdr kw-pair)) v)
+                                       ;; Unknown keyword.
+                                       (if (not aok)
+                                           (scm-error 'keyword-argument-error
+                                                      "eval" "Unrecognized 
keyword"
+                                                      '() #f)))
+                                   (lp (cddr args)))
+                                 (if (pair? args)
+                                     (if rest?
+                                         ;; Be lenient parsing rest args.
+                                         (lp (cdr args))
+                                         (scm-error 'keyword-argument-error
+                                                    "eval" "Invalid keyword"
+                                                    '() #f))
+                                     ;; Finished parsing keywords. Fill in
+                                     ;; uninitialized kwargs by evalling init
+                                     ;; expressions in their appropriate
+                                     ;; environment.
+                                     (let lp ((i (- imax kw-base))
+                                              (inits inits))
+                                       (if (pair? inits)
+                                           (let ((tail (list-tail env i)))
+                                             (if (eq? (car tail) unbound-arg)
+                                                 (set-car! tail
+                                                           (eval (car inits)
+                                                                 (cdr tail))))
+                                             (lp (1- i) (cdr inits)))
+                                           ;; Finally, eval the body.
+                                           (eval body env)))))))))))))))
 
     ;; The "engine". EXP is a memoized expression.
     (define (eval exp env)
@@ -407,7 +425,10 @@
               (memoize-variable-access! exp #f))))
 
         (('define (name . x))
-         (define! name (eval x env)))
+         (let ((x (eval x env)))
+           (if (and (procedure? x) (not (procedure-property x 'name)))
+               (set-procedure-property! x 'name name))
+           (define! name x)))
       
         (('toplevel-set! (var-or-sym . x))
          (variable-set!
diff --git a/test-suite/tests/procprop.test b/test-suite/tests/procprop.test
index 3998a62..25dd4c2 100644
--- a/test-suite/tests/procprop.test
+++ b/test-suite/tests/procprop.test
@@ -1,7 +1,7 @@
 ;;;; procprop.test --- Procedure properties -*- mode: scheme; coding: utf-8; 
-*-
 ;;;; Ludovic Courtès <address@hidden>
 ;;;;
-;;;;   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+;;;;   Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
 ;;;;
 ;;;; This library is free software; you can redistribute it and/or
 ;;;; modify it under the terms of the GNU Lesser General Public
@@ -26,7 +26,12 @@
     (eq? 'display (procedure-name display)))
 
   (pass-if "gsubr"
-    (eq? 'hashq-ref (procedure-name hashq-ref))))
+    (eq? 'hashq-ref (procedure-name hashq-ref)))
+
+  (pass-if "from eval"
+    (eq? 'foobar (procedure-name
+                  (eval '(begin (define (foobar) #t) foobar)
+                        (current-module))))))
 
 
 (with-test-prefix "procedure-arity"
@@ -52,4 +57,19 @@
 
   (pass-if "list"
     (equal? (procedure-minimum-arity list)
-            '(0 0 #t))))
+            '(0 0 #t)))
+
+  (pass-if "fixed, eval"
+    (equal? (procedure-minimum-arity (eval '(lambda (a b) #t)
+                                           (current-module)))
+            '(2 0 #f)))
+
+  (pass-if "rest, eval"
+    (equal? (procedure-minimum-arity (eval '(lambda (a b . c) #t)
+                                           (current-module)))
+            '(2 0 #t)))
+
+  (pass-if "opt, eval"
+    (equal? (procedure-minimum-arity (eval '(lambda* (a b #:optional c) #t)
+                                           (current-module)))
+            '(2 1 #f))))


hooks/post-receive
-- 
GNU Guile



reply via email to

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