#include "h.h" #include static int const lp = '(', rp = ')'; static int let(ui c){return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= 0xa000 & c < 0xa490);} extern int od; // number of primordial values cp cx = code; int cd = 0; // current depth static void cb(ui o) {if(o>255) crsh("invalid op %x\n", cx); if(cx-code >= codesize) Bye("Too much code"); *(cx++) = o;} ui symbols[md]; void compile(){ui c; ui gc(){c = g(); return c;} ui gu(){while(1){if(gc()==';') while(gc()!=10) ; else return c;}} // filter comments ui sl(){while(gu() == ' ' || c==10) ; return c;} // filter white space if(sl() == lp) { int const ql = cd; if(sl() == 0x3bb){ // 0x3bb is code point for lambda while(let(sl())) {if(cd >= md) Bye("Too many nested levels"); symbols[cd++] = c; cb(255);} if(c != '.') {if(1) Bye("One dot per lambda, Dammit!"); else back();} if(cd==ql) Bye("Lambda dot is invalid");} else back(); {cp twoth = cx; compile(); // require at least one expression in the appl. while(sl() != rp) {int siz = cx-twoth; back(); if((cx+=3)-code >= codesize) Bye("Too much code"); memmove(twoth+3, twoth, siz); *twoth = 254; if (siz > 1<<16) Bye("Program too big to compile"); *(us*)(twoth+1) = siz; compile();}} cd = ql;} else if(c <= '9' && c >= '0') {nis x = c - '0'; while (gc() <= '9' && c >= '0') {x = 10*x + c - '0';} cb(253); back(); {void pb7(nis w, uchar e) {if(w>127) pb7(w>>7, 0); cb(w & 0x7f | e);} pb7(x, 128);}} else if(let(c)) {int j = cd; while(j--) if(c == symbols[j]) {cb(cd-j-1); return;} printf("Free variable %d deep, 0x%x, %c\n", cd-od, c, c); Bye("");} else {printf("Screwy text, expecting expression: 0x%x, %c\n", c, c); Bye("");}}