@@ -109,6 +109,27 @@ static void check_prim_arity(obj f, obj args) {
109109 minim_error1 ("eval_expr" , "primitive arity unsupported" , Mfixnum (Mprim_arity (f )));
110110}
111111
112+ // performs `apply` primitive
113+ // flattens the last argument (checks that it is a list)
114+ static obj do_apply (obj args ) {
115+ obj hd ;
116+
117+ if (Mnullp (Mcdr (args ))) {
118+ if (!Mlistp (Mcar (args )))
119+ minim_error1 ("apply" , "expected list?" , Mcar (args ));
120+ return Mcar (args );
121+ } else {
122+ hd = args ;
123+ while (!Mnullp (Mcddr (args ))) args = Mcdr (args );
124+
125+ if (!Mlistp (Mcadr (args )))
126+ minim_error1 ("apply" , "expected list?" , Mcadr (args ));
127+ Mcdr (args ) = Mcadr (args );
128+
129+ return hd ;
130+ }
131+ }
132+
112133// performs `values` primitive
113134// if there is only 1 argument, the argument is returned
114135// otherwise, the arguments are written to the values buffer
@@ -212,11 +233,14 @@ static obj do_prim(obj f, obj args) {
212233
213234 switch (Mprim_arity (f ))
214235 {
215- case 0 : return fn ();
216- case 1 : return fn (Mcar (args ));
217- case 2 : return fn (Mcar (args ), Mcadr (args ));
218- case 3 : return fn (Mcar (args ), Mcadr (args ), Mcaddr (args ));
219-
236+ case 0 :
237+ return fn ();
238+ case 1 :
239+ return fn (Mcar (args ));
240+ case 2 :
241+ return fn (Mcar (args ), Mcadr (args ));
242+ case 3 :
243+ return fn (Mcar (args ), Mcadr (args ), Mcaddr (args ));
220244 default :
221245 minim_error1 ("eval_expr" , "primitive arity unsupported" , Mfixnum (Mprim_arity (f )));
222246 }
@@ -440,7 +464,13 @@ static obj eval_k(obj e) {
440464 if (Mprimp (f )) {
441465 check_prim_arity (f , args );
442466 if (Mprim_specialp (f )) {
443- x = do_special_prim (f , args );
467+ if (f == apply_prim ) {
468+ f = Mcar (args );
469+ args = do_apply (Mcdr (args ));
470+ goto do_app ;
471+ } else {
472+ x = do_special_prim (f , args );
473+ }
444474 } else {
445475 x = do_prim (f , args );
446476 }
0 commit comments