aboutsummaryrefslogtreecommitdiff
path: root/atom.h
blob: 7240670767718a730c981362e721a8399b4c5b85 (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
#ifndef ATOM_H
#define ATOM_H

#include <sys/queue.h>

#define ATOM_TYPE(ATOM) ((ATOM)->type)

#define IS_INT(ATOM) ((ATOM_TYPE(ATOM)) == ATOM_INT)
#define IS_STR(ATOM) ((ATOM_TYPE(ATOM)) == ATOM_STR)
#define IS_SYM(ATOM) ((ATOM_TYPE(ATOM)) == ATOM_SYMBOL)
#define IS_LIST(ATOM) ((ATOM_TYPE(ATOM)) == ATOM_LIST)
#define IS_ATOM(ATOM) (!(IS_LIST(ATOM)))

#define IS_TRUE(ATOM) (ATOM_TYPE(ATOM) == ATOM_TRUE)
#define IS_FALSE(ATOM) (ATOM_TYPE(ATOM) == ATOM_FALSE)

#define IS_NIL(ATOM) (ATOM_TYPE(ATOM) == ATOM_NIL)

#define IS_CLOSURE(ATOM) (ATOM_TYPE(ATOM) == ATOM_CLOSURE)

#define CAR(LIST) (LIST_FIRST(LIST))
#define CDR(LIST) ((LIST) != NULL ? LIST_NEXT((LIST), entries) : NULL)
#define CDDR(LIST) CDR(CDR(LIST))

enum
{
    ATOM_NIL,
    ATOM_INT,
    ATOM_STR,
    ATOM_SYMBOL,
    ATOM_LIST,
    ATOM_TRUE,
    ATOM_FALSE,
    ATOM_CLOSURE
};

struct atom;
struct env;

struct closure
{
    struct env *env;
    struct atom *params;
    struct atom *body;
};

LIST_HEAD(list, atom);

struct atom
{
    char type;

    union
    {
        long l;
        struct
        {
            char *str;
            int len;
        } str;
        struct list *list;
        struct closure closure;
    };

    LIST_ENTRY(atom) entries;
};

struct atom *atom_new(char type);
struct atom *atom_new_int(long l);
struct atom *atom_new_str(const char *str, int len);
struct atom *atom_new_sym(const char *sym, int len);
struct atom *atom_new_list(struct list *list);
struct atom *atom_new_list_empty();
struct atom *atom_new_closure(struct atom *params, struct atom *body,
    struct env *env);
struct atom *atom_clone();

void print_atom(struct atom *atom, int level);

struct atom *atom_list_append(struct atom *list, int count, ...);
int atom_list_length(struct atom *list);

extern struct atom true_atom;
extern struct atom false_atom;
extern struct atom nil_atom;

#endif