# To unbundle, run this file echo mkfile sed 's/.//' >mkfile <<'//GO.SYSIN DD mkfile' -pico.y <<'//GO.SYSIN DD pico.y' -%{ -#include -#include -#include -#include -#include -#include -#include - -#define DX 248 -#define DY 248 - -#ifdef USED /* plan9port */ -#define system system9 -#define CC "9c" -#define LD "9l" -#else -#define CC "8c" -#define LD "8l" -#endif - -char *newname; -char *cmd; -Fmt codefmt; - -int yylex(void); -int yyparse(void); -void yyerror(char*); - -void checkref(char*); -void checkrefn(int); - -%} - -%union -{ - char* s; - int i; -} - -%token NAME NEW OLD NUM EOF ERROR -%token FN NAME -%type index zindex newname command expr fileref value -%type NUM - -%right '=' -%right '?' ':' -%left '|' -%left '^' -%left '&' -%left EQ NE -%right LSH RSH -%left '<' '>' LE GE -%left '+' '-' -%left '*' '/' '%' -%right POW -%right '!' - -%% - -start: command EOF { cmd = $1; return 0; } - -index: - '[' expr ',' expr ']' { $$ = smprint("%s, %s", $2, $4); } - -zindex: - index -| { $$ = "x, y"; } - -newname: - NEW { $$ = "new"; } -| NEW NAME { $$ = $2; } -| NAME { $$ = $1; } - -command: - newname zindex '=' expr - { newname = $1; $$ = smprint("T = %s; *WIMAGE(%s, %s) = CLIP(T);", $4, $1, $2); } -| expr - { newname = "new"; $$ = smprint("T = %s; *WIMAGE(new, x,y) = CLIP(T);", $1); } - -expr: - value -| fileref -| 'x' { $$ = "x"; } -| 'y' { $$ = "y"; } -| 'X' { $$ = "X"; } -| 'Y' { $$ = "Y"; } -| 'Z' { $$ = "Z"; } -| "(" expr ")" { $$ = $2; } -| FN "(" expr ")" { $$ = smprint("%s(%s)", $1, $3); } -| '-' expr %prec '!' { $$ = smprint("-(%s)", $2); } -| '!' expr { $$ = smprint("!(%s)", $2); } -| expr '+' expr { $$ = smprint("(%s)+(%s)", $1, $3); } -| expr '-' expr { $$ = smprint("(%s)-(%s)", $1, $3); } -| expr '*' expr { $$ = smprint("(%s)*(%s)", $1, $3); } -| expr '/' expr { $$ = smprint("DIV(%s, %s)", $1, $3); } -| expr '%' expr { $$ = smprint("MOD(%s, %s)", $1, $3); } -| expr '<' expr { $$ = smprint("(%s) < (%s)", $1, $3); } -| expr '>' expr { $$ = smprint("(%s) > (%s)", $1, $3); } -| expr LE expr { $$ = smprint("(%s) <= (%s)", $1, $3); } -| expr GE expr { $$ = smprint("(%s) >= (%s)", $1, $3); } -| expr EQ expr { $$ = smprint("(%s) == (%s)", $1, $3); } -| expr NE expr { $$ = smprint("(%s) != (%s)", $1, $3); } -| expr LSH expr { $$ = smprint("(%s) << (%s)", $1, $3); } -| expr RSH expr { $$ = smprint("(%s) >> (%s)", $1, $3); } -| expr '^' expr { $$ = smprint("(%s) ^ (%s)", $1, $3); } -| expr '&' expr { $$ = smprint("(%s) & (%s)", $1, $3); } -| expr '|' expr { $$ = smprint("(%s) | (%s)", $1, $3); } -| expr '?' expr ':' expr { $$ = smprint("(%s) ? (%s) : (%s)", $1, $3, $5); } -| expr POW expr { $$ = smprint("POW(%s, %s)", $1, $3); } - -fileref: - NAME zindex { checkref($1); $$ = smprint("IMAGE(%s, %s)", $1, $2); } -| "$" NUM zindex { checkrefn($2); $$ = smprint("IMAGE(OLD[%d-1], %s)", $2, $3); } -| OLD zindex { checkrefn(1); $$ = smprint("IMAGE(old, %s)", $2); } - -value: - NUM { $$ = smprint("%d", $1); } - -%% - -char *inp; - -#define follow(x, y) (*inp == x ? (inp++, y) : c) -#define follow2(x, y, x1, y1) (*inp == x ? (inp++, y) : *inp == x1 ? (inp++, y1) : c) - -jmp_buf boomer; - -void -kaboom(char *fmt, ...) -{ - va_list arg; - va_start(arg, fmt); - vfprint(2, fmt, arg); - va_end(arg); - fprint(2, "\n"); - longjmp(boomer, 1); -} - -void -yyerror(char *msg) -{ - kaboom("%s", msg); -} - -int -yylex() -{ - int c; - - while((c = *inp) != 0 && isspace(c)) - inp++; - if(c == 0) - return EOF; - inp++; - - switch(c){ - case '+': - case '-': - case '/': - case '%': - case '?': - case ':': - case '|': - case '^': - case '&': - case '$': - case '[': - case ']': - case ',': - case 'X': - case 'Y': - case 'Z': - case '(': - case ')': - return c; - case '*': - return follow('*', POW); - case '<': - return follow2('=', LE, '<', LSH); - case '>': - return follow2('=', GE, '>', RSH); - case '=': - return follow('=', EQ); - case '!': - return follow('=', NE); - } - - if(isdigit(c)){ - int n = c - '0'; - while((c = *inp) != 0 && isdigit(c)) { - n = n * 10 + c - '0'; - inp++; - } - yylval.i = n; - return NUM; - } - - if(islower(c)){ - char buf[100]; - char *p = buf; - char *ep = buf+sizeof buf-1; - *p++ = c; - while(ppid != pid) - ; - if(w == nil){ - fprint(2, "%s: wait not found\n", s); - return -1; - } - if(w->msg && w->msg[0]) { - fprint(2, "%s: failed\n", s); - return -1; - } - return 0; -} - -void show(Memimage*); - -void -xquit(int argc, char **argv) -{ - USED(argc); - USED(argv); - exits(0); -} - -struct { - char *name; - char *path; - Memimage *m; - int ref; -} *files; -int nfiles; - -Memimage* -namei(char *name, int warn) -{ - int i; - - for(i=0; i nfiles) - kaboom("no image $%d", n); - files[n-1].ref++; -} - -Memimage* -readi(char *name) -{ - int fd; - Memimage *m, *m1; - - if((fd = open(name, OREAD)) < 0){ - fprint(2, "open %s: %r\n", name); - return nil; - } - m = readmemimage(fd); - close(fd); - if(m == nil){ - fprint(2, "readmemimage: %r\n"); - return nil; - } - if(m->chan != GREY8 || !eqrect(m->r, Rect(0, 0, DX, DY))){ - if((m1 = allocmemimage(Rect(0, 0, DX, DY), GREY8)) == nil) - abort(); - memfillcolor(m1, DBlack); - memimagedraw(m1, m1->r, m, m->r.min, memopaque, ZP, S); - freememimage(m); - m = m1; - } - return m; -} - -int -writei(Memimage *m, char *name) -{ - int fd; - - if((fd = create(name, OWRITE, 0666)) < 0){ - fprint(2, "create %s: %r\n", name); - return -1; - } - if(writememimage(fd, m) < 0){ - fprint(2, "writememimage %s: %r\n", name); - close(fd); - return -1; - } - close(fd); - return 0; -} - -void -xfiles(int argc, char **argv) -{ - USED(argv); - int i; - if(argc != 1){ - fprint(2, "usage: f\n"); - return; - } - for(i=0; i 3){ - fprint(2, "usage: r image [filename]\n"); - return; - } - m = readi(argc == 3 ? argv[2] : argv[1]); - iput(argv[1], m); -} - -void -xwrite(int argc, char **argv) -{ - if(argc < 2 || argc > 3){ - fprint(2, "usage: w image [filename]\n"); - return; - } - Memimage *m = namei(argv[1], 1); - if(m == nil) - return; - writei(m, argc == 3 ? argv[2] : argv[1]); -} - -void -xdisplay(int argc, char **argv) -{ - int i; - - if(argc == 1){ - if(nfiles > 0) - show(files[nfiles-1].m); - return; - } - - for(i=1; i\n" - "#include \n" - "#include \n" - "#include \n" - "\n" - "Memimage*\n" - "READ(char *file)\n" - "{\n" - " Memimage *m;\n" - " int fd = open(file, OREAD);\n" - " if(fd < 0) sysfatal(\"open %s: %r\", file);\n" - " m = readmemimage(fd);\n" - " if(m == nil) sysfatal(\"readmemimage %s: %r\", file);\n" - " return m;\n" - "}\n\n" - "void\n" - "WRITE(Memimage *m, char *file)\n" - "{\n" - " int fd = create(file, OWRITE, 0666);\n" - " if(fd < 0) sysfatal(\"create %s: %r\", file);\n" - " if(writememimage(fd, m) < 0) sysfatal(\"writememimage %s: %r\", file);\n" - "}\n\n" - "int\n" - "POW(int a, int b)\n" - "{\n" - " int t;\n" - " if(b <= 0) return 1;\n" - " if(b == 1) return a;\n" - " t = POW(a, b/2);\n" - " t *= t;\n" - " if(b%2) t *= a;\n" - " return t;\n" - "}\n" - "\n" - "int\n" - "DIV(int a, int b)\n" - "{\n" - " if(b == 0) return 0;\n" - " return a/b;\n" - "}\n" - "\n" - "int\n" - "MOD(int a, int b)\n" - "{\n" - " if(b == 0) return 0;\n" - " return a%b;\n" - "}\n" - "\n" - "#define X 248\n" - "#define Y 248\n" - "#define Z 255\n" - "\n" - "uchar\n" - "IMAGE(uchar *p, int x, int y)\n" - "{\n" - " if(x < 0 || y < 0 || x >= X || y >= Y) return 0;\n" - " return p[y*X+x];\n" - "}\n" - "\n" - "uchar*\n" - "WIMAGE(uchar *p, int x, int y)\n" - "{\n" - " static uchar devnull;\n" - " if(x < 0 || y < 0 || x >= X || y >= Y) return &devnull;\n" - " return &p[y*X+x];\n" - "}\n" - "\n" - "#define CLIP(x) ((x) < 0 ? 0 : (x) > 255 ? 255 : (x))\n" - "\n" - "void main(void) {\n" - " int x, y, T;\n" - ; - -int quiet; - -void -runprog(char *name, char *cmd) -{ - int i, fd, isnew; - Memimage *m; - - if((fd = create("/tmp/pico-run.c", OWRITE, 0666)) < 0){ - fprint(2, "create /tmp/pico-run.c: %r"); - return; - } - - write(fd, prolog, strlen(prolog)); - - fprint(fd, "\tuchar* OLD[%d+1]; USED(OLD);\n", nfiles); - fprint(fd, "\tuchar* old = 0; USED(old);\n"); - fprint(fd, "\tMemimage *M[%d+1];\n", nfiles); - - isnew = namei(name, 0) == 0; - if(isnew){ - fprint(fd, "\tMemimage *NEW = allocmemimage(Rect(0, 0, X, Y), GREY8);\n"); - fprint(fd, "\tif(NEW == nil) sysfatal(\"allocmemimage: %%r\");\n"); - fprint(fd, "\tuchar* %s = NEW->data->bdata;\n", name); - } - - for(i=0; idata->bdata;\n", *files[i].name ? "uchar* " :"", files[i].name, *files[i].name ? " = " : "", i, i); - if(strcmp(files[i].name, name) == 0) - fprint(fd, "Memimage* NEW = M[%d];\n", i); - } - - fprint(fd, "\tfor(x=0; x<%d; x++) for(y=0; y<%d; y++) {\n", DX, DY); - fprint(fd, "\t\t%s\n", cmd); - fprint(fd, "\t}"); - fprint(fd, "\tWRITE(NEW, \"/tmp/pico-run.out.png\");\n"); - fprint(fd, "\texits(0);\n}\n"); - close(fd); - - if(system(CC " -o /tmp/pico-run.o /tmp/pico-run.c") < 0) - goto cleanup; - if(system(LD " -o /tmp/pico-run /tmp/pico-run.o") < 0) - goto cleanup; - - for(i=0; i "); - if((p = Brdline(&b, '\n')) == 0) - break; - p[Blinelen(&b)-1] = 0; - while(*p != 0 && isspace(*p)) - p++; - if(*p == 0) - goto reread; - for(i=0; ir, displayed, nil, ZP); - flushimage(display, 1); -} - -void -showloop(Memimage *m) -{ - if(initdraw(0, 0, "pico") < 0){ - fprint(2, "initdraw: %r\n"); - return; - } - - einit(Emouse|Ekeyboard); - doresize(); - if((displayed = allocimage(display, Rect(0, 0, DX, DY), GREY8, 0, DBlack)) == nil){ - fprint(2, "allocimage: %r\n"); - return; - } - if(loadimage(displayed, displayed->r, byteaddr(m, ZP), DX*DY) < 0){ - fprint(2, "loadimage: %r\n"); - return; - } - close(0); - eresized(0); - for(;;){ - Event e; - flushimage(display, 0); - switch(eread(Emouse|Ekeyboard, &e)){ - case Ekeyboard: - if(e.kbdc == 'q') - return; - eresized(0); - break; - case Emouse: - if(e.mouse.buttons&4) - return; - break; - } - } -} - -void -show(Memimage *m) -{ - if(newwin() != 0) - return; - showloop(m); - exits(0); -} //GO.SYSIN DD pico.y