This commit is contained in:
Devine Lu Linvega 2024-04-22 20:08:29 -07:00
parent 9c95b4567b
commit ba48cfffa6
1 changed files with 22 additions and 20 deletions

View File

@ -6,7 +6,7 @@ typedef struct {
} Rule; } Rule;
static int flip, quiet, rmin = 0xff, rmax = 0x00, cycles = 0x10000; static int flip, quiet, rmin = 0xff, rmax = 0x00, cycles = 0x10000;
static Rule rules[0x1000], lambda, *rules_ = rules; static Rule rules[0x1000], *rules_ = rules + 1;
static char dict[0x8000], *dict_ = dict; static char dict[0x8000], *dict_ = dict;
static char bank_a[0x4000], *src_ = bank_a; static char bank_a[0x4000], *src_ = bank_a;
static char bank_b[0x4000], *dst_ = bank_b; static char bank_b[0x4000], *dst_ = bank_b;
@ -99,46 +99,47 @@ write_rule(Rule *r, char *s, int create)
static int static int
run_rule(Rule *r, char *s) run_rule(Rule *r, char *s)
{ {
char c, *a = r->a;
if(rmax) { /* clean registers */
int i; int i;
char c, *a = r->a, *p = s;
if(rmax) {
for(i = rmin; i <= rmax; i++) for(i = rmin; i <= rmax; i++)
regs[i] = 0; regs[i] = 0;
rmin = 0xff, rmax = 0x00; rmin = 0xff, rmax = 0x00;
} }
while((c = *a)) { /* find match */ while((c = *a)) {
if(c == '?') { if(c == '?') {
int regid = (int)*(++a); int regid = (int)*(++a);
char *pcap = walk(s), *reg = regs[regid]; char *pcap = walk(p), *reg = regs[regid];
if(reg) { /* reg cmp */ if(reg) { /* reg cmp */
char *rcap = walk(reg), *pp = s; char *rcap = walk(reg), *pp = p;
while(reg < rcap || pp < pcap) while(reg < rcap || pp < pcap)
if(*reg++ != *pp++) return 0; if(*reg++ != *pp++) return 0;
} else { /* reg set */ } else { /* reg set */
regs[regid] = s; regs[regid] = p;
if(regid < rmin) rmin = regid; if(regid < rmin) rmin = regid;
if(regid > rmax) rmax = regid; if(regid > rmax) rmax = regid;
} }
a++, s = pcap; a++, p = pcap;
if(!spacer(*a)) if(!spacer(*a))
while((c = *a) && !spacer(c)) a++; while((c = *a) && !spacer(c)) a++;
continue; continue;
} }
if(c != *s) return 0; if(c != *p) return 0;
a++, s++; a++, p++;
} }
if((c = *s) && spacer(c)) { /* write match */ c = *p;
if(spacer(c)) {
char *b = r->b, *reg, *origin = dst_; char *b = r->b, *reg, *origin = dst_;
while((c = *b++)) while((c = *b++))
if(c == '?' && (reg = regs[(int)*b])) if(c == '?' && (reg = regs[(int)*b]))
write_reg(*b++, reg); write_reg(*b++, reg);
else else
*dst_++ = c; *dst_++ = c;
if(dst_ == origin) { /* trim */ if(dst_ == origin) {
while(*s == ' ') s++; while(*p == ' ') p++;
if(*s == ')' && *(dst_ - 1) == ' ') dst_--; if(*p == ')' && *(dst_ - 1) == ' ') dst_--;
} }
return write_rule(r, s, 0); return write_rule(r, p, 0);
} }
return 0; return 0;
} }
@ -178,13 +179,14 @@ rewrite(void)
} }
if(c == '?' && s[1] == '(') { /* lambda */ if(c == '?' && s[1] == '(') { /* lambda */
cap = walk(s + 1); cap = walk(s + 1);
r = &lambda, r->id = -1; r = &rules[0], r->id = -1;
r->a = dict_, s = parse_frag(s + 2); r->a = dict_, s = parse_frag(s + 2);
r->b = dict_, parse_frag(s), s = cap; r->b = dict_, parse_frag(s), s = cap;
while(*s == ' ') s++; while(*s == ' ') s++;
if(run_rule(r, s)) return 1; r = rules;
} } else
for(r = rules; r < rules_; r++) r = rules + 1;
for(; r < rules_; r++)
if(run_rule(r, s)) return 1; if(run_rule(r, s)) return 1;
} }
*dst_++ = last = c; *dst_++ = last = c;