ecl/src/c/cfun.d
jjgarcia ee391629b6 New bytecodes compiler and interpreter, which use 8-bits large bytecodes and
16-bits large arguments.
Macros are implemented as two-argument functions, leaving argument checking
to funcall() and apply() and thus saving space.
AND, WHEN and OR are plain macros. No optimizer is required in the bytecodes
compiler.
2003-08-05 10:01:57 +00:00

147 lines
3 KiB
D

/*
cfun.c -- Compiled functions.
*/
/*
Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya.
Copyright (c) 1990, Giuseppe Attardi.
Copyright (c) 2001, Juan Jose Garcia Ripoll.
ECL is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
See file '../Copyright' for full details.
*/
#include "ecl.h"
#include <string.h> /* for memmove() */
cl_object
cl_make_cfun(cl_object (*self)(), cl_object name, cl_object cblock, int narg)
{
cl_object cf;
cf = cl_alloc_object(t_cfun);
cf->cfun.entry = self;
cf->cfun.name = name;
cf->cfun.block = cblock;
cf->cfun.narg = narg;
if (narg < 0 || narg >= C_ARGUMENTS_LIMIT)
FEprogram_error("cl_make_cfun: function requires too many arguments.",0);
return(cf);
}
cl_object
cl_make_cfun_va(cl_objectfn self, cl_object name, cl_object cblock)
{
cl_object cf;
cf = cl_alloc_object(t_cfun);
cf->cfun.entry = self;
cf->cfun.name = name;
cf->cfun.block = cblock;
cf->cfun.narg = -1;
return(cf);
}
cl_object
cl_make_cclosure_va(cl_objectfn self, cl_object env, cl_object block)
{
cl_object cc;
cc = cl_alloc_object(t_cclosure);
cc->cclosure.entry = self;
cc->cclosure.env = env;
cc->cclosure.block = block;
return(cc);
}
void
cl_def_c_function(cl_object sym, cl_object (*self)(), int narg)
{
si_fset(2, sym,
cl_make_cfun(self, sym, symbol_value(@'si::*cblock*'), narg));
}
void
cl_def_c_macro(cl_object sym, cl_object (*self)(cl_object, cl_object))
{
si_fset(3, sym,
cl_make_cfun(self, sym, symbol_value(@'si::*cblock*'), 2),
Ct);
}
void
cl_def_c_function_va(cl_object sym, cl_objectfn self)
{
si_fset(2, sym,
cl_make_cfun_va(self, sym, symbol_value(@'si::*cblock*')));
}
cl_object
si_compiled_function_name(cl_object fun)
{
cl_object output;
switch(type_of(fun)) {
case t_bytecodes:
output = fun->bytecodes.name; break;
case t_cfun:
output = fun->cfun.name; break;
case t_cclosure:
output = Cnil; break;
default:
FEinvalid_function(fun);
}
@(return output)
}
cl_object
cl_function_lambda_expression(cl_object fun)
{
cl_object output, name = Cnil, lex = Cnil;
switch(type_of(fun)) {
case t_bytecodes:
lex = fun->bytecodes.lex;
name = fun->bytecodes.name;
output = fun->bytecodes.definition;
if (!CONSP(output))
output = Cnil;
else if (name == Cnil)
output = cl_cons(@'lambda', output);
else
output = @list*(3, @'lambda-block', name, output);
break;
case t_cfun:
name = fun->cfun.name;
lex = Cnil;
output = Cnil;
break;
case t_cclosure:
name = Cnil;
lex = Ct;
output = Cnil;
break;
default:
FEinvalid_function(fun);
}
@(return output lex name)
}
cl_object
si_compiled_function_block(cl_object fun)
{
cl_object output;
switch(type_of(fun)) {
case t_cfun:
output = fun->cfun.block; break;
case t_cclosure:
output = fun->cclosure.block; break;
default:
FEerror("~S is not a compiled-function.", 1, fun);
}
@(return output)
}