Special registers that are non-emitting should erase themselves

This commit is contained in:
Devine Lu Linvega 2024-04-22 21:37:40 -07:00
parent 157d1909ea
commit 95d8bf3d8e
1 changed files with 10 additions and 9 deletions

View File

@ -30,7 +30,7 @@ walk(char *s)
return s; return s;
} }
static void static int
write_reg(char r, char *reg) write_reg(char r, char *reg)
{ {
char c, *cap = walk(reg); char c, *cap = walk(reg);
@ -48,20 +48,20 @@ write_reg(char r, char *reg)
} else } else
putc(c, stdout); putc(c, stdout);
} }
return; return 0;
case '~': /* op: input */ case '~': /* op: input */
while(fread(&c, 1, 1, stdin) && c >= ' ') while(fread(&c, 1, 1, stdin) && c >= ' ')
*dst_++ = c; *dst_++ = c;
return; return 1;
case '^': /* op: join */ case '^': /* op: join */
if(*reg == '(') reg++, --cap; if(*reg == '(') reg++, --cap;
while(reg < cap && (c = *reg++)) while(reg < cap && (c = *reg++))
if(!spacer(c)) *dst_++ = c; if(!spacer(c)) *dst_++ = c;
return; return 1;
case '.': /* op: unwrap */ case '.': /* op: unwrap */
if(*reg == '(') reg++, --cap; if(*reg == '(') reg++, --cap;
while(reg < cap) *dst_++ = *reg++; while(reg < cap) *dst_++ = *reg++;
return; return 1;
case '*': { /* op: explode */ case '*': { /* op: explode */
int i, depth = 0; int i, depth = 0;
if(*reg == '(') { /* tuple */ if(*reg == '(') { /* tuple */
@ -77,10 +77,11 @@ write_reg(char r, char *reg)
*dst_++ = c, *dst_++ = ' ', *dst_++ = '(', depth++; *dst_++ = c, *dst_++ = ' ', *dst_++ = '(', depth++;
} }
for(i = 0; i < depth; i++) *dst_++ = ')'; for(i = 0; i < depth; i++) *dst_++ = ')';
return; return 1;
} }
default: default:
while(reg < cap) *dst_++ = *reg++; while(reg < cap) *dst_++ = *reg++;
return 1;
} }
} }
@ -137,9 +138,9 @@ apply_rule(Rule *r, char *s)
if(!(c = *s) || spacer(c)) { /* phase: write rule */ if(!(c = *s) || spacer(c)) { /* phase: write rule */
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); if(!write_reg(*b++, reg) && dst_ != origin) dst_--;
else } else
*dst_++ = c; *dst_++ = c;
if(dst_ == origin) { if(dst_ == origin) {
while(*s == ' ') s++; while(*s == ' ') s++;