git.haldean.org expel / dce2630
forgot to commit: lots of resolver work Haldean Brown 6 years ago
7 changed file(s) with 514 addition(s) and 54 deletion(s). Raw diff Collapse all Expand all
4949 struct xl_stream sstdin;
5050 struct xl_env env = {0};
5151 struct xl_scheduler *s;
52 local(resolve_context) struct xl_resolve_context rctx = {0};
5253 size_t n_graphs;
5354 size_t i;
5455 xl_error err;
7071 c(parse_err);
7172 c(err);
7273
73 c(xl_resolve(ast));
74 c(xl_resolve(ast, "(stdin)", &rctx));
7475
7576 c(xl_compile_ast(&graphs, &n_graphs, ast, NULL));
7677
142143 free(teardown_err);
143144 }
144145
145 free(err);
146146 return err == OK ? EXIT_SUCCESS : EXIT_FAILURE;
147147 }
148148
5050
5151 struct xl_ast;
5252 struct xl_resolve_scope;
53 struct xl_resolve_name_loc;
5354
5455 enum type_type
5556 {
7071 } qualified;
7172 };
7273 enum atom_type atom_type;
74 struct xl_resolve_name_loc *name_loc;
7375 };
7476
7577 struct xl_ast_arg_list
2828 RESOLVE_LOCAL = 1,
2929 /* if a name resolves globally, then the name should be accessed by
3030 * using a load node with the userdef scope. */
31 RESOLVE_GLOBAL
31 RESOLVE_GLOBAL,
32 /* if a name resolves through closure, then the ast needs to be
33 * transformed such that the name can be accessed as a local. */
34 RESOLVE_CLOSURE,
3235 };
3336
3437 struct xl_resolve_name
3639 char *name;
3740 enum xl_resolve_type type;
3841 struct xl_dagc_node *node;
42 };
43
44 struct xl_resolve_name_loc
45 {
46 enum xl_resolve_type type;
3947 };
4048
4149 /* Scope boundaries are used to determine whether something is
5159 enum xl_resolve_boundary_type
5260 {
5361 BOUNDARY_BLOCK = 1,
62 BOUNDARY_GLOBAL,
5463 BOUNDARY_FUNCTION,
55 BOUNDARY_GLOBAL
5664 };
5765
5866 struct xl_resolve_scope
6472 enum xl_resolve_boundary_type boundary;
6573 };
6674
75 enum xl_resolve_error_type
76 {
77 RESOLVE_ERR_NAME_NOT_FOUND = 1,
78 };
79
80 struct xl_resolve_error
81 {
82 enum xl_resolve_error_type err_type;
83 char *name;
84 };
85
86 struct xl_resolve_context
87 {
88 struct xl_resolve_scope *native_scope;
89 struct xl_vector scope_allocs;
90 struct xl_vector allocs;
91 struct xl_vector errors;
92 };
93
6794 no_ignore xl_error
68 xl_resolve(struct xl_ast *ast);
95 xl_resolve(
96 struct xl_ast *ast,
97 char *source_name,
98 struct xl_resolve_context *ctx);
99
100 void
101 xl_resolve_context_free(struct xl_resolve_context *ctx);
352352 size_t *n_subexprs,
353353 struct xl_ast_expr *expr)
354354 {
355
356 }
355 *subast = NULL;
356 *n_subexprs = 0;
357
358 switch (expr->expr_type)
359 {
360 case EXPR_ATOM:
361 return OK;
362
363 case EXPR_APPLY:
364 subexprs[0] = expr->apply.head;
365 subexprs[1] = expr->apply.tail;
366 *n_subexprs = 2;
367 return OK;
368
369 case EXPR_LAMBDA:
370 subexprs[0] = expr->lambda.body;
371 *n_subexprs = 1;
372 return OK;
373
374 case EXPR_CONSTRUCTOR:
375 *subast = expr->constructor.scope;
376 return OK;
377
378 case EXPR_CONDITIONAL:
379 subexprs[0] = expr->condition.cond;
380 subexprs[1] = expr->condition.implied;
381 subexprs[2] = expr->condition.opposed;
382 *n_subexprs = 3;
383 return OK;
384
385 case EXPR_BLOCK:
386 *subast = expr->block;
387 return OK;
388 }
389
390 return xl_raise(ERR_BAD_TYPE, "bad type in expr subexpressions");
391 }
1717 */
1818
1919 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22
2023 #include "expel/ast.h"
24 #include "expel/env.h"
25 #include "expel/natives.h"
2126 #include "expel/resolve.h"
27 #include "expel/util.h"
2228
2329 no_ignore xl_error
2430 assign_all_initial_scopes(
31 struct xl_resolve_context *ctx,
2532 struct xl_ast *ast,
26 struct xl_resolve_scope *parent);
27
28 no_ignore xl_error
29 update_scopes_with_bindings(struct xl_ast *ast);
33 struct xl_resolve_scope *parent,
34 bool is_root);
35
36 no_ignore xl_error
37 update_scopes_with_bindings(
38 struct xl_resolve_context *ctx,
39 struct xl_ast *ast);
40
41 no_ignore xl_error
42 update_scopes_with_args(
43 struct xl_resolve_context *ctx,
44 struct xl_ast *ast);
45
46 no_ignore xl_error
47 update_names_with_resolution_types(
48 struct xl_resolve_context *ctx,
49 struct xl_ast *ast);
50
51 no_ignore xl_error
52 xl_resolve_context_missing_name(struct xl_resolve_context *ctx, char *name);
3053
3154
3255 no_ignore static xl_error
3356 assign_initial_scopes(
34 struct xl_ast_expr *expr, struct xl_resolve_scope *parent)
57 struct xl_resolve_context *ctx,
58 struct xl_ast_expr *expr,
59 struct xl_resolve_scope *parent)
3560 {
3661 struct xl_ast *subast;
3762 struct xl_ast_expr *subexprs[8];
5176 expr->scope = calloc(1, sizeof(struct xl_resolve_scope));
5277 if (expr->scope == NULL)
5378 return xl_raise(ERR_NO_MEMORY, "expr scope alloc");
79 err = xl_vector_append(&ctx->scope_allocs, expr->scope);
80 if (err != OK)
81 {
82 free(expr->scope);
83 return err;
84 }
85
5486 expr->scope->parent = parent;
5587 expr->scope->boundary = BOUNDARY_FUNCTION;
5688 break;
6092 expr->scope = calloc(1, sizeof(struct xl_resolve_scope));
6193 if (expr->scope == NULL)
6294 return xl_raise(ERR_NO_MEMORY, "expr scope alloc");
95 err = xl_vector_append(&ctx->scope_allocs, expr->scope);
96 if (err != OK)
97 {
98 free(expr->scope);
99 return err;
100 }
101
63102 expr->scope->parent = parent;
64103 expr->scope->boundary = BOUNDARY_BLOCK;
65104 break;
75114
76115 if (subast != NULL)
77116 {
78 err = assign_all_initial_scopes(subast, expr->scope);
117 err = assign_all_initial_scopes(ctx, subast, expr->scope, false);
79118 if (err != OK)
80119 return err;
81120 }
82121
83122 for (i = 0; i < n_subexprs; i++)
84123 {
85 err = assign_initial_scopes(subexprs[i], expr->scope);
124 err = assign_initial_scopes(ctx, subexprs[i], expr->scope);
86125 if (err != OK)
87126 return err;
88127 }
91130
92131 no_ignore xl_error
93132 assign_all_initial_scopes(
94 struct xl_ast *ast, struct xl_resolve_scope *parent)
133 struct xl_resolve_context *ctx,
134 struct xl_ast *ast,
135 struct xl_resolve_scope *parent,
136 bool is_root)
95137 {
96138 size_t i;
97139 struct xl_ast_binding *bind;
100142 ast->scope = calloc(1, sizeof(struct xl_resolve_scope));
101143 if (ast->scope == NULL)
102144 return xl_raise(ERR_NO_MEMORY, "ast scope alloc");
145 err = xl_vector_append(&ctx->scope_allocs, ast->scope);
146 if (err != OK)
147 {
148 free(ast->scope);
149 return err;
150 }
151
103152 ast->scope->parent = parent;
104 ast->scope->boundary =
105 parent == NULL ? BOUNDARY_GLOBAL : BOUNDARY_BLOCK;
153 ast->scope->boundary = is_root ? BOUNDARY_GLOBAL : BOUNDARY_BLOCK;
106154
107155 for (i = 0; i < ast->bindings.n; i++)
108156 {
109157 bind = ast->bindings.elems[i];
110 err = assign_initial_scopes(bind->expr, ast->scope);
158 err = assign_initial_scopes(ctx, bind->expr, ast->scope);
111159 if (err != OK)
112160 return err;
113161 }
114162
115163 if (ast->immediate != NULL)
116164 {
117 err = assign_initial_scopes(ast->immediate, ast->scope);
165 err = assign_initial_scopes(ctx, ast->immediate, ast->scope);
118166 if (err != OK)
119167 return err;
120168 }
123171 }
124172
125173 no_ignore static xl_error
126 find_blocks_and_bind(struct xl_ast_expr *expr)
174 find_blocks_and_bind(
175 struct xl_resolve_context *ctx,
176 struct xl_ast_expr *expr)
127177 {
128178 struct xl_ast *subast;
129179 struct xl_ast_expr *subexprs[8];
137187
138188 if (subast != NULL)
139189 {
140 err = update_scopes_with_bindings(subast);
190 err = update_scopes_with_bindings(ctx, subast);
141191 if (err != OK)
142192 return err;
143193 }
144194
145195 for (i = 0; i < n_subexprs; i++)
146196 {
147 err = find_blocks_and_bind(subexprs[i]);
148 if (err != OK)
149 return err;
150 }
151 return OK;
152 }
153
154 no_ignore xl_error
155 update_scopes_with_bindings(struct xl_ast *ast)
197 err = find_blocks_and_bind(ctx, subexprs[i]);
198 if (err != OK)
199 return err;
200 }
201 return OK;
202 }
203
204 no_ignore xl_error
205 update_scopes_with_bindings(
206 struct xl_resolve_context *ctx,
207 struct xl_ast *ast)
156208 {
157209 size_t i;
158210 struct xl_ast_binding *bind;
165217 name = calloc(1, sizeof(struct xl_resolve_name));
166218 if (name == NULL)
167219 return xl_raise(ERR_NO_MEMORY, "bind to scope alloc");
220 err = xl_vector_append(&ctx->allocs, name);
221 if (err != OK)
222 {
223 free(name);
224 return err;
225 }
226
168227 name->name = bind->name;
169228 name->type = ast->scope->boundary == BOUNDARY_GLOBAL
170229 ? RESOLVE_GLOBAL
174233 if (err != OK)
175234 return err;
176235
177 err = find_blocks_and_bind(bind->expr);
236 err = find_blocks_and_bind(ctx, bind->expr);
178237 if (err != OK)
179238 return err;
180239 }
181240
182241 if (ast->immediate != NULL)
183242 {
184 err = find_blocks_and_bind(ast->immediate);
185 if (err != OK)
186 return err;
187 }
188
189 return OK;
190 }
191
192 no_ignore xl_error
193 xl_resolve(struct xl_ast *ast)
194 {
195 xl_error err;
196
197 err = assign_all_initial_scopes(ast, NULL);
198 if (err != OK)
199 return err;
200
201 err = update_scopes_with_bindings(ast);
202 if (err != OK)
203 return err;
204
205 return OK;
206 }
243 err = find_blocks_and_bind(ctx, ast->immediate);
244 if (err != OK)
245 return err;
246 }
247
248 return OK;
249 }
250
251 no_ignore static xl_error
252 find_lambdas_and_bind(
253 struct xl_resolve_context *ctx,
254 struct xl_ast_expr *expr)
255 {
256 struct xl_ast_arg_list *args;
257 struct xl_resolve_name *name;
258 struct xl_ast *subast;
259 struct xl_ast_expr *subexprs[8];
260 size_t n_subexprs;
261 size_t i;
262 xl_error err;
263
264 if (expr->expr_type == EXPR_LAMBDA)
265 {
266 args = expr->lambda.args;
267 while (args->name != NULL)
268 {
269 name = calloc(1, sizeof(struct xl_resolve_name));
270 if (name == NULL)
271 return xl_raise(ERR_NO_MEMORY, "args to scope");
272 err = xl_vector_append(&ctx->allocs, name);
273 if (err != OK)
274 {
275 free(name);
276 return err;
277 }
278 name->name = args->name;
279 name->type = RESOLVE_LOCAL;
280
281 err = xl_vector_append(&expr->scope->names, name);
282 if (err != OK)
283 return err;
284
285 args = args->next;
286 }
287 }
288
289 err = xl_ast_subexprs(&subast, subexprs, &n_subexprs, expr);
290 if (err != OK)
291 return err;
292
293 if (subast != NULL)
294 {
295 err = update_scopes_with_args(ctx, subast);
296 if (err != OK)
297 return err;
298 }
299
300 for (i = 0; i < n_subexprs; i++)
301 {
302 err = find_lambdas_and_bind(ctx, subexprs[i]);
303 if (err != OK)
304 return err;
305 }
306 return OK;
307 }
308
309 no_ignore xl_error
310 update_scopes_with_args(
311 struct xl_resolve_context *ctx,
312 struct xl_ast *ast)
313 {
314 size_t i;
315 struct xl_ast_binding *bind;
316 xl_error err;
317
318 for (i = 0; i < ast->bindings.n; i++)
319 {
320 bind = ast->bindings.elems[i];
321 err = find_lambdas_and_bind(ctx, bind->expr);
322 if (err != OK)
323 return err;
324 }
325
326 if (ast->immediate != NULL)
327 {
328 err = find_lambdas_and_bind(ctx, ast->immediate);
329 if (err != OK)
330 return err;
331 }
332
333 return OK;
334 }
335
336 no_ignore xl_error
337 find_name_resolution_types(
338 struct xl_resolve_context *ctx,
339 struct xl_ast_expr *expr)
340 {
341 bool found;
342 char *name;
343 size_t i;
344 size_t n_subexprs;
345 enum xl_resolve_boundary_type highest_bdry;
346 struct xl_ast *subast;
347 struct xl_ast_expr *subexprs[8];
348 struct xl_resolve_name_loc *name_loc;
349 struct xl_resolve_scope *scope;
350 xl_error err;
351
352 if (expr->expr_type == EXPR_ATOM && expr->atom->atom_type == ATOM_NAME)
353 {
354 name_loc = calloc(1, sizeof(struct xl_resolve_name_loc));
355 if (name_loc == NULL)
356 return xl_raise(ERR_NO_MEMORY, "name res type");
357 err = xl_vector_append(&ctx->allocs, name_loc);
358 if (err != OK)
359 {
360 free(name_loc);
361 return err;
362 }
363 expr->atom->name_loc = name_loc;
364
365 name = expr->atom->str;
366 highest_bdry = BOUNDARY_BLOCK;
367 scope = expr->scope;
368 found = false;
369
370 while (!found && scope != NULL)
371 {
372 for (i = 0; i < scope->names.n; i++)
373 {
374 if (strcmp(name, scope->names.elems[i]) == 0)
375 found = true;
376 }
377 if (!found && scope->boundary == BOUNDARY_FUNCTION)
378 highest_bdry = BOUNDARY_FUNCTION;
379 scope = scope->parent;
380 }
381
382 if (!found)
383 {
384 err = xl_resolve_context_missing_name(ctx, name);
385 if (err != OK)
386 return err;
387 }
388
389 expr->atom->name_loc->type = highest_bdry == BOUNDARY_FUNCTION
390 ? RESOLVE_CLOSURE
391 : RESOLVE_LOCAL;
392 }
393
394 err = xl_ast_subexprs(&subast, subexprs, &n_subexprs, expr);
395 if (err != OK)
396 return err;
397
398 if (subast != NULL)
399 {
400 err = update_names_with_resolution_types(ctx, subast);
401 if (err != OK)
402 return err;
403 }
404
405 for (i = 0; i < n_subexprs; i++)
406 {
407 err = find_name_resolution_types(ctx, subexprs[i]);
408 if (err != OK)
409 return err;
410 }
411 return OK;
412 }
413
414 no_ignore xl_error
415 update_names_with_resolution_types(
416 struct xl_resolve_context *ctx,
417 struct xl_ast *ast)
418 {
419 size_t i;
420 struct xl_ast_binding *bind;
421 xl_error err;
422
423 for (i = 0; i < ast->bindings.n; i++)
424 {
425 bind = ast->bindings.elems[i];
426 err = find_name_resolution_types(ctx, bind->expr);
427 if (err != OK)
428 return err;
429 }
430
431 if (ast->immediate != NULL)
432 {
433 err = find_name_resolution_types(ctx, ast->immediate);
434 if (err != OK)
435 return err;
436 }
437
438 return OK;
439 }
440
441 no_ignore static xl_error
442 add_uri_to_scope(void *ctx_v, struct xl_env *env, struct xl_uri *uri)
443 {
444 struct xl_resolve_context *ctx;
445 struct xl_resolve_name *name;
446 xl_error err;
447 unused(env);
448
449 ctx = ctx_v;
450
451 name = calloc(1, sizeof(struct xl_resolve_name));
452 if (name == NULL)
453 return xl_raise(ERR_NO_MEMORY, "add uri to scope");
454 err = xl_vector_append(&ctx->allocs, name);
455 if (err != OK)
456 {
457 free(name);
458 return err;
459 }
460
461 name->name = uri->name;
462 name->type = RESOLVE_GLOBAL;
463 return xl_vector_append(&ctx->native_scope->names, name);
464 }
465
466 no_ignore static xl_error
467 create_native_scope(struct xl_resolve_context *ctx)
468 {
469 struct xl_env env = {0};
470 xl_error err;
471
472 ctx->native_scope = calloc(1, sizeof(struct xl_resolve_scope));
473 if (ctx->native_scope == NULL)
474 return xl_raise(ERR_NO_MEMORY, "native scope alloc");
475
476 err = xl_natives_register(&env);
477 if (err != OK)
478 return err;
479
480 err = xl_env_iterate(add_uri_to_scope, &env, ctx);
481 if (err != OK)
482 return err;
483
484 err = xl_env_free(&env);
485 if (err != OK)
486 return err;
487
488 return OK;
489 }
490
491 no_ignore xl_error
492 xl_resolve(
493 struct xl_ast *ast,
494 char *source_name,
495 struct xl_resolve_context *ctx)
496 {
497 struct xl_resolve_error *resolv_err;
498 xl_error err;
499 size_t i;
500
501 err = create_native_scope(ctx);
502 if (err != OK)
503 return err;
504
505 err = assign_all_initial_scopes(ctx, ast, ctx->native_scope, true);
506 if (err != OK)
507 return err;
508
509 err = update_scopes_with_bindings(ctx, ast);
510 if (err != OK)
511 return err;
512
513 err = update_scopes_with_args(ctx, ast);
514 if (err != OK)
515 return err;
516
517 err = update_names_with_resolution_types(ctx, ast);
518 if (err != OK)
519 return err;
520
521 if (ctx->errors.n != 0)
522 {
523 for (i = 0; i < ctx->errors.n; i++)
524 {
525 resolv_err = ctx->errors.elems[i];
526 switch (resolv_err->err_type)
527 {
528 case RESOLVE_ERR_NAME_NOT_FOUND:
529 fprintf(stderr,
530 "\x1b[37m%s:%lu:%lu:\x1b[31m "
531 "error:\x1b[0m name not found: %s\n",
532 source_name, 0ul, 0ul, resolv_err->name);
533 }
534 }
535 return xl_raise(ERR_BAD_VALUE, "couldn't resolve some names");
536 }
537 return OK;
538 }
539
540 no_ignore xl_error
541 xl_resolve_context_missing_name(struct xl_resolve_context *ctx, char *name)
542 {
543 struct xl_resolve_error *resolv_err;
544 xl_error err;
545
546 resolv_err = calloc(1, sizeof(struct xl_resolve_error));
547 if (resolv_err == NULL)
548 return xl_raise(ERR_NO_MEMORY, "resolve error alloc");
549
550 resolv_err->err_type = RESOLVE_ERR_NAME_NOT_FOUND;
551 resolv_err->name = name;
552
553 err = xl_vector_append(&ctx->errors, resolv_err);
554 if (err != OK)
555 {
556 free(resolv_err);
557 return err;
558 }
559 return OK;
560 }
561
562 void
563 xl_resolve_context_free(struct xl_resolve_context *ctx)
564 {
565 struct xl_resolve_scope *scope;
566 size_t i;
567
568 xl_vector_free(&ctx->native_scope->names);
569 free(ctx->native_scope);
570
571 for (i = 0; i < ctx->scope_allocs.n; i++)
572 {
573 scope = ctx->scope_allocs.elems[i];
574 xl_vector_free(&scope->names);
575 free(scope);
576 }
577 xl_vector_free(&ctx->scope_allocs);
578
579 for (i = 0; i < ctx->allocs.n; i++)
580 free(ctx->allocs.elems[i]);
581 xl_vector_free(&ctx->allocs);
582
583 for (i = 0; i < ctx->errors.n; i++)
584 free(ctx->errors.elems[i]);
585 xl_vector_free(&ctx->errors);
586 }
1313 syntax match expelSubbind "=>"
1414 syntax match expelSubbind "/>"
1515 syntax match expelSubbind "->"
16 syntax match expelSubbind "\\"
1617 highlight link expelSubbind Keyword
1718
1819 syntax region expelString start=/"/ skip=/\\"/ end=/"/ oneline
0 : so-deep
1 ^ Word -> Word
2 = \ x -> {
3 : y ^ Word = uadd x 2
4 != \ z -> uadd x (uadd y z)
5 }
6
7 # + 4 (+ (+ 4 2) 8) == 18
8 != emit (humanize ((so-deep 4) 8))