aboutsummaryrefslogtreecommitdiff
path: root/include/ast.h
blob: eb3e1fc5efcab7154eac02de7409d28cb16cbbfc (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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#ifndef CMONKEY_AST_H
#define CMONKEY_AST_H

#include "token.h"
#include "vector.h"

enum node_type {
	NODE_PROGRAM,
	NODE_STATEMENT,
	NODE_EXPRESSION,
};

enum statement_type {
	STATEMENT_LET,
	STATEMENT_RETURN,
	STATEMENT_EXPRESSION,
	STATEMENT_BLOCK,
};

enum expression_type {
	EXPRESSION_IDENT,
	EXPRESSION_INT,
	EXPRESSION_BOOL,
	EXPRESSION_PREFIX,
	EXPRESSION_INFIX,
	EXPRESSION_IF,
	EXPRESSION_FUNC,
	EXPRESSION_CALL,
};

struct identifier {
	struct token token;
	struct slice value;
};

struct prefix_expression {
	struct token token;
	struct slice operator;
	struct expression *right;
};

struct infix_expression {
	struct token token;
	struct slice operator;
	struct expression *left;
	struct expression *right;
};

struct integer_expression {
	struct token token;
	int64_t value;
};

struct boolean_expression {
	struct token token;
	bool value;
};

struct if_expression {
	struct token token;
	struct expression *condition;
	struct statement *consequence;
	struct statement *alternative;
};

struct func_literal {
	struct token token;
	struct vector *parameters; // expression type ident
	struct statement *body;
};

struct call_expression {
	struct token token;
	struct expression *func;
	struct vector *arguments; // expressions
};

struct expression {
	enum expression_type type;
	union {
		struct token token; // Common initial sequence
		struct identifier ident;
		struct integer_expression integer;
		struct boolean_expression boolean;
		struct prefix_expression prefix;
		struct infix_expression infix;
		struct if_expression cond;
		struct func_literal func;
		struct call_expression call;
	};
};

struct expression_statement {
	struct token token;
	struct expression *expr;
};

struct return_statement {
	struct token token;
	struct expression *value;
};

struct let_statement {
	struct token token;
	struct identifier *name;
	struct expression *value;
};

struct block_statement {
	struct token token;
	struct vector *statements;
};

struct program {
	struct vector *statements;
};

struct statement {
	enum statement_type type;
	union {
		struct token token; // Common initial sequence
		struct let_statement let;
		struct return_statement retrn;
		struct expression_statement expr;
		struct block_statement block;
	};
};

struct slice expression_token_literal(struct expression *);
struct slice statement_token_literal(struct statement *);
struct slice program_token_literal(struct program *);

#define node_token_literal(n) _Generic((n), \
		struct program *: program_token_literal, \
		struct statement *: statement_token_literal, \
		struct expression *: expression_token_literal \
		)(n)

char *expression_sprint(struct expression *, char *str);
char *statement_sprint(struct statement *, char *str);
char *program_sprint(struct program *, char *str);

#define node_sprint(n, a) _Generic((n), \
		struct expression *: expression_sprint, \
		struct statement *: statement_sprint, \
		struct program *: program_sprint \
		)(n, a)

struct vector *expression_vector_dup(const struct vector *);
struct vector *statement_vector_dup(const struct vector *);

struct expression *expression_dup(const struct expression *);
struct statement *statement_dup(const struct statement *);

#define node_dup(n) _Generic((n), \
		struct expression *: expression_dup, \
		struct statement *: statement_dup \
		)(n)

void expression_destroy(struct expression *);
void statement_destroy(struct statement *);
void program_destroy(struct program *);

#define node_destroy(n) _Generic((n), \
		struct expression *: expression_destroy, \
		struct statement *: statement_destroy, \
		struct program *: program_destroy \
		)(n)

#endif