aboutsummaryrefslogtreecommitdiff
path: root/src/prc1/print.c
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi92@disroot.org>2026-10-01 01:04:30 +0200
committerXavier Del Campo Romero <xavi92@disroot.org>2026-10-05 00:38:49 +0200
commit2b0d4ead061a39da9dbd705c18c9955549c4d405 (patch)
tree1412ac39adce3428b96caf67b1e7543f6c1246a5 /src/prc1/print.c
parent9140988be4e5bb028b7140aca1a67af1370c72a7 (diff)
downloadprc-2b0d4ead061a39da9dbd705c18c9955549c4d405.tar.gz
WIP symsym
Diffstat (limited to 'src/prc1/print.c')
-rw-r--r--src/prc1/print.c176
1 files changed, 146 insertions, 30 deletions
diff --git a/src/prc1/print.c b/src/prc1/print.c
index abdb149..e257b8b 100644
--- a/src/prc1/print.c
+++ b/src/prc1/print.c
@@ -1,14 +1,16 @@
#include "print.h"
+#include "dbg.h"
#include "errloc.h"
#include "fn.h"
#include "lit.h"
#include "parse.h"
#include "prv.h"
#include "stmt.h"
-#include "storage.h"
+#include "sym.h"
#include "type.h"
#include <stdlib.h>
-#include <string.h>
+
+#if 0
static int entry(const struct lex *l, const struct tk *tk, struct print *pr,
struct prv *p)
@@ -58,46 +60,160 @@ static int entry(const struct lex *l, const struct tk *tk, struct print *pr,
return 0;
}
+#endif
-void print_free(struct print *pr)
+static int etc(const struct lex *, struct prv *);
+
+static const struct seq seqs[] =
{
- free(pr->entries);
-}
+ {(struct step[]){{ID, "etc"}, {0}}, .fn = etc},
+ {0}
+};
-int print(const struct lex *l, struct prv *p,
- int (*fn)(const struct lex *, const struct prv *, const struct print *))
+static const struct sym *inner(const struct sym *s)
{
- const struct tk *tk = p->stk + 1;
- struct print pr = {0};
- struct pos *pos = &p->pos[p->i];
- int eof;
+ for (; s; s = s->child)
+ if (!s->child)
+ break;
- if (lex_eof(l, tk))
+ return s;
+}
+
+static int fill(struct prv *p, const struct sym *s, struct prisym *ps)
+{
+ switch (s->type)
{
- errloc(tk - 1, "incomplete %s statement", p->stk->s);
+ case SYM_LIT:
+ if (!(ps->u.lit = lit_push(s->tk, p)))
+ return -1;
+
+ ps->type = PRS_LIT;
+ break;
+
+ case SYM_ID:
+ case SYM_TMP:
+ case SYM_NUM:
+ fprintf(stderr, "%s: TODO\n", __func__);
+ return -1;
+
+ case SYM_CAST:
+ case SYM_ADDR:
+ case SYM_SZ:
+ case SYM_CNT:
+ case SYM_OFF:
+ fprintf(stderr, "%s: unreachable\n", __func__);
return -1;
}
- for (;;)
- if (entry(l, tk, &pr, p))
- goto failure;
- else if ((eof = lex_eof(l, ++tk)) || kw(tk->s))
- break;
+ return 0;
+}
- if (eof || strcmp(tk->s, "etc"))
- pr.println = 1;
- else if (!eof)
- tk++;
+static int onsym(const struct lex *l, struct prv *p, const struct sym *s)
+{
+ struct stmt *stmt = stmt_cur(p);
+ struct print *pr = &stmt->u.print;
+ size_t n = pr->nsyms + 1;
+ struct prisym *syms, *nsym;
- if (fn(l, p, &pr))
- goto failure;
+ if (!(syms = realloc(pr->syms, n * sizeof *syms)))
+ {
+ perror("realloc(3)");
+ return -1;
+ }
- pos->seq = pos->stseq = stmts;
- pos->step = stmts->steps;
- p->stk = tk;
- return 1;
+ pr->syms = syms;
+ nsym = &syms[pr->nsyms++];
+ *nsym = (struct prisym){.s = s};
+ return fill(p, inner(s), nsym);
+}
-failure:
- print_free(&pr);
+static int cg_str(const struct prisym *s, const char *f)
+{
+ fprintf(stderr, "%s: TODO\n", __func__);
+ return -1;
+}
+
+static int cg_ptr(const struct prisym *s, const char *f)
+{
+ fprintf(stderr, "%s: TODO\n", __func__);
return -1;
}
+
+static int cg_num(const struct prisym *s, const char *f)
+{
+ fprintf(stderr, "%s: TODO\n", __func__);
+ return -1;
+}
+
+static int cg_lit(const struct prisym *s, const char *f)
+{
+ const struct lit *l = s->u.lit;
+ const char *tmp;
+
+ if (!l)
+ {
+ fprintf(stderr, "%s: unexpected null literal\n", __func__);
+ return -1;
+ }
+
+ /* TODO: ask target for sizeof (void *) */
+ tmp = cgen_tmp(sizeof (void *));
+ printf("%%%s =l loadl $%s\n", tmp, f);
+ printf("call $fputs(l $%s, w %%%s)\n", l->name, tmp);
+ return 0;
+}
+
+int print_cgen(const struct print *pr, struct cgen *c, const char *f)
+{
+ for (size_t i = 0; i < pr->nsyms; i++)
+ {
+ const struct prisym *ps = &pr->syms[i];
+ static int (*fn[])(const struct prisym *, const char *) =
+ {
+ [PRS_LIT] = cg_lit,
+ [PRS_STR] = cg_str,
+ [PRS_PTR] = cg_ptr,
+ [PRS_NUM] = cg_num
+ };
+
+ if (fn[ps->type](ps, f))
+ return -1;
+ }
+
+ if (!pr->skipln)
+ {
+ printf("%%v =l loadl $%s\n", f);
+ puts("call $fputc(l 10 , w %v)");
+ }
+
+ return 0;
+}
+
+static int etc(const struct lex *l, struct prv *p)
+{
+ struct stmt *stmt = stmt_cur(p);
+ struct print *pr = &stmt->u.print;
+
+ pr->skipln = 1;
+ reset(p);
+ return 0;
+}
+
+void print_free(struct print *pr)
+{
+ free(pr->syms);
+}
+
+int print(const struct lex *l, struct prv *p)
+{
+ struct pos init =
+ {
+ .name = __func__,
+ .seq = seqs
+ };
+
+ if (push(&init, p))
+ return -1;
+
+ return sym(p, onsym);
+}