commit 29465804bb9f3bc0eb0f538ec450e9177c0c4767
parent 130db985e5594204897ad28d7463e7e9b5ef94c7
Author: Louis Burda <quent.burda@gmail.com>
Date: Wed, 26 Jul 2023 19:05:46 +0200
Implement limited integer literal parsing
Diffstat:
10 files changed, 73 insertions(+), 35 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1,5 +1,5 @@
-tis-as
-tis-curses
+tis100
+tis100-curses
compile_commands.json
.cache
notes
diff --git 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);
diff --git a/test.sh b/test.sh
@@ -5,7 +5,7 @@ for f in test/*.asm; do
in="$(echo "$f" | cut -d. -f1).in"
out="$(echo "$f" | cut -d. -f1).out"
tmp="/tmp/tis-test.out"
- ./tis-as "$f" "$in" "$tmp"
+ ./tis100 "$f" "$in" "$tmp"
if [ $? -ne 0 ]; then
echo "$f"
elif ! diff "$out" "$tmp"; then
diff --git a/test/jro.asm b/test/jro.asm
@@ -0,0 +1,12 @@
+stdin X1 Y1
+stdout X1 Y1
+
+tpu X1 Y1
+ mov UP, ACC
+ jro 2
+ mov LEFT, NIL
+ mov ACC, DOWN
+ jro 300
+ jro -300
+end
+
diff --git a/test/jro.in b/test/jro.in
@@ -0,0 +1 @@
+test
diff --git a/test/jro.out b/test/jro.out
@@ -0,0 +1 @@
+test
diff --git a/tis100 b/tis100
Binary files differ.
diff --git a/tis100-curses b/tis100-curses
Binary files differ.
diff --git a/tpu.c b/tpu.c
@@ -96,7 +96,7 @@ label_map_link_pos(struct label_map *map, const char *name)
}
bool
-label_map_add(struct label_map *map, const char *name, size_t pc)
+label_map_add(struct label_map *map, const char *name, int pc)
{
struct label_map_link **pos, *link;
@@ -117,13 +117,13 @@ label_map_add(struct label_map *map, const char *name, size_t pc)
return true;
}
-size_t
+int
label_map_get(struct label_map *map, const char *name)
{
struct label_map_link **link;
link = label_map_link_pos(map, name);
- if (!*link) return TPU_MAX_INST_CNT;
+ if (!*link) return -1;
return (*link)->pc;
}
@@ -338,7 +338,7 @@ tpu_port_read(struct tpu *tpu, enum tpu_port_dir dir)
}
static bool
-tpu_port_write(struct tpu *tpu, enum tpu_port_dir dir, uint8_t lit)
+tpu_port_write(struct tpu *tpu, enum tpu_port_dir dir, int lit)
{
struct tpu_port *port;
@@ -354,11 +354,8 @@ tpu_port_write(struct tpu *tpu, enum tpu_port_dir dir, uint8_t lit)
static void
tpu_jmp_label(struct tpu *tpu, const char *label)
{
- size_t pc;
-
- pc = label_map_get(&tpu->label_map, label);
- if (pc >= TPU_MAX_INST_CNT) abort();
- tpu->pc = (uint8_t) pc;
+ tpu->pc = label_map_get(&tpu->label_map, label);
+ if (tpu->pc < 0 || tpu->pc >= tpu->inst_cnt) abort();
}
int
@@ -378,7 +375,7 @@ tpu_exec_get(struct tpu *tpu, struct tpu_inst_op *op)
v = tpu_port_read(tpu, (enum tpu_port_dir) i);
if (v >= 0) {
tpu->last = i;
- return (uint8_t) v;
+ return v;
}
}
return -1;
@@ -393,7 +390,7 @@ tpu_exec_get(struct tpu *tpu, struct tpu_inst_op *op)
}
bool
-tpu_exec_put(struct tpu *tpu, struct tpu_inst_op *op, uint8_t lit)
+tpu_exec_put(struct tpu *tpu, struct tpu_inst_op *op, int lit)
{
int i;
@@ -432,7 +429,7 @@ tpu_exec_mov(struct tpu *tpu, struct tpu_inst *inst)
lit = tpu_exec_get(tpu, &inst->ops[0]);
if (lit < 0) return STATUS_READ;
- if (!tpu_exec_put(tpu, &inst->ops[1], (uint8_t) lit))
+ if (!tpu_exec_put(tpu, &inst->ops[1], lit))
return STATUS_WRITE;
return STATUS_RUN;
@@ -467,13 +464,13 @@ tpu_exec(struct tpu *tpu, struct tpu_inst *inst)
case INST_ADD:
val = tpu_exec_get(tpu, &inst->ops[0]);
if (val < 0) return STATUS_READ;
- tpu->acc += (uint8_t) val;
+ tpu->acc = MIN(MAX(tpu->acc + val, -999), 999);
tpu->pc += 1;
return STATUS_RUN;
case INST_SUB:
val = tpu_exec_get(tpu, &inst->ops[0]);
if (val < 0) return STATUS_READ;
- tpu->acc -= (uint8_t) val;
+ tpu->acc = MIN(MAX(tpu->acc - val, -999), 999);
tpu->pc += 1;
return STATUS_RUN;
case INST_NEG:
@@ -509,7 +506,9 @@ tpu_exec(struct tpu *tpu, struct tpu_inst *inst)
return STATUS_RUN;
case INST_JRO:
tpu->pc += inst->ops[0].val.lit;
- if (tpu->pc >= tpu->inst_cnt) tpu->pc = 0;
+ if (tpu->pc < 0) tpu->pc = 0;
+ if (tpu->pc >= tpu->inst_cnt)
+ tpu->pc = (int) tpu->inst_cnt - 1;
return STATUS_RUN;
default:
abort();
diff --git a/tpu.h b/tpu.h
@@ -42,7 +42,7 @@ union tpu_inst_op_val {
struct label_map_link {
char *label;
- size_t pc;
+ int pc;
struct label_map_link *next;
};
@@ -88,7 +88,7 @@ struct tpu {
struct label_map label_map;
struct tpu_inst insts[TPU_MAX_INST_CNT];
- size_t inst_cnt, label_cnt;
+ int inst_cnt, label_cnt;
};
struct tpu_map_link {
@@ -109,8 +109,8 @@ struct tis {
void label_map_init(struct label_map *map);
void label_map_deinit(struct label_map *map);
-bool label_map_add(struct label_map *map, const char *name, size_t pc);
-size_t label_map_get(struct label_map *map, const char *name);
+bool label_map_add(struct label_map *map, const char *name, int pc);
+int label_map_get(struct label_map *map, const char *name);
void tpu_port_init(struct tpu_port *port);
void tpu_port_deinit(struct tpu_port *port);