diff --git a/examples/file.modal b/examples/file.modal new file mode 100644 index 0000000..5d89dd4 --- /dev/null +++ b/examples/file.modal @@ -0,0 +1,3 @@ +<> (?_ import) (?_) + +(examples/postcard.modal import) \ No newline at end of file diff --git a/makefile b/makefile index 563ad91..075d996 100644 --- a/makefile +++ b/makefile @@ -10,12 +10,13 @@ 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 -a examples/file.modal test: all bin/modal-debug bin/modal @ bin/modal -v @ bin/modal-debug -q examples/fizzbuzz.modal @ bin/modal-debug -q examples/sierpinski.modal @ bin/modal-debug -q examples/tests.modal + @ bin/modal-debug -a examples/file.modal install: bin/modal cp bin/modal ~/bin/ uninstall: diff --git a/src/modal.c b/src/modal.c index 255a96b..315a87d 100644 --- a/src/modal.c +++ b/src/modal.c @@ -5,7 +5,7 @@ typedef struct { char *a, *b; } Rule; -static int flip, quiet, debug, cycles = 0x200000; +static int flip, quiet, debug, access, cycles = 0x200000; static Rule rules[0x1000], *rules_ = rules; static char dict[0x8000], *dict_ = dict, empty; static char bank_a[0x4000], *src_ = bank_a; @@ -95,12 +95,42 @@ device_read(void) dst_--; } +static void +file_import(char *path) +{ + FILE *f; + int pr = 0; + char c, last = 0; + if((f = fopen(path, "r"))) { + while(fread(&c, 1, 1, f)) { + c = c <= 0x20 ? 0x20 : c; + if(c == ' ' && last == '(') continue; + if(c == ')' && last == ' ') dst_--; + if(c == ' ' && last == ' ') dst_--; + if(c == '(') pr++; + if(c == ')') pr--; + if(c == '(' && last != '?' && !spacer(last)) *dst_++ = ' '; + if(last == ')' && !spacer(c)) *dst_++ = ' '; + *dst_++ = last = c; + } + fclose(f); + if(pr) fprintf(stderr, "Modal program imbalanced.\n"); + } else + *dst_++ = 'N', *dst_++ = 'A', *dst_++ = 'F'; +} + static void write_reg(char r, char *reg) { switch(r) { case ':': device_write(reg); return; case '~': device_read(); return; + case '_': { + char filepath[0x80], *path = filepath, *cap = walk(reg); + while(reg < cap) *path++ = *reg++; + file_import(filepath); + return; + } case '^': { /* op: join */ char c, *cap = walk(reg); if(*reg == '(') reg++, --cap; @@ -282,9 +312,7 @@ rewrite(void) int main(int argc, char **argv) { - FILE *f; - int i, pr = 0, rw = 0; - char c, last = 0, *w = bank_a; + int i, rw = 0; if(argc < 2) return !printf("usage: modal [-vqn] source.modal\n"); for(i = 1; i < argc && *argv[i] == '-'; i++) { @@ -292,25 +320,11 @@ main(int argc, char **argv) case 'v': /* version */ return !printf("Modal Interpreter, 9 May 2024.\n"); case 'q': /* quiet */ quiet = 1; break; case 'p': /* debug */ debug = 1; break; + case 'a': /* access */ access = 1; break; case 'n': /* infinite */ cycles = 0xffffffff; break; } } - if(!(f = fopen(argv[i], "r"))) - return !printf("Modal file invalid: %s.\n", argv[i]); - while(fread(&c, 1, 1, f)) { - c = c <= 0x20 ? 0x20 : c; - if(c == ' ' && last == '(') continue; - if(c == ')' && last == ' ') w--; - if(c == ' ' && last == ' ') w--; - if(c == '(') pr++; - if(c == ')') pr--; - if(c == '(' && last != '?' && !spacer(last)) *w++ = ' '; - if(last == ')' && !spacer(c)) *w++ = ' '; - *w++ = last = c; - } - fclose(f); - if(pr) - return !fprintf(stderr, "Modal program imbalanced.\n"); + dst_ = bank_a, file_import(argv[i]), dst_ = bank_b; while(rewrite() && ++rw) if(!cycles--) return !fprintf(stderr, "Modal rewrites exceeded.\n"); if(!quiet) {