From 49614f1a61ca38970ecb668d803b8dfce509d8b2 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Fri, 26 Apr 2024 20:50:22 -0700 Subject: [PATCH 01/45] Initial implementation of undefine rules --- examples/tests.modal | 4 +-- src/modal.c | 59 +++++++++++++++++++++++++++++--------------- 2 files changed, 41 insertions(+), 22 deletions(-) diff --git a/examples/tests.modal b/examples/tests.modal index cc8a36b..62acf6e 100644 --- a/examples/tests.modal +++ b/examples/tests.modal @@ -8,8 +8,8 @@ ?(?-) (Formatter) -?((?x ?y) one) aaa(bbb) = one (formatter 1) test -?((?x ?y) one) (bbb)aaa = one (formatter 2) test +?((?x ?y) two) aaa(bbb) = two (formatter 1) test +?((?x ?y) two) (bbb)aaa = two (formatter 2) test (a b c ) = (a b c) (formatter 3) test ( a b c) = (a b c) (formatter 4) test ( a b c ) = (a b c) (formatter 5) test diff --git a/src/modal.c b/src/modal.c index 0c1a83f..f0012eb 100644 --- a/src/modal.c +++ b/src/modal.c @@ -2,7 +2,7 @@ typedef struct { unsigned int id, refs, ptr; - char *a, *b, reg[0x10]; + char *a, *b, reg[0x8]; } Rule; static int flip, quiet, cycles = 0x10000; @@ -87,7 +87,7 @@ write_reg(char r, char *reg) } static int -write_rule(Rule *r, char *s, int create) +write_rule(Rule *r, char *s) { while((*dst_++ = *s++)) ; @@ -96,12 +96,7 @@ write_rule(Rule *r, char *s, int create) src_ = bank_b, dst_ = bank_a; else src_ = bank_a, dst_ = bank_b; - if(!quiet) { - if(create) - fprintf(stderr, "<> (%s) (%s)\n", r->a, r->b); - else - fprintf(stderr, "%02d %s\n", r->id, src_), ++r->refs; - } + if(!quiet && r) fprintf(stderr, "%02d %s\n", r->id, src_), ++r->refs; return 1; } @@ -109,7 +104,7 @@ static int apply_rule(Rule *r, char *s) { unsigned int i, id; - char c, *a = r->a, *b = r->b, *origin = dst_, *reg, *regs[0x08]; + char c, *a = r->a, *b = r->b, *origin = dst_, *reg, *regs[0x8]; /* phase: clean registers */ for(i = 0; i < r->ptr; i++) regs[i] = NULL; @@ -145,7 +140,7 @@ apply_rule(Rule *r, char *s) while(*s == ' ') s++; if(*s == ')' && *(dst_ - 1) == ' ') dst_--; } - return write_rule(r, s, 0); + return write_rule(r, s); } static int @@ -194,6 +189,19 @@ compile_rule(Rule *r, int id, char *src) return src; } +static Rule * +find_rule(char *s) +{ + Rule *r = rules; + while(r < rules_) { + char *ss = s, *a = r->a; + while(*ss++ == *a++) + if(!*a) return r; + r++; + } + return NULL; +} + static int rewrite(void) { @@ -202,23 +210,34 @@ rewrite(void) while((c = *s)) { if(c == '(' || spacer(last)) { Rule *r = NULL; - /* phase: rule */ - if(c == '<' && s[1] == '>') { - r = rules_++; - s = compile_rule(r, rules_ - rules - 1, s + 2); - while(*s == ' ') s++; - return write_rule(r, s, 1); - } /* phase: lambda */ if(c == '?' && s[1] == '(') { cap = walk(s + 1), compile_rule(&lambda, -1, s + 2), s = cap; while(*s == ' ') s++; - if(!apply_rule(&lambda, s)) write_rule(&lambda, s, 0); + if(!apply_rule(&lambda, s)) write_rule(&lambda, s); return 1; } + /* phase: define */ + if(c == '<' && s[1] == '>') { + r = rules_++; + s = compile_rule(r, rules_ - rules - 1, s + 2); + if(!quiet && r->a) fprintf(stderr, "<> (%s) (%s)\n", r->a, r->b); + while(*s == ' ') s++; + return write_rule(NULL, s); + } + /* phase: undefine */ + if(c == '>' && s[1] == '<') { + s += 2; + while(*s == ' ') s++; + r = find_rule(s), r->a = 0; + if(!quiet && r->a) fprintf(stderr, ">< (%s)\n", r->a); + s = walk(s); + while(*s == ' ') s++; + return write_rule(NULL, s); + } /* phase: match */ for(r = rules; r < rules_; r++) - if(apply_rule(r, s)) return 1; + if(r->a && apply_rule(r, s)) return 1; } *dst_++ = last = c; s++; @@ -263,6 +282,6 @@ main(int argc, char **argv) if(!cycles--) return !fprintf(stdout, "Modal rewrites exceeded.\n"); while(rules_-- > rules && !quiet) if(!rules_->refs) printf("-- Unused rule: %d <> (%s) (%s)\n", rules_->refs, rules_->a, rules_->b); - if(!quiet) printf(".. %s\n", src_); + if(!quiet) printf(".. [%s]\n", src_); return 0; } \ No newline at end of file From 37effa5dfdf86b0ef546951214c000c2fd0e9cc7 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Fri, 26 Apr 2024 21:04:54 -0700 Subject: [PATCH 02/45] Housekeeping --- src/modal.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/modal.c b/src/modal.c index f0012eb..081bb87 100644 --- a/src/modal.c +++ b/src/modal.c @@ -229,9 +229,8 @@ rewrite(void) if(c == '>' && s[1] == '<') { s += 2; while(*s == ' ') s++; - r = find_rule(s), r->a = 0; + r = find_rule(s), r->a = 0, s = walk(s); if(!quiet && r->a) fprintf(stderr, ">< (%s)\n", r->a); - s = walk(s); while(*s == ' ') s++; return write_rule(NULL, s); } @@ -282,6 +281,6 @@ main(int argc, char **argv) if(!cycles--) return !fprintf(stdout, "Modal rewrites exceeded.\n"); while(rules_-- > rules && !quiet) if(!rules_->refs) printf("-- Unused rule: %d <> (%s) (%s)\n", rules_->refs, rules_->a, rules_->b); - if(!quiet) printf(".. [%s]\n", src_); + if(!quiet) printf(".. %s\n", src_); return 0; } \ No newline at end of file From 541e8937b0081369840a0c55f938e0f58aedc209 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Fri, 26 Apr 2024 21:18:02 -0700 Subject: [PATCH 03/45] Unwrap rules during match --- src/modal.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/modal.c b/src/modal.c index 081bb87..7b3dcdd 100644 --- a/src/modal.c +++ b/src/modal.c @@ -190,16 +190,17 @@ compile_rule(Rule *r, int id, char *src) } static Rule * -find_rule(char *s) +find_rule(char *s, char *cap) { Rule *r = rules; + if(*s == '(') s++, cap--; while(r < rules_) { char *ss = s, *a = r->a; while(*ss++ == *a++) if(!*a) return r; r++; } - return NULL; + return r; } static int @@ -227,12 +228,12 @@ rewrite(void) } /* phase: undefine */ if(c == '>' && s[1] == '<') { - s += 2; + s += 2, cap = walk(s); while(*s == ' ') s++; - r = find_rule(s), r->a = 0, s = walk(s); + r = find_rule(s, cap), r->a = 0; if(!quiet && r->a) fprintf(stderr, ">< (%s)\n", r->a); - while(*s == ' ') s++; - return write_rule(NULL, s); + while(*cap == ' ') cap++; + return write_rule(NULL, cap); } /* phase: match */ for(r = rules; r < rules_; r++) From f3d16b4bd646ee95365c5e38a92ba81bc450a509 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Fri, 26 Apr 2024 21:35:31 -0700 Subject: [PATCH 04/45] Fixed issue in undefinition --- src/modal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modal.c b/src/modal.c index 7b3dcdd..21f0f64 100644 --- a/src/modal.c +++ b/src/modal.c @@ -228,9 +228,9 @@ rewrite(void) } /* phase: undefine */ if(c == '>' && s[1] == '<') { - s += 2, cap = walk(s); + s += 2; while(*s == ' ') s++; - r = find_rule(s, cap), r->a = 0; + cap = walk(s), r = find_rule(s, cap), r->a = 0; if(!quiet && r->a) fprintf(stderr, ">< (%s)\n", r->a); while(*cap == ' ') cap++; return write_rule(NULL, cap); From 06f2cd4487429f794bb4c523246b73a6903db9ad Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Fri, 26 Apr 2024 21:37:08 -0700 Subject: [PATCH 05/45] Do not warn of unused empty rules --- src/modal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modal.c b/src/modal.c index 21f0f64..43d40de 100644 --- a/src/modal.c +++ b/src/modal.c @@ -281,7 +281,7 @@ main(int argc, char **argv) while(rewrite()) if(!cycles--) return !fprintf(stdout, "Modal rewrites exceeded.\n"); while(rules_-- > rules && !quiet) - if(!rules_->refs) printf("-- Unused rule: %d <> (%s) (%s)\n", rules_->refs, rules_->a, rules_->b); + if(!rules_->refs && rules_->a) printf("-- Unused rule: %d <> (%s) (%s)\n", rules_->refs, rules_->a, rules_->b); if(!quiet) printf(".. %s\n", src_); return 0; } \ No newline at end of file From 8b618d24252dbb507f8495047a7f9d683d03fee8 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Fri, 26 Apr 2024 22:07:53 -0700 Subject: [PATCH 06/45] Fixed issue with weird undefinitions --- src/modal.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/modal.c b/src/modal.c index 43d40de..1a1168d 100644 --- a/src/modal.c +++ b/src/modal.c @@ -196,8 +196,9 @@ find_rule(char *s, char *cap) if(*s == '(') s++, cap--; while(r < rules_) { char *ss = s, *a = r->a; - while(*ss++ == *a++) - if(!*a) return r; + if(a) + while(*ss++ == *a++) + if(!*a) return r; r++; } return r; From e83ac9ce029149ed69c466c7b0208be11845ef00 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sat, 27 Apr 2024 08:46:31 -0700 Subject: [PATCH 07/45] Display rewrites count --- src/modal.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/modal.c b/src/modal.c index 1a1168d..fdc68e8 100644 --- a/src/modal.c +++ b/src/modal.c @@ -87,7 +87,7 @@ write_reg(char r, char *reg) } static int -write_rule(Rule *r, char *s) +write_tail(char *s) { while((*dst_++ = *s++)) ; @@ -96,7 +96,6 @@ write_rule(Rule *r, char *s) src_ = bank_b, dst_ = bank_a; else src_ = bank_a, dst_ = bank_b; - if(!quiet && r) fprintf(stderr, "%02d %s\n", r->id, src_), ++r->refs; return 1; } @@ -105,7 +104,7 @@ apply_rule(Rule *r, char *s) { unsigned int i, id; char c, *a = r->a, *b = r->b, *origin = dst_, *reg, *regs[0x8]; - /* phase: clean registers */ + /* phase: clean regs */ for(i = 0; i < r->ptr; i++) regs[i] = NULL; /* phase: match rule */ @@ -140,11 +139,12 @@ apply_rule(Rule *r, char *s) while(*s == ' ') s++; if(*s == ')' && *(dst_ - 1) == ' ') dst_--; } - return write_rule(r, s); + if(!quiet && r) fprintf(stderr, "%02d %s\n", r->id, src_), ++r->refs; + return write_tail(s); } static int -find_register(Rule *r, char reg) +find_reg(Rule *r, char reg) { int i; for(i = 0; i < (int)r->ptr; i++) @@ -166,7 +166,7 @@ compile_rule(Rule *r, int id, char *src) while(src < cap) { c = *src, *dict_++ = *src++; if(c == '?') { - c = *src++, reg = find_register(r, c); + c = *src++, reg = find_reg(r, c); if(reg == -1 && c != '(') r->reg[r->ptr] = c, reg = r->ptr++; *dict_++ = '0' + reg; @@ -181,7 +181,7 @@ compile_rule(Rule *r, int id, char *src) while(src < cap) { c = *src, *dict_++ = *src++; if(c == '?') { - c = *src++, reg = find_register(r, c); + c = *src++, reg = find_reg(r, c); *dict_++ = reg != -1 ? '0' + reg : c; } } @@ -212,20 +212,13 @@ rewrite(void) while((c = *s)) { if(c == '(' || spacer(last)) { Rule *r = NULL; - /* phase: lambda */ - if(c == '?' && s[1] == '(') { - cap = walk(s + 1), compile_rule(&lambda, -1, s + 2), s = cap; - while(*s == ' ') s++; - if(!apply_rule(&lambda, s)) write_rule(&lambda, s); - return 1; - } /* phase: define */ if(c == '<' && s[1] == '>') { r = rules_++; s = compile_rule(r, rules_ - rules - 1, s + 2); if(!quiet && r->a) fprintf(stderr, "<> (%s) (%s)\n", r->a, r->b); while(*s == ' ') s++; - return write_rule(NULL, s); + return write_tail(s); } /* phase: undefine */ if(c == '>' && s[1] == '<') { @@ -234,7 +227,14 @@ rewrite(void) cap = walk(s), r = find_rule(s, cap), r->a = 0; if(!quiet && r->a) fprintf(stderr, ">< (%s)\n", r->a); while(*cap == ' ') cap++; - return write_rule(NULL, cap); + return write_tail(cap); + } + /* phase: lambda */ + if(c == '?' && s[1] == '(') { + cap = walk(s + 1), compile_rule(&lambda, -1, s + 2), s = cap; + while(*s == ' ') s++; + if(!apply_rule(&lambda, s)) write_tail(s); + return 1; } /* phase: match */ for(r = rules; r < rules_; r++) @@ -251,13 +251,13 @@ int main(int argc, char **argv) { FILE *f; - int i, pl = 0, pr = 0; + int i, pl = 0, pr = 0, rw = 0; char c, last = 0, *w = bank_a; if(argc < 2) 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, 26 Apr 2024.\n"); + case 'v': /* version */ return !printf("Modal Interpreter, 27 Apr 2024.\n"); case 'q': /* quiet */ quiet = 1; break; case 'n': /* infinite */ cycles = 0xffffffff; break; } @@ -279,10 +279,10 @@ main(int argc, char **argv) fclose(f); if(pr != pl) return !fprintf(stdout, "Modal program imbalanced.\n"); - while(rewrite()) + while(rewrite() && ++rw) if(!cycles--) return !fprintf(stdout, "Modal rewrites exceeded.\n"); while(rules_-- > rules && !quiet) if(!rules_->refs && rules_->a) printf("-- Unused rule: %d <> (%s) (%s)\n", rules_->refs, rules_->a, rules_->b); - if(!quiet) printf(".. %s\n", src_); + if(!quiet) printf(".. %s\nCompleted in %d rewrites.\n", src_, rw); return 0; } \ No newline at end of file From 392e05d19e5013415ad48fcea197eec4d5cc45a4 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sat, 27 Apr 2024 09:02:56 -0700 Subject: [PATCH 08/45] Send everything to stdout --- src/modal.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/modal.c b/src/modal.c index fdc68e8..8a594e1 100644 --- a/src/modal.c +++ b/src/modal.c @@ -139,7 +139,7 @@ apply_rule(Rule *r, char *s) while(*s == ' ') s++; if(*s == ')' && *(dst_ - 1) == ' ') dst_--; } - if(!quiet && r) fprintf(stderr, "%02d %s\n", r->id, src_), ++r->refs; + if(!quiet && r) printf("%02d %s\n", r->id, src_), ++r->refs; return write_tail(s); } @@ -216,7 +216,7 @@ rewrite(void) if(c == '<' && s[1] == '>') { r = rules_++; s = compile_rule(r, rules_ - rules - 1, s + 2); - if(!quiet && r->a) fprintf(stderr, "<> (%s) (%s)\n", r->a, r->b); + if(!quiet && r->a) printf("<> (%s) (%s)\n", r->a, r->b); while(*s == ' ') s++; return write_tail(s); } @@ -225,7 +225,7 @@ rewrite(void) s += 2; while(*s == ' ') s++; cap = walk(s), r = find_rule(s, cap), r->a = 0; - if(!quiet && r->a) fprintf(stderr, ">< (%s)\n", r->a); + if(!quiet && r->a) printf(">< (%s)\n", r->a); while(*cap == ' ') cap++; return write_tail(cap); } @@ -263,7 +263,7 @@ main(int argc, char **argv) } } if(!(f = fopen(argv[i], "r"))) - return !fprintf(stdout, "Modal file invalid: %s.\n", argv[i]); + return !printf("Modal file invalid: %s.\n", argv[i]); while(fread(&c, 1, 1, f)) { c = c <= 0x20 ? 0x20 : c; if(c == ' ' && last == '(') continue; @@ -278,11 +278,14 @@ main(int argc, char **argv) while(*(--w) <= ' ') *w = 0; fclose(f); if(pr != pl) - return !fprintf(stdout, "Modal program imbalanced.\n"); + return !printf("Modal program imbalanced.\n"); while(rewrite() && ++rw) - if(!cycles--) return !fprintf(stdout, "Modal rewrites exceeded.\n"); - while(rules_-- > rules && !quiet) - if(!rules_->refs && rules_->a) printf("-- Unused rule: %d <> (%s) (%s)\n", rules_->refs, rules_->a, rules_->b); - if(!quiet) printf(".. %s\nCompleted in %d rewrites.\n", src_, rw); + if(!cycles--) return !printf("Modal rewrites exceeded.\n"); + if(!quiet) { + while(rules_-- > rules) + if(!rules_->refs && rules_->a) + printf("-- Unused rule: %d <> (%s) (%s)\n", rules_->refs, rules_->a, rules_->b); + printf(".. %s\nCompleted in %d rewrites.\n", src_, rw); + } return 0; } \ No newline at end of file From a2ea2a6ac26a33b72954908a09329af184dd9a1e Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sat, 27 Apr 2024 09:24:48 -0700 Subject: [PATCH 09/45] Pretty print rules --- src/modal.c | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/src/modal.c b/src/modal.c index 8a594e1..c7bc1a4 100644 --- a/src/modal.c +++ b/src/modal.c @@ -2,7 +2,7 @@ typedef struct { unsigned int id, refs, ptr; - char *a, *b, reg[0x8]; + char *a, *b, reg[8]; } Rule; static int flip, quiet, cycles = 0x10000; @@ -102,8 +102,8 @@ write_tail(char *s) static int apply_rule(Rule *r, char *s) { - unsigned int i, id; - char c, *a = r->a, *b = r->b, *origin = dst_, *reg, *regs[0x8]; + unsigned int i, rid; + char c, *a = r->a, *b = r->b, *origin = dst_, *reg, *regs[8]; /* phase: clean regs */ for(i = 0; i < r->ptr; i++) regs[i] = NULL; @@ -111,13 +111,13 @@ apply_rule(Rule *r, char *s) while((c = *a++)) { if(c == '?') { char *pcap = walk(s); - id = *a++ - '0'; - if((reg = regs[id])) { /* reg cmp */ + rid = *a++ - '0'; + if((reg = regs[rid])) { /* reg cmp */ char *rcap = walk(reg), *pp = s; while(reg < rcap || pp < pcap) if(*reg++ != *pp++) return 0; } else /* reg set */ - regs[id] = s; + regs[rid] = s; s = pcap; } else if(c != *s++) return 0; @@ -127,9 +127,9 @@ apply_rule(Rule *r, char *s) /* phase: write rule */ while((c = *b++)) { if(c == '?') { - id = *b - '0'; - if(id < 9 && (reg = regs[id])) - b++, write_reg(r->reg[id], reg); + rid = *b - '0'; + if(rid < 9 && (reg = regs[rid])) + b++, write_reg(r->reg[rid], reg); else *dst_++ = c; } else @@ -146,9 +146,9 @@ apply_rule(Rule *r, char *s) static int find_reg(Rule *r, char reg) { - int i; - for(i = 0; i < (int)r->ptr; i++) - if(r->reg[i] == reg) return i; + int rid; + for(rid = 0; rid < (int)r->ptr; rid++) + if(r->reg[rid] == reg) return rid; return -1; } @@ -204,6 +204,20 @@ find_rule(char *s, char *cap) return r; } +static void +echo_rule(Rule *r, char *field) +{ + char c, *s = field; + putc('(', stdout); + while((c = *s++)) { + int rid; + putc(c, stdout); + if(c == '?') + c = *s++, rid = c - '0', putc(rid < 8 ? r->reg[rid] : c, stdout); + } + putc(')', stdout), putc(' ', stdout); +} + static int rewrite(void) { @@ -216,7 +230,8 @@ rewrite(void) if(c == '<' && s[1] == '>') { r = rules_++; s = compile_rule(r, rules_ - rules - 1, s + 2); - if(!quiet && r->a) printf("<> (%s) (%s)\n", r->a, r->b); + if(!quiet && r->a) + printf("<> "), echo_rule(r, r->a), echo_rule(r, r->b), putc('\n', stdout); while(*s == ' ') s++; return write_tail(s); } @@ -225,7 +240,8 @@ rewrite(void) s += 2; while(*s == ' ') s++; cap = walk(s), r = find_rule(s, cap), r->a = 0; - if(!quiet && r->a) printf(">< (%s)\n", r->a); + if(!quiet && r->a) + printf(">< "), echo_rule(r, r->a), putc('\n', stdout); while(*cap == ' ') cap++; return write_tail(cap); } From 1fae8de0d580e7987787c5d68415006479bdb5fa Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sat, 27 Apr 2024 09:48:10 -0700 Subject: [PATCH 10/45] rid is always unsigned --- examples/postcard.modal | 2 -- src/modal.c | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/examples/postcard.modal b/examples/postcard.modal index 478b784..ffa521d 100644 --- a/examples/postcard.modal +++ b/examples/postcard.modal @@ -1,4 +1,3 @@ - <> (what is ?x) (is ?x a (programming language)) <> (is ?x a ?y) (or, is ?x (a virtual machine)) <> (or, is ?x ?y) (?x is ?y <> ?y (a meta-language)) @@ -6,4 +5,3 @@ <> (?x is ?x) (?(?: ?:) ?x) what is modal - diff --git a/src/modal.c b/src/modal.c index c7bc1a4..1cb3d72 100644 --- a/src/modal.c +++ b/src/modal.c @@ -210,10 +210,10 @@ echo_rule(Rule *r, char *field) char c, *s = field; putc('(', stdout); while((c = *s++)) { - int rid; + unsigned int rid; putc(c, stdout); if(c == '?') - c = *s++, rid = c - '0', putc(rid < 8 ? r->reg[rid] : c, stdout); + c = *s++, rid = c - '0', putc(rid < 9 ? r->reg[rid] : c, stdout); } putc(')', stdout), putc(' ', stdout); } From f8657a5f674a06c9d95b3565bf745a5201a0cb51 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sat, 27 Apr 2024 10:04:01 -0700 Subject: [PATCH 11/45] Display undefinitions --- src/modal.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modal.c b/src/modal.c index 1cb3d72..05833e2 100644 --- a/src/modal.c +++ b/src/modal.c @@ -239,9 +239,10 @@ rewrite(void) if(c == '>' && s[1] == '<') { s += 2; while(*s == ' ') s++; - cap = walk(s), r = find_rule(s, cap), r->a = 0; + cap = walk(s), r = find_rule(s, cap); if(!quiet && r->a) printf(">< "), echo_rule(r, r->a), putc('\n', stdout); + r->a = 0; while(*cap == ' ') cap++; return write_tail(cap); } From d03f359f4c5e3b626ce4cff871073d1d6c21316e Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sat, 27 Apr 2024 10:51:50 -0700 Subject: [PATCH 12/45] Better rules lookup --- src/modal.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/modal.c b/src/modal.c index 05833e2..c4413de 100644 --- a/src/modal.c +++ b/src/modal.c @@ -196,18 +196,17 @@ 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) return r; + while(*ss++ == *a++) + if(!*a && ss == cap) return r; r++; } return r; } static void -echo_rule(Rule *r, char *field) +echo_rule(Rule *r, char *s) { - char c, *s = field; + char c; putc('(', stdout); while((c = *s++)) { unsigned int rid; From 3d01efe11a4723167e7d58574e5e997c0ae853a9 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sat, 27 Apr 2024 11:05:50 -0700 Subject: [PATCH 13/45] Print right statement during undefinition --- src/modal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modal.c b/src/modal.c index c4413de..af90ee5 100644 --- a/src/modal.c +++ b/src/modal.c @@ -240,7 +240,7 @@ rewrite(void) while(*s == ' ') s++; cap = walk(s), r = find_rule(s, cap); if(!quiet && r->a) - printf(">< "), echo_rule(r, r->a), putc('\n', stdout); + printf(">< "), echo_rule(r, r->a), echo_rule(r, r->b), putc('\n', stdout); r->a = 0; while(*cap == ' ') cap++; return write_tail(cap); From 62b8317cc99de564322992b45666c0a9f715777f Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sat, 27 Apr 2024 11:24:00 -0700 Subject: [PATCH 14/45] Added tests --- examples/tests.modal | 13 +++++++++++++ src/modal.c | 5 +++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/examples/tests.modal b/examples/tests.modal index 62acf6e..68e7c8f 100644 --- a/examples/tests.modal +++ b/examples/tests.modal @@ -93,6 +93,19 @@ reverse (modal) = ladom (reverse 1) test nap tap (inline 1) test +?(?-) (Undefinition) + +<> (undefine-me) (abc) +<> (undefine-me) (def) +<> (undefine-me) (ghi) +>< (undefine-me) + +(undefine-me) = (def) (undefinition 1) test + +>< (undefine-me) + +(undefine-me) = (ghi) (undefinition 2) test + ?(?-) (Late Test Primitives) <> (?x = ?y ?n test) (?(?: ?:) (#fail ?n found: ?x expect: ?y\n)) \ No newline at end of file diff --git a/src/modal.c b/src/modal.c index af90ee5..221ade7 100644 --- a/src/modal.c +++ b/src/modal.c @@ -196,8 +196,9 @@ find_rule(char *s, char *cap) if(*s == '(') s++, cap--; while(r < rules_) { char *ss = s, *a = r->a; - while(*ss++ == *a++) - if(!*a && ss == cap) return r; + if(a) + while(*ss++ == *a++) + if(!*a && ss == cap) return r; r++; } return r; From 2ba7085bfb6cdfcec76f1fd9463e0a1bcd2fdc27 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sat, 27 Apr 2024 11:29:46 -0700 Subject: [PATCH 15/45] Added tests --- examples/tests.modal | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/tests.modal b/examples/tests.modal index 68e7c8f..a642d9f 100644 --- a/examples/tests.modal +++ b/examples/tests.modal @@ -106,6 +106,12 @@ nap tap (inline 1) test (undefine-me) = (ghi) (undefinition 2) test +>< (undefine-unknown) + +?(* (>< (undefine-me))) * + +(undefine-me) = (undefine-me) (undefinition 3) test + ?(?-) (Late Test Primitives) <> (?x = ?y ?n test) (?(?: ?:) (#fail ?n found: ?x expect: ?y\n)) \ No newline at end of file From b0f9ba84e304b1b718fc2fefb4c7c2766e2cfeae Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sat, 27 Apr 2024 11:55:32 -0700 Subject: [PATCH 16/45] Added tests --- examples/tests.modal | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/tests.modal b/examples/tests.modal index a642d9f..7351dbe 100644 --- a/examples/tests.modal +++ b/examples/tests.modal @@ -86,6 +86,15 @@ abc ?(?x) def = abc (lambda 2) test reverse (modal) = ladom (reverse 1) test +?(?-) (Incomplete definitions) + +<> (incomplete-basic) +<> (incomplete-reg ?x) +<> (waste-rule) * + +(incomplete-basic) = () (incomplete 1) test +(incomplete-reg abcdef) = () (incomplete 2) test + ?(?-) (Inline rules) <> ((?x -> ?y)) (<> ?x ?y) From d520ab848960a899fb93de36911713d175a2135f Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sat, 27 Apr 2024 12:30:40 -0700 Subject: [PATCH 17/45] Added tests, ignoring empty rules --- examples/tests.modal | 3 +++ src/modal.c | 11 +++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/examples/tests.modal b/examples/tests.modal index 7351dbe..9f6bd51 100644 --- a/examples/tests.modal +++ b/examples/tests.modal @@ -88,12 +88,15 @@ reverse (modal) = ladom (reverse 1) test ?(?-) (Incomplete definitions) +<> <> +<> () () <> (incomplete-basic) <> (incomplete-reg ?x) <> (waste-rule) * (incomplete-basic) = () (incomplete 1) test (incomplete-reg abcdef) = () (incomplete 2) test +(?(?x) incomplete-lambda) = () (incomplete 3) test ?(?-) (Inline rules) diff --git a/src/modal.c b/src/modal.c index 221ade7..837f271 100644 --- a/src/modal.c +++ b/src/modal.c @@ -228,11 +228,14 @@ rewrite(void) Rule *r = NULL; /* phase: define */ if(c == '<' && s[1] == '>') { - r = rules_++; + r = rules_; s = compile_rule(r, rules_ - rules - 1, s + 2); - if(!quiet && r->a) - printf("<> "), echo_rule(r, r->a), echo_rule(r, r->b), putc('\n', stdout); - while(*s == ' ') s++; + if(*r->a) { + if(!quiet && r->a) + printf("<> "), echo_rule(r, r->a), echo_rule(r, r->b), putc('\n', stdout); + while(*s == ' ') s++; + rules_++; + } return write_tail(s); } /* phase: undefine */ From dd1fddb20c317ada93b6cd1b63d1b086857c16c8 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sat, 27 Apr 2024 14:47:06 -0700 Subject: [PATCH 18/45] Removed rules compilation step --- src/modal.c | 69 +++++++++++++++++------------------------------------ 1 file changed, 22 insertions(+), 47 deletions(-) diff --git a/src/modal.c b/src/modal.c index 837f271..19e19f3 100644 --- a/src/modal.c +++ b/src/modal.c @@ -1,15 +1,17 @@ #include typedef struct { - unsigned int id, refs, ptr; - char *a, *b, reg[8]; + unsigned int id, refs; + char *a, *b; } Rule; +static unsigned char rmin = 0xff, rmax = 0x00; static int flip, quiet, cycles = 0x10000; static Rule rules[0x1000], *rules_ = rules, lambda; static char dict[0x8000], *dict_ = dict, empty; static char bank_a[0x4000], *src_ = bank_a; static char bank_b[0x4000], *dst_ = bank_b; +static char *regs[0x100]; #define spacer(c) (c <= ' ' || c == '(' || c == ')') @@ -103,21 +105,27 @@ static int apply_rule(Rule *r, char *s) { unsigned int i, rid; - char c, *a = r->a, *b = r->b, *origin = dst_, *reg, *regs[8]; + char c, *a = r->a, *b = r->b, *origin = dst_, *reg; /* phase: clean regs */ - for(i = 0; i < r->ptr; i++) - regs[i] = NULL; + if(rmax) { + for(i = 0; i <= rmax; i++) + regs[i] = 0; + rmin = 0xff, rmax = 0x00; + } /* phase: match rule */ while((c = *a++)) { if(c == '?') { char *pcap = walk(s); - rid = *a++ - '0'; + rid = *a++; if((reg = regs[rid])) { /* reg cmp */ char *rcap = walk(reg), *pp = s; while(reg < rcap || pp < pcap) if(*reg++ != *pp++) return 0; - } else /* reg set */ + } else { /* reg set */ regs[rid] = s; + if(rid < rmin) rmin = rid; + if(rid > rmax) rmax = rid; + } s = pcap; } else if(c != *s++) return 0; @@ -127,9 +135,9 @@ apply_rule(Rule *r, char *s) /* phase: write rule */ while((c = *b++)) { if(c == '?') { - rid = *b - '0'; - if(rid < 9 && (reg = regs[rid])) - b++, write_reg(r->reg[rid], reg); + rid = *b; + if((reg = regs[rid])) + b++, write_reg(rid, reg); else *dst_++ = c; } else @@ -143,21 +151,12 @@ apply_rule(Rule *r, char *s) return write_tail(s); } -static int -find_reg(Rule *r, char reg) -{ - int rid; - for(rid = 0; rid < (int)r->ptr; rid++) - if(r->reg[rid] == reg) return rid; - return -1; -} - static char * compile_rule(Rule *r, int id, char *src) { char c, *cap; - int wrapped, reg; - r->id = id, r->ptr = 0, r->a = &empty, r->b = ∅ + int wrapped; + r->id = id, r->a = &empty, r->b = ∅ /* phase: compile left */ while((c = *src) && c == ' ') src++; if(c == ')' || (c == '<' && src[1] == '>')) return src; @@ -165,12 +164,6 @@ compile_rule(Rule *r, int id, char *src) if(wrapped) src++, cap--; while(src < cap) { c = *src, *dict_++ = *src++; - if(c == '?') { - c = *src++, reg = find_reg(r, c); - if(reg == -1 && c != '(') - r->reg[r->ptr] = c, reg = r->ptr++; - *dict_++ = '0' + reg; - } } src += wrapped, *dict_++ = 0; /* phase: compile right */ @@ -180,10 +173,6 @@ compile_rule(Rule *r, int id, char *src) if(wrapped) src++, cap--; while(src < cap) { c = *src, *dict_++ = *src++; - if(c == '?') { - c = *src++, reg = find_reg(r, c); - *dict_++ = reg != -1 ? '0' + reg : c; - } } src += wrapped, *dict_++ = 0; return src; @@ -204,20 +193,6 @@ find_rule(char *s, char *cap) return r; } -static void -echo_rule(Rule *r, char *s) -{ - char c; - putc('(', stdout); - while((c = *s++)) { - unsigned int rid; - putc(c, stdout); - if(c == '?') - c = *s++, rid = c - '0', putc(rid < 9 ? r->reg[rid] : c, stdout); - } - putc(')', stdout), putc(' ', stdout); -} - static int rewrite(void) { @@ -232,7 +207,7 @@ rewrite(void) s = compile_rule(r, rules_ - rules - 1, s + 2); if(*r->a) { if(!quiet && r->a) - printf("<> "), echo_rule(r, r->a), echo_rule(r, r->b), putc('\n', stdout); + printf("<> (%s) (%s)\n", r->a, r->b); while(*s == ' ') s++; rules_++; } @@ -244,7 +219,7 @@ rewrite(void) while(*s == ' ') s++; cap = walk(s), r = find_rule(s, cap); if(!quiet && r->a) - printf(">< "), echo_rule(r, r->a), echo_rule(r, r->b), putc('\n', stdout); + printf(">< (%s) (%s)\n", r->a, r->b); r->a = 0; while(*cap == ' ') cap++; return write_tail(cap); From 93326ecf73fd8eb1bb300bb1b8ece9de1a3e0d63 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sat, 27 Apr 2024 15:06:00 -0700 Subject: [PATCH 19/45] Merged rule parsers --- src/modal.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/modal.c b/src/modal.c index 19e19f3..efa3e57 100644 --- a/src/modal.c +++ b/src/modal.c @@ -104,7 +104,7 @@ write_tail(char *s) static int apply_rule(Rule *r, char *s) { - unsigned int i, rid; + unsigned char i, rid; char c, *a = r->a, *b = r->b, *origin = dst_, *reg; /* phase: clean regs */ if(rmax) { @@ -152,28 +152,23 @@ apply_rule(Rule *r, char *s) } static char * -compile_rule(Rule *r, int id, char *src) +parse_frag(Rule *r, int side, char *src) { - char c, *cap; int wrapped; - r->id = id, r->a = &empty, r->b = ∅ - /* phase: compile left */ + char c, *cap; + if(side) + r->b = ∅ + else + r->a = ∅ while((c = *src) && c == ' ') src++; if(c == ')' || (c == '<' && src[1] == '>')) return src; - r->a = dict_, cap = walk(src), wrapped = c == '('; + if(side) + r->b = dict_; + else + r->a = dict_; + cap = walk(src), wrapped = c == '('; if(wrapped) src++, cap--; - while(src < cap) { - c = *src, *dict_++ = *src++; - } - src += wrapped, *dict_++ = 0; - /* phase: compile right */ - while((c = *src) && c == ' ') src++; - if(c == ')' || (c == '<' && src[1] == '>')) return src; - r->b = dict_, cap = walk(src), wrapped = c == '('; - if(wrapped) src++, cap--; - while(src < cap) { - c = *src, *dict_++ = *src++; - } + while(src < cap) c = *src, *dict_++ = *src++; src += wrapped, *dict_++ = 0; return src; } @@ -203,8 +198,8 @@ rewrite(void) Rule *r = NULL; /* phase: define */ if(c == '<' && s[1] == '>') { - r = rules_; - s = compile_rule(r, rules_ - rules - 1, s + 2); + r = rules_, r->id = rules_ - rules - 1; + s = parse_frag(r, 1, parse_frag(r, 0, s + 2)); if(*r->a) { if(!quiet && r->a) printf("<> (%s) (%s)\n", r->a, r->b); @@ -226,7 +221,10 @@ rewrite(void) } /* phase: lambda */ if(c == '?' && s[1] == '(') { - cap = walk(s + 1), compile_rule(&lambda, -1, s + 2), s = cap; + cap = walk(s + 1); + r = &lambda, r->id = -1; + parse_frag(r, 1, parse_frag(r, 0, s + 2)); + s = cap; while(*s == ' ') s++; if(!apply_rule(&lambda, s)) write_tail(s); return 1; From 481e2b56cf0ce1a009e0dd1bfa83213fedf477f3 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sat, 27 Apr 2024 21:12:14 -0700 Subject: [PATCH 20/45] Housekeeping --- examples/tests.modal | 1 + src/modal.c | 53 +++++++++++++++++++++----------------------- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/examples/tests.modal b/examples/tests.modal index 9f6bd51..36a12d9 100644 --- a/examples/tests.modal +++ b/examples/tests.modal @@ -97,6 +97,7 @@ reverse (modal) = ladom (reverse 1) test (incomplete-basic) = () (incomplete 1) test (incomplete-reg abcdef) = () (incomplete 2) test (?(?x) incomplete-lambda) = () (incomplete 3) test +(?() abc) = (abc) (incomplete 4) test ?(?-) (Inline rules) diff --git a/src/modal.c b/src/modal.c index efa3e57..8677d23 100644 --- a/src/modal.c +++ b/src/modal.c @@ -152,21 +152,16 @@ apply_rule(Rule *r, char *s) } static char * -parse_frag(Rule *r, int side, char *src) +parse_frag(char **side, char *src) { int wrapped; char c, *cap; - if(side) - r->b = ∅ - else - r->a = ∅ while((c = *src) && c == ' ') src++; - if(c == ')' || (c == '<' && src[1] == '>')) return src; - if(side) - r->b = dict_; - else - r->a = dict_; - cap = walk(src), wrapped = c == '('; + if(c == ')' || (c == '<' && src[1] == '>')) { + *side = ∅ + return src; + } + *side = dict_, cap = walk(src), wrapped = c == '('; if(wrapped) src++, cap--; while(src < cap) c = *src, *dict_++ = *src++; src += wrapped, *dict_++ = 0; @@ -185,7 +180,7 @@ find_rule(char *s, char *cap) if(!*a && ss == cap) return r; r++; } - return r; + return NULL; } static int @@ -196,34 +191,36 @@ rewrite(void) while((c = *s)) { if(c == '(' || spacer(last)) { Rule *r = NULL; - /* phase: define */ - if(c == '<' && s[1] == '>') { - r = rules_, r->id = rules_ - rules - 1; - s = parse_frag(r, 1, parse_frag(r, 0, s + 2)); - if(*r->a) { - if(!quiet && r->a) - printf("<> (%s) (%s)\n", r->a, r->b); - while(*s == ' ') s++; - rules_++; - } - return write_tail(s); - } /* phase: undefine */ if(c == '>' && s[1] == '<') { s += 2; while(*s == ' ') s++; cap = walk(s), r = find_rule(s, cap); - if(!quiet && r->a) - printf(">< (%s) (%s)\n", r->a, r->b); - r->a = 0; + if(r != NULL){ + if(!quiet && r->a) + printf(">< (%s) (%s)\n", r->a, r->b); + r->a = 0; + } while(*cap == ' ') cap++; return write_tail(cap); } + /* phase: define */ + if(c == '<' && s[1] == '>') { + r = rules_, r->id = rules_ - rules - 1; + s = parse_frag(&r->b, parse_frag(&r->a, s + 2)); + if(*r->a){ + if(!quiet) + printf("<> (%s) (%s)\n", r->a, r->b); + rules_++; + } + while(*s == ' ') s++; + return write_tail(s); + } /* phase: lambda */ if(c == '?' && s[1] == '(') { cap = walk(s + 1); r = &lambda, r->id = -1; - parse_frag(r, 1, parse_frag(r, 0, s + 2)); + parse_frag(&r->b, parse_frag(&r->a, s + 2)); s = cap; while(*s == ' ') s++; if(!apply_rule(&lambda, s)) write_tail(s); From f5cd5d3fa3b572ee4dcff59856b972b9c8e73f37 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sat, 27 Apr 2024 21:21:15 -0700 Subject: [PATCH 21/45] Removed extra check --- src/modal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modal.c b/src/modal.c index 8677d23..e9b54fe 100644 --- a/src/modal.c +++ b/src/modal.c @@ -197,7 +197,7 @@ rewrite(void) while(*s == ' ') s++; cap = walk(s), r = find_rule(s, cap); if(r != NULL){ - if(!quiet && r->a) + if(!quiet) printf(">< (%s) (%s)\n", r->a, r->b); r->a = 0; } From 42ab70b09d418f82c1404d0bd678761c3c48dd19 Mon Sep 17 00:00:00 2001 From: Sebastian LaVine Date: Sun, 28 Apr 2024 03:15:25 -0400 Subject: [PATCH 22/45] Re-add stderr usage This commit spiritually reverts 392e05d. With debug messages and interpreter state sent to stderr and the actual output of the program sent to stdout, it is easier to read both independently. For instance, one can redirect stdout or stderr to another terminal window to keep an eye on both outputs independently: bin/modal examples/hello.modal >/dev/pts/5 --- src/modal.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/modal.c b/src/modal.c index e9b54fe..fe3767e 100644 --- a/src/modal.c +++ b/src/modal.c @@ -147,7 +147,7 @@ apply_rule(Rule *r, char *s) while(*s == ' ') s++; if(*s == ')' && *(dst_ - 1) == ' ') dst_--; } - if(!quiet && r) printf("%02d %s\n", r->id, src_), ++r->refs; + if(!quiet && r) fprintf(stderr, "%02d %s\n", r->id, src_), ++r->refs; return write_tail(s); } @@ -198,7 +198,7 @@ rewrite(void) cap = walk(s), r = find_rule(s, cap); if(r != NULL){ if(!quiet) - printf(">< (%s) (%s)\n", r->a, r->b); + fprintf(stderr, ">< (%s) (%s)\n", r->a, r->b); r->a = 0; } while(*cap == ' ') cap++; @@ -210,7 +210,7 @@ rewrite(void) s = parse_frag(&r->b, parse_frag(&r->a, s + 2)); if(*r->a){ if(!quiet) - printf("<> (%s) (%s)\n", r->a, r->b); + fprintf(stderr, "<> (%s) (%s)\n", r->a, r->b); rules_++; } while(*s == ' ') s++; @@ -268,14 +268,14 @@ main(int argc, char **argv) while(*(--w) <= ' ') *w = 0; fclose(f); if(pr != pl) - return !printf("Modal program imbalanced.\n"); + return !fprintf(stderr, "Modal program imbalanced.\n"); while(rewrite() && ++rw) - if(!cycles--) return !printf("Modal rewrites exceeded.\n"); + if(!cycles--) return !fprintf(stderr, "Modal rewrites exceeded.\n"); if(!quiet) { while(rules_-- > rules) if(!rules_->refs && rules_->a) - printf("-- Unused rule: %d <> (%s) (%s)\n", rules_->refs, rules_->a, rules_->b); - printf(".. %s\nCompleted in %d rewrites.\n", src_, rw); + fprintf(stderr, "-- Unused rule: %d <> (%s) (%s)\n", rules_->refs, rules_->a, rules_->b); + fprintf(stderr, ".. %s\nCompleted in %d rewrites.\n", src_, rw); } return 0; -} \ No newline at end of file +} From 06c5c3c3da79a17535ec17e2ef6fc9ce1a3c19e6 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sun, 28 Apr 2024 12:32:46 -0700 Subject: [PATCH 23/45] Display references in debug --- src/modal.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/modal.c b/src/modal.c index fe3767e..7fcba74 100644 --- a/src/modal.c +++ b/src/modal.c @@ -6,7 +6,7 @@ typedef struct { } Rule; static unsigned char rmin = 0xff, rmax = 0x00; -static int flip, quiet, cycles = 0x10000; +static int flip, quiet, debug, cycles = 0x10000; static Rule rules[0x1000], *rules_ = rules, lambda; static char dict[0x8000], *dict_ = dict, empty; static char bank_a[0x4000], *src_ = bank_a; @@ -247,8 +247,9 @@ 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, 27 Apr 2024.\n"); + case 'v': /* version */ return !printf("Modal Interpreter, 28 Apr 2024.\n"); case 'q': /* quiet */ quiet = 1; break; + case 'p': /* debug */ debug = 1; break; case 'n': /* infinite */ cycles = 0xffffffff; break; } } @@ -272,9 +273,12 @@ main(int argc, char **argv) while(rewrite() && ++rw) if(!cycles--) return !fprintf(stderr, "Modal rewrites exceeded.\n"); if(!quiet) { - while(rules_-- > rules) + while(rules_-- > rules){ if(!rules_->refs && rules_->a) - fprintf(stderr, "-- Unused rule: %d <> (%s) (%s)\n", rules_->refs, rules_->a, rules_->b); + fprintf(stderr, "-- Unused rule: %d <> (%s) (%s)\n", rules_->id, rules_->a, rules_->b); + if(debug && rules_->a) + fprintf(stderr, " (%s) (%s), %d times.\n", rules_->a, rules_->b, rules_->refs); + } fprintf(stderr, ".. %s\nCompleted in %d rewrites.\n", src_, rw); } return 0; From 1ddc66e1dd377a343a20c0ef461bfa21148250f6 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sun, 28 Apr 2024 17:27:38 -0700 Subject: [PATCH 24/45] Added print flag --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 033992c..f3ca1ea 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ cc src/modal.c -o bin/modal bin/modal examples/hello.modal -v Print version -q Quiet mode, no step printing + -p Print summary with refs count -n Infinite mode, no rewrites limit ``` From 53b89bcf653d904a3403dfae54e8d622a5e984eb Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sun, 28 Apr 2024 18:55:03 -0700 Subject: [PATCH 25/45] Isolated device read/write functions --- src/modal.c | 59 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/src/modal.c b/src/modal.c index 7fcba74..4095b43 100644 --- a/src/modal.c +++ b/src/modal.c @@ -31,32 +31,47 @@ walk(char *s) return s; } +static void +device_write(char *s) +{ + char c, *cap = walk(s); + if(*s == '(') s++, --cap; + while(s < cap) { + c = *s++; + if(c == '\\') { + switch(*s++) { + case 't': putc(0x09, stdout); break; + case 'n': putc(0x0a, stdout); break; + case 's': putc(0x20, stdout); break; + } + } else + putc(c, stdout); + } +} + +static void +device_read(char *s) +{ + char c; + while(fread(&c, 1, 1, stdin) && c >= ' ') + *dst_++ = c; + if(feof(stdin)) + *dst_++ = 'E', *dst_++ = 'O', *dst_++ = 'F'; +} + static void write_reg(char r, char *reg) { char c, *cap = walk(reg); switch(r) { - case ':': /* op: output */ - if(*reg == '(') reg++, --cap; - while(reg < cap) { - c = *reg++; - if(c == '\\') { - switch(*reg++) { - case 't': putc(0x09, stdout); break; - case 'n': putc(0x0a, stdout); break; - case 's': putc(0x20, stdout); break; - } - } else - putc(c, stdout); - } + case '>': /* op: output */ + case ':': + device_write(reg); return; - case '~': { /* op: input */ - while(fread(&c, 1, 1, stdin) && c >= ' ') - *dst_++ = c; - if(feof(stdin)) - *dst_++ = 'E', *dst_++ = 'O', *dst_++ = 'F'; + case '<': /* op: input */ + case '~': + device_read(reg); return; - } case '^': /* op: join */ if(*reg == '(') reg++, --cap; while(reg < cap && (c = *reg++)) @@ -196,7 +211,7 @@ rewrite(void) s += 2; while(*s == ' ') s++; cap = walk(s), r = find_rule(s, cap); - if(r != NULL){ + if(r != NULL) { if(!quiet) fprintf(stderr, ">< (%s) (%s)\n", r->a, r->b); r->a = 0; @@ -208,7 +223,7 @@ rewrite(void) if(c == '<' && s[1] == '>') { r = rules_, r->id = rules_ - rules - 1; s = parse_frag(&r->b, parse_frag(&r->a, s + 2)); - if(*r->a){ + if(*r->a) { if(!quiet) fprintf(stderr, "<> (%s) (%s)\n", r->a, r->b); rules_++; @@ -273,7 +288,7 @@ main(int argc, char **argv) while(rewrite() && ++rw) if(!cycles--) return !fprintf(stderr, "Modal rewrites exceeded.\n"); if(!quiet) { - while(rules_-- > rules){ + while(rules_-- > rules) { if(!rules_->refs && rules_->a) fprintf(stderr, "-- Unused rule: %d <> (%s) (%s)\n", rules_->id, rules_->a, rules_->b); if(debug && rules_->a) From 25837b08f945144e9b7817e0b4d699daf08095f5 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sun, 28 Apr 2024 19:45:46 -0700 Subject: [PATCH 26/45] Starting ALU --- src/modal.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/modal.c b/src/modal.c index 4095b43..bd87ae0 100644 --- a/src/modal.c +++ b/src/modal.c @@ -31,10 +31,30 @@ walk(char *s) return s; } +static int +sint(char *s) +{ + int acc = 0; + char c; + while((c = *s++) && c > 0x20) acc *= 10, acc += c - '0'; + return acc; +} + static void device_write(char *s) { - char c, *cap = walk(s); + int acc = 0; + char c = *s, *cap = walk(s), *reg = regs['0']; + if(reg) { + switch(c) { + case '+': + for(acc = sint(reg++); *reg; reg++) acc = acc + sint(reg); + break; + } + dst_ += snprintf(dst_, 0x10, "%d\n", acc); + return; + } + if(*s == '(') s++, --cap; while(s < cap) { c = *s++; From 0a1b6bfb5c8b97f184cbe6432e998694c55559f2 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sun, 28 Apr 2024 20:07:41 -0700 Subject: [PATCH 27/45] Added rest of ALU --- makefile | 2 +- src/modal.c | 26 +++++++++++++++++--------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/makefile b/makefile index 24e2457..563ad91 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,5 @@ RELEASE_flags=-DNDEBUG -O2 -g0 -s -DEBUG_flags=-std=c89 -D_POSIX_C_SOURCE=199309L -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined +DEBUG_flags=-std=c99 -D_POSIX_C_SOURCE=199309L -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined .PHONY: all debug dest run debug test install uninstall format clean archive diff --git a/src/modal.c b/src/modal.c index bd87ae0..f3d95ae 100644 --- a/src/modal.c +++ b/src/modal.c @@ -44,17 +44,25 @@ static void device_write(char *s) { int acc = 0; - char c = *s, *cap = walk(s), *reg = regs['0']; - if(reg) { + char c = *s, *cap = walk(s), **reg = regs + '0'; + /* phase: ALU */ + if(*reg) { switch(c) { - case '+': - for(acc = sint(reg++); *reg; reg++) acc = acc + sint(reg); - break; + /* clang-format off */ + case '+': for(acc = sint(*reg++); *reg != 0; reg++) acc += sint(*reg); break; + case '-': for(acc = sint(*reg++); *reg != 0; reg++) acc -= sint(*reg); break; + case '*': for(acc = sint(*reg++); *reg != 0; reg++) acc *= sint(*reg); break; + case '/': for(acc = sint(*reg++); *reg != 0; reg++) acc /= sint(*reg); break; + case '%': for(acc = sint(*reg++); *reg != 0; reg++) acc %= sint(*reg); break; + case '&': for(acc = sint(*reg++); *reg != 0; reg++) acc &= sint(*reg); break; + case '^': for(acc = sint(*reg++); *reg != 0; reg++) acc ^= sint(*reg); break; + case '|': for(acc = sint(*reg++); *reg != 0; reg++) acc |= sint(*reg); break; + /* clang-format on */ } - dst_ += snprintf(dst_, 0x10, "%d\n", acc); + dst_ += snprintf(dst_, 0x10, "%d", acc); return; } - + /* phase: string */ if(*s == '(') s++, --cap; while(s < cap) { c = *s++; @@ -70,7 +78,7 @@ device_write(char *s) } static void -device_read(char *s) +device_read(void) { char c; while(fread(&c, 1, 1, stdin) && c >= ' ') @@ -90,7 +98,7 @@ write_reg(char r, char *reg) return; case '<': /* op: input */ case '~': - device_read(reg); + device_read(); return; case '^': /* op: join */ if(*reg == '(') reg++, --cap; From c9e932765a37bc507d8f100bacfeb3fd34885ec9 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sun, 28 Apr 2024 20:13:51 -0700 Subject: [PATCH 28/45] Added logic operators to ALU --- src/modal.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/modal.c b/src/modal.c index f3d95ae..1590db5 100644 --- a/src/modal.c +++ b/src/modal.c @@ -47,8 +47,8 @@ device_write(char *s) char c = *s, *cap = walk(s), **reg = regs + '0'; /* phase: ALU */ if(*reg) { - switch(c) { /* clang-format off */ + switch(c) { case '+': for(acc = sint(*reg++); *reg != 0; reg++) acc += sint(*reg); break; case '-': for(acc = sint(*reg++); *reg != 0; reg++) acc -= sint(*reg); break; case '*': for(acc = sint(*reg++); *reg != 0; reg++) acc *= sint(*reg); break; @@ -57,8 +57,12 @@ device_write(char *s) case '&': for(acc = sint(*reg++); *reg != 0; reg++) acc &= sint(*reg); break; case '^': for(acc = sint(*reg++); *reg != 0; reg++) acc ^= sint(*reg); break; case '|': for(acc = sint(*reg++); *reg != 0; reg++) acc |= sint(*reg); break; - /* clang-format on */ + case '=': for(acc = sint(*reg++); *reg != 0; reg++) acc = acc == sint(*reg); break; + case '!': for(acc = sint(*reg++); *reg != 0; reg++) acc = acc != sint(*reg); break; + case '>': for(acc = sint(*reg++); *reg != 0; reg++) acc = acc > sint(*reg); break; + case '<': for(acc = sint(*reg++); *reg != 0; reg++) acc = acc < sint(*reg); break; } + /* clang-format on */ dst_ += snprintf(dst_, 0x10, "%d", acc); return; } From e84ef37c5dfd3d796ced3ab781bb251c6cdb26cf Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sun, 28 Apr 2024 20:37:53 -0700 Subject: [PATCH 29/45] Housekeeping --- src/modal.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/modal.c b/src/modal.c index 1590db5..8d20a94 100644 --- a/src/modal.c +++ b/src/modal.c @@ -34,10 +34,10 @@ walk(char *s) static int sint(char *s) { - int acc = 0; + int r = 0; char c; - while((c = *s++) && c > 0x20) acc *= 10, acc += c - '0'; - return acc; + while((c = *s++) && c > 0x20) r = r * 10 + c - '0'; + return r; } static void @@ -97,13 +97,9 @@ write_reg(char r, char *reg) char c, *cap = walk(reg); switch(r) { case '>': /* op: output */ - case ':': - device_write(reg); - return; + case ':': device_write(reg); return; case '<': /* op: input */ - case '~': - device_read(); - return; + case '~': device_read(); return; case '^': /* op: join */ if(*reg == '(') reg++, --cap; while(reg < cap && (c = *reg++)) @@ -244,8 +240,7 @@ rewrite(void) while(*s == ' ') s++; cap = walk(s), r = find_rule(s, cap); if(r != NULL) { - if(!quiet) - fprintf(stderr, ">< (%s) (%s)\n", r->a, r->b); + if(!quiet) fprintf(stderr, ">< (%s) (%s)\n", r->a, r->b); r->a = 0; } while(*cap == ' ') cap++; @@ -256,8 +251,7 @@ rewrite(void) r = rules_, r->id = rules_ - rules - 1; s = parse_frag(&r->b, parse_frag(&r->a, s + 2)); if(*r->a) { - if(!quiet) - fprintf(stderr, "<> (%s) (%s)\n", r->a, r->b); + if(!quiet) fprintf(stderr, "<> (%s) (%s)\n", r->a, r->b); rules_++; } while(*s == ' ') s++; From c644597eac7cf97a71aef99103b499c71bd8fe99 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sun, 28 Apr 2024 20:49:27 -0700 Subject: [PATCH 30/45] Fixed issue with delayed output --- src/modal.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/modal.c b/src/modal.c index 8d20a94..ebc959a 100644 --- a/src/modal.c +++ b/src/modal.c @@ -132,7 +132,7 @@ write_reg(char r, char *reg) } static int -write_tail(char *s) +write_tail(char *s, Rule *r) { while((*dst_++ = *s++)) ; @@ -141,6 +141,7 @@ write_tail(char *s) src_ = bank_b, dst_ = bank_a; else src_ = bank_a, dst_ = bank_b; + if(!quiet && r) fprintf(stderr, "%02d %s\n", r->id, src_), ++r->refs; return 1; } @@ -190,8 +191,7 @@ apply_rule(Rule *r, char *s) while(*s == ' ') s++; if(*s == ')' && *(dst_ - 1) == ' ') dst_--; } - if(!quiet && r) fprintf(stderr, "%02d %s\n", r->id, src_), ++r->refs; - return write_tail(s); + return write_tail(s, r); } static char * @@ -244,7 +244,7 @@ rewrite(void) r->a = 0; } while(*cap == ' ') cap++; - return write_tail(cap); + return write_tail(cap, NULL); } /* phase: define */ if(c == '<' && s[1] == '>') { @@ -255,7 +255,7 @@ rewrite(void) rules_++; } while(*s == ' ') s++; - return write_tail(s); + return write_tail(s, NULL); } /* phase: lambda */ if(c == '?' && s[1] == '(') { @@ -264,7 +264,7 @@ rewrite(void) parse_frag(&r->b, parse_frag(&r->a, s + 2)); s = cap; while(*s == ' ') s++; - if(!apply_rule(&lambda, s)) write_tail(s); + if(!apply_rule(&lambda, s)) write_tail(s, r); return 1; } /* phase: match */ From fb394db72d97295e8529ea3ba6e340e5d117c41b Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sun, 28 Apr 2024 20:58:47 -0700 Subject: [PATCH 31/45] Fixed issue with empty ?~ filling in blanks --- src/modal.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modal.c b/src/modal.c index ebc959a..305041e 100644 --- a/src/modal.c +++ b/src/modal.c @@ -84,11 +84,13 @@ device_write(char *s) static void device_read(void) { - char c; + char c, *origin = dst_; while(fread(&c, 1, 1, stdin) && c >= ' ') *dst_++ = c; if(feof(stdin)) *dst_++ = 'E', *dst_++ = 'O', *dst_++ = 'F'; + if(dst_ - origin == 0) + dst_--; } static void From 2f1df92c215394610c54817c32a77becddf0c719 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sun, 28 Apr 2024 21:15:56 -0700 Subject: [PATCH 32/45] Added arithmetic tests --- examples/tests.modal | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/examples/tests.modal b/examples/tests.modal index 36a12d9..845aa12 100644 --- a/examples/tests.modal +++ b/examples/tests.modal @@ -125,6 +125,13 @@ nap tap (inline 1) test (undefine-me) = (undefine-me) (undefinition 3) test +?(?-) (Arithmetic) + +?((?: ?0 ?1 ?2) (?:)) + 1 2 3 = 6 (Arithmetic 1) test +?((?0 ?: ?1) (?:)) 16 - 8 = 8 (Arithmetic 2) test +?((?0 ?1 ?:) (?:)) 12 10 * = 120 (Arithmetic 3) test + ?(?-) (Late Test Primitives) -<> (?x = ?y ?n test) (?(?: ?:) (#fail ?n found: ?x expect: ?y\n)) \ No newline at end of file +<> (?x = ?y ?n test) (?(?: ?:) (#fail ?n found: ?x expect: ?y\n)) + From 3d9ecb0b7b56ffd3e9f05dc0fba1ec334da1b024 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sun, 28 Apr 2024 21:23:27 -0700 Subject: [PATCH 33/45] Housekeeping --- src/modal.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/modal.c b/src/modal.c index 305041e..e4f5b6f 100644 --- a/src/modal.c +++ b/src/modal.c @@ -43,24 +43,24 @@ sint(char *s) static void device_write(char *s) { - int acc = 0; char c = *s, *cap = walk(s), **reg = regs + '0'; /* phase: ALU */ if(*reg) { + int acc = sint(*reg++); /* clang-format off */ switch(c) { - case '+': for(acc = sint(*reg++); *reg != 0; reg++) acc += sint(*reg); break; - case '-': for(acc = sint(*reg++); *reg != 0; reg++) acc -= sint(*reg); break; - case '*': for(acc = sint(*reg++); *reg != 0; reg++) acc *= sint(*reg); break; - case '/': for(acc = sint(*reg++); *reg != 0; reg++) acc /= sint(*reg); break; - case '%': for(acc = sint(*reg++); *reg != 0; reg++) acc %= sint(*reg); break; - case '&': for(acc = sint(*reg++); *reg != 0; reg++) acc &= sint(*reg); break; - case '^': for(acc = sint(*reg++); *reg != 0; reg++) acc ^= sint(*reg); break; - case '|': for(acc = sint(*reg++); *reg != 0; reg++) acc |= sint(*reg); break; - case '=': for(acc = sint(*reg++); *reg != 0; reg++) acc = acc == sint(*reg); break; - case '!': for(acc = sint(*reg++); *reg != 0; reg++) acc = acc != sint(*reg); break; - case '>': for(acc = sint(*reg++); *reg != 0; reg++) acc = acc > sint(*reg); break; - case '<': for(acc = sint(*reg++); *reg != 0; reg++) acc = acc < sint(*reg); break; + case '+': for(;*reg != 0; reg++) acc += sint(*reg); break; + case '-': for(;*reg != 0; reg++) acc -= sint(*reg); break; + case '*': for(;*reg != 0; reg++) acc *= sint(*reg); break; + case '/': for(;*reg != 0; reg++) acc /= sint(*reg); break; + case '%': for(;*reg != 0; reg++) acc %= sint(*reg); break; + case '&': for(;*reg != 0; reg++) acc &= sint(*reg); break; + case '^': for(;*reg != 0; reg++) acc ^= sint(*reg); break; + case '|': for(;*reg != 0; reg++) acc |= sint(*reg); break; + case '=': for(;*reg != 0; reg++) acc = acc == sint(*reg); break; + case '!': for(;*reg != 0; reg++) acc = acc != sint(*reg); break; + case '>': for(;*reg != 0; reg++) acc = acc > sint(*reg); break; + case '<': for(;*reg != 0; reg++) acc = acc < sint(*reg); break; } /* clang-format on */ dst_ += snprintf(dst_, 0x10, "%d", acc); From d24af000981b450e76619caf00c4aef5f9790f56 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Mon, 29 Apr 2024 09:08:41 -0700 Subject: [PATCH 34/45] Added negative numbers support --- src/modal.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/modal.c b/src/modal.c index e4f5b6f..7bce9ef 100644 --- a/src/modal.c +++ b/src/modal.c @@ -34,10 +34,11 @@ walk(char *s) static int sint(char *s) { - int r = 0; char c; + int r = 0, n = 1; + if(*s == '-') { n = -1, s++; } while((c = *s++) && c > 0x20) r = r * 10 + c - '0'; - return r; + return r * n; } static void From c61958173973e54d36990096dc7e1f93e991a825 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Mon, 29 Apr 2024 09:46:27 -0700 Subject: [PATCH 35/45] Fixed rewrite count --- examples/tests.modal | 10 +++++++--- src/modal.c | 15 +++++++++------ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/examples/tests.modal b/examples/tests.modal index 845aa12..2c9d38e 100644 --- a/examples/tests.modal +++ b/examples/tests.modal @@ -127,9 +127,13 @@ nap tap (inline 1) test ?(?-) (Arithmetic) -?((?: ?0 ?1 ?2) (?:)) + 1 2 3 = 6 (Arithmetic 1) test -?((?0 ?: ?1) (?:)) 16 - 8 = 8 (Arithmetic 2) test -?((?0 ?1 ?:) (?:)) 12 10 * = 120 (Arithmetic 3) test +?((?: ?0 ?1 ?2) ?:) + 1 2 3 = 6 (Arithmetic 1) test +?((?0 ?: ?1) ?:) 16 - 8 = 8 (Arithmetic 2) test +?((?0 ?1 ?:) ?:) 12 10 * = 120 (Arithmetic 3) test + +<> (?0 ?1 `?:) (?:) + +(12 45 `+ -2 `+) = (55) (Arithmetic 4) test ?(?-) (Late Test Primitives) diff --git a/src/modal.c b/src/modal.c index 7bce9ef..2381ae0 100644 --- a/src/modal.c +++ b/src/modal.c @@ -291,7 +291,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, 28 Apr 2024.\n"); + case 'v': /* version */ return !printf("Modal Interpreter, 29 Apr 2024.\n"); case 'q': /* quiet */ quiet = 1; break; case 'p': /* debug */ debug = 1; break; case 'n': /* infinite */ cycles = 0xffffffff; break; @@ -318,12 +318,15 @@ main(int argc, char **argv) if(!cycles--) return !fprintf(stderr, "Modal rewrites exceeded.\n"); if(!quiet) { while(rules_-- > rules) { - if(!rules_->refs && rules_->a) - fprintf(stderr, "-- Unused rule: %d <> (%s) (%s)\n", rules_->id, rules_->a, rules_->b); - if(debug && rules_->a) - fprintf(stderr, " (%s) (%s), %d times.\n", rules_->a, rules_->b, rules_->refs); + if(rules_->a) { + if(!rules_->refs) + fprintf(stderr, "-- Unused rule: %d <> (%s) (%s)\n", rules_->id, rules_->a, rules_->b); + if(debug) + fprintf(stderr, " (%s) (%s), %d times.\n", rules_->a, rules_->b, rules_->refs); + } } - fprintf(stderr, ".. %s\nCompleted in %d rewrites.\n", src_, rw); + if(rw) + fprintf(stderr, "Completed in %d rewrites.\n", rw - 1); } return 0; } From 40789198117a44b98675d783ed9d0d7374325119 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Mon, 29 Apr 2024 09:50:43 -0700 Subject: [PATCH 36/45] Replaced ari for loop with while --- src/modal.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/modal.c b/src/modal.c index 2381ae0..81e9a38 100644 --- a/src/modal.c +++ b/src/modal.c @@ -50,18 +50,18 @@ device_write(char *s) int acc = sint(*reg++); /* clang-format off */ switch(c) { - case '+': for(;*reg != 0; reg++) acc += sint(*reg); break; - case '-': for(;*reg != 0; reg++) acc -= sint(*reg); break; - case '*': for(;*reg != 0; reg++) acc *= sint(*reg); break; - case '/': for(;*reg != 0; reg++) acc /= sint(*reg); break; - case '%': for(;*reg != 0; reg++) acc %= sint(*reg); break; - case '&': for(;*reg != 0; reg++) acc &= sint(*reg); break; - case '^': for(;*reg != 0; reg++) acc ^= sint(*reg); break; - case '|': for(;*reg != 0; reg++) acc |= sint(*reg); break; - case '=': for(;*reg != 0; reg++) acc = acc == sint(*reg); break; - case '!': for(;*reg != 0; reg++) acc = acc != sint(*reg); break; - case '>': for(;*reg != 0; reg++) acc = acc > sint(*reg); break; - case '<': for(;*reg != 0; reg++) acc = acc < sint(*reg); break; + case '+': while(*reg) acc += sint(*reg++); break; + case '-': while(*reg) acc -= sint(*reg++); break; + case '*': while(*reg) acc *= sint(*reg++); break; + case '/': while(*reg) acc /= sint(*reg++); break; + case '%': while(*reg) acc %= sint(*reg++); break; + case '&': while(*reg) acc &= sint(*reg++); break; + case '^': while(*reg) acc ^= sint(*reg++); break; + case '|': while(*reg) acc |= sint(*reg++); break; + case '=': while(*reg) acc = acc == sint(*reg++); break; + case '!': while(*reg) acc = acc != sint(*reg++); break; + case '>': while(*reg) acc = acc > sint(*reg++); break; + case '<': while(*reg) acc = acc < sint(*reg++); break; } /* clang-format on */ dst_ += snprintf(dst_, 0x10, "%d", acc); From 8d207d42a5cc3e419e4b6e339c895fd13c1d4ae3 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Mon, 29 Apr 2024 09:54:37 -0700 Subject: [PATCH 37/45] Fixed off by one rule id --- src/modal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modal.c b/src/modal.c index 81e9a38..2f43fba 100644 --- a/src/modal.c +++ b/src/modal.c @@ -251,7 +251,7 @@ rewrite(void) } /* phase: define */ if(c == '<' && s[1] == '>') { - r = rules_, r->id = rules_ - rules - 1; + r = rules_, r->id = rules_ - rules; s = parse_frag(&r->b, parse_frag(&r->a, s + 2)); if(*r->a) { if(!quiet) fprintf(stderr, "<> (%s) (%s)\n", r->a, r->b); From b52a4adb2fb61a7f980dc25c36a83aae199321d6 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Mon, 29 Apr 2024 14:05:37 -0700 Subject: [PATCH 38/45] Fixed rw counter --- src/modal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modal.c b/src/modal.c index 2f43fba..630a15b 100644 --- a/src/modal.c +++ b/src/modal.c @@ -326,7 +326,7 @@ main(int argc, char **argv) } } if(rw) - fprintf(stderr, "Completed in %d rewrites.\n", rw - 1); + fprintf(stderr, "Completed in %d rewrites.\n", rw); } return 0; } From 9b50f530ecc4dafa487e86fb97a71f957f1877ff Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Mon, 29 Apr 2024 17:20:00 -0700 Subject: [PATCH 39/45] Added fib example --- examples/fib.modal | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 examples/fib.modal diff --git a/examples/fib.modal b/examples/fib.modal new file mode 100644 index 0000000..e422a49 --- /dev/null +++ b/examples/fib.modal @@ -0,0 +1,6 @@ +<> (`?: ?0 ?1) ((Int ?:)) +<> (fib ?n) (?n (Int 0) (Int 1) Fib) +<> ((Int 0) (Int ?0) (Int ?1) Fib) ?0 +<> ((Int ?x) (Int ?y) (Int ?z) Fib) (`- ?x 1 (Int ?z) `+ ?z ?y Fib) + +fib (Int 11) \ No newline at end of file From 2f24c7d83fefd5a0410abf23a8b6940075b62f01 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Mon, 29 Apr 2024 18:06:17 -0700 Subject: [PATCH 40/45] Added fizzbuzz-alu example --- examples/fizzbuzz-alu.modal | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 examples/fizzbuzz-alu.modal diff --git a/examples/fizzbuzz-alu.modal b/examples/fizzbuzz-alu.modal new file mode 100644 index 0000000..3371eda --- /dev/null +++ b/examples/fizzbuzz-alu.modal @@ -0,0 +1,9 @@ +<> (fizzbuzz ?x ?x) (done.) +<> (?x Int 0 Int 0 test) (?(?: ?:) (Fizz Buzz\n)) +<> (?x Int 0 Int ?z test) (?(?: ?:) Fizz\n) +<> (?x Int ?y Int 0 test) (?(?: ?:) Buzz\n) +<> (?x Int ?y Int ?z test) (?(?: ?:) (?x \n)) +<> (?x eval) (?x ?((?0 ?1 ?:) (Int ?:)) ?x 3 % ?((?0 ?1 ?:) (Int ?:)) ?x 5 % test) +<> (fizzbuzz ?x ?y) (?x eval fizzbuzz ?((?0 ?1 ?:) ?:) ?x 1 + ?y) + +fizzbuzz 1 30 \ No newline at end of file From c4407255599f698b0b71a5fcf92a11f1b9a30e10 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Tue, 30 Apr 2024 08:45:23 -0700 Subject: [PATCH 41/45] Removed python --- old/modal.py | 419 --------------------------------------------------- 1 file changed, 419 deletions(-) delete mode 100644 old/modal.py diff --git a/old/modal.py b/old/modal.py deleted file mode 100644 index e3afa9b..0000000 --- a/old/modal.py +++ /dev/null @@ -1,419 +0,0 @@ -""" - *------------------------------------------------------------* - |modal.py : An Implementation of Modal in Python | - | | - |This is an implementation of Modal, a programming language | - |based on term rewriting. This particular implementation | - |is based on the idea of cyclic delimited string rewriting | - |using a central queue and a dictionary of variable bindings.| - | | - |© 2019-2024 wryl, Paradigital | - *------------------------------------------------------------* -""" - -# `sys` for I/O and arguments. -# `time` for measuring the runtime of the interpreter. -import sys, time - -# A decorator intended for measuring the runtime of a given function. -def measure(function): - def measurement(*arguments): - start = time.time() - result = function(*arguments) - end = time.time() - milliseconds = (end - start) * 1000.0 - print("\nTook {:.3f}ms".format(milliseconds)) - return result - return measurement - -# Enqueue an item by appending it to the queue. -def enqueue(queue, item): - return queue + item - -# Dequeue an item by slicing the queue. The last item is the head. -def dequeue(queue, length=1): - if length > len(queue): - return queue - return queue[length:] - -# Get the item(s) at the head of the queue. -def peek(queue, length=1): - if length > len(queue): - return None - if length == 1: - return queue[0] - return queue[:length] - -# Roll/cycle the queue by a certain amount by slicing. -# This dequeues and enqueues a number of items, "cycling" the queue. -def roll(queue, length=1): - if length > len(queue): - return queue - return queue[length:] + queue[:length] - -# Seek to a certain position in the queue by repeatedly rolling it. -def seek(queue, pattern): - if pattern not in queue: - return queue - while peek(queue, len(pattern)) != pattern: - queue = roll(queue) - return queue - -# Extract a delimited fragment (subtree) from the queue. -def extract(queue): - results = [] - depth = 0 - for element in queue: - if element[0] == "SRT": - return [] - if element[0] == "INC": - depth = depth + 1 - if element[0] == "DEC": - if depth == 0: - return results - depth = depth - 1 - results.append(element) - if depth == 0: - return results - return results - -# Generate a list of variable bindings from the current queue and a pattern. -def match(pattern, queue, context=None): - if context == None: - context = {} - if peek(queue) == None: - return context - for element in pattern: - if element[0] == "VAR": - variable = element[1] - value = extract(queue) - if variable in context: - if context[variable] != value: - return None - queue = dequeue(queue, len(context[variable])) - else: - if len(value) == 0: - return None - context[variable] = value - queue = dequeue(queue, len(context[variable])) - elif element != peek(queue): - return None - else: - queue = dequeue(queue) - return context - -# Fill in a pattern with variables in it using a list of variable bindings. -def construct(pattern, context): - results = [] - for element in pattern: - if element[0] == "VAR": - if element[1] in context: - for element in context[element[1]]: - results.append(element) - else: - results.append(element) - else: - results.append(element) - return results - -# Apply a pattern/replacement rule to the queue. -def apply(queue, rules, pattern, replacement): - context = match(pattern, queue) - if context == None: - return (False, roll(queue)) - pattern = construct(pattern, context) - if not pattern: - return (False, roll(queue)) - replacement = construct(replacement, context) - return (True, enqueue(dequeue(queue, len(pattern)), replacement)) - -def define(queue, rules, pattern): - context = match(pattern, queue) - left = context["left"] - right = context["right"] - if right and left: - if len(left) > 1: - left = left[1:][:-1] - if len(right) > 1: - right = right[1:][:-1] - rules.append((left, apply, [right])) - return (True, dequeue(queue, len(construct(pattern, context)))) - return (False, roll(queue)) - -def undefine(queue, rules, pattern): - context = match(pattern, queue) - left = context["left"] - if left: - if len(left) > 1: - left = left[1:][:-1] - for rule, index in zip(rules, range(0, len(rules))): - candidate , _, _ = rule - if candidate == left: - del rules[index] - return (True, dequeue(queue, len(construct(pattern, context)))) - return (False, roll(queue)) - -def add(queue, rules, pattern): - context = match(pattern, queue) - left = context["left"] - right = context["right"] - if left and right: - if left[0][0] == "NUM" and right[0][0] == "NUM": - queue = dequeue(queue, len(construct(pattern, context))) - queue = enqueue(queue, parse(str(left[0][1] + right[0][1]))) - return (True, queue) - return (False, roll(queue)) - -def subtract(queue, rules, pattern): - context = match(pattern, queue) - left = context["left"] - right = context["right"] - if left and right: - if left[0][0] == "NUM" and right[0][0] == "NUM": - queue = dequeue(queue, len(construct(pattern, context))) - queue = enqueue(queue, parse(str(left[0][1] - right[0][1]))) - return (True, queue) - return (False, roll(queue)) - -def multiply(queue, rules, pattern): - context = match(pattern, queue) - left = context["left"] - right = context["right"] - if left and right: - if left[0][0] == "NUM" and right[0][0] == "NUM": - queue = dequeue(queue, len(construct(pattern, context))) - queue = enqueue(queue, parse(str(left[0][1] * right[0][1]))) - return (True, queue) - return (False, roll(queue)) - -def divide(queue, rules, pattern): - context = match(pattern, queue) - left = context["left"] - right = context["right"] - if left and right: - if left[0][0] == "NUM" and right[0][0] == "NUM": - queue = dequeue(queue, len(construct(pattern, context))) - queue = enqueue(queue, parse(str(left[0][1] // right[0][1]))) - return (True, queue) - return (False, roll(queue)) - -def modulo(queue, rules, pattern): - context = match(pattern, queue) - left = context["left"] - right = context["right"] - if left and right: - if left[0][0] == "NUM" and right[0][0] == "NUM": - queue = dequeue(queue, len(construct(pattern, context))) - queue = enqueue(queue, parse(str(left[0][1] % right[0][1]))) - return (True, queue) - return (False, roll(queue)) - -def display(queue, rules, pattern): - context = match(pattern, queue) - left = context["left"] - if left: - if left[0][0] == "LIT" or left[0][0] == "NUM": - if left[0][1] == "space": - print(' ', end="") - elif left[0][1] == "newline": - print('\n', end="") - elif left[0][1] == "tab": - print('\t', end="") - else: - print(left[0][1], end="") - return (True, dequeue(queue, len(construct(pattern, context)))) - return (False, roll(queue)) - -def applicable(rules, queue): - results = [] - for pattern, operation, parameters in rules: - if match(pattern, queue) != None: - results.append((pattern, operation, parameters)) - return results - -def pick(list): - if len(list) == 0: - return None - return list[0] - -def reconstruct(pattern): - for element in pattern: - if element[0] == "INC": - yield '(' - elif element[0] == "DEC": - yield ')' - elif element[0] == "NUM": - yield str(element[1]) - elif element[0] == "LIT": - yield element[1] - elif element[0] == "VAR": - yield '?' + element[1] - yield ' ' - -def number(string): - try: - result = int(string) - return True - except: - return False - -def literal(string, index=0): - token = "" - while index != len(string): - character = string[index] - if character in ['(', ')', '{', '}', '[', ']', '?', ' ', '\t', '\n', '\r']: - break - else: - token = token + string[index] - index = index + 1 - return (token, index) - -def parse(string, index=0): - results = [] - while index != len(string): - character = string[index] - if character in ['(', ')', '{', '}', '[', ']', '?', ' ', '\t', '\n', '\r']: - index = index + 1 - if character in ['(', '{', '[']: - results.append(["INC"]) - elif character in [')', '}', ']']: - results.append(["DEC"]) - elif character not in [' ', '\t', '\n', '\r']: - token, index = literal(string, index) - if character == '?': - results.append(["VAR", token]) - elif number(token): - results.append(["NUM", int(token)]) - else: - results.append(["LIT", token]) - return results - -@measure -def run(rules, queue, limit=pow(2, 32)): - steps = 0 - failures = 0 - queue = [["SRT"]] + queue - while failures != len(queue) and steps != limit: - rule = pick(applicable(rules, queue)) - if rule == None: - queue = roll(queue) - failures = failures + 1 - else: - pattern, operation, parameters = rule - result, queue = operation(queue, rules, pattern, *parameters) - if result == True: - failures = 0 - print("<>: ", inspect(seek(queue, ["SRT"]))) - #print("<>: ", inspect(queue)) - #input() - steps = steps + 1 - if steps == limit: - print("Execution limit reached.") - return queue - -def read(file): - try: - with open(file) as file: - content = file.read() - return content - except EnvironmentError: - return None - -def inspect(pattern): - return "".join(reconstruct(pattern)) - -def usage(name): - print(name + ':', "a programming language based on rewriting.") - print("Usage:") - print((' ' * 4) + name, "") - -def prompt(prompt): - try: - return input(prompt) - except: - return None - -def help(): - prefix = ' ' * 4 - print("Commands:") - print(prefix + "rules : Display the current ruleset.") - print(prefix + "clear : Clear the current ruleset.") - print(prefix + "help : This message.") - print(prefix + "quit : Quit.") - -def main(): - defaults = [ - (parse("define ?left ?right"), define, []), - (parse("undefine ?left"), undefine, []), - (parse("add (?left) (?right)"), add, []), - (parse("add (?left) ?right"), add, []), - (parse("add ?left (?right)"), add, []), - (parse("add ?left ?right"), add, []), - (parse("subtract (?left) (?right)"), subtract, []), - (parse("subtract (?left) ?right"), subtract, []), - (parse("subtract ?left (?right)"), subtract, []), - (parse("subtract ?left ?right"), subtract, []), - (parse("multiply (?left) (?right)"), multiply, []), - (parse("multiply (?left) ?right"), multiply, []), - (parse("multiply ?left (?right)"), multiply, []), - (parse("multiply ?left ?right"), multiply, []), - (parse("divide (?left) (?right)"), divide, []), - (parse("divide (?left) ?right"), divide, []), - (parse("divide ?left (?right)"), divide, []), - (parse("divide ?left ?right"), divide, []), - (parse("modulo (?left) (?right)"), modulo, []), - (parse("modulo (?left) ?right"), modulo, []), - (parse("modulo ?left (?right)"), modulo, []), - (parse("modulo ?left ?right"), modulo, []), - (parse("(?left) + (?right)"), add, []), - (parse("(?left) + ?right"), add, []), - (parse("?left + (?right)"), add, []), - (parse("?left + ?right"), add, []), - (parse("(?left) - (?right)"), subtract, []), - (parse("(?left) - ?right"), subtract, []), - (parse("?left - (?right)"), subtract, []), - (parse("?left - ?right"), subtract, []), - (parse("(?left) * (?right)"), multiply, []), - (parse("(?left) * ?right"), multiply, []), - (parse("?left * (?right)"), multiply, []), - (parse("?left * ?right"), multiply, []), - (parse("?left / ?right"), divide, []), - (parse("?left % ?right"), modulo, []), - (parse("display ?left"), display, []), - ] - rules = defaults.copy() - if len(sys.argv) >= 2: - content = read(sys.argv[1]) - if content == None: - print("No such file.") - return - print("Initializating...") - run(rules, parse(content)) - else: - usage(sys.argv[0]) - return - print("Modal v0.02") - help() - while True: - input = prompt("::> ") - if input == None: - break - elif parse(input) == parse("rules"): - print("Rules:") - prefix = ' ' * 4 - for pattern, operation, parameters in rules: - if operation == apply: - print(prefix + inspect(pattern) + "-> " + inspect(parameters[0])) - elif parse(input) == parse("clear"): - rules = defaults - elif parse(input) == parse("help"): - help() - elif parse(input) == parse("quit") or parse(input) == parse("exit"): - break - else: - print("Reducing...") - print(inspect(seek(run(rules, parse(input)), ["SRT"]))) - return - -if __name__ == "__main__": - main() From e1f4641f69672903b53ac6c4f55e26ec1f1636de Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Thu, 2 May 2024 16:02:33 -0700 Subject: [PATCH 42/45] Moved print out of write_tail --- src/modal.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/modal.c b/src/modal.c index 630a15b..3bce6af 100644 --- a/src/modal.c +++ b/src/modal.c @@ -135,7 +135,7 @@ write_reg(char r, char *reg) } static int -write_tail(char *s, Rule *r) +write_tail(char *s) { while((*dst_++ = *s++)) ; @@ -144,7 +144,6 @@ write_tail(char *s, Rule *r) src_ = bank_b, dst_ = bank_a; else src_ = bank_a, dst_ = bank_b; - if(!quiet && r) fprintf(stderr, "%02d %s\n", r->id, src_), ++r->refs; return 1; } @@ -194,7 +193,8 @@ apply_rule(Rule *r, char *s) while(*s == ' ') s++; if(*s == ')' && *(dst_ - 1) == ' ') dst_--; } - return write_tail(s, r); + if(!quiet) fprintf(stderr, "%02d %s\n", r->id, src_), ++r->refs; + return write_tail(s); } static char * @@ -247,7 +247,7 @@ rewrite(void) r->a = 0; } while(*cap == ' ') cap++; - return write_tail(cap, NULL); + return write_tail(cap); } /* phase: define */ if(c == '<' && s[1] == '>') { @@ -258,7 +258,7 @@ rewrite(void) rules_++; } while(*s == ' ') s++; - return write_tail(s, NULL); + return write_tail(s); } /* phase: lambda */ if(c == '?' && s[1] == '(') { @@ -267,7 +267,10 @@ rewrite(void) parse_frag(&r->b, parse_frag(&r->a, s + 2)); s = cap; while(*s == ' ') s++; - if(!apply_rule(&lambda, s)) write_tail(s, r); + if(!apply_rule(&lambda, s)) { + if(!quiet) fprintf(stderr, "%02d %s\n", r->id, src_), ++r->refs; + write_tail(s); + } return 1; } /* phase: match */ @@ -291,7 +294,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, 29 Apr 2024.\n"); + case 'v': /* version */ return !printf("Modal Interpreter, 2 May 2024.\n"); case 'q': /* quiet */ quiet = 1; break; case 'p': /* debug */ debug = 1; break; case 'n': /* infinite */ cycles = 0xffffffff; break; From 19d03dc116405d726aa609df0efcfe1d33c229e8 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sat, 4 May 2024 12:25:19 -0700 Subject: [PATCH 43/45] Do not consume dictionary in lambdas --- src/modal.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modal.c b/src/modal.c index 3bce6af..66c0dfb 100644 --- a/src/modal.c +++ b/src/modal.c @@ -37,7 +37,7 @@ sint(char *s) char c; int r = 0, n = 1; if(*s == '-') { n = -1, s++; } - while((c = *s++) && c > 0x20) r = r * 10 + c - '0'; + while((c = *s++) && !spacer(c)) r = r * 10 + c - '0'; return r * n; } @@ -99,9 +99,7 @@ write_reg(char r, char *reg) { char c, *cap = walk(reg); switch(r) { - case '>': /* op: output */ case ':': device_write(reg); return; - case '<': /* op: input */ case '~': device_read(); return; case '^': /* op: join */ if(*reg == '(') reg++, --cap; @@ -262,6 +260,7 @@ rewrite(void) } /* phase: lambda */ if(c == '?' && s[1] == '(') { + char *d_ = dict_; cap = walk(s + 1); r = &lambda, r->id = -1; parse_frag(&r->b, parse_frag(&r->a, s + 2)); @@ -271,6 +270,7 @@ rewrite(void) if(!quiet) fprintf(stderr, "%02d %s\n", r->id, src_), ++r->refs; write_tail(s); } + dict_ = d_; return 1; } /* phase: match */ From 7c247d718149334554fb02a1e444e48d2c7fcecf Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sat, 4 May 2024 12:34:38 -0700 Subject: [PATCH 44/45] Smarter clean up of dirty registers --- src/modal.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/modal.c b/src/modal.c index 66c0dfb..f14f906 100644 --- a/src/modal.c +++ b/src/modal.c @@ -5,13 +5,12 @@ typedef struct { char *a, *b; } Rule; -static unsigned char rmin = 0xff, rmax = 0x00; static int flip, quiet, debug, cycles = 0x10000; static Rule rules[0x1000], *rules_ = rules, lambda; static char dict[0x8000], *dict_ = dict, empty; static char bank_a[0x4000], *src_ = bank_a; static char bank_b[0x4000], *dst_ = bank_b; -static char *regs[0x100]; +static char *regs[0x100], stack[0x10], *stack_ = stack; #define spacer(c) (c <= ' ' || c == '(' || c == ')') @@ -148,14 +147,10 @@ write_tail(char *s) static int apply_rule(Rule *r, char *s) { - unsigned char i, rid; + unsigned char rid; char c, *a = r->a, *b = r->b, *origin = dst_, *reg; /* phase: clean regs */ - if(rmax) { - for(i = 0; i <= rmax; i++) - regs[i] = 0; - rmin = 0xff, rmax = 0x00; - } + while(stack_ != stack) regs[(int)*(--stack_)] = 0; /* phase: match rule */ while((c = *a++)) { if(c == '?') { @@ -165,11 +160,8 @@ apply_rule(Rule *r, char *s) char *rcap = walk(reg), *pp = s; while(reg < rcap || pp < pcap) if(*reg++ != *pp++) return 0; - } else { /* reg set */ - regs[rid] = s; - if(rid < rmin) rmin = rid; - if(rid > rmax) rmax = rid; - } + } else /* reg set */ + regs[rid] = s, *stack_++ = rid; s = pcap; } else if(c != *s++) return 0; @@ -294,7 +286,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, 2 May 2024.\n"); + case 'v': /* version */ return !printf("Modal Interpreter, 4 May 2024.\n"); case 'q': /* quiet */ quiet = 1; break; case 'p': /* debug */ debug = 1; break; case 'n': /* infinite */ cycles = 0xffffffff; break; From 0f3c1b4fb8b6841adf10d7a79ef6600f25ba6740 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sat, 4 May 2024 14:47:31 -0700 Subject: [PATCH 45/45] Print output --- src/modal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modal.c b/src/modal.c index f14f906..d2986ae 100644 --- a/src/modal.c +++ b/src/modal.c @@ -321,7 +321,7 @@ main(int argc, char **argv) } } if(rw) - fprintf(stderr, "Completed in %d rewrites.\n", rw); + fprintf(stderr, ".. %s\nCompleted in %d rewrites.\n", src_, rw); } return 0; }