summaryrefslogtreecommitdiffstats
path: root/asm.c
diff options
context:
space:
mode:
authorLouis Burda <quent.burda@gmail.com>2023-07-26 18:38:11 +0200
committerLouis Burda <quent.burda@gmail.com>2023-07-26 18:38:11 +0200
commit130db985e5594204897ad28d7463e7e9b5ef94c7 (patch)
treeb5c825de9374b82713b642ab423ad4e18b7fd00b /asm.c
parentd9dd10cd6a69f6da102814ebefe1d7ad2a32a020 (diff)
downloadtis100-130db985e5594204897ad28d7463e7e9b5ef94c7.tar.gz
tis100-130db985e5594204897ad28d7463e7e9b5ef94c7.zip
Restrict assembly input to fit game spec
Diffstat (limited to 'asm.c')
-rw-r--r--asm.c37
1 files changed, 28 insertions, 9 deletions
diff --git a/asm.c b/asm.c
index b8a2724..022ec5f 100644
--- a/asm.c
+++ b/asm.c
@@ -136,7 +136,7 @@ strlcat_op_name(char *buf, struct tpu_inst_op *op, size_t n)
char hhbuf[4];
if (op->type == OP_LIT) {
- snprintf(hhbuf, 4, "%hhu", op->val.lit);
+ snprintf(hhbuf, 4, "%i", op->val.lit);
return strdcat(buf, hhbuf, n);
} else if (op->type == OP_LABEL) {
return strdcat(buf, op->val.label, n);
@@ -271,7 +271,7 @@ tpu_validate(struct tpu *tpu)
&& 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)
+ if (dst == TPU_MAX_INST_CNT)
die("load: tpu X%i Y%i, label '%s' not defined",
tpu->x, tpu->y,
tpu->insts[i].ops[0].val.label);
@@ -284,7 +284,8 @@ tis_load(struct tis *tis, const char *filepath)
{
struct asm_tokenizer tokenizer;
struct tpu_inst_op op1, op2;
- enum tpu_inst_type inst;
+ enum tpu_inst_type inst_type;
+ struct tpu_inst *inst;
struct tpu *tpu = NULL;
struct tpu_map_link *link;
struct tpu_port *port;
@@ -292,7 +293,8 @@ tis_load(struct tis *tis, const char *filepath)
int stdin_x, stdin_y;
int stdout_x, stdout_y;
enum asm_tok tok, optok;
- size_t i;
+ char instbuf[TPU_MAX_INST_LEN+1];
+ size_t i, len;
tis_deinit(tis);
tis_init(tis);
@@ -352,13 +354,13 @@ tis_load(struct tis *tis, const char *filepath)
case TOK_JEZ: case TOK_JNZ: case TOK_JGZ: case TOK_JLZ:
case TOK_JRO:
if (!tpu) goto disallowed;
- inst = tok_to_inst(tok);
+ inst_type = tok_to_inst(tok);
optok = tok_next_in(&tokenizer, TOK_ACC,
TOK_NIL, TOK_LEFT, TOK_RIGHT, TOK_UP, TOK_DOWN,
TOK_ANY, TOK_LAST, TOK_LIT, TOK_NAME, TOK_NL, -1);
if (optok == TOK_NL) {
- if (!tpu_add_inst(tpu, inst, 0, op1, op2))
+ if (!tpu_add_inst(tpu, inst_type, 0, op1, op2))
die("load: line %lu, invalid instruction",
tokenizer.lineno-1);
break;
@@ -369,7 +371,7 @@ tis_load(struct tis *tis, const char *filepath)
TOK_NIL, TOK_LEFT, TOK_RIGHT, TOK_UP, TOK_DOWN,
TOK_ANY, TOK_LAST, TOK_LIT, TOK_NAME, TOK_NL, -1);
if (optok == TOK_NL) {
- if (!tpu_add_inst(tpu, inst, 1, op1, op2))
+ if (!tpu_add_inst(tpu, inst_type, 1, op1, op2))
die("load: line %lu, invalid instruction",
tokenizer.lineno-1);
break;
@@ -377,18 +379,35 @@ tis_load(struct tis *tis, const char *filepath)
op2 = tok_to_op(&tokenizer, optok);
tok_next_in(&tokenizer, TOK_NL, -1);
- if (!tpu_add_inst(tpu, inst, 2, op1, op2))
- die("load: line %lu, invalid instruction",
+
+ inst = tpu_add_inst(tpu, inst_type, 2, op1, op2);
+ if (!inst) die("load: line %lu, invalid instruction",
+ tokenizer.lineno-1);
+
+ len = asm_print_inst(instbuf, sizeof(instbuf), inst);
+ if (len >= sizeof(instbuf))
+ die("load: line %lu, inst too long",
+ tokenizer.lineno-1);
+
+ if (tpu->inst_cnt + tpu->label_cnt > TPU_MAX_INST_CNT)
+ die("load: line %lu, line does not fit",
tokenizer.lineno-1);
break;
case TOK_COMMENT:
tok_next_in(&tokenizer, TOK_NL, -1);
break;
case TOK_LABEL:
+ if (strlen(tokenizer.tokstr) > TPU_MAX_INST_LEN - 1)
+ die("load: line %lu, label too long",
+ tokenizer.lineno);
if (!label_map_add(&tpu->label_map,
tokenizer.tokstr, tpu->inst_cnt))
die("load: line %lu, duplicate label (pos)",
tokenizer.lineno);
+ tpu->label_cnt += 1;
+ if (tpu->inst_cnt + tpu->label_cnt > TPU_MAX_INST_CNT)
+ die("load: line %lu, line does not fit",
+ tokenizer.lineno);
break;
case TOK_NL:
break;