aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2024-02-20 03:10:25 +0100
committerThomas Voss <mail@thomasvoss.com> 2024-02-20 03:10:25 +0100
commit3d92d615396d8b3f1c43ad59196e40f15a87bcc8 (patch)
treede6c34bf190b02725241af5a3a5b9b9d5a34690b
parentf806f5d28593be474fc5ef864b6fcbfbe131b4d0 (diff)
Add the assume() macro
-rw-r--r--src/ahoy/emulator.c3
-rw-r--r--src/c8asm/assembler.c10
-rw-r--r--src/c8asm/parser.c19
-rw-r--r--src/common/macros.h21
4 files changed, 20 insertions, 33 deletions
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 <stddef.h>
-# 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 */