Join memory during undefinition
This commit is contained in:
parent
fc903be471
commit
ff0c53cf68
|
@ -0,0 +1,19 @@
|
|||
<> rule0 data
|
||||
<> rule1 data-1
|
||||
<> rule2
|
||||
<> rule3 data-10
|
||||
<> rule4 data-100
|
||||
|
||||
?(?-) (Undefine an empty rule)
|
||||
|
||||
>< rule2
|
||||
|
||||
?(?-) (Undefine the last rule)
|
||||
|
||||
>< rule4
|
||||
|
||||
?(?-) (Undefine a non-existant rule)
|
||||
|
||||
>< rule5
|
||||
|
||||
a sample program
|
2
makefile
2
makefile
|
@ -10,7 +10,7 @@ dest:
|
|||
run: all bin/modal
|
||||
@ bin/modal -q examples/hello.modal
|
||||
debug: all bin/modal-debug
|
||||
@ bin/modal-debug examples/hello.modal
|
||||
@ bin/modal-debug examples/rules.modal
|
||||
test: all bin/modal-debug bin/modal
|
||||
@ bin/modal -v
|
||||
@ bin/modal-debug -q examples/fizzbuzz.modal
|
||||
|
|
44
src/modal.c
44
src/modal.c
|
@ -22,6 +22,15 @@ copy(char *src, char *dst, int length)
|
|||
return dst;
|
||||
}
|
||||
|
||||
static int
|
||||
slen(char *s)
|
||||
{
|
||||
char *cap = s;
|
||||
while(*cap++)
|
||||
;
|
||||
return cap - s;
|
||||
}
|
||||
|
||||
static char *
|
||||
walk(char *s)
|
||||
{
|
||||
|
@ -233,10 +242,10 @@ parse_frag(char **side, char *s)
|
|||
{
|
||||
char c, *cap;
|
||||
while((c = *s) && c == ' ') s++;
|
||||
if(c == ')') {
|
||||
if(c == ')' || (c == '<' && s[1] == '>') || (c == '>' && s[1] == '<')) {
|
||||
*side = NULL;
|
||||
return s;
|
||||
} else if((c == '<' && s[1] == '>') || (c == '>' && s[1] == '<') || (c == '(' && s[1] == ')')) {
|
||||
} else if((c == '(' && s[1] == ')')) {
|
||||
*side = NULL;
|
||||
return s + 2;
|
||||
} else {
|
||||
|
@ -257,14 +266,31 @@ find_rule(char *s, char *cap)
|
|||
if(*s == '(') s++, cap--;
|
||||
while(r < rules_) {
|
||||
char *ss = s, *a = r->a;
|
||||
if(a)
|
||||
while(*ss++ == *a++)
|
||||
if(!*a && ss == cap) return r;
|
||||
while(*ss++ == *a++)
|
||||
if(!*a && ss == cap) return r;
|
||||
r++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_rule(Rule *r)
|
||||
{
|
||||
if(r < rules_ - 1) {
|
||||
int distance = slen(r->a) + (r->b != NULL ? slen(r->b) : 0);
|
||||
char *memsrc = (r + 1)->a;
|
||||
copy(memsrc, r->a, dict_ - memsrc);
|
||||
while(r < rules_ - 1) {
|
||||
Rule *next = r + 1;
|
||||
r->id = next->id, r->refs = next->refs;
|
||||
r->a = next->a - distance;
|
||||
r->b = next->b == NULL ? NULL : next->b - distance;
|
||||
r++;
|
||||
}
|
||||
}
|
||||
rules_--;
|
||||
}
|
||||
|
||||
static int
|
||||
rewrite(void)
|
||||
{
|
||||
|
@ -272,7 +298,7 @@ rewrite(void)
|
|||
while(*s == ' ') s++;
|
||||
while((c = *s)) {
|
||||
if(c == '(' || spacer(last)) {
|
||||
Rule *r = NULL;
|
||||
Rule *r;
|
||||
/* phase: undefine */
|
||||
if(c == '>' && s[1] == '<') {
|
||||
s += 2;
|
||||
|
@ -280,7 +306,7 @@ rewrite(void)
|
|||
cap = walk(s), r = find_rule(s, cap);
|
||||
if(r != NULL) {
|
||||
if(!quiet) fprintf(stderr, ">< (%s) (%s)\n", r->a ? r->a : "", r->b ? r->b : "");
|
||||
r->a = 0;
|
||||
remove_rule(r);
|
||||
}
|
||||
while(*cap == ' ') cap++;
|
||||
return write_tail(cap);
|
||||
|
@ -310,7 +336,7 @@ rewrite(void)
|
|||
}
|
||||
/* phase: match */
|
||||
for(r = rules; r < rules_; r++)
|
||||
if(r->a != NULL && apply_rule(r, s)) return 1;
|
||||
if(apply_rule(r, s)) return 1;
|
||||
}
|
||||
*dst_++ = last = c, s++;
|
||||
}
|
||||
|
@ -326,7 +352,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, 17 May 2024.\n");
|
||||
case 'v': /* version */ return !printf("Modal Interpreter, 21 May 2024.\n");
|
||||
case 'q': /* quiet */ quiet = 1; break;
|
||||
case 'p': /* debug */ debug = 1; break;
|
||||
case 'a': /* access */ access = 1; break;
|
||||
|
|
Loading…
Reference in New Issue