aboutsummaryrefslogtreecommitdiff
path: root/src/value.h
blob: 48d178c631fe6b26f4168a9b10e0674801c9c9a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#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