]> git.lizzy.rs Git - nothing.git/blob - src/script/expr.h
(#395) Make region print eval errors on stdout
[nothing.git] / src / script / expr.h
1 #ifndef EXPR_H_
2 #define EXPR_H_
3
4 #include <stdbool.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7
8 typedef struct Gc Gc;
9 typedef struct Scope Scope;
10
11 struct Cons;
12 struct Atom;
13
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, P) atom_as_expr(create_native_atom(G, F, P))
18 #define CONS(G, CAR, CDR) cons_as_expr(create_cons(G, CAR, CDR))
19 #define NIL(G) SYMBOL(G, "nil")
20
21 #define CAR(O) ((O).cons->car)
22 #define CDR(O) ((O).cons->cdr)
23
24 enum ExprType
25 {
26     EXPR_ATOM = 0,
27     EXPR_CONS,
28     EXPR_VOID
29 };
30
31 struct Expr
32 {
33     enum ExprType type;
34     union {
35         struct Cons *cons;
36         struct Atom *atom;
37     };
38 };
39
40 struct Expr atom_as_expr(struct Atom *atom);
41 struct Expr cons_as_expr(struct Cons *cons);
42 struct Expr void_expr(void);
43
44 void destroy_expr(struct Expr expr);
45 void print_expr_as_sexpr(FILE *stream, struct Expr expr);
46 int expr_as_sexpr(struct Expr expr, char *output, size_t n);
47
48 // TODO(#337): EvalResult does not belong to expr unit
49 struct EvalResult
50 {
51     bool is_error;
52     struct Expr expr;
53 };
54
55
56 typedef struct EvalResult (*NativeFunction)(void *param, Gc *gc, struct Scope *scope, struct Expr args);
57
58 struct Native
59 {
60     NativeFunction fun;
61     void *param;
62 };
63
64 enum AtomType
65 {
66     ATOM_SYMBOL = 0,
67     ATOM_NUMBER,
68     ATOM_STRING,
69     ATOM_NATIVE
70 };
71
72 struct Atom
73 {
74     enum AtomType type;
75     union
76     {
77         // TODO(#330): Atom doesn't support floats
78         long int num;           // ATOM_NUMBER
79         char *sym;              // ATOM_SYMBOL
80         char *str;              // ATOM_STRING
81         struct Native native;   // ATOM_NATIVE
82     };
83 };
84
85 struct Atom *create_number_atom(Gc *gc, long int num);
86 struct Atom *create_string_atom(Gc *gc, const char *str, const char *str_end);
87 struct Atom *create_symbol_atom(Gc *gc, const char *sym, const char *sym_end);
88 struct Atom *create_native_atom(Gc *gc, NativeFunction fun, void *param);
89 void destroy_atom(struct Atom *atom);
90 void print_atom_as_sexpr(FILE *stream, struct Atom *atom);
91
92 struct Cons
93 {
94     struct Expr car;
95     struct Expr cdr;
96 };
97
98 struct Cons *create_cons(Gc *gc, struct Expr car, struct Expr cdr);
99 void destroy_cons(struct Cons *cons);
100 void print_cons_as_sexpr(FILE *stream, struct Cons *cons);
101
102 #endif  // EXPR_H_