summaryrefslogtreecommitdiffstats
path: root/asm.c
diff options
context:
space:
mode:
authorLouis Burda <quent.burda@gmail.com>2023-07-26 19:05:46 +0200
committerLouis Burda <quent.burda@gmail.com>2023-07-26 19:07:22 +0200
commit29465804bb9f3bc0eb0f538ec450e9177c0c4767 (patch)
tree25c48b99b944c1b8cfa166023643c9206126c8d7 /asm.c
parent130db985e5594204897ad28d7463e7e9b5ef94c7 (diff)
downloadtis100-29465804bb9f3bc0eb0f538ec450e9177c0c4767.tar.gz
tis100-29465804bb9f3bc0eb0f538ec450e9177c0c4767.zip
Implement limited integer literal parsing
Diffstat (limited to 'asm.c')
-rw-r--r--asm.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/asm.c b/asm.c
index 022ec5f..5200ffc 100644
--- a/asm.c
+++ b/asm.c
@@ -2,6 +2,7 @@
#include "util.h"
#include "tpu.h"
+#include <ctype.h>
#include <stdarg.h>
#include <stdbool.h>
#include <string.h>
@@ -72,13 +73,13 @@ static const char *tok_reprs[] = {
static bool
is_lit(const char *str)
{
- unsigned long v;
- char *end;
-
- v = strtoul(str, &end, 10);
- if (!end || *end) return false;
+ const char *c;
- return v < 256;
+ c = str;
+ if (*c == '-') c++;
+ else if (*c == '+') c++;
+ for (; *c && isdigit(*c); c++);
+ return !*c;
}
static bool
@@ -94,10 +95,35 @@ is_int(const char *str)
return true;
}
-static uint8_t
+static int
str_to_lit(const char *str)
{
- return (uint8_t) atoi(str);
+ int m, v, b, i, o;
+
+ if (*str == '-') {
+ m = -1;
+ o = 1;
+ } else if (*str == '+') {
+ m = 1;
+ o = 1;
+ } else {
+ m = 1;
+ o = 0;
+ }
+
+ for (b = 1, i = o; str[i]; i++)
+ b *= 10;
+
+ if (i >= 4 + o) {
+ v = 1000;
+ } else {
+ for (v = 0, i = o; str[i]; i++) {
+ b /= 10;
+ v += b * (str[i] - '0');
+ }
+ }
+
+ return MIN(MAX(m * v, -999), 999);
}
enum tpu_inst_type
@@ -133,10 +159,10 @@ tok_to_op(struct asm_tokenizer *tokenizer, enum asm_tok tok)
static size_t
strlcat_op_name(char *buf, struct tpu_inst_op *op, size_t n)
{
- char hhbuf[4];
+ char hhbuf[5];
if (op->type == OP_LIT) {
- snprintf(hhbuf, 4, "%i", op->val.lit);
+ snprintf(hhbuf, 5, "%i", op->val.lit);
return strdcat(buf, hhbuf, n);
} else if (op->type == OP_LABEL) {
return strdcat(buf, op->val.label, n);
@@ -263,15 +289,14 @@ tok_next_in(struct asm_tokenizer *tokenizer, ...)
static void
tpu_validate(struct tpu *tpu)
{
- size_t dst;
- int i;
+ int dst, i;
for (i = 0; i < tpu->inst_cnt; i++) {
if (tpu->insts[i].opcnt >= 1
&& tpu->insts[i].ops[0].type == OP_LABEL) {
dst = label_map_get(&tpu->label_map,
tpu->insts[i].ops[0].val.label);
- if (dst == TPU_MAX_INST_CNT)
+ if (dst < 0)
die("load: tpu X%i Y%i, label '%s' not defined",
tpu->x, tpu->y,
tpu->insts[i].ops[0].val.label);