diff options
| author | Xavier Del Campo Romero <xavi92@disroot.org> | 2026-10-01 01:04:30 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi92@disroot.org> | 2026-10-05 00:38:49 +0200 |
| commit | 2b0d4ead061a39da9dbd705c18c9955549c4d405 (patch) | |
| tree | 1412ac39adce3428b96caf67b1e7543f6c1246a5 /src/prc1/pr.c | |
| parent | 9140988be4e5bb028b7140aca1a67af1370c72a7 (diff) | |
| download | prc-sym.tar.gz | |
WIP symsym
Diffstat (limited to 'src/prc1/pr.c')
| -rw-r--r-- | src/prc1/pr.c | 343 |
1 files changed, 132 insertions, 211 deletions
diff --git a/src/prc1/pr.c b/src/prc1/pr.c index 3a4221a..1cedd4d 100644 --- a/src/prc1/pr.c +++ b/src/prc1/pr.c @@ -6,82 +6,29 @@ #include "parse.h" #include "stmt.h" #include "storage.h" +#include "sym.h" #include <stdio.h> #include <stdlib.h> #include <string.h> -static int prey(const struct lex *l, struct prv *p); -static int pren(const struct lex *l, struct prv *p); -static int pryy(const struct lex *l, struct prv *p); -static int pryn(const struct lex *l, struct prv *p); -static int prny(const struct lex *l, struct prv *p); -static int prnn(const struct lex *l, struct prv *p); +static int etc(const struct lex *, struct prv *); +static int using(const struct lex *, struct prv *); +static int s_returning(const struct lex *, struct prv *); + +static const struct seq returning = + {(struct step[]){{ID, "returning"}, {0}}, .fn = s_returning}; static const struct seq seqs[] = { - /* function definition with variadic parameters and return variable */ - { - (struct step[]) - { - {ID, "using"}, - {ID, NULL, 1}, - {ID, "etc",}, - {ID, "returning"}, - {ID}, - {0} - }, - .fn = prey - }, - - /* function definition with variadic parameters and no return variable */ - { - (struct step[]) - { - {ID, "using"}, - {ID, NULL, 1}, - {ID, "etc",}, - {0} - }, - .fn = pren - }, - - /* function definition with parameters and return variable */ - { - (struct step[]) - { - {ID, "using"}, - {ID, NULL, 1}, - {ID, "returning"}, - {ID}, - {0} - }, - .fn = pryy - }, - - /* function definition with parameters, no return variable */ - { - (struct step[]) - { - {ID, "using"}, - {ID, NULL, 1}, - {0} - }, - - .fn = pryn - }, - - /* function definition with no parameters, with return variable */ - { - (struct step[]) - { - {ID, "returning"}, - {ID}, - {0} - }, - - .fn = prny - }, + {(struct step[]){{ID, "using"}, {0}}, .fn = using}, + returning, + {0} +}; +static const struct seq useqs[] = +{ + {(struct step[]){{ID, "etc"}, {0}}, .fn = etc}, + returning, {0} }; @@ -117,7 +64,17 @@ static int param(const struct tk *tk, const struct stentry *e, struct pr *pr) static int setret(const struct tk *tk, const struct stentry *e, struct pr *pr) { - if (!(pr->ret = malloc(sizeof *pr->ret))) + const struct tk *prm = findparam(tk->s, pr); + + if (prm) + { + const struct loc *loc = &prm->loc; + + errloc(tk, "return value \"%s\" already listed as " + "parameter at %s:%d:%d", tk->s, loc->f, loc->line, loc->col); + return -1; + } + else if (!(pr->ret = malloc(sizeof *pr->ret))) { perror("malloc(3)"); return -1; @@ -133,196 +90,164 @@ static int finalize(const struct lex *l, struct prv *p) const struct pr *pr = fn->pr; struct pos init = { - .seq = stmts, - .stseq = stmts, - .step = stmts->steps + .name = __func__, + .seq = stmts }; - if (p->proto) + if (pr->using && !pr->params) + { + errloc(p->stk, "missing parameters"); + return -1; + } + else if (pr->returning && !pr->ret) + { + errloc(p->stk, "missing return variable"); + return -1; + } + else if (p->proto) { if (pop(l, p)) return -1; - fputc('\t', stderr); + dbg("\t"); } else if (push(&init, p)) return -1; - dbg("\tadding procedure using %zu%s parameters and%s return value\n", - pr->nparams, pr->variadic ? " variadic" : "", pr->ret ? "" : " no"); + dbg("\tadd procedure to %s using %zu%s parameters and%s return value\n", + fn->tk->s, pr->nparams, pr->variadic ? " variadic" : "", + pr->ret ? "" : " no"); p->stk = p->tk; - return 1; + return 0; } -static int prret(const struct lex *l, const struct tk *tk, struct prv *p) +static int check(const struct lex *l, struct prv *p, const struct sym *s, + int param, const struct stentry **out) { const struct fn *fn = fn_cur(p); - struct pr *pr = fn->pr; - const char *s = tk->s; - const struct storage *lk = fn->lk, *gl = fn->gl; + const struct tk *tk = s->tk; const struct stentry *e, *gle; - const struct tk *prm; + const struct storage *lk = fn->lk, *gl = fn->gl; - if (!lk || !(e = storage_find(s, lk))) + if (s->type != SYM_ID) { - errloc(tk, "return value \"%s\" not in %s", s, tk->s); + errloc(tk, "expected identifier"); return -1; } - else if (gl && (gle = storage_find(s, gl))) + else if (!lk || !(e = storage_find(tk->s, lk))) { - const struct loc *loc = &gle->tk->loc; - - errloc(tk, "return value \"%s\" also in %s at %s:%d:%d", s, gl->name, - loc->f, loc->line, loc->col); - return -1; + if (param && p->proto) + { + /* ambiguous syntax: param might be confused + * with next custom type. */ + p->stk = s->tk; + return pop(l, p); + } + else + { + errloc(tk, "\"%s\" not in linkage section", tk->s); + return -1; + } } - else if ((prm = findparam(s, pr))) + else if (gl && (gle = storage_find(tk->s, gl))) { - const struct loc *loc = &prm->loc; + const struct loc *loc = &gle->tk->loc; - errloc(tk, "return value \"%s\" already listed as " - "parameter at %s:%d:%d", tk->s, loc->f, loc->line, loc->col); + errloc(tk, "\"%s\" also in %s at %d:%d", s, gl->name, + loc->line, loc->col); return -1; } - else if (setret(tk, e, pr)) - return -1; - return finalize(l, p); + *out = e; + return 0; } -static const struct tk *prparams(const struct lex *l, struct prv *p, int *ret) +static int usym(const struct lex *l, struct prv *p, const struct sym *s) { - const struct tk *tk = p->stk + 1; + const struct tk *tk = s->tk; const struct fn *fn = fn_cur(p); - struct pr *pr = fn->pr; - - if (ret) - *ret = 0; + const struct stentry *e = NULL; - for (;;) - { - const struct storage *lk = fn->lk, *gl = fn->gl; - const struct stentry *e, *gle; - const struct tk *prm; - const char *s; - - if (lex_eof(l, tk)) - return tk; - else if (!strcmp((s = tk->s), "returning") && ret) - { - *ret = 1; - return ++tk; - } - else if (!strcmp(s, "etc")) - { - if (pr->variadic) - { - errloc(tk, "keyword \"etc\" may only appear once as a " - "parameter"); - return NULL; - } - - pr->variadic = tk++ - p->stk; - } - else if (kw(s)) - return tk; - else if (pr->variadic) - { - errloc(tk, "keyword \"etc\" must appear as the last parameter"); - return NULL; - } - else if ((prm = findparam(s, pr))) - { - const struct loc *loc = &prm->loc; - - errloc(tk, "parameter \"%s\" already listed at %d:%d", s, - loc->line, loc->col); - return NULL; - } - else if (!lk || !(e = storage_find(s, lk))) - { - if (p->proto) - { - /* ambiguous syntax: param might be confused - * with next custom type. */ - p->tk = p->stk + pr->nparams + 1; - return tk; - } - else - { - errloc(tk, "parameter \"%s\" not in %s", s, tk->s); - return NULL; - } - } - else if (gl && (gle = storage_find(s, gl))) - { - const struct loc *loc = &gle->tk->loc; - - errloc(tk, "parameter \"%s\" also in %s at %d:%d", s, gl->name, - loc->line, loc->col); - return NULL; - } - else if (param(tk, e, pr)) - return NULL; - else - tk++; - } + if (check(l, p, s, 1, &e)) + return -1; + else if (e) + return param(tk, e, fn->pr); - return tk; + return 0; } -static int prey(const struct lex *l, struct prv *p) +static int etc(const struct lex *l, struct prv *p) { - int ret; - const struct tk *tk = prparams(l, p, &ret); + const struct fn *fn = fn_cur(p); + struct pr *pr = fn->pr; - if (!tk) + if (pr->variadic) + { + errloc(p->stk, "procedure for \"%s\" already set as variadic", + fn->tk->s); return -1; - else if (ret) - return prret(l, tk, p); + } - return finalize(l, p); + pr->variadic = 1; + reset(p); + return 0; } -static int pren(const struct lex *l, struct prv *p) +static int rsym(const struct lex *l, struct prv *p, const struct sym *s) { - const struct tk *tk = prparams(l, p, NULL); + const struct tk *tk = s->tk; + const struct fn *fn = fn_cur(p); + const struct stentry *e = NULL; - if (!tk) + if (check(l, p, s, 0, &e)) return -1; + else if (e) + { + if (setret(tk, e, fn->pr)) + return -1; - return finalize(l, p); + return pop(l, p); + } + + return 0; } -static int pryy(const struct lex *l, struct prv *p) +static int s_returning(const struct lex *l, struct prv *p) { - int ret; - const struct tk *tk = prparams(l, p, &ret); + const struct fn *fn = fn_cur(p); + struct pr *pr = fn->pr; - if (!tk) + if (pr->returning) + { + errloc(p->stk, "\"returning\" for \"%s\" already set", fn->tk->s); return -1; - else if (ret) - return prret(l, tk, p); + } - return finalize(l, p); + pr->returning = 1; + return sym(p, rsym); } -static int pryn(const struct lex *l, struct prv *p) +static int using(const struct lex *l, struct prv *p) { - if (!prparams(l, p, NULL)) - return -1; + const struct fn *fn = fn_cur(p); + struct pr *pr = fn->pr; + struct pos init = + { + .name = __func__, + .seq = useqs + }; - return finalize(l, p); -} + if (pr->using) + { + errloc(p->stk, "\"using\" for \"%s\" already set", fn->tk->s); + return -1; + } -static int prny(const struct lex *l, struct prv *p) -{ - return prret(l, p->stk + 1, p); -} + if (push(&init, p)) + return -1; -static int prnn(const struct lex *l, struct prv *p) -{ - return finalize(l, p); + pr->using = 1; + return sym(p, usym); } void pr_free(struct pr *pr) @@ -338,13 +263,13 @@ void pr_free(struct pr *pr) int pr(const struct lex *l, struct prv *p) { - const struct tk *tk = p->tk - 1, *next = p->tk; + const struct tk *tk = p->stk; struct fn *fn = fn_cur(p); struct pos init = { + .name = __func__, .seq = seqs, - .stseq = seqs, - .step = seqs->steps + .end = finalize }; if (fn->pr) @@ -363,13 +288,9 @@ int pr(const struct lex *l, struct prv *p) *fn->pr = (struct pr){.tk = tk}; - /* on no parameters or return values, go directly to next sequences list. */ - if (lex_eof(l, next) - || (strcmp(next->s, "using") && strcmp(next->s, "returning"))) - return prnn(l, p); - else if (push(&init, p)) + if (push(&init, p)) return -1; p->stk = p->tk; - return 1; + return 0; } |
