harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 1b18c38423bcaf53678fa69f41a3d27c2cde9174
parent 5acb5c6f08f6ebfe939b1028d647ec7611d26a04
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sun, 20 Dec 2020 15:05:33 -0500

gen: implement expression lists

Diffstat:
Minclude/qbe.h | 3+++
Msrc/check.c | 1+
Msrc/emit.c | 3+++
Msrc/gen.c | 29+++++++++++++++++++++++++++++
Msrc/qbe.c | 8++++++++
5 files changed, 44 insertions(+), 0 deletions(-)

diff --git a/include/qbe.h b/include/qbe.h @@ -141,6 +141,7 @@ enum qbe_instr { extern const char *qbe_instr[Q_LAST_INSTR]; enum qbe_statement_type { + Q_COMMENT, Q_INSTR, Q_LABEL, }; @@ -159,6 +160,7 @@ struct qbe_statement { struct qbe_arguments *args; }; char *label; + char *comment; }; }; @@ -195,6 +197,7 @@ void geni(struct qbe_statement *stmt, enum qbe_instr instr, const struct qbe_val const char *genl(struct qbe_statement *stmt, uint64_t *id, const char *fmt); void pushi(struct qbe_func *func, enum qbe_instr instr, const struct qbe_value *out, ...); const char *pushl(struct qbe_func *func, uint64_t *id, const char *fmt); +void pushc(struct qbe_func *func, const char *text); void constw(struct qbe_value *val, uint32_t l); void constl(struct qbe_value *val, uint64_t l); diff --git a/src/check.c b/src/check.c @@ -93,6 +93,7 @@ check_expr_list(struct context *ctx, while (alist) { struct expression *lexpr = calloc(1, sizeof(struct expression)); check_expression(ctx, alist->expr, lexpr); + list->expr = lexpr; alist = alist->next; if (alist) { diff --git a/src/emit.c b/src/emit.c @@ -67,6 +67,9 @@ static void emit_stmt(struct qbe_statement *stmt, FILE *out) { switch (stmt->type) { + case Q_COMMENT: + fprintf(out, "\t# %s\n", stmt->comment); + break; case Q_INSTR: fprintf(out, "\t"); if (stmt->out != NULL) { diff --git a/src/gen.c b/src/gen.c @@ -90,11 +90,19 @@ gen_loadtemp(struct gen_context *ctx, gen_load(ctx, dest, src, is_signed); } +static void gen_expression(struct gen_context *ctx, + const struct expression *expr, struct qbe_value *out); + static void gen_constant(struct gen_context *ctx, const struct expression *expr, struct qbe_value *out) { + if (out == NULL) { + pushc(ctx->current, "useless constant expression discarded"); + return; + } + const struct qbe_type *qtype = qtype_for_type(ctx, expr->result, false); struct qbe_value val = {0}; switch (qtype->stype) { @@ -117,10 +125,28 @@ gen_constant(struct gen_context *ctx, case Q__VOID: assert(0); // Invariant } + gen_store(ctx, out, &val); } static void +gen_expr_list(struct gen_context *ctx, + const struct expression *expr, + struct qbe_value *out) +{ + const struct expression_list *list = &expr->list; + while (list) { + struct qbe_value *dest = NULL; + if (!list->next) { + // Last value determines expression result + dest = out; + } + gen_expression(ctx, list->expr, dest); + list = list->next; + } +} + +static void gen_expression(struct gen_context *ctx, const struct expression *expr, struct qbe_value *out) @@ -143,7 +169,10 @@ gen_expression(struct gen_context *ctx, case EXPR_FUNC: case EXPR_IF: case EXPR_INDEX: + assert(0); // TODO case EXPR_LIST: + gen_expr_list(ctx, expr, out); + break; case EXPR_MATCH: case EXPR_MEASURE: case EXPR_SLICE: diff --git a/src/qbe.c b/src/qbe.c @@ -239,6 +239,14 @@ pushl(struct qbe_func *func, uint64_t *id, const char *fmt) } void +pushc(struct qbe_func *func, const char *text) +{ + struct qbe_statement stmt = {0}; + stmt.comment = strdup(text); + push(func, &stmt); +} + +void constw(struct qbe_value *val, uint32_t w) { val->kind = QV_CONST;