r/o

Binary operators, imm b24d9d60 parent 5c186f2c

authored by Yuki Izumi

1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
5
#include "parser.h"
6
7
/* ast_expr_t */
8
9
ast_expr_t *ast_string_alloc(char const *value) {
10
ast_expr_t *expr = malloc(sizeof(*expr));
11
memset(expr, 0, sizeof(*expr));
12
expr->type = EXPR_STRING;
13
expr->string = strdup(value);
14
15
int len = strlen(expr->string);
16
if (len > 0 && expr->string[len - 1] == '"') {
17
expr->string[len - 1] = 0;
18
}
19
20
return expr;
21
}
22
23
ast_expr_t *ast_binary_alloc(char op, ast_expr_t *a, ast_expr_t *b) {
24
ast_expr_t *expr = malloc(sizeof(*expr));
25
memset(expr, 0, sizeof(*expr));
26
expr->type = EXPR_BINARY;
27
expr->binary.op = op;
28
expr->binary.a = a;
29
expr->binary.b = b;
30
31
return expr;
32
}
33
34
ast_expr_t *ast_integer_alloc(int i) {
35
ast_expr_t *expr = malloc(sizeof(*expr));
36
memset(expr, 0, sizeof(*expr));
37
expr->type = EXPR_INTEGER;
38
expr->integer = i;
39
40
return expr;
41
}
42
43
void ast_expr_pp(ast_expr_t *expr) {
44
switch (expr->type) {
45
case EXPR_STRING:
46
printf("\"%s\"", expr->string);
47
break;
48
49
case EXPR_BINARY:
50
printf("(");
51
ast_expr_pp(expr->binary.a);
52
printf(" %c ", expr->binary.op);
53
ast_expr_pp(expr->binary.b);
54
printf(")");
55
break;
56
57
case EXPR_INTEGER:
58
printf("%d", expr->integer);
59
break;
60
61
default:
62
fprintf(stderr, "UNKNOWN EXPR TYPE %d\n", expr->type);
63
}
64
}
65
66
void ast_expr_free(ast_expr_t *expr) {
67
switch (expr->type) {
68
case EXPR_STRING:
69
free(expr->string);
70
break;
71
72
case EXPR_BINARY:
73
ast_expr_free(expr->binary.a);
74
ast_expr_free(expr->binary.b);
75
break;
76
77
case EXPR_INTEGER:
78
/* empty */
79
break;
80
81
default:
82
fprintf(stderr, "UNKNOWN EXPR TYPE %d\n", expr->type);
83
}
84
free(expr);
85
}
86
87
void ast_expr_free_list(ast_expr_t *expr) {
88
while (expr) {
89
ast_expr_t *next = expr->next;
90
ast_expr_free(expr);
91
expr = next;
92
}
93
}
94
95
/* ast_comment_t */
96
97
ast_comment_t *ast_comment_alloc(char const *value, int is_rem) {
98
ast_comment_t *comment = malloc(sizeof(*comment));
99
memset(comment, 0, sizeof(*comment));
100
comment->value = strdup(value);
101
comment->is_rem = is_rem;
102
return comment;
103
}
104
105
void ast_comment_free(ast_comment_t *comment) {
106
free(comment->value);
107
free(comment);
108
}
109
110
/* ast_token_t */
111
112
ast_token_t *ast_token_alloc(char const *value) {
113
ast_token_t *token = malloc(sizeof(*token));
114
memset(token, 0, sizeof(*token));
115
token->value = strdup(value);
116
return token;
117
}
118
119
void ast_token_free(ast_token_t *token) {
120
free(token->value);
121
free(token);
122
}
123
124
/* ast_stmt_t */
125
126
ast_stmt_t *ast_stmt_alloc(ast_stmt_type_t type) {
127
ast_stmt_t *stmt = malloc(sizeof(*stmt));
128
memset(stmt, 0, sizeof(*stmt));
129
stmt->type = type;
130
return stmt;
131
}
132
133
void ast_stmt_pp(ast_stmt_t *stmt) {
134
switch (stmt->type) {
135
case STMT_CALL:
136
printf("%s", stmt->call.target->value);
137
138
ast_expr_t *args = stmt->call.args;
139
while (args) {
140
printf(" ");
141
ast_expr_pp(args);
142
if (args->next) {
143
printf("%c", args->nexttype);
144
}
145
args = args->next;
146
}
147
148
printf("\n");
149
break;
150
151
case STMT_COMMENT:
152
printf("%s%s\n", stmt->comment->is_rem ? "REM" : "'", stmt->comment->value);
153
break;
154
155
default:
156
fprintf(stderr, "UNKNOWN STMT TYPE %d\n", stmt->type);
157
break;
158
}
159
}
160
161
void ast_stmt_free(ast_stmt_t *stmt) {
162
switch (stmt->type) {
163
case STMT_CALL:
164
ast_token_free(stmt->call.target);
165
ast_expr_free_list(stmt->call.args);
166
break;
167
168
case STMT_COMMENT:
169
ast_comment_free(stmt->comment);
170
break;
171
172
default:
173
fprintf(stderr, "UNKNOWN STMT TYPE %d\n", stmt->type);
174
break;
175
}
176
free(stmt);
177
}
178
179
void ast_stmt_free_list(ast_stmt_t *stmt) {
180
while (stmt) {
181
ast_stmt_t *next = stmt->next;
182
ast_stmt_free(stmt);
183
stmt = next;
184
}
185
}
186
187
/* ast_t */
188
189
ast_t *ast_alloc(void) {
190
ast_t *ast = malloc(sizeof(*ast));
191
memset(ast, 0, sizeof(*ast));
192
return ast;
193
}
194
195
void ast_append_stmt(ast_t *ast, ast_stmt_t *stmt) {
196
ast_stmt_t **writer = &ast->stmts;
197
while (*writer) {
198
writer = &(*writer)->next;
199
}
200
*writer = stmt;
201
}
202
203
void ast_pp(ast_t *ast) {
204
ast_stmt_t *stmt = ast->stmts;
205
while (stmt) {
206
ast_stmt_pp(stmt);
207
stmt = stmt->next;
208
}
209
}
210
211
void ast_free(ast_t *ast) {
212
ast_stmt_free_list(ast->stmts);
213
free(ast);
214
}
215
216
/* flex/bison */
217
218
int yywrap(void) {
219
return 1;
220
}
221
222
void yyerror(ast_t *ast, char const *s) {
223
fprintf(stderr, "parse error: %s\n", s);
224
}
225
226
int parser_test(void) {
227
ast_t *ast = ast_alloc();
228
229
begin_scan(
230
"PRINT \"Hello\"; \"there\", \"pals\" \"!\"\n"
231
"REM 1 + 2 * 3\n"
232
"PRINT 1 + 2 * 3\n"
233
"REM (1 + 2) * 3\n"
234
"PRINT (1 + 2) * 3\n"
235
"REM 1 * 2 + 3\n"
236
"PRINT 1 * 2 + 3\n"
237
"REM 1 * (2 + 3)\n"
238
"PRINT 1 * (2 + 3)\n"
239
"GOTO\n"
240
"\n"
241
"REM Okay, sure thing.\n"
242
"'I guess.\n");
243
yyparse(ast);
244
finish_scan();
245
246
ast_pp(ast);
247
248
free(ast);
249
250
return 0;
251
}
252
253
/* vim: set sw=4 et: */
254