#ifndef VALUE_H #define VALUE_H #include "lexer.h" #include "env.h" typedef struct value * value_t; #define VALUE_EMPTY NULL typedef value_t (*builtin_proc_t)(value_t *args); #define VALUE_TYPES(X) \ X(VALUE_NIL) \ X(VALUE_ATOM) \ X(VALUE_STR) \ X(VALUE_INT) \ X(VALUE_CONS) \ X(VALUE_PROC) \ X(VALUE_MACRO) \ X(VALUE_PROC_BUILTIN) #define TO_ENUM(type) type, #define TO_STRING(type) #type, extern const char * const value_type_string[]; struct value { enum value_type { VALUE_TYPES(TO_ENUM) } type; union value_union { char *atom; char *str; int num; struct cons { value_t left; value_t right; } cons; struct proc { env_t parent_env; value_t *arg_keys; size_t argc; struct toklist *body; } proc; struct proc_builtin { size_t argc; builtin_proc_t proc; } proc_builtin; } value; size_t refs; }; #define vvalue_type(v) ((v)->type) #define vvalue_refs(v) ((v)->refs) #define vvalue_atom(v) ((v)->value.atom) #define vvalue_str(v) ((v)->value.str) #define vvalue_num(v) ((v)->value.num) #define vvalue_cons(v) ((v)->value.cons) #define vvalue_proc(v) ((v)->value.proc) #define vvalue_proc_builtin(v) ((v)->value.proc_builtin) #define value_set_type(v, type) (vvalue_type(v) = type) #define value_set_refs(v, refs) (vvalue_refs(v) = refs) #define value_inc_refs(v) (++vvalue_refs(v)) #define value_dec_refs(v) (--vvalue_refs(v)) value_t value_create(enum value_type type, void * value); void value_destroy(value_t value); value_t value_from_token(struct token *token); value_t value_copy(value_t value); int value_string(value_t value, size_t buf_sz, char *buf); char *value_static_string(value_t value); #ifdef DEBUG void value_print(value_t value); #endif #endif