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
|
run: all bin/modal
|
||||||
@ bin/modal -q examples/hello.modal
|
@ bin/modal -q examples/hello.modal
|
||||||
debug: all bin/modal-debug
|
debug: all bin/modal-debug
|
||||||
@ bin/modal-debug examples/hello.modal
|
@ bin/modal-debug examples/rules.modal
|
||||||
test: all bin/modal-debug bin/modal
|
test: all bin/modal-debug bin/modal
|
||||||
@ bin/modal -v
|
@ bin/modal -v
|
||||||
@ bin/modal-debug -q examples/fizzbuzz.modal
|
@ bin/modal-debug -q examples/fizzbuzz.modal
|
||||||
|
|
40
src/modal.c
40
src/modal.c
|
@ -22,6 +22,15 @@ copy(char *src, char *dst, int length)
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
slen(char *s)
|
||||||
|
{
|
||||||
|
char *cap = s;
|
||||||
|
while(*cap++)
|
||||||
|
;
|
||||||
|
return cap - s;
|
||||||
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
walk(char *s)
|
walk(char *s)
|
||||||
{
|
{
|
||||||
|
@ -233,10 +242,10 @@ parse_frag(char **side, char *s)
|
||||||
{
|
{
|
||||||
char c, *cap;
|
char c, *cap;
|
||||||
while((c = *s) && c == ' ') s++;
|
while((c = *s) && c == ' ') s++;
|
||||||
if(c == ')') {
|
if(c == ')' || (c == '<' && s[1] == '>') || (c == '>' && s[1] == '<')) {
|
||||||
*side = NULL;
|
*side = NULL;
|
||||||
return s;
|
return s;
|
||||||
} else if((c == '<' && s[1] == '>') || (c == '>' && s[1] == '<') || (c == '(' && s[1] == ')')) {
|
} else if((c == '(' && s[1] == ')')) {
|
||||||
*side = NULL;
|
*side = NULL;
|
||||||
return s + 2;
|
return s + 2;
|
||||||
} else {
|
} else {
|
||||||
|
@ -257,7 +266,6 @@ find_rule(char *s, char *cap)
|
||||||
if(*s == '(') s++, cap--;
|
if(*s == '(') s++, cap--;
|
||||||
while(r < rules_) {
|
while(r < rules_) {
|
||||||
char *ss = s, *a = r->a;
|
char *ss = s, *a = r->a;
|
||||||
if(a)
|
|
||||||
while(*ss++ == *a++)
|
while(*ss++ == *a++)
|
||||||
if(!*a && ss == cap) return r;
|
if(!*a && ss == cap) return r;
|
||||||
r++;
|
r++;
|
||||||
|
@ -265,6 +273,24 @@ find_rule(char *s, char *cap)
|
||||||
return NULL;
|
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
|
static int
|
||||||
rewrite(void)
|
rewrite(void)
|
||||||
{
|
{
|
||||||
|
@ -272,7 +298,7 @@ rewrite(void)
|
||||||
while(*s == ' ') s++;
|
while(*s == ' ') s++;
|
||||||
while((c = *s)) {
|
while((c = *s)) {
|
||||||
if(c == '(' || spacer(last)) {
|
if(c == '(' || spacer(last)) {
|
||||||
Rule *r = NULL;
|
Rule *r;
|
||||||
/* phase: undefine */
|
/* phase: undefine */
|
||||||
if(c == '>' && s[1] == '<') {
|
if(c == '>' && s[1] == '<') {
|
||||||
s += 2;
|
s += 2;
|
||||||
|
@ -280,7 +306,7 @@ rewrite(void)
|
||||||
cap = walk(s), r = find_rule(s, cap);
|
cap = walk(s), r = find_rule(s, cap);
|
||||||
if(r != NULL) {
|
if(r != NULL) {
|
||||||
if(!quiet) fprintf(stderr, ">< (%s) (%s)\n", r->a ? r->a : "", r->b ? r->b : "");
|
if(!quiet) fprintf(stderr, ">< (%s) (%s)\n", r->a ? r->a : "", r->b ? r->b : "");
|
||||||
r->a = 0;
|
remove_rule(r);
|
||||||
}
|
}
|
||||||
while(*cap == ' ') cap++;
|
while(*cap == ' ') cap++;
|
||||||
return write_tail(cap);
|
return write_tail(cap);
|
||||||
|
@ -310,7 +336,7 @@ rewrite(void)
|
||||||
}
|
}
|
||||||
/* phase: match */
|
/* phase: match */
|
||||||
for(r = rules; r < rules_; r++)
|
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++;
|
*dst_++ = last = c, s++;
|
||||||
}
|
}
|
||||||
|
@ -326,7 +352,7 @@ main(int argc, char **argv)
|
||||||
return !printf("usage: modal [-vqn] source.modal\n");
|
return !printf("usage: modal [-vqn] source.modal\n");
|
||||||
for(i = 1; i < argc && *argv[i] == '-'; i++) {
|
for(i = 1; i < argc && *argv[i] == '-'; i++) {
|
||||||
switch(argv[i][1]) {
|
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 'q': /* quiet */ quiet = 1; break;
|
||||||
case 'p': /* debug */ debug = 1; break;
|
case 'p': /* debug */ debug = 1; break;
|
||||||
case 'a': /* access */ access = 1; break;
|
case 'a': /* access */ access = 1; break;
|
||||||
|
|
Loading…
Reference in New Issue