103 lines
3.0 KiB
C
103 lines
3.0 KiB
C
#ifndef INCLUDED_FUNCTION_H
|
|
#define INCLUDED_FUNCTION_H
|
|
|
|
#include "base.h"
|
|
|
|
DECLARE_SYMBOL(and_optional);
|
|
DECLARE_SYMBOL(and_rest);
|
|
DECLARE_SYMBOL(and_key);
|
|
DECLARE_SYMBOL(and_allow_other_keys);
|
|
|
|
struct LambdaList {
|
|
size_t n_req;
|
|
size_t n_opt;
|
|
bool allow_other_keys;
|
|
LispVal *req; // list of symbols
|
|
LispVal *opt; // list of lists of (name default has-p-name)
|
|
LispVal *kw; // hash table mapping name (a keyword) to a list of (index name
|
|
// default has-p-name). This is nil if we are not a keyword
|
|
// function.
|
|
LispVal *rest; // symbol (non-nil if we have a rest arg)
|
|
};
|
|
|
|
#define MAX_NATIVE_FUNCTION_ARGS 5
|
|
union native_function {
|
|
LispVal *(*zero)(void);
|
|
LispVal *(*one)(LispVal *);
|
|
LispVal *(*two)(LispVal *, LispVal *);
|
|
LispVal *(*three)(LispVal *, LispVal *, LispVal *);
|
|
LispVal *(*four)(LispVal *, LispVal *, LispVal *, LispVal *);
|
|
LispVal *(*five)(LispVal *, LispVal *, LispVal *, LispVal *, LispVal *);
|
|
};
|
|
|
|
struct interp_function {
|
|
LispVal *body; // list of forms
|
|
LispVal *lexenv;
|
|
};
|
|
|
|
typedef enum {
|
|
FUNCTION_NATIVE,
|
|
FUNCTION_INTERP,
|
|
} LispFunctionType;
|
|
|
|
struct function_flags {
|
|
LispFunctionType type : 2;
|
|
unsigned int no_eval_args : 1;
|
|
};
|
|
|
|
DEFOBJTYPE(Function, FUNCTION, FUNCTIONP, {
|
|
LispVal *name; // symbol (or nil for a lambda)
|
|
struct function_flags flags;
|
|
struct LambdaList args;
|
|
LispVal *docstr;
|
|
union {
|
|
union native_function native;
|
|
struct interp_function interp;
|
|
} impl;
|
|
});
|
|
|
|
typedef enum {
|
|
LLPS_OK,
|
|
LLPS_DOTTED,
|
|
LLPS_REPEAT_SECTION,
|
|
LLPS_REPEAT_NAME,
|
|
LLPS_ORDER,
|
|
LLPS_BAD_NAME,
|
|
LLPS_REPEAT_REST,
|
|
LLPS_AFTER_ALLOW_OTHER_KEYS,
|
|
LLPS_INVALID_OPT_SPEC,
|
|
LLPS_N_ERROS,
|
|
} LambdaListParseStatus;
|
|
|
|
const char *llps_strerror(LambdaListParseStatus status);
|
|
|
|
typedef struct {
|
|
struct LambdaList lambda_list;
|
|
LambdaListParseStatus status;
|
|
LispVal *err_obj; // the object the caused the above status
|
|
} LambdaListParseResult;
|
|
|
|
void parse_lambda_list(LambdaListParseResult *out, LispVal *list);
|
|
|
|
// This will cause the program to exit if an error occurs while parsing
|
|
// LISP_ARGS!
|
|
LispVal *make_builtin_function(LispVal *name, LispVal *(*func)(void),
|
|
const char *lisp_args, size_t args_len,
|
|
LispVal *docstr);
|
|
#define BUILTIN_FUNCTION_OBJ(cname) \
|
|
make_builtin_function( \
|
|
Q##cname, (LispVal * (*) (void) ) F##cname, \
|
|
internal_F##cname##_argstr, internal_F##cname##_argstr_len, \
|
|
make_lisp_string(internal_F##cname##_docstr, \
|
|
internal_F##cname##_docstr_len, false, false))
|
|
|
|
DECLARE_FUNCTION(funcall, (LispVal * func, LispVal *args));
|
|
#define CALL(func, ...) (Ffuncall((func), LIST(__VA_ARGS__)))
|
|
|
|
DECLARE_FUNCTION(lambda, (LispVal * args, LispVal *body));
|
|
|
|
DECLARE_SYMBOL(declare);
|
|
DECLARE_SYMBOL(name);
|
|
|
|
#endif
|