diff options
Diffstat (limited to 'src/prc1/print.c')
| -rw-r--r-- | src/prc1/print.c | 176 |
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); +} |
