]> git.lizzy.rs Git - nothing.git/blob - src/script/expr.h
TODO(#337)
[nothing.git] / src / script / expr.h
1 #ifndef EXPR_H_
2 #define EXPR_H_
3
4 #include <stdlib.h>
5 #include <stdbool.h>
6
7 typedef struct Gc Gc;
8 typedef struct Scope Scope;
9
10 struct Cons;
11 struct Atom;
12
13 // TODO(#321): get rid of gc argument from expr macros (just assume that it's `gc` in the current scope)
14 #define NUMBER(G, X) atom_as_expr(create_number_atom(G, X))
15 #define STRING(G, S) atom_as_expr(create_string_atom(G, S, NULL))
16 #define SYMBOL(G, S) atom_as_expr(create_symbol_atom(G, S, NULL))
17 #define NATIVE(G, F) atom_as_expr(create_native_atom(G, F))
18 #define CONS(G, CAR, CDR) cons_as_expr(create_cons(G, CAR, CDR))
19 #define NIL(G) SYMBOL(G, "nil")
20
21 enum ExprType
22 {
23     EXPR_ATOM = 0,
24     EXPR_CONS,
25     EXPR_VOID
26 };
27
28 // TODO(#285): there is no way to execute struct Expr
29 struct Expr
30 {
31     enum ExprType type;
32     union {
33         struct Cons *cons;
34         struct Atom *atom;
35     };
36 };
37
38 struct Expr atom_as_expr(struct Atom *atom);
39 struct Expr cons_as_expr(struct Cons *cons);
40 struct Expr void_expr(void);
41
42 void destroy_expr(struct Expr expr);
43 void print_expr_as_sexpr(struct Expr expr);
44
45 // TODO(#337): EvalResult does not belong to expr unit
46 struct EvalResult
47 {
48     bool is_error;
49     struct Expr expr;
50 };
51
52 typedef struct EvalResult (*NativeFunction)(Gc *gc, struct Scope *scope, struct Expr args);
53
54 enum AtomType
55 {
56     ATOM_SYMBOL = 0,
57     ATOM_NUMBER,
58     ATOM_STRING,
59     ATOM_NATIVE
60 };
61
62 struct Atom
63 {
64     enum AtomType type;
65     union
66     {
67         // TODO(#330): Atom doesn't support floats
68         long int num;           // ATOM_NUMBER
69         char *sym;              // ATOM_SYMBOL
70         char *str;              // ATOM_STRING
71         NativeFunction fun;     // ATOM_NATIVE
72     };
73 };
74
75 struct Atom *create_number_atom(Gc *gc, long int num);
76 struct Atom *create_string_atom(Gc *gc, const char *str, const char *str_end);
77 struct Atom *create_symbol_atom(Gc *gc, const char *sym, const char *sym_end);
78 struct Atom *create_native_atom(Gc *gc, NativeFunction fun);
79 void destroy_atom(struct Atom *atom);
80 void print_atom_as_sexpr(struct Atom *atom);
81
82 struct Cons
83 {
84     struct Expr car;
85     struct Expr cdr;
86 };
87
88 struct Cons *create_cons(Gc *gc, struct Expr car, struct Expr cdr);
89 void destroy_cons(struct Cons *cons);
90 void print_cons_as_sexpr(struct Cons *cons);
91
92 #endif  // EXPR_H_