#include #include #include #include "tape.h" struct tape *tape_new(int blank) { struct tape *r; r = (struct tape *)malloc(sizeof(struct tape)); if (r != NULL) { r->head = 0; r->blank = blank; r->ncapacity = r->pcapacity = 0; r->nsyms = r->psyms = NULL; } return r; } int tape_read(struct tape *t, int pos) { if (pos >= 0) { if (pos >= t->pcapacity) return t->blank; else return t->psyms[pos]; } else { pos = -1 - pos; if (pos >= t->ncapacity) return t->blank; else return t->nsyms[pos]; } } static bool tape_grow(struct tape *t, int pos) { int **side; int *capacity; int newcapacity; int *newside; if (pos >= 0) { side = &t->psyms; capacity = &t->pcapacity; } else { pos = -1 - pos; side = &t->nsyms; capacity = &t->ncapacity; } if (pos + 1 < *capacity) return true; newcapacity = pos + TAPE_CHUNK_SIZE; printf("Grow tape to %d\n", newcapacity); newside = (int *)realloc(*side, newcapacity*sizeof(int)); if (newside == NULL) return false; *side = newside; while (*capacity < newcapacity) (*side)[(*capacity)++] = t->blank; return true; } void tape_write(struct tape *t, int pos, int sym) { if (pos >= 0) { if (pos >= t->pcapacity) { if (sym == t->blank) return; if (!tape_grow(t, pos)) // TODO: error out return; } t->psyms[pos] = sym; } else { pos = -1 - pos; if (pos >= t->ncapacity) { if (sym == t->blank) return; if (!tape_grow(t, -1 - pos)) // TODO: error out return; } t->nsyms[pos] = sym; } } int tape_load(struct tape *t, FILE *f, int offset, struct table *symbols) { char line[1000]; char *l; int ll; char *tok; char *toksave; static char *delim = " \t\f\n\r"; int counter = 0; for (;;) { l = fgets(line, sizeof(line)-1, f); if (l == NULL) break; ll = strlen(l); if (ll > 0) { tok = strtok_r(line, delim, &toksave); while (tok != NULL) { tape_write(t, offset+counter, table_insert(symbols, tok)); counter++; tok = strtok_r(NULL, delim, &toksave); } } } return counter; } #define HL_ON "\x01b[7m" #define HL_OFF "\x01b[0m" void tape_print(struct tape *t, struct table *sym) { int si; int first, last; printf("TAPE: "); if ((t->ncapacity == 0) && (t->pcapacity == 0)) { printf("(empty)\n"); return; } first = t->pcapacity; last = -1-t->ncapacity; for (int i=-1-t->ncapacity; ipcapacity; i++) { si = tape_read(t, i); if ((si != t->blank) || (i == t->head)) { if (i < first) first = i; if (i > last) last = i; } } if ((first == last) && (tape_read(t, first) == t->blank)) { printf("(empty)\n"); return; } for (int i=first; i <= last; i++) { if (i == t->head) printf(HL_ON); si = tape_read(t, i); if (sym == NULL) printf("%d", si); else printf("%s", (char *)table_lookup(sym, si)); if (i == t->head) printf(HL_OFF); printf(" "); } printf("\n"); }