aboutsummaryrefslogtreecommitdiff
path: root/src/sexp.h
blob: d606acfbb46fbdb761b887300903559d1768f34a (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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#ifndef BAMBOO_LISP_SEXP_H_
#define BAMBOO_LISP_SEXP_H_

#include <stdint.h>
#include <stdbool.h>

#include <algds/vec.h>

struct sexp;
typedef struct sexp SExp;

typedef struct {
    int32_t idx;
} SExpRef;

typedef struct {
    SExpRef car;
    SExpRef cdr;
} SExpPair;

typedef struct {
    SExpRef args;
    SExpRef body;
    SExpRef env;
} SExpFunc;

struct interp;
typedef struct interp Interp;
typedef SExpRef (*LispUserFunc)(Interp *interp, SExpRef args);
typedef SExpRef (*LispPrimitive)(Interp *interp, SExpRef sexp, bool istail);

typedef struct {
    SExpRef args;
    SExpRef body;
} SExpMacro;

typedef struct {
    SExpRef parent;
    SExpRef bindings;
} SExpEnv;

typedef struct {
    SExpRef name;
    SExpRef value;
    SExpRef func;
    SExpRef next;
} SExpBinding;

typedef struct {
    SExpRef fn;
    SExpRef args;
} SExpTailcall;

typedef enum {
    kEmptySExp,
    kIntegerSExp,
    kRealSExp,
    kBooleanSExp,
    kNilSExp,
    kCharSExp,
    kStringSExp,
    kSymbolSExp,
    kUserDataSExp,
    kPairSExp,
    kFuncSExp,
    kUserFuncSExp,
    kPrimitiveSExp,
    kEnvSExp,
    kBindingSExp,
    kMacroSExp,
    kErrSignal,
    kReturnSignal,
    kBreakSignal,
    kContinueSignal,
    kTailcallSExp,
} SExpType;

VECTOR_DEF(SExpRef);

typedef struct {
    SExpRef type;
    void (*free)(void *self);
    void (*gcmark)(SExpRefVector *gcstack, void *self);
} LispUserdataMeta;

struct sexp {
    bool marked;
    SExpType type;
    union {
        int64_t integer;
        double real;
        bool boolean;
        char character;
        const char *str;
        struct {
            const void *userdata;
            LispUserdataMeta *userdata_meta;
        };
        SExpPair pair;
        SExpFunc func;
        LispUserFunc userfunc;
        LispPrimitive primitive;
        SExpEnv env;
        SExpBinding binding;
        SExpMacro macro;
        SExpRef ret;
        SExpTailcall tailcall;
    };
};

void SExp_show(SExp self, FILE* fp);
void SExpRef_show(SExpRef self, FILE* fp);

VECTOR_DEF(SExp);

#endif