harec

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

commit a4321b7134e3144f4ebf9169c3c0eaec27058f36
parent 2ff3f3a3928f52bc20b2f851975b40c43b78ec7b
Author: Drew DeVault <sir@cmpwn.com>
Date:   Fri, 25 Dec 2020 14:03:12 -0500

Implement true, false, null constants

Diffstat:
Minclude/ast.h | 1+
Minclude/expr.h | 2+-
Minclude/qbe.h | 1+
Msrc/check.c | 8++++++--
Msrc/gen.c | 22+++++++++++++++++++++-
Msrc/parse.c | 34++++++++++++++++++++++++++++++----
Msrc/qbe.c | 7+++++++
7 files changed, 67 insertions(+), 8 deletions(-)

diff --git a/include/ast.h b/include/ast.h @@ -125,6 +125,7 @@ struct ast_expression_constant { intmax_t ival; uintmax_t uval; uint32_t rune; + bool bval; struct { size_t len; char *value; diff --git a/include/expr.h b/include/expr.h @@ -94,11 +94,11 @@ struct expression_call { }; union expression_constant { - bool bval; struct { char *sval; size_t ssz; }; + bool bval; double fval; intmax_t ival; uintmax_t uval; diff --git a/include/qbe.h b/include/qbe.h @@ -217,5 +217,6 @@ void constw(struct qbe_value *val, uint32_t l); void constl(struct qbe_value *val, uint64_t l); void consts(struct qbe_value *val, float l); void constd(struct qbe_value *val, double l); +void const_void(struct qbe_value *val); #endif diff --git a/src/check.c b/src/check.c @@ -264,11 +264,15 @@ check_expr_constant(struct context *ctx, expr->constant.rune = aexpr->constant.rune; break; case TYPE_STORAGE_BOOL: + expr->constant.bval = aexpr->constant.bval; + break; + case TYPE_STORAGE_NULL: + case TYPE_STORAGE_VOID: + // No storage + break; case TYPE_STORAGE_F32: case TYPE_STORAGE_F64: case TYPE_STORAGE_STRING: - case TYPE_STORAGE_NULL: - case TYPE_STORAGE_VOID: assert(0); // TODO case TYPE_STORAGE_CHAR: case TYPE_STORAGE_ENUM: diff --git a/src/gen.c b/src/gen.c @@ -328,8 +328,28 @@ gen_constant(struct gen_context *ctx, return; } - const struct qbe_type *qtype = qtype_for_type(ctx, expr->result, false); struct qbe_value val = {0}; + + // Special cases + switch (expr->result->storage) { + case TYPE_STORAGE_BOOL: + constw(&val, expr->constant.bval ? 1 : 0); + gen_store(ctx, out, &val); + return; + case TYPE_STORAGE_VOID: + const_void(&val); + gen_store(ctx, out, &val); + return; + case TYPE_STORAGE_NULL: + constl(&val, 0); + gen_store(ctx, out, &val); + return; + default: + // Moving right along + break; + } + + const struct qbe_type *qtype = qtype_for_type(ctx, expr->result, false); switch (qtype->stype) { case Q_BYTE: case Q_HALF: diff --git a/src/parse.c b/src/parse.c @@ -429,12 +429,33 @@ parse_constant(struct parser *par) { trenter(TR_PARSE, "constant"); - struct token tok = {0}; - want(par, T_LITERAL, &tok); - struct ast_expression *exp = xcalloc(1, sizeof(struct ast_expression)); exp->type = EXPR_CONSTANT; - exp->constant.storage = tok.storage; + + struct token tok = {0}; + switch (lex(par->lex, &tok)) { + case T_TRUE: + exp->constant.storage = TYPE_STORAGE_BOOL; + exp->constant.bval = true; + return exp; + case T_FALSE: + exp->constant.storage = TYPE_STORAGE_BOOL; + exp->constant.bval = false; + return exp; + case T_NULL: + exp->constant.storage = TYPE_STORAGE_NULL; + return exp; + case T_VOID: + exp->constant.storage = TYPE_STORAGE_VOID; + return exp; + case T_LITERAL: + exp->constant.storage = tok.storage; + break; + default: + synassert(false, &tok, T_LITERAL, T_TRUE, + T_FALSE, T_NULL, T_VOID, T_EOF); + break; + } switch (tok.storage) { case TYPE_STORAGE_CHAR: @@ -464,6 +485,7 @@ parse_constant(struct parser *par) default: assert(0); // TODO } + trleave(TR_PARSE, "%s", token_str(&tok)); return exp; } @@ -476,6 +498,10 @@ parse_plain_expression(struct parser *par) struct token tok; switch (lex(par->lex, &tok)) { case T_LITERAL: + case T_TRUE: + case T_FALSE: + case T_NULL: + case T_VOID: unlex(par->lex, &tok); return parse_constant(par); case T_NAME: diff --git a/src/qbe.c b/src/qbe.c @@ -294,3 +294,10 @@ constd(struct qbe_value *val, double d) val->type = &qbe_double; val->dval = d; } + +void +const_void(struct qbe_value *val) +{ + val->kind = QV_CONST; + val->type = &qbe_void; +}