#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", 0); 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) { void nrp(char * c){printf("%s didn't end with a right paren.", c); Bye("");}; if(sl() == 0x3bb){ // 0x3bb is code point for lambda if(cd >= md) Bye("Too many nested levels"); symbols[cd++] = sl(); cb(255); compile(); --cd; if(sl() != rp) nrp("Lambda");} else {back(); {cp twoth = cx+1; cb(254); cx+=2; compile(); {ui siz = cx - (twoth+2); if (siz > 1<<16) Bye("Program too big to compile"); *(us*)twoth = siz;} compile(); if(sl() != rp) nrp("function application");}}} 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("");}}