Housekeeping

This commit is contained in:
Devine Lu Linvega 2024-05-09 15:15:04 -07:00
parent 002da4bcc2
commit defe9ed963
1 changed files with 48 additions and 51 deletions

View File

@ -14,12 +14,6 @@ static char *regs[0x100], stack[0x10], *stack_ = stack;
#define spacer(c) (c <= ' ' || c == '(' || c == ')') #define spacer(c) (c <= ' ' || c == '(' || c == ')')
static void
pushchr(char c)
{
*dst_++ = c;
}
static char * static char *
walk(char *s) walk(char *s)
{ {
@ -49,12 +43,12 @@ sint(char *s)
static void static void
device_write(char *s) device_write(char *s)
{ {
char c = *s, *cap = walk(s), **reg = regs + '0'; char **reg = regs + '0';
/* phase: ALU */ /* phase: ALU */
if(*reg) { if(*reg) {
int acc = sint(*reg++); int acc = sint(*reg++);
/* clang-format off */ /* clang-format off */
switch(c) { switch(*s) {
case '+': while(*reg) acc += sint(*reg++); break; case '+': while(*reg) acc += sint(*reg++); break;
case '-': while(*reg) acc -= sint(*reg++); break; case '-': while(*reg) acc -= sint(*reg++); break;
case '*': while(*reg) acc *= sint(*reg++); break; case '*': while(*reg) acc *= sint(*reg++); break;
@ -71,11 +65,12 @@ device_write(char *s)
/* clang-format on */ /* clang-format on */
dst_ += snprintf(dst_, 0x10, "%d", acc); dst_ += snprintf(dst_, 0x10, "%d", acc);
return; return;
} } else {
/* phase: string */ /* phase: string */
char *cap = walk(s);
if(*s == '(') s++, --cap; if(*s == '(') s++, --cap;
while(s < cap) { while(s < cap) {
c = *s++; char c = *s++;
if(c == '\\') { if(c == '\\') {
switch(*s++) { switch(*s++) {
case 't': putc(0x09, stdout); break; case 't': putc(0x09, stdout); break;
@ -86,15 +81,16 @@ device_write(char *s)
putc(c, stdout); putc(c, stdout);
} }
} }
}
static void static void
device_read(void) device_read(void)
{ {
char c, *origin = dst_; char c, *origin = dst_;
while(fread(&c, 1, 1, stdin) && c >= ' ') while(fread(&c, 1, 1, stdin) && c >= ' ')
pushchr(c); *dst_++ = c;
if(feof(stdin)) if(feof(stdin))
pushchr('E'), pushchr('O'), pushchr('F'); *dst_++ = 'E', *dst_++ = 'O', *dst_++ = 'F';
if(dst_ - origin == 0) if(dst_ - origin == 0)
dst_--; dst_--;
} }
@ -102,46 +98,53 @@ device_read(void)
static void static void
write_reg(char r, char *reg) write_reg(char r, char *reg)
{ {
char c, *cap = walk(reg);
switch(r) { switch(r) {
case ':': device_write(reg); return; case ':': device_write(reg); return;
case '~': device_read(); return; case '~': device_read(); return;
case '^': /* op: join */ case '^': { /* op: join */
char c, *cap = walk(reg);
if(*reg == '(') reg++, --cap; if(*reg == '(') reg++, --cap;
while(reg < cap && (c = *reg++)) while(reg < cap && (c = *reg++))
if(!spacer(c)) pushchr(c); if(!spacer(c)) *dst_++ = c;
return; return;
case '.': /* op: unwrap */ }
case '.': { /* op: unwrap */
char *cap = walk(reg);
if(*reg == '(') reg++, --cap; if(*reg == '(') reg++, --cap;
while(reg < cap) pushchr(*reg++); while(reg < cap) *dst_++ = *reg++;
return; return;
}
case '*': { /* op: explode */ case '*': { /* op: explode */
int i, depth = 0; int i, depth = 0;
char c, *cap = walk(reg);
if(*reg == '(' && reg[1] != ')') { /* tuple */ if(*reg == '(' && reg[1] != ')') { /* tuple */
reg++; reg++;
while(reg < cap) { while(reg < cap) {
while((c = *reg) && !spacer(c)) while((c = *reg) && !spacer(c))
pushchr(c), reg++; *dst_++ = c, reg++;
pushchr(' '), pushchr('('), reg++, depth++; *dst_++ = ' ';
*dst_++ = '(', reg++, depth++;
} }
} else /* token */ } else /* token */
while((c = *reg++) && !spacer(c)) while((c = *reg++) && !spacer(c))
pushchr(c), pushchr(' '), pushchr('('), depth++; *dst_++ = c, *dst_++ = ' ', *dst_++ = '(', depth++;
for(i = 0; i < depth; i++) pushchr(')'); for(i = 0; i < depth; i++) *dst_++ = ')';
return; return;
} }
default: default: {
while(reg < cap) pushchr(*reg++); char *cap = walk(reg);
while(reg < cap) *dst_++ = *reg++;
return; return;
} }
} }
}
static int static int
write_tail(char *s) write_tail(char *s)
{ {
while((*dst_++ = *s++)) while((*dst_++ = *s++))
; ;
pushchr(0); *dst_ = 0;
if((flip = !flip)) if((flip = !flip))
src_ = bank_b, dst_ = bank_a; src_ = bank_b, dst_ = bank_a;
else else
@ -175,14 +178,10 @@ apply_rule(Rule *r, char *s)
if(!spacer(c)) return 0; if(!spacer(c)) return 0;
/* phase: write rule */ /* phase: write rule */
while((c = *b++)) { while((c = *b++)) {
if(c == '?') { if(c == '?' && (rid = *b) && (reg = regs[rid]))
rid = *b; write_reg(rid, reg), b++;
if((reg = regs[rid]))
b++, write_reg(rid, reg);
else else
pushchr(c); *dst_++ = c;
} else
pushchr(c);
} }
if(dst_ == origin) { if(dst_ == origin) {
while(*s == ' ') s++; while(*s == ' ') s++;
@ -274,10 +273,9 @@ rewrite(void)
for(r = rules; r < rules_; r++) for(r = rules; r < rules_; r++)
if(r->a && apply_rule(r, s)) return 1; if(r->a && apply_rule(r, s)) return 1;
} }
pushchr(c), last = c; *dst_++ = last = c, s++;
s++;
} }
pushchr(0); *dst_++ = 0;
return 0; return 0;
} }
@ -285,7 +283,7 @@ int
main(int argc, char **argv) main(int argc, char **argv)
{ {
FILE *f; FILE *f;
int i, pl = 0, pr = 0, rw = 0; int i, pr = 0, rw = 0;
char c, last = 0, *w = bank_a; char c, last = 0, *w = bank_a;
if(argc < 2) if(argc < 2)
return !printf("usage: modal [-vqn] source.modal\n"); return !printf("usage: modal [-vqn] source.modal\n");
@ -304,15 +302,14 @@ main(int argc, char **argv)
if(c == ' ' && last == '(') continue; if(c == ' ' && last == '(') continue;
if(c == ')' && last == ' ') w--; if(c == ')' && last == ' ') w--;
if(c == ' ' && last == ' ') w--; if(c == ' ' && last == ' ') w--;
if(c == '(') pl++; if(c == '(') pr++;
if(c == ')') pr++; if(c == ')') pr--;
if(c == '(' && last != '?' && !spacer(last)) *w++ = ' '; if(c == '(' && last != '?' && !spacer(last)) *w++ = ' ';
if(last == ')' && !spacer(c)) *w++ = ' '; if(last == ')' && !spacer(c)) *w++ = ' ';
*w++ = last = c; *w++ = last = c;
} }
while(*(--w) <= ' ') *w = 0;
fclose(f); fclose(f);
if(pr != pl) if(pr)
return !fprintf(stderr, "Modal program imbalanced.\n"); return !fprintf(stderr, "Modal program imbalanced.\n");
while(rewrite() && ++rw) while(rewrite() && ++rw)
if(!cycles--) return !fprintf(stderr, "Modal rewrites exceeded.\n"); if(!cycles--) return !fprintf(stderr, "Modal rewrites exceeded.\n");