stk/Src/proc.c

161 lines
3.5 KiB
C
Raw Normal View History

1996-09-27 06:29:02 -04:00
/*
*
* p r o c . c --
*
1998-04-10 06:59:06 -04:00
* Copyright <EFBFBD> 1993-1998 Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr>
1996-09-27 06:29:02 -04:00
*
*
* Permission to use, copy, and/or distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
* that both the above copyright notice and this permission notice appear in
* all copies and derived works. Fees for distribution or use of this
* software or derived works may only be charged with express written
* permission of the copyright holder.
* This software is provided ``as is'' without express or implied warranty.
*
* This software is a derivative work of other copyrighted softwares; the
* copyright notices of these softwares are placed in the file COPYRIGHTS
*
1998-04-30 07:04:33 -04:00
* $Id: proc.c 1.3 Mon, 09 Mar 1998 08:31:40 +0000 eg $
1996-09-27 06:29:02 -04:00
*
* Author: Erick Gallesio [eg@kaolin.unice.fr]
* Creation date: 15-Nov-1993 22:02
1998-04-10 06:59:06 -04:00
* Last file update: 8-Mar-1998 11:58
1996-09-27 06:29:02 -04:00
*/
#include "stk.h"
#include "extend.h"
/**** Section 6.9 ****/
int STk_is_thunk(SCM obj)
{
switch (TYPE(obj)) {
case tc_closure: /* We can be more clever here.... */
#ifdef USE_STKLOS
case tc_instance:
#endif
1998-04-10 06:59:06 -04:00
case tc_lsubr:
1996-09-27 06:29:02 -04:00
case tc_subr_0:
case tc_subr_0_or_1: return TRUE;
}
return FALSE;
}
1998-04-10 06:59:06 -04:00
SCM STk_makeclosure(SCM code, SCM env)
{
SCM z, tmp;
register int arity = 0;
/* Find procedure arity */
for (tmp = CAR(code); CONSP(tmp); tmp = CDR(tmp))
arity += 1;
if (NNULLP(tmp)) arity = -(arity+1);
NEWCELL(z, tc_closure);
CLOSCODE(z) = code;
CLOSENV(z) = env;
CLOSARITY(z) = arity;
return z;
}
1996-09-27 06:29:02 -04:00
PRIMITIVE STk_procedurep(SCM obj)
{
switch (TYPE(obj)) {
case tc_subr_0:
case tc_subr_1:
case tc_subr_2:
case tc_subr_3:
case tc_subr_0_or_1:
case tc_subr_1_or_2:
case tc_subr_2_or_3:
case tc_lambda:
case tc_lsubr:
case tc_ssubr:
case tc_closure:
case tc_cont:
case tc_apply:
case tc_call_cc:
case tc_dynwind:
#ifdef USE_STKLOS
case tc_instance:
case tc_next_method:
#endif
#ifdef USE_TK
case tc_tkcommand:
#endif
return Truth;
default: if (EXTENDEDP(obj))
return STk_extended_procedurep(obj) ? Truth : Ntruth;
else
return Ntruth;
}
}
static SCM general_map(SCM l, int map, int len)
{
register int i;
SCM res = NIL,*tmp = &res;
SCM fct, args;
1998-04-10 06:59:06 -04:00
if (len <= 1) goto error;
1996-09-27 06:29:02 -04:00
fct = CAR(l);
len -= 1;
args = STk_vector(CDR(l), len);
for ( ; ; ) {
/* Build parameter list */
for (l=NIL, i=len-1; i >= 0; i--) {
if (NULLP(VECT(args)[i])) return res;
if (NCONSP(VECT(args)[i])) goto error;
l = Cons(CAR(VECT(args)[i]), l);
VECT(args)[i] = CDR(VECT(args)[i]);
}
/* See if it's a map or a for-each call */
if (map) {
*tmp = Cons(Apply(fct, l), NIL);
tmp = &CDR(*tmp);
}
else Apply(fct, l);
}
error:
{
char buff[50];
sprintf(buff, "%s: malformed list", map? "map" : "for-each");
Err(buff, l);
}
}
PRIMITIVE STk_map(SCM l, int len)
{
return general_map(l, 1, len);
}
PRIMITIVE STk_for_each(SCM l, int len)
{
1998-04-10 06:59:06 -04:00
general_map(l, 0, len);
return UNDEFINED;
1996-09-27 06:29:02 -04:00
}
PRIMITIVE STk_procedure_body(SCM proc)
{
1998-04-10 06:59:06 -04:00
return TYPEP(proc, tc_closure) ? Cons(Sym_lambda, CLOSCODE(proc)) : Ntruth;
1996-09-27 06:29:02 -04:00
}
PRIMITIVE STk_procedure_environment(SCM proc)
{
1998-04-10 06:59:06 -04:00
return TYPEP(proc, tc_closure) ? STk_makeenv(CLOSENV(proc), 0) : Ntruth;
}
PRIMITIVE STk_procedure_arity(SCM proc)
{
if (NTYPEP(proc, tc_closure)) Err("%procedure-arity: bad closure", proc);
return STk_makeinteger(CLOSARITY(proc));
1996-09-27 06:29:02 -04:00
}