Housekeeping
This commit is contained in:
parent
002da4bcc2
commit
defe9ed963
75
src/modal.c
75
src/modal.c
|
@ -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");
|
||||||
|
|
Loading…
Reference in New Issue