1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-20 11:40:18 +02:00

rename tail-call to goto/args, add some more tail instructions

* libguile/vm-i-system.c (call): Rename continuation invocation from
  `vm_call_cc' to `vm_call_continuation', because that's what it really
  does. Add a note that it doesn't handle multiple values at the moment.
  (goto/arg): Renamed from tail-call, in deference to the progenitors, on
  Dale Smith's suggestion.
  (goto/apply): New instruction, for `apply' in a tail context. Not yet
  used, or vetted for that matter.
  (call/cc): No need to pop the program, I don't think; although this
  isn't tested either.
  (goto/cc): New instruction, for call/cc in a tail context.

* module/language/scheme/translate.scm (*forbidden-primitives*): Rename
  from %forbidden-primitives.

* module/system/il/compile.scm (codegen): Adapt to goto/args instead of
  tail-call.

* module/system/il/inline.scm: Start inlining some macros used in
  r4rs.scm -- not yet fully tested.

* ice-9/boot-9.scm: Allow load of a compiled r4rs file.
This commit is contained in:
Andy Wingo 2008-09-13 19:19:10 +02:00
parent da320011a3
commit f03c31dbad
6 changed files with 49 additions and 12 deletions

View file

@ -208,7 +208,7 @@
;;; {R4RS compliance} ;;; {R4RS compliance}
;;; ;;;
(primitive-load-path "ice-9/r4rs.scm") (primitive-load-path "ice-9/r4rs")

View file

@ -516,8 +516,9 @@ VM_DEFINE_INSTRUCTION (call, "call", 1, -1, 1)
if (SCM_VM_CONT_P (x)) if (SCM_VM_CONT_P (x))
{ {
program = x; program = x;
vm_call_cc: vm_call_continuation:
/* Check the number of arguments */ /* Check the number of arguments */
/* FIXME multiple args */
if (nargs != 1) if (nargs != 1)
scm_wrong_num_args (program); scm_wrong_num_args (program);
@ -534,10 +535,11 @@ VM_DEFINE_INSTRUCTION (call, "call", 1, -1, 1)
goto vm_error_wrong_type_apply; goto vm_error_wrong_type_apply;
} }
VM_DEFINE_INSTRUCTION (tail_call, "tail-call", 1, -1, 1) VM_DEFINE_INSTRUCTION (goto_args, "goto/args", 1, -1, 1)
{ {
register SCM x; register SCM x;
nargs = FETCH (); nargs = FETCH ();
vm_goto_args:
x = sp[-nargs]; x = sp[-nargs];
SCM_TICK; /* allow interrupt here */ SCM_TICK; /* allow interrupt here */
@ -685,7 +687,7 @@ VM_DEFINE_INSTRUCTION (tail_call, "tail-call", 1, -1, 1)
* Continuation call * Continuation call
*/ */
if (SCM_VM_CONT_P (program)) if (SCM_VM_CONT_P (program))
goto vm_call_cc; goto vm_call_continuation;
goto vm_error_wrong_type_apply; goto vm_error_wrong_type_apply;
} }
@ -711,15 +713,43 @@ VM_DEFINE_INSTRUCTION (apply, "apply", 1, -1, 1)
goto vm_call; goto vm_call;
} }
VM_DEFINE_INSTRUCTION (goto_apply, "goto/apply", 1, -1, 1)
{
int len;
SCM ls;
POP (ls);
nargs = FETCH ();
if (nargs < 2)
goto vm_error_wrong_num_args;
len = scm_ilength (ls);
if (len < 0)
goto vm_error_wrong_type_arg;
for (; !SCM_NULLP (ls); ls = SCM_CDR (ls))
PUSH (SCM_CAR (ls));
nargs += len - 2;
goto vm_goto_args;
}
VM_DEFINE_INSTRUCTION (call_cc, "call/cc", 1, 1, 1) VM_DEFINE_INSTRUCTION (call_cc, "call/cc", 1, 1, 1)
{ {
SYNC_BEFORE_GC (); SYNC_BEFORE_GC ();
PUSH (capture_vm_cont (vp)); PUSH (capture_vm_cont (vp));
POP (program);
nargs = 1; nargs = 1;
goto vm_call; goto vm_call;
} }
VM_DEFINE_INSTRUCTION (goto_cc, "goto/cc", 1, 1, 1)
{
SYNC_BEFORE_GC ();
PUSH (capture_vm_cont (vp));
nargs = 1;
goto vm_goto_args;
}
VM_DEFINE_INSTRUCTION (return, "return", 0, 0, 1) VM_DEFINE_INSTRUCTION (return, "return", 0, 0, 1)
{ {
vm_return: vm_return:

View file

@ -40,7 +40,7 @@
;;; Translator ;;; Translator
;;; ;;;
(define %forbidden-primitives (define *forbidden-primitives*
;; Guile's `procedure->macro' family is evil because it crosses the ;; Guile's `procedure->macro' family is evil because it crosses the
;; compilation boundary. One solution might be to evaluate calls to ;; compilation boundary. One solution might be to evaluate calls to
;; `procedure->memoizing-macro' at compilation time, but it may be more ;; `procedure->memoizing-macro' at compilation time, but it may be more
@ -91,7 +91,7 @@
=> (lambda (t) (t e l x))) => (lambda (t) (t e l x)))
;; FIXME: lexical/module overrides of forbidden primitives ;; FIXME: lexical/module overrides of forbidden primitives
((memq head %forbidden-primitives) ((memq head *forbidden-primitives*)
(syntax-error l (format #f "`~a' is forbidden" head) (syntax-error l (format #f "`~a' is forbidden" head)
(cons head tail))) (cons head tail)))

View file

@ -296,6 +296,7 @@
((<ghil-inline> env loc inline args) ((<ghil-inline> env loc inline args)
;; ARGS... ;; ARGS...
;; (INST NARGS) ;; (INST NARGS)
;; FIXME: translate between call and goto/args, etc
(push-call! loc inline args) (push-call! loc inline args)
(maybe-drop) (maybe-drop)
(maybe-return)) (maybe-return))
@ -305,7 +306,7 @@
;; ARGS... ;; ARGS...
;; ([tail-]call NARGS) ;; ([tail-]call NARGS)
(comp-push proc) (comp-push proc)
(push-call! loc (if tail 'tail-call 'call) args) (push-call! loc (if tail 'goto/args 'call) args)
(maybe-drop)))) (maybe-drop))))
;; ;;
;; main ;; main

View file

@ -150,7 +150,7 @@
;;; (make-instl (car x) label)) ;;; (make-instl (car x) label))
;;; ;; (call NARGS) ;;; ;; (call NARGS)
;;; ;; (tail-call NARGS) ;;; ;; (tail-call NARGS)
;;; (((or 'call 'tail-call) n) ;;; (((or 'call 'goto/args) n)
;;; (make-instn (car x) n)) ;;; (make-instn (car x) n))
;;; ;; (INST) ;;; ;; (INST)
;;; ((inst) ;;; ((inst)

View file

@ -194,10 +194,16 @@
(define-inline list? (x) (define-inline list? (x)
(list? x)) (list? x))
(define-inline apply (proc . args)
(apply proc . args))
(define-inline cons* (define-inline cons*
(x) x (x) x
(x y) (cons x y) (x y) (cons x y)
(x y . rest) (cons x (cons* y . rest))) (x y . rest) (cons x (cons* y . rest)))
(define-inline apply (proc . args)
(apply proc . args))
;; From ice-9/r4rs.scm; actually not that bad of a strategy for handling
;; the (apply apply ...) case
(define-inline @apply (proc . args)
(apply proc . args))