Files
glisp/src/function.h

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