From b866c6977680b5dd0424eadef7bedebf7ebd3909 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Wed, 24 Apr 2024 10:31:46 -0700 Subject: [PATCH] Compile rules --- src/modal.c | 70 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 16 deletions(-) diff --git a/src/modal.c b/src/modal.c index a4b3001..0a6ba31 100644 --- a/src/modal.c +++ b/src/modal.c @@ -1,8 +1,8 @@ #include typedef struct { - int id, refs; - char *a, *b; + unsigned int id, refs, ptr; + char *a, *b, key[0x10]; } Rule; static int flip, quiet, cycles = 0x10000; @@ -11,12 +11,7 @@ static char dict[0x8000], *dict_ = dict; static char bank_a[0x4000], *src_ = bank_a; static char bank_b[0x4000], *dst_ = bank_b; -/* clang-format off */ - #define spacer(c) (c <= ' ' || c == '(' || c == ')') -#define get_reg(x) { regid = x; for(i = 0; i < rptr; i++) if(rkey[i] == regid) { reg = rval[i]; break; } } - -/* clang-format on */ static char * walk(char *s) @@ -110,18 +105,22 @@ write_rule(Rule *r, char *s, int create) static int apply_rule(Rule *r, char *s) { - int i, regid, rptr = 0; - char c, *a = r->a, rkey[0x10], *rval[0x10]; + char c, *a = r->a, *regs[0x10] = {NULL}; while((c = *a)) { /* phase: match rule */ if(c == '?') { char *pcap = walk(s), *reg = NULL; - get_reg(*(++a)); + int id = *(++a); + unsigned int id2 = id - '0'; + if(id2 < r->ptr) { + reg = regs[id2]; + } if(reg) { /* reg cmp */ char *rcap = walk(reg), *pp = s; while(reg < rcap || pp < pcap) if(*reg++ != *pp++) return 0; - } else /* reg set */ - rkey[rptr] = regid, rval[rptr++] = s; + } else { /* reg set */ + regs[id2] = s; + } a++, s = pcap; if(!spacer(*a)) while((c = *a) && !spacer(c)) a++; @@ -135,9 +134,14 @@ apply_rule(Rule *r, char *s) while((c = *b++)) { if(c == '?') { char *reg = NULL; - get_reg(*b); + int id = *b; + unsigned int id2 = id - '0'; + if(id2 < r->ptr) { + reg = regs[id2]; + } if(reg) { - if(!write_reg(*b++, reg) && dst_ != origin) dst_--; + b++; + if(!write_reg(r->key[id2], reg) && dst_ != origin) dst_--; } else *dst_++ = c; } else @@ -170,6 +174,38 @@ parse_frag(char *s) return s; } +static void +compile_rule(Rule *r) +{ + int i; + char c, *s; + r->ptr = 0; + s = r->a; + while((c = *s++)) { /* left */ + if(c == '?') { + int reg = -1; + for(i = 0; i < (int)r->ptr; i++) + if(r->key[i] == *s) { + reg = i; + break; + } + if(reg < 0 && *s != '(') + r->key[r->ptr] = *s, reg = r->ptr++; + *s = '0' + reg; + } + } + s = r->b; + while((c = *s++)) { /* right */ + if(c == '?') { + for(i = 0; i < (int)r->ptr; i++) + if(r->key[i] == *s) { + *s = '0' + i; + break; + } + } + } +} + static int rewrite(void) { @@ -177,11 +213,12 @@ rewrite(void) while(*s == ' ') s++; while((c = *s)) { if(spacer(last)) { - Rule *r; + Rule *r = NULL; if(c == '<' && s[1] == '>') { /* rule */ r = rules_++, r->id = rules_ - rules - 1; r->a = dict_, s = parse_frag(s + 2); r->b = dict_, s = parse_frag(s); + compile_rule(r); while(*s == ' ') s++; return write_rule(r, s, 1); } @@ -189,6 +226,7 @@ rewrite(void) cap = walk(s + 1), lambda.id = -1; lambda.a = dict_, s = parse_frag(s + 2); lambda.b = dict_, parse_frag(s), s = cap; + compile_rule(&lambda); while(*s == ' ') s++; return apply_rule(&lambda, s); } @@ -212,7 +250,7 @@ main(int argc, char **argv) return !printf("usage: modal [-vqn] source.modal\n"); for(i = 1; i < argc && *argv[i] == '-'; i++) { switch(argv[i][1]) { - case 'v': /* version */ return !printf("Modal Interpreter, 23 Apr 2024.\n"); + case 'v': /* version */ return !printf("Modal Interpreter, 24 Apr 2024.\n"); case 'q': /* quiet */ quiet = 1; break; case 'n': /* infinite */ cycles = 0xffffffff; break; }