Blame


1 c734c0e9 2021-08-03 op /*
2 c734c0e9 2021-08-03 op * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
3 c734c0e9 2021-08-03 op *
4 c734c0e9 2021-08-03 op * Permission to use, copy, modify, and distribute this software for any
5 c734c0e9 2021-08-03 op * purpose with or without fee is hereby granted, provided that the above
6 c734c0e9 2021-08-03 op * copyright notice and this permission notice appear in all copies.
7 c734c0e9 2021-08-03 op *
8 c734c0e9 2021-08-03 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 c734c0e9 2021-08-03 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 c734c0e9 2021-08-03 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 c734c0e9 2021-08-03 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 c734c0e9 2021-08-03 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 c734c0e9 2021-08-03 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 c734c0e9 2021-08-03 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 c734c0e9 2021-08-03 op */
16 c734c0e9 2021-08-03 op
17 c734c0e9 2021-08-03 op #include "compat.h"
18 c734c0e9 2021-08-03 op
19 c734c0e9 2021-08-03 op #include <assert.h>
20 c734c0e9 2021-08-03 op #include <inttypes.h>
21 c734c0e9 2021-08-03 op #include <stdio.h>
22 c734c0e9 2021-08-03 op #include <stdlib.h>
23 c734c0e9 2021-08-03 op #include <string.h>
24 c734c0e9 2021-08-03 op #include <syslog.h>
25 c734c0e9 2021-08-03 op
26 c734c0e9 2021-08-03 op #include "utils.h"
27 c734c0e9 2021-08-03 op #include "script.h"
28 c734c0e9 2021-08-03 op #include "log.h"
29 c734c0e9 2021-08-03 op
30 c734c0e9 2021-08-03 op #define DEBUG 0
31 c734c0e9 2021-08-03 op
32 c734c0e9 2021-08-03 op static struct procs procs = TAILQ_HEAD_INITIALIZER(procs);
33 c734c0e9 2021-08-03 op static struct tests tests = TAILQ_HEAD_INITIALIZER(tests);
34 c734c0e9 2021-08-03 op
35 d9d02161 2021-08-04 op static struct opstacks blocks = TAILQ_HEAD_INITIALIZER(blocks);
36 d9d02161 2021-08-04 op static struct opstacks args = TAILQ_HEAD_INITIALIZER(args);
37 c734c0e9 2021-08-03 op
38 c734c0e9 2021-08-03 op #define STACK_HEIGHT 16
39 c734c0e9 2021-08-03 op static struct value vstack[STACK_HEIGHT];
40 c734c0e9 2021-08-03 op static int stackh;
41 c734c0e9 2021-08-03 op
42 c734c0e9 2021-08-03 op static struct value v_false = {.type = V_NUM, .v = {.num = 0}};
43 c734c0e9 2021-08-03 op static struct value v_true = {.type = V_NUM, .v = {.num = 1}};
44 c734c0e9 2021-08-03 op
45 d9d02161 2021-08-04 op static inline struct opstack *
46 d9d02161 2021-08-04 op pushstack(struct opstacks *stack)
47 d9d02161 2021-08-04 op {
48 d9d02161 2021-08-04 op struct opstack *ops;
49 d9d02161 2021-08-04 op
50 d9d02161 2021-08-04 op ops = xcalloc(1, sizeof(*ops));
51 d9d02161 2021-08-04 op TAILQ_INSERT_HEAD(stack, ops, entry);
52 d9d02161 2021-08-04 op return ops;
53 d9d02161 2021-08-04 op }
54 d9d02161 2021-08-04 op
55 d9d02161 2021-08-04 op static inline struct opstack *
56 d9d02161 2021-08-04 op peek(struct opstacks *stack)
57 d9d02161 2021-08-04 op {
58 d9d02161 2021-08-04 op if (TAILQ_EMPTY(stack))
59 d9d02161 2021-08-04 op errx(1, "%s: args underflow", __func__);
60 d9d02161 2021-08-04 op
61 d9d02161 2021-08-04 op return TAILQ_FIRST(stack);
62 d9d02161 2021-08-04 op }
63 d9d02161 2021-08-04 op
64 d9d02161 2021-08-04 op static inline struct op *
65 d9d02161 2021-08-04 op finalize(struct opstacks *stack, int *argc)
66 d9d02161 2021-08-04 op {
67 d9d02161 2021-08-04 op struct opstack *ops;
68 d9d02161 2021-08-04 op struct op *op;
69 d9d02161 2021-08-04 op
70 d9d02161 2021-08-04 op if (TAILQ_EMPTY(stack))
71 d9d02161 2021-08-04 op errx(1, "%s: args underflow", __func__);
72 d9d02161 2021-08-04 op
73 d9d02161 2021-08-04 op ops = peek(stack);
74 d9d02161 2021-08-04 op TAILQ_REMOVE(&args, ops, entry);
75 d9d02161 2021-08-04 op op = ops->base.next;
76 d9d02161 2021-08-04 op
77 d9d02161 2021-08-04 op if (argc != NULL)
78 d9d02161 2021-08-04 op *argc = ops->counter;
79 d9d02161 2021-08-04 op
80 d9d02161 2021-08-04 op free(ops);
81 d9d02161 2021-08-04 op return op;
82 d9d02161 2021-08-04 op }
83 d9d02161 2021-08-04 op
84 d9d02161 2021-08-04 op static inline void
85 d9d02161 2021-08-04 op push(struct opstacks *stack, struct op *op)
86 d9d02161 2021-08-04 op {
87 d9d02161 2021-08-04 op struct opstack *ops;
88 d9d02161 2021-08-04 op
89 d9d02161 2021-08-04 op ops = peek(stack);
90 d9d02161 2021-08-04 op if (ops->last == NULL) {
91 d9d02161 2021-08-04 op ops->base.next = op;
92 d9d02161 2021-08-04 op ops->last = op;
93 d9d02161 2021-08-04 op } else {
94 d9d02161 2021-08-04 op ops->last->next = op;
95 d9d02161 2021-08-04 op ops->last = op;
96 d9d02161 2021-08-04 op }
97 d9d02161 2021-08-04 op
98 d9d02161 2021-08-04 op ops->counter++;
99 d9d02161 2021-08-04 op }
100 d9d02161 2021-08-04 op
101 c734c0e9 2021-08-03 op void
102 c734c0e9 2021-08-03 op global_set(char *sym, struct op *op)
103 c734c0e9 2021-08-03 op {
104 c734c0e9 2021-08-03 op assert(op->type == OP_LITERAL);
105 c734c0e9 2021-08-03 op }
106 c734c0e9 2021-08-03 op
107 c734c0e9 2021-08-03 op struct op *
108 c734c0e9 2021-08-03 op newop(int type)
109 c734c0e9 2021-08-03 op {
110 c734c0e9 2021-08-03 op struct op *op;
111 c734c0e9 2021-08-03 op
112 f53af81c 2021-08-04 op op = xcalloc(1, sizeof(*op));
113 c734c0e9 2021-08-03 op op->type = type;
114 c734c0e9 2021-08-03 op
115 c734c0e9 2021-08-03 op return op;
116 c734c0e9 2021-08-03 op }
117 c734c0e9 2021-08-03 op
118 c734c0e9 2021-08-03 op void
119 c734c0e9 2021-08-03 op free_op(struct op *op)
120 c734c0e9 2021-08-03 op {
121 c734c0e9 2021-08-03 op /* TODO: probably more... */
122 c734c0e9 2021-08-03 op free(op);
123 c734c0e9 2021-08-03 op }
124 c734c0e9 2021-08-03 op
125 c734c0e9 2021-08-03 op struct op *
126 c734c0e9 2021-08-03 op op_assign(char *sym, struct op *expr)
127 c734c0e9 2021-08-03 op {
128 c734c0e9 2021-08-03 op struct op *op;
129 c734c0e9 2021-08-03 op
130 c734c0e9 2021-08-03 op op = newop(OP_ASSIGN);
131 c734c0e9 2021-08-03 op op->v.assign.name = sym;
132 c734c0e9 2021-08-03 op op->v.assign.expr = expr;
133 c734c0e9 2021-08-03 op
134 c734c0e9 2021-08-03 op return op;
135 c734c0e9 2021-08-03 op }
136 c734c0e9 2021-08-03 op
137 c734c0e9 2021-08-03 op struct op *
138 c734c0e9 2021-08-03 op op_assert(struct op *expr)
139 c734c0e9 2021-08-03 op {
140 c734c0e9 2021-08-03 op struct op *op;
141 c734c0e9 2021-08-03 op
142 c734c0e9 2021-08-03 op op = newop(OP_ASSERT);
143 c734c0e9 2021-08-03 op op->v.assert = expr;
144 c734c0e9 2021-08-03 op
145 c734c0e9 2021-08-03 op return op;
146 c734c0e9 2021-08-03 op }
147 c734c0e9 2021-08-03 op
148 c734c0e9 2021-08-03 op struct op *
149 c734c0e9 2021-08-03 op op_var(char *sym)
150 c734c0e9 2021-08-03 op {
151 c734c0e9 2021-08-03 op struct op *op;
152 c734c0e9 2021-08-03 op
153 c734c0e9 2021-08-03 op op = newop(OP_VAR);
154 c734c0e9 2021-08-03 op op->v.var = sym;
155 c734c0e9 2021-08-03 op
156 c734c0e9 2021-08-03 op return op;
157 c734c0e9 2021-08-03 op }
158 c734c0e9 2021-08-03 op
159 c734c0e9 2021-08-03 op struct op *
160 c734c0e9 2021-08-03 op op_lit_str(char *str)
161 c734c0e9 2021-08-03 op {
162 c734c0e9 2021-08-03 op struct op *op;
163 c734c0e9 2021-08-03 op
164 c734c0e9 2021-08-03 op op = newop(OP_LITERAL);
165 c734c0e9 2021-08-03 op op->v.literal.type = V_NUM;
166 c734c0e9 2021-08-03 op op->v.literal.v.str = str;
167 c734c0e9 2021-08-03 op
168 c734c0e9 2021-08-03 op return op;
169 c734c0e9 2021-08-03 op }
170 c734c0e9 2021-08-03 op
171 c734c0e9 2021-08-03 op struct op *
172 c734c0e9 2021-08-03 op op_lit_num(uint64_t n)
173 c734c0e9 2021-08-03 op {
174 c734c0e9 2021-08-03 op struct op *op;
175 c734c0e9 2021-08-03 op
176 c734c0e9 2021-08-03 op op = newop(OP_LITERAL);
177 c734c0e9 2021-08-03 op op->v.literal.type = V_NUM;
178 c734c0e9 2021-08-03 op op->v.literal.v.num = n;
179 c734c0e9 2021-08-03 op
180 c734c0e9 2021-08-03 op return op;
181 c734c0e9 2021-08-03 op }
182 c734c0e9 2021-08-03 op
183 c734c0e9 2021-08-03 op struct op *
184 c734c0e9 2021-08-03 op op_cmp_eq(struct op *a, struct op *b)
185 c734c0e9 2021-08-03 op {
186 c734c0e9 2021-08-03 op struct op *op;
187 c734c0e9 2021-08-03 op
188 c734c0e9 2021-08-03 op op = newop(OP_CMP_EQ);
189 c734c0e9 2021-08-03 op op->v.cmp_eq.a = a;
190 c734c0e9 2021-08-03 op op->v.cmp_eq.b = b;
191 c734c0e9 2021-08-03 op
192 c734c0e9 2021-08-03 op return op;
193 c734c0e9 2021-08-03 op }
194 c734c0e9 2021-08-03 op
195 c734c0e9 2021-08-03 op struct op *
196 c734c0e9 2021-08-03 op op_cast(struct op *expr, int totype)
197 c734c0e9 2021-08-03 op {
198 c734c0e9 2021-08-03 op struct op *op;
199 c734c0e9 2021-08-03 op
200 c734c0e9 2021-08-03 op op = newop(OP_CAST);
201 c734c0e9 2021-08-03 op op->v.cast.expr = expr;
202 c734c0e9 2021-08-03 op op->v.cast.totype = totype;
203 c734c0e9 2021-08-03 op
204 c734c0e9 2021-08-03 op return op;
205 c734c0e9 2021-08-03 op }
206 c734c0e9 2021-08-03 op
207 c734c0e9 2021-08-03 op void
208 da4de0c1 2021-08-04 op ppf_val(FILE *f, struct value *val)
209 c734c0e9 2021-08-03 op {
210 c734c0e9 2021-08-03 op switch (val->type) {
211 c734c0e9 2021-08-03 op case V_SYM:
212 da4de0c1 2021-08-04 op fprintf(f, "%s", val->v.str);
213 c734c0e9 2021-08-03 op break;
214 c734c0e9 2021-08-03 op case V_STR:
215 da4de0c1 2021-08-04 op fprintf(f, "\"%s\"", val->v.str);
216 c734c0e9 2021-08-03 op break;
217 c734c0e9 2021-08-03 op case V_NUM:
218 c734c0e9 2021-08-03 op case V_U8:
219 c734c0e9 2021-08-03 op case V_U16:
220 c734c0e9 2021-08-03 op case V_U32:
221 da4de0c1 2021-08-04 op fprintf(f, "%"PRIu64, val->v.num);
222 c734c0e9 2021-08-03 op break;
223 c734c0e9 2021-08-03 op default:
224 da4de0c1 2021-08-04 op fprintf(f, "<unknown value>");
225 c734c0e9 2021-08-03 op break;
226 c734c0e9 2021-08-03 op }
227 c734c0e9 2021-08-03 op }
228 c734c0e9 2021-08-03 op
229 da4de0c1 2021-08-04 op void
230 da4de0c1 2021-08-04 op pp_val(struct value *val)
231 da4de0c1 2021-08-04 op {
232 da4de0c1 2021-08-04 op ppf_val(stdout, val);
233 da4de0c1 2021-08-04 op }
234 da4de0c1 2021-08-04 op
235 c734c0e9 2021-08-03 op int
236 c734c0e9 2021-08-03 op val_trueish(struct value *a)
237 c734c0e9 2021-08-03 op {
238 c734c0e9 2021-08-03 op return a->type == V_NUM && a->v.num;
239 c734c0e9 2021-08-03 op }
240 c734c0e9 2021-08-03 op
241 c734c0e9 2021-08-03 op static inline int
242 c734c0e9 2021-08-03 op val_isnum(struct value *a)
243 c734c0e9 2021-08-03 op {
244 c734c0e9 2021-08-03 op return a->type == V_NUM
245 c734c0e9 2021-08-03 op || a->type == V_U8
246 c734c0e9 2021-08-03 op || a->type == V_U16
247 c734c0e9 2021-08-03 op || a->type == V_U32;
248 c734c0e9 2021-08-03 op }
249 c734c0e9 2021-08-03 op
250 c734c0e9 2021-08-03 op int
251 c734c0e9 2021-08-03 op val_eq(struct value *a, struct value *b)
252 c734c0e9 2021-08-03 op {
253 c734c0e9 2021-08-03 op if (val_isnum(a) && val_isnum(b))
254 c734c0e9 2021-08-03 op return a->v.num == b->v.num;
255 c734c0e9 2021-08-03 op
256 c734c0e9 2021-08-03 op if (a->type != b->type)
257 c734c0e9 2021-08-03 op return 0;
258 c734c0e9 2021-08-03 op
259 c734c0e9 2021-08-03 op switch (a->type) {
260 c734c0e9 2021-08-03 op case V_STR:
261 c734c0e9 2021-08-03 op case V_SYM:
262 c734c0e9 2021-08-03 op return !strcmp(a->v.str, b->v.str);
263 c734c0e9 2021-08-03 op }
264 c734c0e9 2021-08-03 op
265 c734c0e9 2021-08-03 op return 0;
266 da4de0c1 2021-08-04 op }
267 da4de0c1 2021-08-04 op
268 da4de0c1 2021-08-04 op static inline const char *
269 da4de0c1 2021-08-04 op pp_totype(int totype)
270 da4de0c1 2021-08-04 op {
271 da4de0c1 2021-08-04 op /*
272 da4de0c1 2021-08-04 op * Not all of these are valid cast type thought, including
273 da4de0c1 2021-08-04 op * every possibility only to aid debugging.
274 da4de0c1 2021-08-04 op */
275 da4de0c1 2021-08-04 op switch (totype) {
276 da4de0c1 2021-08-04 op case V_STR: return "str";
277 da4de0c1 2021-08-04 op case V_SYM: return "sym";
278 da4de0c1 2021-08-04 op case V_NUM: return "num";
279 da4de0c1 2021-08-04 op case V_QID: return "qid";
280 da4de0c1 2021-08-04 op case V_U8: return "u8";
281 da4de0c1 2021-08-04 op case V_U16: return "u16";
282 da4de0c1 2021-08-04 op case V_U32: return "u32";
283 da4de0c1 2021-08-04 op default: return "unknown";
284 da4de0c1 2021-08-04 op }
285 da4de0c1 2021-08-04 op }
286 da4de0c1 2021-08-04 op
287 da4de0c1 2021-08-04 op int
288 da4de0c1 2021-08-04 op val_cast(struct value *a, int totype)
289 da4de0c1 2021-08-04 op {
290 da4de0c1 2021-08-04 op uint64_t v;
291 da4de0c1 2021-08-04 op
292 da4de0c1 2021-08-04 op #define NUMCAST(v, totype, max) do { \
293 da4de0c1 2021-08-04 op if (v >= max) { \
294 da4de0c1 2021-08-04 op fprintf(stderr, "Can't cast %"PRIu64 \
295 da4de0c1 2021-08-04 op " to %s\n", v, pp_totype(totype)); \
296 da4de0c1 2021-08-04 op return EVAL_ERR; \
297 da4de0c1 2021-08-04 op } \
298 da4de0c1 2021-08-04 op a->type = totype; \
299 da4de0c1 2021-08-04 op return EVAL_OK; \
300 da4de0c1 2021-08-04 op } while (0)
301 da4de0c1 2021-08-04 op
302 da4de0c1 2021-08-04 op if (!val_isnum(a)) {
303 da4de0c1 2021-08-04 op fprintf(stderr, "Can't cast ");
304 da4de0c1 2021-08-04 op ppf_val(stderr, a);
305 da4de0c1 2021-08-04 op fprintf(stderr, " to type %s\n", pp_totype(totype));
306 da4de0c1 2021-08-04 op return EVAL_ERR;
307 da4de0c1 2021-08-04 op }
308 da4de0c1 2021-08-04 op
309 da4de0c1 2021-08-04 op v = a->v.num;
310 da4de0c1 2021-08-04 op switch (totype) {
311 da4de0c1 2021-08-04 op case V_U8: NUMCAST(v, totype, UINT8_MAX);
312 da4de0c1 2021-08-04 op case V_U16: NUMCAST(v, totype, UINT16_MAX);
313 da4de0c1 2021-08-04 op case V_U32: NUMCAST(v, totype, UINT32_MAX);
314 da4de0c1 2021-08-04 op default:
315 da4de0c1 2021-08-04 op fprintf(stderr, "Can't cast %"PRIu64" to %s\n",
316 da4de0c1 2021-08-04 op v, pp_totype(totype));
317 da4de0c1 2021-08-04 op return EVAL_ERR;
318 da4de0c1 2021-08-04 op }
319 da4de0c1 2021-08-04 op
320 da4de0c1 2021-08-04 op #undef NUMCAST
321 c734c0e9 2021-08-03 op }
322 c734c0e9 2021-08-03 op
323 c734c0e9 2021-08-03 op void
324 c734c0e9 2021-08-03 op pp_op(struct op *op)
325 c734c0e9 2021-08-03 op {
326 c734c0e9 2021-08-03 op switch (op->type) {
327 c734c0e9 2021-08-03 op case OP_ASSIGN:
328 c734c0e9 2021-08-03 op printf("%s = ", op->v.assign.name);
329 c734c0e9 2021-08-03 op pp_op(op->v.assign.expr);
330 c734c0e9 2021-08-03 op break;
331 c734c0e9 2021-08-03 op case OP_ASSERT:
332 c734c0e9 2021-08-03 op printf("assert ");
333 c734c0e9 2021-08-03 op pp_op(op->v.assert);
334 c734c0e9 2021-08-03 op break;
335 c734c0e9 2021-08-03 op case OP_FUNCALL:
336 c734c0e9 2021-08-03 op printf("funcall()");
337 c734c0e9 2021-08-03 op break;
338 c734c0e9 2021-08-03 op case OP_LITERAL:
339 c734c0e9 2021-08-03 op pp_val(&op->v.literal);
340 c734c0e9 2021-08-03 op break;
341 c734c0e9 2021-08-03 op case OP_VAR:
342 c734c0e9 2021-08-03 op printf("%s", op->v.var);
343 c734c0e9 2021-08-03 op break;
344 c734c0e9 2021-08-03 op case OP_CAST:
345 c734c0e9 2021-08-03 op pp_op(op->v.cast.expr);
346 c734c0e9 2021-08-03 op printf(":");
347 c734c0e9 2021-08-03 op switch (op->v.cast.totype) {
348 c734c0e9 2021-08-03 op case V_U8: printf("u8"); break;
349 c734c0e9 2021-08-03 op case V_U16: printf("u16"); break;
350 c734c0e9 2021-08-03 op case V_U32: printf("u32"); break;
351 c734c0e9 2021-08-03 op case V_STR: printf("str"); break;
352 c734c0e9 2021-08-03 op default: printf("???"); break;
353 c734c0e9 2021-08-03 op }
354 c734c0e9 2021-08-03 op break;
355 c734c0e9 2021-08-03 op case OP_CMP_EQ:
356 c734c0e9 2021-08-03 op pp_op(op->v.cmp_eq.a);
357 c734c0e9 2021-08-03 op printf(" == ");
358 c734c0e9 2021-08-03 op pp_op(op->v.cmp_eq.b);
359 c734c0e9 2021-08-03 op break;
360 c734c0e9 2021-08-03 op default:
361 c734c0e9 2021-08-03 op printf(" ???[%d] ", op->type);
362 c734c0e9 2021-08-03 op }
363 c734c0e9 2021-08-03 op }
364 c734c0e9 2021-08-03 op
365 c734c0e9 2021-08-03 op void
366 c734c0e9 2021-08-03 op pp_block(struct op *op)
367 c734c0e9 2021-08-03 op {
368 c734c0e9 2021-08-03 op while (op != NULL) {
369 c734c0e9 2021-08-03 op printf("> ");
370 c734c0e9 2021-08-03 op pp_op(op);
371 c734c0e9 2021-08-03 op printf("\n");
372 c734c0e9 2021-08-03 op
373 c734c0e9 2021-08-03 op op = op->next;
374 c734c0e9 2021-08-03 op }
375 c734c0e9 2021-08-03 op }
376 c734c0e9 2021-08-03 op
377 c734c0e9 2021-08-03 op static inline void
378 c734c0e9 2021-08-03 op popv(struct value *v)
379 c734c0e9 2021-08-03 op {
380 c734c0e9 2021-08-03 op if (stackh == 0)
381 c734c0e9 2021-08-03 op errx(1, "can't pop the stack: underflow");
382 c734c0e9 2021-08-03 op memcpy(v, &vstack[--stackh], sizeof(*v));
383 c734c0e9 2021-08-03 op
384 c734c0e9 2021-08-03 op #if DEBUG
385 c734c0e9 2021-08-03 op printf("popping "); pp_val(v); printf("\n");
386 c734c0e9 2021-08-03 op #endif
387 c734c0e9 2021-08-03 op }
388 c734c0e9 2021-08-03 op
389 c734c0e9 2021-08-03 op static inline void
390 c734c0e9 2021-08-03 op pushv(struct value *v)
391 c734c0e9 2021-08-03 op {
392 c734c0e9 2021-08-03 op if (stackh == STACK_HEIGHT)
393 c734c0e9 2021-08-03 op errx(1, "can't push the stack: overflow");
394 c734c0e9 2021-08-03 op
395 c734c0e9 2021-08-03 op #if DEBUG
396 c734c0e9 2021-08-03 op printf("pushing "); pp_val(v); printf("\n");
397 c734c0e9 2021-08-03 op #endif
398 c734c0e9 2021-08-03 op
399 c734c0e9 2021-08-03 op memcpy(&vstack[stackh++], v, sizeof(*v));
400 c734c0e9 2021-08-03 op }
401 c734c0e9 2021-08-03 op
402 c734c0e9 2021-08-03 op static inline void
403 c734c0e9 2021-08-03 op pushbool(int n)
404 c734c0e9 2021-08-03 op {
405 c734c0e9 2021-08-03 op pushv(n ? &v_true : &v_false);
406 c734c0e9 2021-08-03 op }
407 c734c0e9 2021-08-03 op
408 c734c0e9 2021-08-03 op int
409 c734c0e9 2021-08-03 op eval(struct op *op)
410 c734c0e9 2021-08-03 op {
411 c734c0e9 2021-08-03 op struct value a, b;
412 c734c0e9 2021-08-03 op struct proc *proc;
413 c734c0e9 2021-08-03 op struct op *t;
414 c734c0e9 2021-08-03 op int i, ret;
415 c734c0e9 2021-08-03 op
416 c734c0e9 2021-08-03 op #if DEBUG
417 c734c0e9 2021-08-03 op pp_op(op);
418 c734c0e9 2021-08-03 op printf("\n");
419 c734c0e9 2021-08-03 op #endif
420 c734c0e9 2021-08-03 op
421 c734c0e9 2021-08-03 op switch (op->type) {
422 c734c0e9 2021-08-03 op case OP_ASSIGN:
423 c734c0e9 2021-08-03 op printf("TODO: assignment\n");
424 c734c0e9 2021-08-03 op break;
425 c734c0e9 2021-08-03 op
426 c734c0e9 2021-08-03 op case OP_ASSERT:
427 333d8d7d 2021-08-04 op if ((ret = eval(op->v.assert)) != EVAL_OK)
428 c734c0e9 2021-08-03 op return ret;
429 c734c0e9 2021-08-03 op popv(&a);
430 c734c0e9 2021-08-03 op if (!val_trueish(&a)) {
431 c734c0e9 2021-08-03 op printf("assertion failed: ");
432 c734c0e9 2021-08-03 op pp_op(op->v.assert);
433 c734c0e9 2021-08-03 op printf("\n");
434 333d8d7d 2021-08-04 op return EVAL_ERR;
435 c734c0e9 2021-08-03 op }
436 c734c0e9 2021-08-03 op break;
437 c734c0e9 2021-08-03 op
438 c734c0e9 2021-08-03 op case OP_FUNCALL:
439 c734c0e9 2021-08-03 op /* TODO: arity check! */
440 c734c0e9 2021-08-03 op
441 c734c0e9 2021-08-03 op for (i = 0; i < op->v.funcall.argc; ++i) {
442 c734c0e9 2021-08-03 op t = &op->v.funcall.argv[i];
443 333d8d7d 2021-08-04 op if ((ret = eval(t)) != EVAL_OK)
444 c734c0e9 2021-08-03 op return ret;
445 c734c0e9 2021-08-03 op }
446 c734c0e9 2021-08-03 op
447 c734c0e9 2021-08-03 op proc = op->v.funcall.proc;
448 c734c0e9 2021-08-03 op if (proc->nativefn != NULL)
449 c734c0e9 2021-08-03 op proc->nativefn(i);
450 333d8d7d 2021-08-04 op else if ((ret = eval(proc->body)) != EVAL_OK)
451 c734c0e9 2021-08-03 op return ret;
452 c734c0e9 2021-08-03 op break;
453 c734c0e9 2021-08-03 op
454 c734c0e9 2021-08-03 op case OP_LITERAL:
455 c734c0e9 2021-08-03 op pushv(&op->v.literal);
456 c734c0e9 2021-08-03 op break;
457 c734c0e9 2021-08-03 op
458 c734c0e9 2021-08-03 op case OP_VAR:
459 c734c0e9 2021-08-03 op printf("TODO: load variable\n");
460 c734c0e9 2021-08-03 op break;
461 c734c0e9 2021-08-03 op
462 c734c0e9 2021-08-03 op case OP_CAST:
463 da4de0c1 2021-08-04 op if ((ret = eval(op->v.cast.expr)) != EVAL_OK)
464 da4de0c1 2021-08-04 op return ret;
465 da4de0c1 2021-08-04 op popv(&a);
466 da4de0c1 2021-08-04 op if ((ret = val_cast(&a, op->v.cast.totype)) != EVAL_OK)
467 da4de0c1 2021-08-04 op return ret;
468 da4de0c1 2021-08-04 op pushv(&a);
469 c734c0e9 2021-08-03 op break;
470 c734c0e9 2021-08-03 op
471 c734c0e9 2021-08-03 op case OP_CMP_EQ:
472 333d8d7d 2021-08-04 op if ((ret = eval(op->v.cmp_eq.a)) != EVAL_OK)
473 c734c0e9 2021-08-03 op return ret;
474 333d8d7d 2021-08-04 op if ((ret = eval(op->v.cmp_eq.b)) != EVAL_OK)
475 c734c0e9 2021-08-03 op return ret;
476 c734c0e9 2021-08-03 op
477 c734c0e9 2021-08-03 op popv(&b);
478 c734c0e9 2021-08-03 op popv(&a);
479 c734c0e9 2021-08-03 op pushbool(val_eq(&a, &b));
480 c734c0e9 2021-08-03 op
481 c734c0e9 2021-08-03 op break;
482 c734c0e9 2021-08-03 op
483 c734c0e9 2021-08-03 op default:
484 e9f9c9b1 2021-08-04 op fprintf(stderr, "invalid op, aborting.\n");
485 c734c0e9 2021-08-03 op abort();
486 c734c0e9 2021-08-03 op }
487 c734c0e9 2021-08-03 op
488 c734c0e9 2021-08-03 op if (op->next)
489 c734c0e9 2021-08-03 op return eval(op->next);
490 333d8d7d 2021-08-04 op return EVAL_OK;
491 c734c0e9 2021-08-03 op }
492 c734c0e9 2021-08-03 op
493 c734c0e9 2021-08-03 op void
494 d9d02161 2021-08-04 op prepare_funcall(void)
495 c734c0e9 2021-08-03 op {
496 d9d02161 2021-08-04 op pushstack(&args);
497 c734c0e9 2021-08-03 op }
498 c734c0e9 2021-08-03 op
499 c734c0e9 2021-08-03 op void
500 c734c0e9 2021-08-03 op push_arg(struct op *op)
501 c734c0e9 2021-08-03 op {
502 d9d02161 2021-08-04 op push(&args, op);
503 c734c0e9 2021-08-03 op }
504 c734c0e9 2021-08-03 op
505 c734c0e9 2021-08-03 op struct op *
506 d9d02161 2021-08-04 op op_funcall(struct proc *proc)
507 c734c0e9 2021-08-03 op {
508 d9d02161 2021-08-04 op struct op *op, *argv;
509 d9d02161 2021-08-04 op int argc;
510 c734c0e9 2021-08-03 op
511 d9d02161 2021-08-04 op argv = finalize(&args, &argc);
512 d9d02161 2021-08-04 op
513 c734c0e9 2021-08-03 op op = newop(OP_FUNCALL);
514 c734c0e9 2021-08-03 op op->v.funcall.proc = proc;
515 d9d02161 2021-08-04 op op->v.funcall.argv = argv;
516 d9d02161 2021-08-04 op op->v.funcall.argc = argc;
517 c734c0e9 2021-08-03 op
518 c734c0e9 2021-08-03 op return op;
519 c734c0e9 2021-08-03 op }
520 c734c0e9 2021-08-03 op
521 c734c0e9 2021-08-03 op void
522 c734c0e9 2021-08-03 op add_builtin_proc(const char *name, int (*fn)(int))
523 c734c0e9 2021-08-03 op {
524 c734c0e9 2021-08-03 op struct proc *proc;
525 c734c0e9 2021-08-03 op
526 c734c0e9 2021-08-03 op proc = xcalloc(1, sizeof(*proc));
527 c734c0e9 2021-08-03 op proc->name = xstrdup(name);
528 c734c0e9 2021-08-03 op proc->nativefn = fn;
529 c734c0e9 2021-08-03 op
530 c734c0e9 2021-08-03 op TAILQ_INSERT_HEAD(&procs, proc, entry);
531 c734c0e9 2021-08-03 op }
532 c734c0e9 2021-08-03 op
533 c734c0e9 2021-08-03 op void
534 d9d02161 2021-08-04 op prepare_proc(void)
535 c734c0e9 2021-08-03 op {
536 d9d02161 2021-08-04 op pushstack(&args);
537 d9d02161 2021-08-04 op }
538 c734c0e9 2021-08-03 op
539 d9d02161 2021-08-04 op int
540 c734c0e9 2021-08-03 op proc_setup_body(void)
541 c734c0e9 2021-08-03 op {
542 d9d02161 2021-08-04 op struct opstack *argv;
543 d9d02161 2021-08-04 op struct op *op;
544 d9d02161 2021-08-04 op int i;
545 c734c0e9 2021-08-03 op
546 d9d02161 2021-08-04 op argv = peek(&args);
547 d9d02161 2021-08-04 op for (i = 0, op = argv->base.next; op != NULL; i++) {
548 d9d02161 2021-08-04 op /*
549 d9d02161 2021-08-04 op * TODO: should free the whole list but.., we're gonna
550 d9d02161 2021-08-04 op * exit real soon(tm)!
551 d9d02161 2021-08-04 op */
552 c734c0e9 2021-08-03 op if (op->type != OP_VAR)
553 d9d02161 2021-08-04 op return 0;
554 c8878182 2021-08-04 op
555 c8878182 2021-08-04 op op = op->next;
556 c734c0e9 2021-08-03 op }
557 c734c0e9 2021-08-03 op
558 d9d02161 2021-08-04 op assert(i == argv->counter);
559 d9d02161 2021-08-04 op pushstack(&blocks);
560 d9d02161 2021-08-04 op return 1;
561 c734c0e9 2021-08-03 op }
562 c734c0e9 2021-08-03 op
563 c734c0e9 2021-08-03 op void
564 d9d02161 2021-08-04 op proc_done(char *name)
565 c734c0e9 2021-08-03 op {
566 d9d02161 2021-08-04 op struct proc *proc;
567 d9d02161 2021-08-04 op struct op *op, *next, *argv, *body;
568 d9d02161 2021-08-04 op int i, argc;
569 c734c0e9 2021-08-03 op
570 d9d02161 2021-08-04 op argv = finalize(&args, &argc);
571 d9d02161 2021-08-04 op body = finalize(&blocks, NULL);
572 d9d02161 2021-08-04 op
573 d9d02161 2021-08-04 op proc = xcalloc(1, sizeof(*proc));
574 d9d02161 2021-08-04 op proc->name = name;
575 d9d02161 2021-08-04 op proc->minargs = argc;
576 d9d02161 2021-08-04 op
577 b99bdaa1 2021-08-04 op for (i = 0, op = argv; op != NULL; ++i) {
578 d9d02161 2021-08-04 op proc->args[i] = xstrdup(op->v.var);
579 d9d02161 2021-08-04 op
580 d9d02161 2021-08-04 op next = op->next;
581 d9d02161 2021-08-04 op free_op(op);
582 d9d02161 2021-08-04 op op = next;
583 d9d02161 2021-08-04 op }
584 b99bdaa1 2021-08-04 op assert(i == argc);
585 d9d02161 2021-08-04 op
586 d9d02161 2021-08-04 op proc->body = body;
587 d9d02161 2021-08-04 op
588 d9d02161 2021-08-04 op TAILQ_INSERT_HEAD(&procs, proc, entry);
589 c734c0e9 2021-08-03 op }
590 c734c0e9 2021-08-03 op
591 c734c0e9 2021-08-03 op void
592 c734c0e9 2021-08-03 op block_push(struct op *op)
593 c734c0e9 2021-08-03 op {
594 d9d02161 2021-08-04 op push(&blocks, op);
595 c734c0e9 2021-08-03 op }
596 c734c0e9 2021-08-03 op
597 c734c0e9 2021-08-03 op struct proc *
598 c734c0e9 2021-08-03 op proc_by_name(const char *name)
599 c734c0e9 2021-08-03 op {
600 c734c0e9 2021-08-03 op struct proc *p;
601 c734c0e9 2021-08-03 op
602 c734c0e9 2021-08-03 op TAILQ_FOREACH(p, &procs, entry) {
603 c734c0e9 2021-08-03 op if (!strcmp(p->name, name))
604 c734c0e9 2021-08-03 op return p;
605 c734c0e9 2021-08-03 op }
606 c734c0e9 2021-08-03 op
607 c734c0e9 2021-08-03 op return NULL;
608 c734c0e9 2021-08-03 op }
609 c734c0e9 2021-08-03 op
610 c734c0e9 2021-08-03 op void
611 d9d02161 2021-08-04 op prepare_test(void)
612 c734c0e9 2021-08-03 op {
613 d9d02161 2021-08-04 op pushstack(&blocks);
614 c734c0e9 2021-08-03 op }
615 c734c0e9 2021-08-03 op
616 c734c0e9 2021-08-03 op void
617 d9d02161 2021-08-04 op test_done(char *name, char *dir)
618 c734c0e9 2021-08-03 op {
619 d9d02161 2021-08-04 op struct test *test;
620 d9d02161 2021-08-04 op
621 d9d02161 2021-08-04 op test = xcalloc(1, sizeof(*test));
622 d9d02161 2021-08-04 op test->name = name;
623 d9d02161 2021-08-04 op test->dir = dir;
624 d9d02161 2021-08-04 op test->body = finalize(&blocks, NULL);
625 d9d02161 2021-08-04 op
626 5e5c37b5 2021-08-04 op if (TAILQ_EMPTY(&tests))
627 5e5c37b5 2021-08-04 op TAILQ_INSERT_HEAD(&tests, test, entry);
628 5e5c37b5 2021-08-04 op else
629 5e5c37b5 2021-08-04 op TAILQ_INSERT_TAIL(&tests, test, entry);
630 c734c0e9 2021-08-03 op }
631 c734c0e9 2021-08-03 op
632 c734c0e9 2021-08-03 op static int
633 c734c0e9 2021-08-03 op builtin_dummy(int argc)
634 c734c0e9 2021-08-03 op {
635 c734c0e9 2021-08-03 op printf("dummy! yay!\n");
636 333d8d7d 2021-08-04 op return EVAL_OK;
637 c734c0e9 2021-08-03 op }
638 c734c0e9 2021-08-03 op
639 c734c0e9 2021-08-03 op static int
640 c734c0e9 2021-08-03 op run_test(struct test *t)
641 c734c0e9 2021-08-03 op {
642 c734c0e9 2021-08-03 op #if DEBUG
643 c734c0e9 2021-08-03 op puts("=====================");
644 8e0ef4cb 2021-08-04 op pp_block(t->body);
645 c734c0e9 2021-08-03 op puts("=====================");
646 c734c0e9 2021-08-03 op #endif
647 c734c0e9 2021-08-03 op
648 d9d02161 2021-08-04 op return eval(t->body);
649 c734c0e9 2021-08-03 op }
650 c734c0e9 2021-08-03 op
651 c734c0e9 2021-08-03 op int
652 c734c0e9 2021-08-03 op main(int argc, char **argv)
653 c734c0e9 2021-08-03 op {
654 c734c0e9 2021-08-03 op struct test *t;
655 c734c0e9 2021-08-03 op int i, passed = 0, failed = 0, skipped = 0;
656 c734c0e9 2021-08-03 op
657 c734c0e9 2021-08-03 op log_init(1, LOG_DAEMON);
658 c734c0e9 2021-08-03 op log_setverbose(1);
659 c734c0e9 2021-08-03 op
660 c734c0e9 2021-08-03 op add_builtin_proc("dummy", builtin_dummy);
661 c734c0e9 2021-08-03 op
662 c734c0e9 2021-08-03 op for (i = 1; i < argc; ++i)
663 c734c0e9 2021-08-03 op loadfile(argv[i]);
664 c734c0e9 2021-08-03 op
665 e334da07 2021-08-04 op i = 0;
666 c734c0e9 2021-08-03 op TAILQ_FOREACH(t, &tests, entry) {
667 e334da07 2021-08-04 op printf("===> running test \"%s\"... ", t->name);
668 e334da07 2021-08-04 op fflush(stdout);
669 e334da07 2021-08-04 op
670 e334da07 2021-08-04 op switch (run_test(t)) {
671 333d8d7d 2021-08-04 op case EVAL_OK:
672 e334da07 2021-08-04 op printf("ok!\n");
673 e334da07 2021-08-04 op passed++;
674 e334da07 2021-08-04 op break;
675 333d8d7d 2021-08-04 op case EVAL_ERR:
676 e334da07 2021-08-04 op failed++;
677 e334da07 2021-08-04 op /* we've already printed the failure */
678 e334da07 2021-08-04 op printf("\n");
679 e334da07 2021-08-04 op break;
680 333d8d7d 2021-08-04 op case EVAL_SKIP:
681 e334da07 2021-08-04 op printf("skipped!\n");
682 e334da07 2021-08-04 op skipped++;
683 e334da07 2021-08-04 op break;
684 c734c0e9 2021-08-03 op }
685 e334da07 2021-08-04 op
686 e334da07 2021-08-04 op i++;
687 c734c0e9 2021-08-03 op }
688 c734c0e9 2021-08-03 op
689 e334da07 2021-08-04 op printf("passed %d/%d\n", passed, i);
690 e334da07 2021-08-04 op printf("failed %d\n", failed);
691 e334da07 2021-08-04 op printf("skipped %d\n", skipped);
692 c734c0e9 2021-08-03 op
693 c734c0e9 2021-08-03 op return failed != 0;
694 c734c0e9 2021-08-03 op }