#include "im.h" #include "errloc.h" #include "fn.h" #include "prv.h" #include "parse.h" #include #include #include #include #include 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; }