summaryrefslogtreecommitdiffstats
path: root/tis-as.c
diff options
context:
space:
mode:
Diffstat (limited to 'tis-as.c')
-rw-r--r--tis-as.c143
1 files changed, 94 insertions, 49 deletions
diff --git a/tis-as.c b/tis-as.c
index fb0fc49..8077442 100644
--- a/tis-as.c
+++ b/tis-as.c
@@ -25,8 +25,7 @@ enum tok {
TOK_NEG, TOK_JMP, TOK_JEZ, TOK_JNZ, TOK_JGZ, TOK_JLZ, TOK_JRO,
/* Misc */
- TOK_COMMENT, TOK_LABEL, TOK_XPOS, TOK_YPOS,
- TOK_SEP, TOK_NL, TOK_EOF
+ TOK_COMMENT, TOK_LABEL, TOK_XPOS, TOK_YPOS, TOK_NL, TOK_EOF
};
struct tokenizer {
@@ -46,20 +45,28 @@ static struct tpu_port stdout_port;
static struct tpu_map tpu_map;
+static const char *dir_names[] = {
+ "LEFT", "RIGHT", "UP", "DOWN"
+};
+
+static const char *status_names[] = {
+ "IDLE", "RUN", "READ", "WRITE"
+};
+
static const char *tok_reprs[] = {
/* Global */
"'STDIN'", "'STDOUT'", "'TPU'", "'END'",
- /* Operands */
- "'ACC'", "'BAK'", "'NIL'", "'LEFT'", "'RIGHT'", "'UP'",
- "'DOWN'", "'ANY'", "'LAST'", "<LIT>", "<NAME>",
+ /* Operands (order like OP_*) */
+ "'ACC'", "'BAK'", "'NIL'", "'LEFT'", "'RIGHT'",
+ "'UP'", "'DOWN'", "'ANY'", "'LAST'", "<LIT>", "<NAME>",
- /* Instructions */
+ /* Instructions (order like INST_*) */
"'NOP'", "'MOV'", "'SWP'", "'SAV'", "'ADD'", "'SUB'",
"'NEG'", "'JMP'", "'JEZ'", "'JNZ'", "'JGZ'", "'JLZ'", "'JRO'",
/* Misc */
- "#<COMMENT>", "<LABEL>:", "X<INT>", "Y<INT>", "','", "<NL>", "<EOF>"
+ "#<COMMENT>", "<LABEL>:", "X<INT>", "Y<INT>", "<NL>", "<EOF>"
};
const char *progname = "tis-as";
@@ -106,26 +113,38 @@ tok_next(struct tokenizer *tok)
if (feof(tok->file)) return TOK_EOF;
s = fgets(tok->linebuf, sizeof(tok->linebuf), tok->file);
if (!s && !feof(tok->file)) die("fgets:");
- if (!s) return TOK_EOF;
- if (*s && s[strlen(s)-1] != '\n')
+ if (!s) return TOK_NL;
+
+ len = strlen(s);
+ if (len && s[len-1] != '\n' && !feof(tok->file))
die("load: line %lu too long", tok->lineno);
+ if (len && s[len-1] == '\n') s[len-1] = '\0';
+
+ tok->lineno += 1;
+ tok->tokstr = s;
tok->off = 0;
+ return TOK_NL;
}
s = tok->linebuf + tok->off;
len = strspn(s, WHITESPACE);
tok->off += len;
s += len;
+ tok->tokstr = s;
+ if (!*s) return TOK_NL;
- len = strcspn(s, WHITESPACE);
- s[len] = '\0';
+ len = strcspn(s, WHITESPACE ",");
tok->off += len;
- if (!len) return TOK_NL;
+ printf("> %s\n", s);
+ if (s[len]) {
+ s[len] = '\0';
+ tok->off += 1;
+ }
if (!strcasecmp(s, "stdin")) {
return TOK_STDIN;
} else if (!strcasecmp(s, "stdout")) {
- return TOK_STDIN;
+ return TOK_STDOUT;
} else if (!strcasecmp(s, "tpu")) {
return TOK_TPU;
} else if (!strcasecmp(s, "end")) {
@@ -150,8 +169,6 @@ tok_next(struct tokenizer *tok)
return TOK_LAST;
} else if (is_lit(s)) {
return TOK_LIT;
- } else if (strspn(s, NAMEALPH) == strlen(s)) {
- return TOK_NAME;
} else if (!strcasecmp(s, "nop")) {
return TOK_NOP;
} else if (!strcasecmp(s, "mov")) {
@@ -179,7 +196,7 @@ tok_next(struct tokenizer *tok)
} else if (!strcasecmp(s, "jro")) {
return TOK_JRO;
} else if (*s == '#') {
- tok->off = strlen(s);
+ tok->off += strlen(tok->linebuf + tok->off);
return TOK_COMMENT;
} else if (len && strspn(s, NAMEALPH) == len-1 && s[len-1] == ':') {
return TOK_LABEL;
@@ -187,6 +204,8 @@ tok_next(struct tokenizer *tok)
return TOK_XPOS;
} else if (*s == 'Y' && atoi(s+1) > 0) {
return TOK_YPOS;
+ } else if (strspn(s, NAMEALPH) == strlen(s)) {
+ return TOK_NAME;
} else {
die("load: line %lu, invalid token '%s'", tok->lineno, s);
}
@@ -211,9 +230,8 @@ tok_next_in(struct tokenizer *tokenizer, ...)
va_end(cpy);
fprintf(stderr, "tis-as: load: ");
- fprintf(stderr, "line %lu, got tok '%s', expected one of ",
+ fprintf(stderr, "line %lu, got tok %s, expected one of (",
tokenizer->lineno, tok_reprs[tok]);
-
first = true;
va_start(ap, tokenizer);
while ((arg = va_arg(ap, int)) > 0) {
@@ -222,8 +240,8 @@ tok_next_in(struct tokenizer *tokenizer, ...)
first = false;
}
va_end(ap);
+ fputs(")\n", stderr);
- fprintf(stderr, "\n");
exit(1);
}
@@ -246,7 +264,7 @@ load(const char *fname)
file = fopen(fname, "r");
if (!file) die("fopen:");
- tokenizer.lineno = 1;
+ tokenizer.lineno = 0;
tokenizer.file = file;
tokenizer.off = 0;
tokenizer.tokstr = NULL;
@@ -284,6 +302,7 @@ load(const char *fname)
case TOK_END:
if (!tpu) goto disallowed;
tpu = NULL;
+ tok_next_in(&tokenizer, TOK_NL, -1);
break;
case TOK_NOP: case TOK_MOV: case TOK_SWP: case TOK_SAV:
case TOK_ADD: case TOK_SUB: case TOK_NEG: case TOK_JMP:
@@ -292,11 +311,10 @@ load(const char *fname)
if (!tpu) goto disallowed;
inst = tok_to_inst(tok);
- op1_tok = tok_next_in(&tokenizer, TOK_ACC,
- TOK_BAK, TOK_UP, TOK_DOWN,
- TOK_LEFT, TOK_RIGHT, TOK_NL, -1);
+ op1_tok = tok_next_in(&tokenizer, TOK_ACC, TOK_BAK,
+ TOK_NIL, TOK_LEFT, TOK_RIGHT, TOK_UP, TOK_DOWN,
+ TOK_ANY, TOK_LAST, TOK_LIT, TOK_NAME, TOK_NL, -1);
if (op1_tok == TOK_NL) {
- tok_next_in(&tokenizer, TOK_NL, -1);
tpu_add_inst(tpu, inst, -1, 0, -1, 0);
break;
}
@@ -305,13 +323,12 @@ load(const char *fname)
if (op1 == OP_LIT)
op1_lit = str2lit(tokenizer.tokstr);
- op2_tok = tok_next_in(&tokenizer, TOK_ACC,
- TOK_BAK, TOK_UP, TOK_DOWN,
- TOK_LEFT, TOK_RIGHT, TOK_NL, -1);
+ op2_tok = tok_next_in(&tokenizer, TOK_ACC, TOK_BAK,
+ TOK_NIL, TOK_LEFT, TOK_RIGHT, TOK_UP, TOK_DOWN,
+ TOK_ANY, TOK_LAST, TOK_LIT, TOK_NAME, TOK_NL, -1);
if (op2_tok == TOK_NL) {
- tok_next_in(&tokenizer, TOK_NL, -1);
- tpu_add_inst(tpu, inst,
- (int) op1, op1_lit, -1, 0);
+ tpu_add_inst(tpu, inst, (int) op1,
+ op1_lit, -1, 0);
break;
}
@@ -332,6 +349,8 @@ load(const char *fname)
tokenizer.lineno);
tok_next_in(&tokenizer, TOK_NL, -1);
break;
+ case TOK_NL:
+ break;
default:
goto disallowed;
}
@@ -356,14 +375,14 @@ load(const char *fname)
stdin_port.dst_port = port;
}
- if (link->x == stdout_x && link->y == stdout_x) {
+ if (link->x == stdout_x && link->y == stdout_y) {
port = &link->tpu->ports[DIR_DOWN];
if (port->attached)
die("load: stdout port in use");
port->attached = true;
port->dst_tpu = NULL;
port->dst_port = &stdout_port;
- stdout_port.dst_port = port;
+ stdout_port.attached = true;
stdout_port.dst_tpu = NULL;
stdout_port.dst_port = port;
}
@@ -375,34 +394,59 @@ load(const char *fname)
fclose(file);
+ return;
+
disallowed:
- die("load: line %lu, token %s not allowed here",
- tokenizer.lineno, tok_reprs[tok]);
+ if (tok == TOK_NAME) {
+ die("load: line %lu, unexpected token '%s'",
+ tokenizer.lineno, tokenizer.tokstr);
+ } else {
+ die("load: line %lu, token %s not allowed here",
+ tokenizer.lineno, tok_reprs[tok]);
+ }
}
void
run(void)
{
struct tpu_map_link *link;
- struct tpu_inst *inst;
- size_t i, pc;
+ size_t i, k;
+ int c;
+
+ stdin_port.out = -1;
+ stdout_port.reading = true;
+ while (1) {
+ if (stdin_port.dst_port->reading) {
+ c = getchar();
+ if (c < 0) break;
+ stdin_port.out = c;
+ }
- /* initial pass to propagate moves */
- for (i = 0; i < TPU_MAP_BUCKETS; i++) {
- for (link = tpu_map.buckets[i]; link; link = link->next) {
- inst = tpu_current_inst(link->tpu);
- if (inst && inst->type == INST_MOV) {
- pc = link->tpu->pc;
- tpu_exec(link->tpu, inst);
- link->tpu->pc = pc;
+ printf("===\n");
+
+ for (i = 0; i < TPU_MAP_BUCKETS; i++) {
+ for (link = tpu_map.buckets[i]; link; link = link->next) {
+ tpu_step(link->tpu);
}
}
- }
- for (i = 0; i < TPU_MAP_BUCKETS; i++) {
- for (link = tpu_map.buckets[i]; link; link = link->next) {
- inst = tpu_current_inst(link->tpu);
- tpu_step(link->tpu);
+ for (i = 0; i < TPU_MAP_BUCKETS; i++) {
+ for (link = tpu_map.buckets[i]; link; link = link->next) {
+ tpu_update_ports(link->tpu);
+ printf("FINAL %lu %lu: %s\n", link->x, link->y,
+ status_names[link->tpu->status]);
+ for (k = 0; k < 4; k++) {
+ if (link->tpu->ports[k].in >= 0)
+ printf("%lu %lu %5s: %i\n",
+ link->x, link->y, dir_names[k],
+ link->tpu->ports[k].in);
+ }
+ }
+ }
+
+ if (stdout_port.dst_port->out >= 0) {
+ putchar(stdout_port.dst_port->out);
+ stdout_port.dst_port->out = -1;
}
}
}
@@ -419,3 +463,4 @@ main(int argc, const char **argv)
run();
}
+