diff options
| author | Xavier Del Campo Romero <xavi92@disroot.org> | 2026-05-09 02:56:07 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi92@disroot.org> | 2026-06-21 01:15:38 +0200 |
| commit | b25ff71bb198c227b3202ee32a8067cda413bc16 (patch) | |
| tree | 41d665a87d948c10b17a853220cbcdbaeebf3672 /im.c | |
| download | prc-master.tar.gz | |
Diffstat (limited to 'im.c')
| -rw-r--r-- | im.c | 89 |
1 files changed, 89 insertions, 0 deletions
@@ -0,0 +1,89 @@ +#include "im.h" +#include "errloc.h" +#include "fn.h" +#include "prv.h" +#include "parse.h" +#include <errno.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +void im_free(struct im *im) +{ + ast_free(&im->ast); + lex_free(&im->l); +} + +static int doim(const struct lex *l, const struct tk *tk, struct prv *p) +{ + int ret = -1; + FILE *f = NULL; + struct im *im; + struct fn *fn = fn_cur(p); + struct ast *ast; + size_t n = fn->nimps + 1; + const char *path = tk->s; + + if (!strcmp(l->loc.f, path)) + { + errloc(tk, "detected recursive import \"%s\"", path); + goto end; + } + /* TODO: honor -I flags */ + if (!(f = fopen(path, "rb"))) + { + errloc(tk, "could not find import: \"%s\"", path); + goto end; + } + else if (!(im = realloc(fn->imps, n * sizeof *im))) + { + perror("realloc(3)"); + goto end; + } + + fn->imps = im; + im = &fn->imps[fn->nimps++]; + *im = (struct im){.l.loc.f = path}; + ast = &im->ast; + + if (!(ast->fns = malloc(sizeof *ast->fns))) + { + perror("malloc(3)"); + goto end; + } + + *ast->fns = (struct fn){.tk = tk}; + /* hack: treat imports as a function */ + ast->nfns = 1; + + if (lex(&im->l, f) || parse_im(&im->l, ast)) + goto end; + + ret = 0; + +end: + + if (f && fclose(f)) + { + fprintf(stderr, "fclose(3) %s: %s\n", path, strerror(errno)); + ret = -1; + } + + return ret; +} + +int im(const struct lex *l, struct prv *p) +{ + const struct tk *tk = p->stk + 1; + struct pos *pos = &p->pos[p->i]; + + while (!lex_eof(l, tk) && !kw(tk->s)) + if (doim(l, tk++, p)) + return -1; + + pos->seq = pos->stseq; + pos->step = pos->seq->steps; + p->stk = p->tk; + return 1; +} |
