From 3d92d615396d8b3f1c43ad59196e40f15a87bcc8 Mon Sep 17 00:00:00 2001 From: Thomas Voss Date: Tue, 20 Feb 2024 03:10:25 +0100 Subject: Add the assume() macro --- src/ahoy/emulator.c | 3 --- src/c8asm/assembler.c | 10 +++------- src/c8asm/parser.c | 19 +++++++++---------- src/common/macros.h | 21 ++++++++------------- 4 files changed, 20 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/ahoy/emulator.c b/src/ahoy/emulator.c index 8ecdc1b..c805fcd 100644 --- a/src/ahoy/emulator.c +++ b/src/ahoy/emulator.c @@ -314,9 +314,6 @@ opexec(uint16_t op) break; } - - default: - unreachable(); } } diff --git a/src/c8asm/assembler.c b/src/c8asm/assembler.c index ffa9025..daafc11 100644 --- a/src/c8asm/assembler.c +++ b/src/c8asm/assembler.c @@ -77,23 +77,21 @@ assemble(FILE *stream, struct ast ast) bool pad = false; da_foreach (&ast, node) { + assume(node->kind == D_LABEL || node->kind == D_INSTR); if (node->kind == D_LABEL) { struct label lbl = { .addr = i, .sv = node->name, }; pushlabel(node->name.p[0] == '.' ? &locals : &globals, lbl); - } else if (node->kind == D_INSTR) + } else i += node->instr.kind == I_DB ? node->instr.len : 2; - else - unreachable(); } da_foreach (&ast, node) { if (node->kind == D_LABEL) continue; - if (node->kind != D_INSTR) - unreachable(); + assume(node->kind == D_INSTR); /* Instructions need to be 0-padded so they appear on an even byte boundary. */ @@ -229,8 +227,6 @@ assemble(FILE *stream, struct ast ast) PUT(0x8003 | (node->instr.args[0].val << 8) | node->instr.args[1].val << 4); break; - default: - unreachable(); } } diff --git a/src/c8asm/parser.c b/src/c8asm/parser.c index 208511d..01e13ae 100644 --- a/src/c8asm/parser.c +++ b/src/c8asm/parser.c @@ -119,14 +119,12 @@ parseop(void) struct raw_addr parseaddr(struct token tok) { + assume(tok.kind & (T_NUMBER | T_IDENT)); if (tok.kind == T_NUMBER) return (struct raw_addr){.val = parsenum(tok, NS_ADDR)}; - if (tok.kind == T_IDENT) { - if (regtype(tok.sv) != RT_NONE) - DIE_AT_POS_WITH_CODE(tok.sv, tok.sv.p, E_BADLABEL); - return (struct raw_addr){.label = true, .sv = tok.sv}; - } - unreachable(); + if (regtype(tok.sv) != RT_NONE) + DIE_AT_POS_WITH_CODE(tok.sv, tok.sv.p, E_BADLABEL); + return (struct raw_addr){.label = true, .sv = tok.sv}; } enum regtype @@ -150,6 +148,7 @@ regtype(struct u8view v) uint16_t hexval(char ch) { + assume((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f')); return ch >= '0' && ch <= '9' ? ch - '0' : ch >= 'a' && ch <= 'f' ? ch - 'a' + 10 : (unreachable(), 0); @@ -173,6 +172,9 @@ parsenum(struct token tok, enum numsize size) } for (ch = *v.p; v.len; v.p++, v.len--, ch = *v.p) { + assume((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') + || (ch >= 'A' && ch <= 'F') || ch == '\''); + if (ch == '\'') continue; else if (ch >= '0' && ch <= '9') @@ -181,8 +183,6 @@ parsenum(struct token tok, enum numsize size) ch -= 'a' - 10; else if (ch >= 'A' && ch <= 'F') ch -= 'A' - 10; - else - unreachable(); if (acc > cutoff || (acc == cutoff && ch > cutlim)) { const char *s = size == NS_NIBBLE ? "nibble" @@ -386,8 +386,7 @@ parseop_jp(void) "v0-register or address", tokrepr(op.kind)); } ins.args[ins.len++] = parseaddr(reqnext("address", T_NUMBER | T_IDENT)); - } else - unreachable(); + } dapush(&ast, I(ins)); } diff --git a/src/common/macros.h b/src/common/macros.h index 6daf08f..3735af6 100644 --- a/src/common/macros.h +++ b/src/common/macros.h @@ -9,19 +9,14 @@ #define streq(x, y) (!strcmp(x, y)) #define u8eq(x, y) (!u8cmp(x, y)) -#if DEBUG || !defined(unreachable) -# if DEBUG -# include "cerr.h" -# ifdef unreachable -# undef unreachable -# endif -# define unreachable() \ - diex("%s:%d: hit unreachable in %s()", __FILE__, __LINE__, __func__) -# elifdef __clang__ -# define unreachable() __builtin_unreachable() -# else -# include -# endif +#if DEBUG +# include "cerr.h" +# define assume(C) \ + ((C) ? (void)0 \ + : diex("%s:%d: %s(): assumption ā€˜%sā€™ failed", __FILE__, __LINE__, \ + __func__, #C)) +#else +# define assume(C) ((C) ? (void)0 : unreachable()) #endif #endif /* !AHOY_COMMON_MACROS_H */ -- cgit v1.2.3