aboutsummaryrefslogtreecommitdiff
path: root/pr.c
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi92@disroot.org>2026-09-05 17:14:53 +0200
committerXavier Del Campo Romero <xavi92@disroot.org>2026-09-26 03:41:55 +0200
commit3c0819236e4f07c8f57aaf1ca46d0d68aa761558 (patch)
treebd8b57cf5420cabc4ec29815052df545b55026f9 /pr.c
parenta3f56c76444fee090e62a59f257ed5f60b4e552b (diff)
downloadprc-3c0819236e4f07c8f57aaf1ca46d0d68aa761558.tar.gz
Move source to src/prc1
Diffstat (limited to 'pr.c')
-rw-r--r--pr.c375
1 files changed, 0 insertions, 375 deletions
diff --git a/pr.c b/pr.c
deleted file mode 100644
index a171554..0000000
--- a/pr.c
+++ /dev/null
@@ -1,375 +0,0 @@
-#include "pr.h"
-#include "errloc.h"
-#include "fn.h"
-#include "prv.h"
-#include "parse.h"
-#include "stmt.h"
-#include "storage.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 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
- },
-
- {0}
-};
-
-static const struct tk *findparam(const char *s, const struct pr *pr)
-{
- for (size_t i = 0; i < pr->nparams; i++)
- {
- const struct param *p = &pr->params[i];
- const struct tk *tk = p->tk;
-
- if (!strcmp(tk->s, s))
- return tk;
- }
-
- return NULL;
-}
-
-static int param(const struct tk *tk, const struct stentry *e, struct pr *pr)
-{
- size_t n = pr->nparams + 1;
- struct param *params = realloc(pr->params, n * sizeof *params);
-
- if (!params)
- {
- perror("realloc(3)");
- return -1;
- }
-
- pr->params = params;
- pr->params[pr->nparams++] = (struct param){.tk = tk, .entry = e};
- return 0;
-}
-
-static int setret(const struct tk *tk, const struct stentry *e, struct pr *pr)
-{
- if (!(pr->ret = malloc(sizeof *pr->ret)))
- {
- perror("malloc(3)");
- return -1;
- }
-
- *pr->ret = (struct param){.tk = tk, .entry = e};
- return 0;
-}
-
-static int finalize(const struct lex *l, struct prv *p)
-{
- const struct fn *fn = fn_cur(p);
- const struct pr *pr = fn->pr;
- struct pos init =
- {
- .seq = stmts,
- .stseq = stmts,
- .step = stmts->steps
- };
-
- if (p->proto)
- {
- if (pop(l, p))
- return -1;
-
- fputc('\t', stderr);
- }
- else if (push(&init, p))
- return -1;
-
- fprintf(stderr, "\tadding procedure using %zu%s parameters "
- "and%s return value\n", pr->nparams, pr->variadic ? " variadic" : "",
- pr->ret ? "" : " no");
- p->stk = p->tk;
- return 1;
-}
-
-static int prret(const struct lex *l, const struct tk *tk, struct prv *p)
-{
- 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 stentry *e, *gle;
- const struct tk *prm;
-
- if (!lk || !(e = storage_find(s, lk)))
- {
- errloc(tk, "return value \"%s\" not in %s", s, tk->s);
- return -1;
- }
- else if (gl && (gle = storage_find(s, gl)))
- {
- 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;
- }
- else if ((prm = findparam(s, pr)))
- {
- 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 (setret(tk, e, pr))
- return -1;
-
- return finalize(l, p);
-}
-
-static const struct tk *prparams(const struct lex *l, struct prv *p, int *ret)
-{
- const struct tk *tk = p->stk + 1;
- const struct fn *fn = fn_cur(p);
- struct pr *pr = fn->pr;
-
- if (ret)
- *ret = 0;
-
- 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++;
- }
-
- return tk;
-}
-
-static int prey(const struct lex *l, struct prv *p)
-{
- int ret;
- const struct tk *tk = prparams(l, p, &ret);
-
- if (!tk)
- return -1;
- else if (ret)
- return prret(l, tk, p);
-
- return finalize(l, p);
-}
-
-static int pren(const struct lex *l, struct prv *p)
-{
- const struct tk *tk = prparams(l, p, NULL);
-
- if (!tk)
- return -1;
-
- return finalize(l, p);
-}
-
-static int pryy(const struct lex *l, struct prv *p)
-{
- int ret;
- const struct tk *tk = prparams(l, p, &ret);
-
- if (!tk)
- return -1;
- else if (ret)
- return prret(l, tk, p);
-
- return finalize(l, p);
-}
-
-static int pryn(const struct lex *l, struct prv *p)
-{
- if (!prparams(l, p, NULL))
- return -1;
-
- return finalize(l, p);
-}
-
-static int prny(const struct lex *l, struct prv *p)
-{
- return prret(l, p->stk + 1, p);
-}
-
-static int prnn(const struct lex *l, struct prv *p)
-{
- return finalize(l, p);
-}
-
-void pr_free(struct pr *pr)
-{
- if (pr)
- {
- free(pr->params);
- free(pr->ret);
- }
-
- free(pr);
-}
-
-int pr(const struct lex *l, struct prv *p)
-{
- const struct tk *tk = p->tk - 1, *next = p->tk;
- struct fn *fn = fn_cur(p);
- struct pos init =
- {
- .seq = seqs,
- .stseq = seqs,
- .step = seqs->steps
- };
-
- if (fn->pr)
- {
- const struct loc *loc = &fn->pr->tk->loc;
-
- errloc(tk, "procedure already defined at %s:%d:%d", loc->f, loc->line,
- loc->col);
- return -1;
- }
- else if (!(fn->pr = malloc(sizeof *fn->pr)))
- {
- perror("malloc(3)");
- return -1;
- }
-
- *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))
- return -1;
-
- p->stk = p->tk;
- return 1;
-}