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:
parent
da320011a3
commit
f03c31dbad
6 changed files with 49 additions and 12 deletions
|
@ -208,7 +208,7 @@
|
||||||
;;; {R4RS compliance}
|
;;; {R4RS compliance}
|
||||||
;;;
|
;;;
|
||||||
|
|
||||||
(primitive-load-path "ice-9/r4rs.scm")
|
(primitive-load-path "ice-9/r4rs")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)))
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue