multiple values
authorBT Templeton <bt@hcoop.net>
Fri, 16 Aug 2013 01:43:51 +0000 (21:43 -0400)
committerRobin Templeton <robin@terpri.org>
Sun, 19 Apr 2015 07:43:01 +0000 (03:43 -0400)
* src/eval.c (values_to_list, Fmultiple_value_call, Fvalues)
  (eval_sub_1, Ffuncall1): New functions.
  (eval_sub, Ffuncall): Return only the first value.

src/eval.c
src/lisp.h

index d56a8ef..3d8573f 100644 (file)
@@ -2102,8 +2102,8 @@ set_lisp_eval_depth (void *data)
 
 /* Eval a sub-expression of the current expression (i.e. in the same
    lexical scope).  */
-Lisp_Object
-eval_sub (Lisp_Object form)
+static Lisp_Object
+eval_sub_1 (Lisp_Object form)
 {
   Lisp_Object fun, val, original_fun, original_args;
   Lisp_Object funcar;
@@ -2320,6 +2320,42 @@ eval_sub (Lisp_Object form)
 
   return val;
 }
+
+Lisp_Object
+eval_sub (Lisp_Object form)
+{
+  return scm_c_value_ref (eval_sub_1 (form), 0);
+}
+\f
+static Lisp_Object
+values_to_list (Lisp_Object values)
+{
+  Lisp_Object list = Qnil;
+  for (int i = scm_c_nvalues (values) - 1; i >= 0; i--)
+    list = Fcons (scm_c_value_ref (values, i), list);
+  return list;
+}
+
+DEFUN ("multiple-value-call", Fmultiple_value_call, Smultiple_value_call,
+       2, UNEVALLED, 0,
+       doc: /* Call with multiple values.
+usage: (multiple-value-call FUNCTION-FORM FORM)  */)
+  (Lisp_Object args)
+{
+  Lisp_Object function_form = eval_sub (XCAR (args));
+  Lisp_Object values = Qnil;
+  while (CONSP (args = XCDR (args)))
+    values = nconc2 (Fnreverse (values_to_list (eval_sub_1 (XCAR (args)))),
+                     values);
+  return apply1 (function_form, Fnreverse (values));
+}
+
+DEFUN ("values", Fvalues, Svalues, 0, MANY, 0,
+       doc: /* Return multiple values. */)
+  (ptrdiff_t nargs, Lisp_Object *args)
+{
+  return scm_c_values (args, nargs);
+}
 \f
 DEFUN ("apply", Fapply, Sapply, 1, MANY, 0,
        doc: /* Call FUNCTION with our remaining args, using our last arg as list of args.
@@ -2784,7 +2820,7 @@ DEFUN ("functionp", Ffunctionp, Sfunctionp, 1, 1, 0,
   return Qnil;
 }
 
-DEFUN ("funcall", Ffuncall, Sfuncall, 1, MANY, 0,
+DEFUN ("funcall", Ffuncall1, Sfuncall, 1, MANY, 0,
        doc: /* Call first argument as a function, passing remaining arguments to it.
 Return the value that function returns.
 Thus, (funcall 'cons 'x 'y) returns (x . y).
@@ -2940,6 +2976,12 @@ usage: (funcall FUNCTION &rest ARGUMENTS)  */)
   scm_dynwind_end ();
   return val;
 }
+
+Lisp_Object
+Ffuncall (ptrdiff_t nargs, Lisp_Object *args)
+{
+  return scm_c_value_ref (Ffuncall1 (nargs, args), 0);
+}
 \f
 static Lisp_Object
 apply_lambda (Lisp_Object fun, Lisp_Object args)
index edbd167..14d378f 100644 (file)
@@ -3389,6 +3389,7 @@ extern _Noreturn void xsignal3 (Lisp_Object, Lisp_Object, Lisp_Object,
                                Lisp_Object);
 extern _Noreturn void signal_error (const char *, Lisp_Object);
 extern Lisp_Object eval_sub (Lisp_Object form);
+extern Lisp_Object Ffuncall (ptrdiff_t nargs, Lisp_Object *args);
 extern Lisp_Object apply1 (Lisp_Object, Lisp_Object);
 extern Lisp_Object call0 (Lisp_Object);
 extern Lisp_Object call1 (Lisp_Object, Lisp_Object);