├── foo ├── 1.out ├── 2.out ├── 3.out ├── 4.out ├── while-if-1.out ├── if-1.out ├── while.out ├── 5.out ├── hello-world.out ├── hello-world.foo ├── npiet-trace.png ├── npiet-foogol.png ├── Makefile ├── expr-2.out ├── expr-0.out ├── expr-1.out ├── 4.foo ├── while.foo ├── if-1.foo ├── 1.foo ├── while-if-1.foo ├── foogol-example.out ├── 5.foo ├── 7.foo ├── README ├── 3.foo ├── 2.foo ├── expr-0.foo ├── foogol-example.foo ├── 7.out ├── 99-bottles.foo ├── expr-2.foo ├── expr-1.foo ├── runtest.sh └── 99-bottles.out ├── .gitignore ├── examples ├── nfhello.foo ├── hi.png ├── loop.gif ├── nfib.png ├── nhello.gif ├── nprime.gif ├── loop-big.gif ├── nhello-big.gif ├── nprime-big.gif ├── loop-trace-big.png ├── Makefile ├── nhello-trace-big.png ├── runtest.sh ├── README ├── hi.ppm ├── loop.ppm ├── nfib.ppm ├── nprime.ppm └── nhello.ppm ├── config.h.in ├── configure.in ├── npietedit.1 ├── README.npiet ├── npiet-foogol.1 ├── Makefile.in ├── Makefile ├── ChangeLog ├── npiet.1 ├── install-sh ├── COPYING ├── npietedit └── npiet-foogol.y /foo/1.out: -------------------------------------------------------------------------------- 1 | 345 2 | -------------------------------------------------------------------------------- /foo/2.out: -------------------------------------------------------------------------------- 1 | 123 2 | -------------------------------------------------------------------------------- /foo/3.out: -------------------------------------------------------------------------------- 1 | 123 2 | -------------------------------------------------------------------------------- /foo/4.out: -------------------------------------------------------------------------------- 1 | 123 2 | -------------------------------------------------------------------------------- /foo/while-if-1.out: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /foo/if-1.out: -------------------------------------------------------------------------------- 1 | 110 2 | -------------------------------------------------------------------------------- /foo/while.out: -------------------------------------------------------------------------------- 1 | 54321 2 | -------------------------------------------------------------------------------- /foo/5.out: -------------------------------------------------------------------------------- 1 | 23231323232323232323 2 | -------------------------------------------------------------------------------- /foo/hello-world.out: -------------------------------------------------------------------------------- 1 | Hello World! 2 | -------------------------------------------------------------------------------- /examples/nfhello.foo: -------------------------------------------------------------------------------- 1 | begin 2 | prints ("Hello World!\n") 3 | end 4 | -------------------------------------------------------------------------------- /foo/hello-world.foo: -------------------------------------------------------------------------------- 1 | begin 2 | prints ("Hello World!\n") 3 | end 4 | -------------------------------------------------------------------------------- /examples/hi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinh/npiet/master/examples/hi.png -------------------------------------------------------------------------------- /examples/loop.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinh/npiet/master/examples/loop.gif -------------------------------------------------------------------------------- /examples/nfib.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinh/npiet/master/examples/nfib.png -------------------------------------------------------------------------------- /examples/nhello.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinh/npiet/master/examples/nhello.gif -------------------------------------------------------------------------------- /examples/nprime.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinh/npiet/master/examples/nprime.gif -------------------------------------------------------------------------------- /foo/npiet-trace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinh/npiet/master/foo/npiet-trace.png -------------------------------------------------------------------------------- /examples/loop-big.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinh/npiet/master/examples/loop-big.gif -------------------------------------------------------------------------------- /foo/npiet-foogol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinh/npiet/master/foo/npiet-foogol.png -------------------------------------------------------------------------------- /examples/nhello-big.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinh/npiet/master/examples/nhello-big.gif -------------------------------------------------------------------------------- /examples/nprime-big.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinh/npiet/master/examples/nprime-big.gif -------------------------------------------------------------------------------- /examples/loop-trace-big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinh/npiet/master/examples/loop-trace-big.png -------------------------------------------------------------------------------- /foo/Makefile: -------------------------------------------------------------------------------- 1 | 2 | all test: 3 | ./runtest.sh 4 | 5 | clean clobber realclean mrproper: 6 | true 7 | -------------------------------------------------------------------------------- /examples/Makefile: -------------------------------------------------------------------------------- 1 | 2 | all test: 3 | ./runtest.sh 4 | 5 | clean clobber realclean mrproper: 6 | true 7 | -------------------------------------------------------------------------------- /examples/nhello-trace-big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinh/npiet/master/examples/nhello-trace-big.png -------------------------------------------------------------------------------- /foo/expr-2.out: -------------------------------------------------------------------------------- 1 | 1 ok 2 | 1a ok 3 | 1b ok 4 | 2 ok 5 | 2 ok 6 | 2 ok 7 | 3 ok 8 | 3a ok 9 | 3b ok 10 | -------------------------------------------------------------------------------- /foo/expr-0.out: -------------------------------------------------------------------------------- 1 | 9 2 | 10 3 | 11 4 | 99 5 | 100 6 | 101 7 | 999 8 | 1000 9 | 1001 10 | 9999 11 | 10000 12 | 10001 13 | -------------------------------------------------------------------------------- /foo/expr-1.out: -------------------------------------------------------------------------------- 1 | 1 ok 2 | 2 ok 3 | 3 ok 4 | 3 ok 5 | 4 ok 6 | 5 ok 7 | 6 ok 8 | 7 ok 9 | 8 ok 10 | 9 ok 11 | 10 ok 12 | 11 ok 13 | 12 ok 14 | -------------------------------------------------------------------------------- /foo/4.foo: -------------------------------------------------------------------------------- 1 | begin 2 | 3 | if 1 = 1 then 4 | printn (1); 5 | 6 | if 0 = 1 then 7 | printn (4); 8 | 9 | if 2 + 4 = 3 * 2 then 10 | printn (2); 11 | 12 | printn (3); 13 | prints ("\n") 14 | 15 | end 16 | -------------------------------------------------------------------------------- /foo/while.foo: -------------------------------------------------------------------------------- 1 | begin 2 | 3 | integer i; 4 | 5 | i := 5; 6 | 7 | while i # 0 do begin 8 | 9 | printn (i); 10 | i := i - 1 11 | end; 12 | 13 | prints (" "); 14 | prints ("\n") 15 | 16 | end 17 | -------------------------------------------------------------------------------- /foo/if-1.foo: -------------------------------------------------------------------------------- 1 | begin 2 | 3 | if 1 then printn (1); 4 | if 0 then printn (1); 5 | 6 | if 1 then printn (1) else printn (0); 7 | if 0 then printn (1) else printn (0); 8 | 9 | prints ("\n") 10 | 11 | end 12 | -------------------------------------------------------------------------------- /foo/1.foo: -------------------------------------------------------------------------------- 1 | begin 2 | 3 | integer i, j; 4 | 5 | i := 3; 6 | j := 5; 7 | 8 | begin 9 | 10 | integer l; 11 | 12 | l := 4; 13 | 14 | printn (i); 15 | printn (l) 16 | end; 17 | 18 | printn (j); 19 | 20 | prints ("\n") 21 | 22 | end 23 | -------------------------------------------------------------------------------- /foo/while-if-1.foo: -------------------------------------------------------------------------------- 1 | begin 2 | 3 | integer i; 4 | 5 | i := 1; 6 | 7 | while i < 4 do begin 8 | 9 | if 2 # 3 then 10 | if 1 = 3 then 11 | printn (5 + 2); 12 | 13 | i := i + 1 14 | 15 | end 16 | 17 | end 18 | -------------------------------------------------------------------------------- /foo/foogol-example.out: -------------------------------------------------------------------------------- 1 | 2 is prime number 1 2 | 3 is prime number 2 3 | 5 is prime number 3 4 | 7 is prime number 4 5 | 11 is prime number 5 6 | 13 is prime number 6 7 | 17 is prime number 7 8 | 19 is prime number 8 9 | 23 is prime number 9 10 | 29 is prime number 10 11 | -------------------------------------------------------------------------------- /foo/5.foo: -------------------------------------------------------------------------------- 1 | begin 2 | 3 | integer i, j; 4 | 5 | 6 | j := 0; 7 | 8 | while j # 10 do begin 9 | 10 | j := j + 1; 11 | i := 0; 12 | 13 | while i # 10 do begin 14 | 15 | i := i + 1; 16 | 17 | if i = 3 then 18 | if j # 3 then 19 | printn (20 + i) 20 | else 21 | printn (10 + i) 22 | 23 | end 24 | end; 25 | 26 | if i # 0 then 27 | prints ("\n") 28 | 29 | end 30 | -------------------------------------------------------------------------------- /foo/7.foo: -------------------------------------------------------------------------------- 1 | begin 2 | 3 | integer i, j; 4 | 5 | j := 0; 6 | 7 | while j # 6 do begin 8 | 9 | i := 0; 10 | 11 | while i # 6 do begin 12 | 13 | prints ("i="); 14 | printn (i); 15 | prints (" j="); 16 | printn (j); 17 | prints (" -> "); 18 | printn (10 * j + i); 19 | prints ("\n"); 20 | 21 | i := i + 1 22 | 23 | end; 24 | 25 | j := j + 1 26 | 27 | end 28 | 29 | end 30 | -------------------------------------------------------------------------------- /foo/README: -------------------------------------------------------------------------------- 1 | 2 | 3 | foo/README: 08'2004 4 | (schoenfr@web.de) 5 | 6 | 7 | some foo language examples to test the npiet-foogol compiler and npiet 8 | interpreter. 9 | 10 | 11 | especially: 12 | 13 | hello-world.foo - prints Hello-World! 14 | 15 | foogol-example.foo - the original foogol (and cfoogol) prime tester 16 | example 17 | 18 | 99-bottles.foo - prints the 99 bottles of beer lyrics 19 | 20 | 21 | 22 | -- 23 | Tue Aug 10 20:57:13 MEST 2004 24 | -------------------------------------------------------------------------------- /foo/3.foo: -------------------------------------------------------------------------------- 1 | begin 2 | 3 | integer i, j; 4 | 5 | i := 3; 6 | 7 | if i = 3 then 8 | if i # 3 then 9 | printn (2) 10 | else 11 | printn (1); 12 | 13 | if i # 3 then 14 | if i = 3 then 15 | printn (4) 16 | else 17 | printn (3) 18 | else 19 | printn (2); 20 | 21 | if i # 3 then 22 | if i = 3 then 23 | printn (5) 24 | else 25 | printn (6) 26 | else 27 | if i = 3 then 28 | printn (3) 29 | else 30 | printn (1); 31 | 32 | if 1 = 1 then 33 | prints ("\n") 34 | 35 | end 36 | -------------------------------------------------------------------------------- /foo/2.foo: -------------------------------------------------------------------------------- 1 | begin 2 | 3 | integer i, j; 4 | 5 | i := 3; 6 | 7 | if i = 3 then 8 | if i # 3 then 9 | printn (2) 10 | else 11 | printn (1); 12 | 13 | if i # 3 then 14 | if i = 3 then 15 | printn (4) 16 | else 17 | printn (3) 18 | else 19 | printn (2); 20 | 21 | if i # 3 then 22 | if i = 3 then 23 | printn (5) 24 | else 25 | printn (6) 26 | else 27 | if i = 3 then 28 | printn (3) 29 | else 30 | printn (1); 31 | 32 | if 1 = 1 then 33 | prints ("\n") 34 | 35 | end 36 | 37 | -------------------------------------------------------------------------------- /foo/expr-0.foo: -------------------------------------------------------------------------------- 1 | begin 2 | 3 | printn (9); 4 | prints ("\n"); 5 | printn (10); 6 | prints ("\n"); 7 | printn (11); 8 | prints ("\n"); 9 | 10 | printn (99); 11 | prints ("\n"); 12 | printn (100); 13 | prints ("\n"); 14 | printn (101); 15 | prints ("\n"); 16 | 17 | printn (999); 18 | prints ("\n"); 19 | printn (1000); 20 | prints ("\n"); 21 | printn (1001); 22 | prints ("\n"); 23 | 24 | printn (9999); 25 | prints ("\n"); 26 | printn (10000); 27 | prints ("\n"); 28 | printn (10001); 29 | prints ("\n") 30 | 31 | 32 | end 33 | -------------------------------------------------------------------------------- /config.h.in: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004 Erik Schoenfelder (schoenfr@web.de) 3 | * 4 | * This file is part of npiet 5 | * 6 | * config.h.in for use with configure 7 | * configurational parameters: 8 | */ 9 | 10 | #ifndef CONFIG_H_HOOK 11 | #define CONFIG_H_HOOK 12 | 13 | /* Define if you have the header file. */ 14 | #undef HAVE_GD_H 15 | 16 | /* Define if you have the header file. */ 17 | #undef HAVE_PNG_H 18 | 19 | /* Define if you have the header file. */ 20 | #undef HAVE_GIF_LIB_H 21 | 22 | 23 | #endif /* CONFIG_H_HOOK */ 24 | -------------------------------------------------------------------------------- /foo/foogol-example.foo: -------------------------------------------------------------------------------- 1 | begin 2 | integer n, div, sub, test, testcopy, found, max; 3 | test := 2; max := 10; /* number of primes wanted */ 4 | while n # max do begin 5 | div:= test-1; found:= 0; 6 | while div-1 do begin 7 | testcopy:= test; sub:= 0; 8 | while testcopy do begin 9 | sub:= sub+1; if sub = div then sub:= 0; 10 | testcopy:= testcopy-1 11 | end; 12 | if sub = 0 then found:= 1; 13 | div:= div-1 14 | end; 15 | if found = 0 then begin 16 | n:= n+1; 17 | printn(test); prints(" is prime number "); printn(n); print 18 | end; 19 | test:= test+1 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /examples/runtest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | for f in hi.??? nfib.??? nprime.??? loop.??? nhello.??? ; do 5 | echo "**" 6 | echo "** running: npiet $f:" 7 | echo "**" 8 | echo -- output start -- 9 | if [ $f = nprime.gif ] ; then 10 | echo 991 | ../npiet $f 11 | elif [ $f = nprime.ppm ] ; then 12 | echo 1000 | ../npiet $f 13 | else 14 | ../npiet $f 15 | fi 16 | echo -- output end -- 17 | echo 18 | done 19 | 20 | echo "**" 21 | echo "** running: npiet -te 0 check - expect two Hi:" 22 | echo "**" 23 | rm -f npiet-trace.png 2>/dev/null 24 | ../npiet -te 0 hi.png 25 | ../npiet npiet-trace.png 26 | rm -f npiet-trace.png 2>/dev/null 27 | -------------------------------------------------------------------------------- /foo/7.out: -------------------------------------------------------------------------------- 1 | i=0 j=0 -> 0 2 | i=1 j=0 -> 1 3 | i=2 j=0 -> 2 4 | i=3 j=0 -> 3 5 | i=4 j=0 -> 4 6 | i=5 j=0 -> 5 7 | i=0 j=1 -> 10 8 | i=1 j=1 -> 11 9 | i=2 j=1 -> 12 10 | i=3 j=1 -> 13 11 | i=4 j=1 -> 14 12 | i=5 j=1 -> 15 13 | i=0 j=2 -> 20 14 | i=1 j=2 -> 21 15 | i=2 j=2 -> 22 16 | i=3 j=2 -> 23 17 | i=4 j=2 -> 24 18 | i=5 j=2 -> 25 19 | i=0 j=3 -> 30 20 | i=1 j=3 -> 31 21 | i=2 j=3 -> 32 22 | i=3 j=3 -> 33 23 | i=4 j=3 -> 34 24 | i=5 j=3 -> 35 25 | i=0 j=4 -> 40 26 | i=1 j=4 -> 41 27 | i=2 j=4 -> 42 28 | i=3 j=4 -> 43 29 | i=4 j=4 -> 44 30 | i=5 j=4 -> 45 31 | i=0 j=5 -> 50 32 | i=1 j=5 -> 51 33 | i=2 j=5 -> 52 34 | i=3 j=5 -> 53 35 | i=4 j=5 -> 54 36 | i=5 j=5 -> 55 37 | -------------------------------------------------------------------------------- /configure.in: -------------------------------------------------------------------------------- 1 | dnl 2 | dnl This file is an input file used by the GNU "autoconf" program to 3 | dnl generate the file "configure", which is run during installation 4 | dnl to configure the system for the local environment. 5 | dnl 6 | AC_INIT(npiet.c) 7 | AC_CONFIG_HEADER(config.h) 8 | 9 | AC_PROG_CC 10 | AC_PROG_INSTALL 11 | 12 | AC_CHECK_HEADERS(gd.h png.h gif_lib.h) 13 | AC_CHECK_LIB(gd, main, [LIBS="$LIBS -lgd"]) 14 | AC_CHECK_LIB(png, main, [LIBS="$LIBS -lpng"]) 15 | AC_CHECK_LIB(gif, main, [LIBS="$LIBS -lgif"]) 16 | AC_CHECK_LIB(z, main, [LIBS="$LIBS -lz"]) 17 | AC_CHECK_LIB(m, main, [LIBS="$LIBS -lm"]) 18 | 19 | AC_SUBST(DEFS) 20 | AC_SUBST(LIBS) 21 | 22 | AC_OUTPUT(Makefile) 23 | -------------------------------------------------------------------------------- /examples/README: -------------------------------------------------------------------------------- 1 | 2 | 3 | examples/README: 07'2004 4 | (schoenfr@web.de) 08'2004 5 | 6 | 7 | 8 | some examples of the piet programming language: 9 | 10 | (with varying codel size) 11 | 12 | 13 | hi.png - prints Hi 14 | 15 | loop.png - a simple loop printing from 10 backward 16 | 17 | nfib.png - prints the Fionacci numbers below 1000 18 | 19 | nhello.png - easy hello world example 20 | 21 | nprime.gif - prime number tester 22 | reads a number from input and outputs Y or N 23 | 24 | nfhello.foo - foogol Hello World source 25 | nfhello.gif - sample foogol Hello World piet program 26 | 27 | 28 | 29 | -- 30 | Tue Aug 10 20:57:45 MEST 2004 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /foo/99-bottles.foo: -------------------------------------------------------------------------------- 1 | begin 2 | 3 | /* 99-bottles.foo: */ 4 | 5 | /* you can find a copy of the ``foogol'' posting here: */ 6 | /* http://www.bertnase.de/html/foogol.html */ 7 | 8 | integer i; 9 | 10 | i := 99; 11 | 12 | while i # 0 do begin 13 | 14 | printn (i); 15 | prints (" bottle"); if i # 1 then prints ("s"); 16 | prints (" of beer on the wall,\n"); 17 | printn (i); 18 | prints (" bottle"); if i # 1 then prints ("s"); 19 | prints (" of beer,\n"); 20 | prints ("take one down, pass it around,\n"); 21 | i := i - 1; 22 | if i # 0 then printn (i) else prints ("no more"); 23 | prints (" bottle"); if i # 1 then prints ("s"); 24 | prints (" of beer on the wall.\n\n") 25 | 26 | end; 27 | 28 | prints ("Time to buy some more beer...\n") 29 | 30 | end 31 | -------------------------------------------------------------------------------- /foo/expr-2.foo: -------------------------------------------------------------------------------- 1 | begin 2 | 3 | /* note: contains extensions to foogol */ 4 | 5 | integer i, j; 6 | 7 | i := 999; 8 | j := 128; 9 | 10 | if i * i / j = 7796 then prints ("1 ok\n") else prints ("1 err\n"); 11 | if (i * i) / j = 7796 then prints ("1a ok\n") else prints ("1a err\n"); 12 | if ((i * i) / j) = 7796 then prints ("1b ok\n") else prints ("1b err\n"); 13 | if i / j * i = 6993 then prints ("2 ok\n") else prints ("2 err\n"); 14 | if (i / j) * i = 6993 then prints ("2 ok\n") else prints ("2 err\n"); 15 | if ((i / j) * i) = 6993 then prints ("2 ok\n") else prints ("2 err\n"); 16 | if i / j * i + 1 = (((999 / 128) * 999) + 1) then 17 | prints ("3 ok\n") else prints ("3 err\n"); 18 | if (((i / j) * i) + 1) = 6994 then 19 | prints ("3a ok\n") else prints ("3a err\n"); 20 | if 1 + i / j * i = (1 + ((999 / 128) * 999)) then 21 | prints ("3b ok\n") else prints ("3b err\n") 22 | 23 | end 24 | -------------------------------------------------------------------------------- /foo/expr-1.foo: -------------------------------------------------------------------------------- 1 | begin 2 | 3 | /* note: contains extensions to foogol */ 4 | 5 | integer i, j; 6 | 7 | i := 3; 8 | j := 5; 9 | 10 | begin 11 | 12 | if (i * j) = 15 then prints ("1 ok\n") else prints ("1 err\n"); 13 | if (j * i) = 15 then prints ("2 ok\n") else prints ("2 err\n"); 14 | if (j * i + 1) = 16 then prints ("3 ok\n") else prints ("3 err\n"); 15 | if (1 + j * i) = 16 then prints ("3 ok\n") else prints ("3 err\n"); 16 | if (-1 + 2) = 1 then prints ("4 ok\n") else prints ("4 err\n"); 17 | if (2 + -1) = 1 then prints ("5 ok\n") else prints ("5 err\n"); 18 | if (-2 - -1) = -1 then prints ("6 ok\n") else prints ("6 err\n"); 19 | if (1 < 2) = 1 then prints ("7 ok\n") else prints ("7 err\n"); 20 | if (1 > 2) = 0 then prints ("8 ok\n") else prints ("8 err\n"); 21 | if (2 < 1) = 0 then prints ("9 ok\n") else prints ("9 err\n"); 22 | if (2 > 1) = 1 then prints ("10 ok\n") else prints ("10 err\n"); 23 | if (2 = 1) = 0 then prints ("11 ok\n") else prints ("11 err\n"); 24 | if (2 # 1) = 1 then prints ("12 ok\n") else prints ("12 err\n") 25 | 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /npietedit.1: -------------------------------------------------------------------------------- 1 | .TH NPIETEDIT 1 "May 2004" "npietedit v0.1" 2 | .SH NAME 3 | npietedit \- an simple editor for the piet programming language 4 | .SH SYNOPSIS 5 | .B npietedit 6 | .I "[ ]" 7 | .SH DESCRIPTION 8 | .B npietedit 9 | is an simple editor (written in Tk/Tcl) for the piet programming language. 10 | .br 11 | TBD: write more 12 | .br 13 | quick: 14 | .br 15 | - reads ppm ascii or formats read by Tk/Tcl. 16 | .br 17 | - writes ppm ascii output (regardless of the suffix !) 18 | .br 19 | - every pixel read is a codel (knows nothing about codelsizes) 20 | .br 21 | - left mouse selects color from color bar 22 | .br 23 | - left mouse paints color on paint area 24 | .br 25 | - middle mouse selects color from paint area 26 | .br 27 | - left mouse selects next-color from command area 28 | .br 29 | - shrink / enlarge decreases / increases width and height 30 | .br 31 | - ... 32 | .SH FILES 33 | .B "npietedit-filename.ppm" 34 | - name of the default input / output file. 35 | .SH AUTHOR 36 | Erik Schoenfelder . 37 | .SH BUGS 38 | None seen - they are hidden in the oil painting ;-) 39 | .SH SEE ALSO 40 | .BR npiet (1) 41 | .BR wish (1) 42 | .br 43 | .B "http://www.bertnase.de/npiet/" 44 | .br 45 | .B "http://www.dangermouse.net/esoteric/piet.html" 46 | -------------------------------------------------------------------------------- /examples/hi.ppm: -------------------------------------------------------------------------------- 1 | P3 2 | # a piet program hi.ppm 3 | 10 10 4 | 255 5 | 0 0 255 0 0 255 0 0 255 0 0 192 0 0 192 6 | 0 0 192 0 0 0 0 255 0 0 255 0 0 0 0 7 | 0 0 255 0 0 255 0 0 255 0 0 192 0 0 192 8 | 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 9 | 0 0 255 0 0 255 0 0 255 0 0 192 0 0 192 10 | 0 0 192 192 192 255 192 0 192 0 192 192 0 255 0 11 | 255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 12 | 255 0 0 255 0 0 0 255 255 255 0 0 0 255 0 13 | 255 0 0 255 0 0 255 0 0 255 0 0 0 255 0 14 | 0 192 192 0 255 255 0 255 255 0 255 255 0 255 0 15 | 255 0 0 255 0 0 255 0 0 255 0 0 0 255 0 16 | 255 0 0 255 0 0 0 255 255 0 192 0 0 255 0 17 | 255 255 0 255 255 0 0 0 0 0 0 0 0 255 0 18 | 0 0 0 0 0 0 0 255 255 0 192 0 0 192 0 19 | 255 255 0 255 255 0 0 0 0 0 255 0 0 255 0 20 | 0 255 0 0 0 0 0 255 255 0 255 255 192 255 192 21 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 22 | 0 0 0 0 0 0 0 0 0 0 255 255 0 192 192 23 | 255 255 0 255 255 0 0 0 0 255 255 0 255 255 0 24 | 255 255 0 255 255 0 0 0 0 0 255 255 0 0 192 25 | -------------------------------------------------------------------------------- /examples/loop.ppm: -------------------------------------------------------------------------------- 1 | P3 2 | # a piet program loop.ppm 3 | 14 7 4 | 255 5 | 0 0 255 0 0 192 192 192 255 192 0 192 255 255 255 255 255 255 6 | 0 0 255 0 255 0 192 192 0 192 192 0 192 192 0 192 192 0 7 | 192 192 0 255 255 192 0 0 255 0 0 192 255 255 255 255 255 255 8 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 9 | 255 255 255 255 255 255 255 255 255 255 192 255 0 0 255 255 255 255 10 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 11 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 192 192 12 | 0 0 255 255 255 255 0 0 0 0 0 0 0 0 0 255 255 255 13 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 14 | 255 255 255 192 0 192 0 0 255 0 0 0 0 0 255 0 0 255 15 | 0 0 255 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 16 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 17 | 0 0 0 255 255 255 0 0 0 255 255 255 255 255 255 255 255 255 18 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 19 | 255 255 255 255 255 255 0 0 0 255 255 255 255 255 255 255 255 255 20 | 255 0 255 192 255 192 255 192 255 0 255 255 192 255 255 255 192 255 21 | 0 0 192 0 0 255 22 | -------------------------------------------------------------------------------- /foo/runtest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | maxe=10000000 4 | 5 | if [ "$1" = "-g" ] ; then 6 | gen=1 7 | shift 8 | fi 9 | 10 | if [ "$1" = "-rnd" ] ; then 11 | rndopts="-rnd" 12 | shift 13 | else 14 | rndopts='' 15 | fi 16 | 17 | 18 | if [ "$1" != "" ] ; then 19 | ../npiet-foogol -q $1 20 | if [ "$gen" = 1 ] ; then 21 | ../npiet -e $maxe npiet-foogol.png >& `basename $1 .foo`.out 22 | ls -l `basename $1 .foo`.out 23 | else 24 | ../npiet -e $maxe -tpic -te 1000 npiet-foogol.png 25 | fi 26 | 27 | exit 0 28 | fi 29 | 30 | 31 | for f in *.foo ; do 32 | b=`basename $f .foo` 33 | 34 | echo running test $f 35 | fail=0 36 | 37 | for wrap in 3173 2048 1024 222 128 66 48 24 23 22 16 15 14 13 12 11 10 ; do 38 | 39 | for rnd in '' $rndopts ; do 40 | 41 | echo -n "." 42 | 43 | if [ $fail = 0 ] ; then 44 | targ="-w $wrap" 45 | 46 | ../npiet-foogol $rnd -q $targ $f > /tmp/$b-tmp-$wrap.out 47 | ../npiet -e $maxe npiet-foogol.png > /tmp/$b-tmp-$wrap.out 48 | if diff -q $b.out /tmp/$b-tmp-$wrap.out >/dev/null ; then 49 | rm -f ./a.out 2>/dev/null 50 | else 51 | echo ==== file=$f wrap=$wrap rnd=$rnd ==== 52 | diff -u $b.out /tmp/$b-tmp-$wrapout 53 | fail=1 54 | fi 55 | rm -f /tmp/$b-tmp-$wrap.out 56 | fi 57 | 58 | done 59 | done 60 | 61 | echo 62 | done 63 | 64 | exit 0 65 | -------------------------------------------------------------------------------- /README.npiet: -------------------------------------------------------------------------------- 1 | 2 | 3 | README.npiet: Jun 2004 4 | (schoenfr@web.de) Nov 2009 5 | (gleitz@mit.edu) Oct 2013 6 | 7 | 8 | 9 | - npiet is an interperter for the piet programming language and 10 | 11 | - npietedit is a very simple editor for small piet programs. 12 | 13 | - npietedit-foogol is a ``foogol to piet'' compiler. 14 | 15 | 16 | about the piet programming language please look at: 17 | 18 | http://www.dangermouse.net/esoteric/piet.html 19 | 20 | 21 | and you find more about npiet at: 22 | 23 | http://bertnase.de/npiet 24 | 25 | 26 | and a copy of the foogol (and cfoogol) postings, about a ``ALGOL-like 27 | language'' definition is avail here: 28 | 29 | http://bertnase.de/html/foogol.html 30 | 31 | 32 | to compile and install npiet and the additional programs and files run 33 | 34 | brew install libgd # mac os 35 | ./configure 36 | make 37 | make install 38 | 39 | this installs the binaries npiet, npietedit and npiet-foogol, 40 | together with the manpages npiet.1, npietedit.1 and npiet-foogol.1 . 41 | 42 | 43 | if compiled with gd-lib and png-lib support (if avail), graphical 44 | trace output can be created by npiet - great fun ;-) 45 | 46 | 47 | npietedit is a Tk/Tcl program, so you need Tk/Tcl installed to run it. 48 | 49 | npiet-foogil needs libgd to compile and run. 50 | 51 | 52 | a quick npiet-foogol and npiet test would be: 53 | 54 | echo 'begin prints ("Yo\n") end' | ./npiet-foogol - 55 | ./npiet npiet-foogol.png 56 | 57 | or additionally to create a trace picture named npiet-trace.png: 58 | 59 | ./npiet -tpic npiet-foogol.png 60 | 61 | 62 | Have fun! 63 | 64 | 65 | -- 66 | Fri Aug 5 23:14:42 CEST 2011 67 | 68 | -------------------------------------------------------------------------------- /examples/nfib.ppm: -------------------------------------------------------------------------------- 1 | P3 2 | # a piet program nfib.ppm 3 | 12 12 4 | 255 5 | 255 0 0 192 0 0 0 0 192 255 192 255 192 255 255 0 255 0 6 | 255 255 255 255 0 0 255 0 0 192 0 0 255 0 255 192 0 192 7 | 0 0 0 0 0 0 255 255 0 0 0 192 0 0 192 0 0 192 8 | 255 0 0 255 0 0 255 0 0 255 255 0 255 255 0 255 192 255 9 | 0 0 192 192 0 0 255 255 255 255 0 255 192 0 0 255 0 0 10 | 255 0 0 255 0 0 255 255 255 192 0 192 255 0 0 0 255 0 11 | 0 0 192 0 0 192 0 0 192 0 0 192 0 0 192 255 255 0 12 | 255 0 0 255 0 0 255 255 0 0 0 0 255 255 0 255 192 255 13 | 0 0 192 0 0 192 0 0 192 0 0 192 0 0 192 0 0 192 14 | 0 0 192 0 0 192 255 255 0 192 0 192 192 0 192 192 0 192 15 | 0 0 192 0 0 192 0 0 192 0 0 192 0 0 192 0 0 0 16 | 0 0 192 0 0 192 0 0 192 0 0 0 255 255 0 255 255 255 17 | 0 0 192 0 0 192 0 0 192 0 0 192 0 0 192 255 0 0 18 | 0 0 192 0 0 192 0 0 192 0 0 0 255 255 0 255 255 255 19 | 0 0 192 255 255 0 0 0 0 0 0 0 255 0 0 255 0 0 20 | 255 0 0 0 0 0 255 255 0 255 255 0 255 255 0 255 255 255 21 | 192 192 255 192 192 255 192 192 255 0 255 255 255 255 0 255 0 0 22 | 255 255 255 255 255 0 255 255 0 0 0 255 255 255 0 0 255 255 23 | 0 0 255 255 255 0 0 0 0 0 255 255 255 255 0 0 0 0 24 | 255 255 255 255 255 0 255 255 0 0 0 255 255 255 0 0 255 0 25 | 192 192 0 192 0 192 255 0 0 0 255 255 0 192 192 0 0 255 26 | 192 192 0 255 255 255 255 0 0 0 0 255 0 0 192 192 192 255 27 | 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 28 | 255 255 0 255 255 0 255 255 0 0 0 0 192 192 255 192 192 255 29 | 30 | -------------------------------------------------------------------------------- /npiet-foogol.1: -------------------------------------------------------------------------------- 1 | .TH NPIET-FOOGOL 1 "Aug 2011" "npiet v1.3" 2 | .SH NAME 3 | npiet-foogol \- a foogol to piet compiler 4 | .SH SYNOPSIS 5 | .B npiet-foogol 6 | [ 7 | .B \-v 8 | | 9 | .B \-d 10 | ] [ 11 | .BI "-w" " " 12 | ] [ 13 | .BI "-b" " " 14 | ] [ 15 | .BI "-cs" " " 16 | ] 17 | .I inputfile 18 | .SH DESCRIPTION 19 | .B npiet-foogol 20 | translates foogol input to a piet program. So npiet-foogol creates a 21 | picture from foogol source. The picture is, well should be, a valid 22 | piet program and can be executed, eg. by the npiet interpreter. 23 | .br 24 | .SH OPTIONS 25 | .TP 26 | .B \-h 27 | print usage help and exit. 28 | .TP 29 | .B \-v 30 | be somewhat verbose. 31 | .TP 32 | .B \-d 33 | print debug output (lot's of more or less cryptic and mostly useless blurb). 34 | .TP 35 | .B \-w 36 | Sets a wrap-width in pixel. This gives the compiler a hint about a 37 | block width to use when generating expressions or statements. 38 | .br 39 | Usually code is generated left to right until the wrap-width is reached 40 | and then to the left. To avoid codel overlaps in loops and conditionals, code 41 | is generated with a virtual left border, but this wrap-width too. 42 | Here is lot of optimisation possible. 43 | .TP 44 | .B \-b 45 | Sets the base used by generating a number. The default is 7 and a 46 | value greater or equal of 2 is acceptable. 47 | .br 48 | In a piet program the number of codels (here pixels) of a color block 49 | represents a number. To be able to push a large number on the stack 50 | without wasting a lot of ink, the number is calculated and the given 51 | base is used to do so. 52 | 53 | .TP 54 | .B \-cs 55 | Sets the output codel size to n pixels. The default is 1. 56 | Use a higher value to get a larger output picture. 57 | 58 | .TP 59 | .B \-rnd 60 | Experimental feature to set the start codel not always to red, but to 61 | a somewhat more random value. This does not work reliable - please 62 | avoid if running in trouble... 63 | 64 | .B \-o 65 | Sets the output filename. Default is npiet-foogol.png. 66 | .TP 67 | .B inputfile 68 | The foogol program to read. Use a - to read from . 69 | .SH FILES 70 | .B "npiet-foogol.png" 71 | - default name of the piet program file to write. It is overwritten if 72 | it exists. 73 | .SH AUTHOR 74 | Erik Schoenfelder . 75 | .SH BUGS 76 | Surely lots. 77 | .SH SEE ALSO 78 | .BR npiet(1), 79 | .BR npietedit(1) 80 | .br 81 | .B "http://www.bertnase.de/npiet/" 82 | -------------------------------------------------------------------------------- /Makefile.in: -------------------------------------------------------------------------------- 1 | ## 2 | ## Makefile for the npiet interpreter (and npietedit editor) 3 | ## 4 | 5 | prefix = @prefix@ 6 | exec_prefix = @exec_prefix@ 7 | 8 | BINDIR = $(exec_prefix)/bin 9 | MANDIR = $(prefix)/man/man1 10 | 11 | CC = @CC@ 12 | 13 | ## 14 | ## warn flags for gcc compiler: 15 | ## 16 | # GWARN = -W -Wcomment -Wpointer-arith -Wcast-qual 17 | GWAR2 = -Wall 18 | WARN = $(GWARN) $(GWAR2) 19 | 20 | ## 21 | ## system dependent flags: 22 | ## 23 | DEFS = -DHAVE_CONFIG_H 24 | ## 25 | 26 | ## 27 | ## Flags for debugging and production: 28 | ## 29 | # FLAGS = -O 30 | FLAGS = -g -O2 31 | # LDFLAGS = 32 | LDFLAGS = -g 33 | 34 | ## Uncomment for profiling: 35 | # PROF = -pg 36 | 37 | ## win cygwin static flag: 38 | # CYG = -mno-cygwin -static 39 | # CYG_LIBS = -lgd -lpng -lgif -lz -lm 40 | 41 | ## 42 | ## libraries: 43 | ## 44 | LIBS = @LIBS@ $(CYG_LIBS) 45 | 46 | ## 47 | ## installation commands: 48 | ## 49 | INSTALL = @INSTALL@ 50 | INSTALL_PROGRAM = @INSTALL_PROGRAM@ 51 | INSTALL_DATA = @INSTALL_DATA@ 52 | 53 | ## 54 | ## commonly used binaries: 55 | ## 56 | SHELL = /bin/sh 57 | RM = rm 58 | 59 | ## 60 | ## And more: 61 | ## 62 | ## Anything else below here should be independent. 63 | ## 64 | CFLAGS = $(FLAGS) $(PROF) $(CYG) $(WARN) $(DEFS) $(LIBDIRPATH) 65 | 66 | ## 67 | ## How to build the target: 68 | ## 69 | all: npiet npiet-foogol html 70 | 71 | npiet: npiet.o 72 | $(CC) $(LDFLAGS) $(PROF) -o npiet npiet.o $(LIBS) 73 | 74 | npiet.o: npiet.c 75 | $(CC) $(CFLAGS) $(PROF) -c npiet.c 76 | 77 | html: npiet.1.html npietedit.1.html npiet-foogol.1.html 78 | 79 | npiet.1.html: npiet.1 80 | groff -man -T html npiet.1 > npiet.1.html 81 | 82 | npietedit.1.html: npietedit.1 83 | groff -man -T html npietedit.1 > npietedit.1.html 84 | 85 | npiet-foogol.1.html: npiet-foogol.1 86 | groff -man -T html npiet-foogol.1 > npiet-foogol.1.html 87 | 88 | win: 89 | cp -p *.html win 90 | cp -p npietedit win/npietedit.tcl 91 | chmod -x win/* 92 | 93 | al: ftest 94 | 95 | npiet-foogol: npiet-foogol.o 96 | $(CC) $(LDFLAGS) $(PROF) -o npiet-foogol npiet-foogol.o $(LIBS) 97 | 98 | npiet-foogol.o: npiet-foogol.c 99 | $(CC) $(CFLAGS) $(PROF) -c npiet-foogol.c 100 | 101 | npiet-foogol.c: npiet-foogol.y 102 | bison -v -t -o npiet-foogol.c npiet-foogol.y 103 | 104 | ftest: npiet-foogol 105 | ./npiet-foogol a.foo 106 | 107 | 108 | test: check 109 | 110 | check: 111 | (cd examples ; make) 112 | (cd foo ; make) 113 | 114 | ## 115 | ## installation: 116 | ## 117 | install: $(PRG) 118 | $(INSTALL_PROGRAM) npiet $(BINDIR) 119 | $(INSTALL_PROGRAM) npietedit $(BINDIR) 120 | $(INSTALL_PROGRAM) npiet-foogol $(BINDIR) 121 | $(INSTALL_DATA) npiet.1 $(MANDIR) 122 | $(INSTALL_DATA) npietedit.1 $(MANDIR) 123 | $(INSTALL_DATA) npiet-foogol.1 $(MANDIR) 124 | 125 | ## 126 | ## some possible ``clean'' targets: 127 | ## 128 | clean: 129 | $(RM) -f npiet npiet-foogol *.o gmon.out \ 130 | npiet-foogol.c npiet-foogol.output *~ core 131 | 132 | mrproper realclean clobber: clean 133 | $(RM) -f config.status config.log config.h config.cache 134 | 135 | distclean: realclean 136 | $(RM) -f Makefile configure 137 | autoconf 138 | echo 'all:' > Makefile 139 | echo ' ./configure' >> Makefile 140 | echo ' @echo now run make again' >> Makefile 141 | 142 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ## 2 | ## Makefile for the npiet interpreter (and npietedit editor) 3 | ## 4 | 5 | prefix = /usr/local 6 | exec_prefix = ${prefix} 7 | 8 | BINDIR = $(exec_prefix)/bin 9 | MANDIR = $(prefix)/man/man1 10 | 11 | CC = gcc 12 | 13 | ## 14 | ## warn flags for gcc compiler: 15 | ## 16 | # GWARN = -W -Wcomment -Wpointer-arith -Wcast-qual 17 | GWAR2 = -Wall 18 | WARN = $(GWARN) $(GWAR2) 19 | 20 | ## 21 | ## system dependent flags: 22 | ## 23 | DEFS = -DHAVE_CONFIG_H 24 | ## 25 | 26 | ## 27 | ## Flags for debugging and production: 28 | ## 29 | # FLAGS = -O 30 | FLAGS = -g -O2 31 | # LDFLAGS = 32 | LDFLAGS = -g 33 | 34 | ## Uncomment for profiling: 35 | # PROF = -pg 36 | 37 | ## win cygwin static flag: 38 | # CYG = -mno-cygwin -static 39 | # CYG_LIBS = -lgd -lpng -lgif -lz -lm 40 | 41 | ## 42 | ## libraries: 43 | ## 44 | LIBS = -lgd -lz -lm $(CYG_LIBS) 45 | 46 | ## 47 | ## installation commands: 48 | ## 49 | INSTALL = /usr/bin/install -c 50 | INSTALL_PROGRAM = ${INSTALL} 51 | INSTALL_DATA = ${INSTALL} -m 644 52 | 53 | ## 54 | ## commonly used binaries: 55 | ## 56 | SHELL = /bin/sh 57 | RM = rm 58 | 59 | ## 60 | ## And more: 61 | ## 62 | ## Anything else below here should be independent. 63 | ## 64 | CFLAGS = $(FLAGS) $(PROF) $(CYG) $(WARN) $(DEFS) $(LIBDIRPATH) 65 | 66 | ## 67 | ## How to build the target: 68 | ## 69 | all: npiet npiet-foogol html 70 | 71 | npiet: npiet.o 72 | $(CC) $(LDFLAGS) $(PROF) -o npiet npiet.o $(LIBS) 73 | 74 | npiet.o: npiet.c 75 | $(CC) $(CFLAGS) $(PROF) -c npiet.c 76 | 77 | html: npiet.1.html npietedit.1.html npiet-foogol.1.html 78 | 79 | npiet.1.html: npiet.1 80 | groff -man -T html npiet.1 > npiet.1.html 81 | 82 | npietedit.1.html: npietedit.1 83 | groff -man -T html npietedit.1 > npietedit.1.html 84 | 85 | npiet-foogol.1.html: npiet-foogol.1 86 | groff -man -T html npiet-foogol.1 > npiet-foogol.1.html 87 | 88 | win: 89 | cp -p *.html win 90 | cp -p npietedit win/npietedit.tcl 91 | chmod -x win/* 92 | 93 | al: ftest 94 | 95 | npiet-foogol: npiet-foogol.o 96 | $(CC) $(LDFLAGS) $(PROF) -o npiet-foogol npiet-foogol.o $(LIBS) 97 | 98 | npiet-foogol.o: npiet-foogol.c 99 | $(CC) $(CFLAGS) $(PROF) -c npiet-foogol.c 100 | 101 | npiet-foogol.c: npiet-foogol.y 102 | bison -v -t -o npiet-foogol.c npiet-foogol.y 103 | 104 | ftest: npiet-foogol 105 | ./npiet-foogol a.foo 106 | 107 | 108 | test: check 109 | 110 | check: 111 | (cd examples ; make) 112 | (cd foo ; make) 113 | 114 | ## 115 | ## installation: 116 | ## 117 | install: $(PRG) 118 | $(INSTALL_PROGRAM) npiet $(BINDIR) 119 | $(INSTALL_PROGRAM) npietedit $(BINDIR) 120 | $(INSTALL_PROGRAM) npiet-foogol $(BINDIR) 121 | $(INSTALL_DATA) npiet.1 $(MANDIR) 122 | $(INSTALL_DATA) npietedit.1 $(MANDIR) 123 | $(INSTALL_DATA) npiet-foogol.1 $(MANDIR) 124 | 125 | ## 126 | ## some possible ``clean'' targets: 127 | ## 128 | clean: 129 | $(RM) -f npiet npiet-foogol *.o gmon.out \ 130 | npiet-foogol.c npiet-foogol.output *~ core 131 | 132 | mrproper realclean clobber: clean 133 | $(RM) -f config.status config.log config.h config.cache 134 | 135 | distclean: realclean 136 | $(RM) -f Makefile configure 137 | autoconf 138 | echo 'all:' > Makefile 139 | echo ' ./configure' >> Makefile 140 | echo ' @echo now run make again' >> Makefile 141 | 142 | -------------------------------------------------------------------------------- /examples/nprime.ppm: -------------------------------------------------------------------------------- 1 | P3 2 | # a piet program nprime.ppm 3 | 22 16 4 | 255 5 | 255 0 0 255 0 0 192 192 255 192 255 192 255 255 255 0 0 255 6 | 0 0 192 255 192 255 255 255 255 255 0 0 0 0 255 0 0 192 7 | 192 192 0 255 255 255 255 255 255 255 255 255 255 0 0 0 192 192 8 | 255 255 255 0 255 0 0 255 0 0 192 0 255 255 255 255 255 255 9 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 10 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 11 | 0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 0 255 0 12 | 255 255 255 192 0 0 255 255 255 255 255 255 255 255 255 255 255 255 13 | 255 255 255 255 0 0 255 255 255 255 255 255 255 255 255 255 255 255 14 | 255 255 255 255 255 255 0 0 0 0 0 255 0 0 255 255 255 255 15 | 0 0 0 255 0 0 255 255 255 0 255 0 192 0 0 192 0 0 16 | 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 17 | 255 0 0 255 0 0 255 0 0 255 0 0 192 0 0 255 0 255 18 | 255 0 255 192 0 192 0 0 255 0 0 255 0 0 0 0 0 255 19 | 255 255 255 0 255 0 192 0 0 192 0 0 255 0 0 255 0 0 20 | 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 21 | 255 0 0 255 0 255 255 0 255 255 0 255 255 255 0 255 255 0 22 | 0 0 0 0 0 0 255 255 255 0 255 0 255 255 255 0 255 0 23 | 192 0 0 192 0 0 255 255 255 255 255 255 255 0 0 255 0 0 24 | 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 255 25 | 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 26 | 255 255 0 255 255 255 255 0 0 0 255 0 192 0 0 192 0 0 27 | 0 192 192 255 255 255 255 0 0 255 0 0 255 0 0 255 0 0 28 | 255 0 0 255 0 0 255 0 0 255 0 255 255 255 0 0 0 0 29 | 255 255 0 255 255 0 255 255 0 0 0 0 255 255 0 255 0 0 30 | 255 0 0 0 255 0 0 0 0 255 192 192 255 0 0 255 255 255 31 | 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 32 | 255 0 0 255 0 255 255 255 0 255 255 0 255 255 0 255 255 0 33 | 255 255 0 255 255 0 255 255 0 255 0 0 255 255 255 0 255 0 34 | 255 255 255 192 192 0 255 255 255 255 255 255 255 0 0 255 0 0 35 | 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 255 36 | 255 255 0 255 255 0 255 255 0 0 0 0 255 255 0 255 255 0 37 | 255 255 0 192 0 0 255 255 255 0 255 0 255 255 255 255 255 192 38 | 192 192 255 255 255 255 255 0 0 255 0 0 255 0 0 255 0 0 39 | 255 0 0 255 0 0 255 255 255 255 0 255 255 255 0 255 255 0 40 | 255 255 0 0 0 0 255 255 0 255 255 0 255 255 0 255 192 192 41 | 255 255 255 0 0 0 255 255 255 0 255 0 0 255 0 255 255 255 42 | 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 43 | 255 255 255 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 44 | 255 255 0 255 255 0 255 255 0 255 192 192 0 0 0 255 0 0 45 | 0 0 0 255 255 192 255 255 192 255 255 255 255 0 0 255 0 0 46 | 255 0 0 255 0 0 255 0 0 255 0 0 255 255 255 255 255 0 47 | 255 255 0 0 0 0 255 255 0 255 255 0 255 255 0 0 0 0 48 | 255 255 0 255 0 0 0 0 0 255 0 0 255 255 255 192 0 0 49 | 0 192 192 255 255 255 255 0 0 255 0 0 255 0 0 255 0 0 50 | 255 0 0 255 0 0 255 255 255 255 255 255 255 255 0 255 255 0 51 | 0 0 0 0 0 0 0 0 0 255 255 0 255 255 0 192 192 0 52 | 0 0 0 255 0 0 0 0 0 0 0 0 0 255 255 0 0 0 53 | 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 54 | 255 255 255 255 255 255 255 255 255 255 255 0 255 255 0 255 255 0 55 | 255 255 0 255 255 0 255 255 255 255 192 255 192 255 255 0 0 0 56 | 255 255 255 255 255 255 192 255 255 192 255 255 255 255 255 255 255 255 57 | 255 255 255 255 255 255 255 255 255 255 255 192 255 255 255 255 255 255 58 | 255 255 255 0 0 0 255 0 0 255 255 255 255 255 255 255 255 255 59 | 0 0 0 192 255 255 192 255 255 255 255 255 255 255 255 255 255 255 60 | 192 255 255 192 255 255 255 192 255 192 192 0 255 255 0 255 255 0 61 | 255 255 192 255 255 192 255 0 0 0 0 255 255 192 192 192 0 0 62 | 255 0 0 255 255 255 255 255 192 0 192 192 0 255 255 192 255 255 63 | 192 255 255 255 255 255 255 255 255 255 255 255 64 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | 2 | 2011-09-23 3 | 4 | * version set to 1.3a 5 | 6 | * npiet.c: added patch from "Maks Verver" 7 | fixing compile incompatibility for libpng v1.5.0 or newer. 8 | 9 | 2011-08-05 10 | 11 | * version set to 1.3 12 | 13 | * npiet.c: if -te 0 (trace end option) is set, do not paint 14 | starting dot at all. 15 | 16 | * npiet.c: if -ts or -te (trace start / end) is present 17 | implicitly assume graphical tracing should take place. 18 | 19 | * npiet-foogol.y: ass options -cs to set a output codel size, 20 | allowing to create larger codel sizes by option. 21 | 22 | * npiet-foogol.y: add new experimental option -rnd to get some 23 | more randomisation at starting colors - currently demonstrates 24 | the fragile output generation at first place - use with care ;-) 25 | 26 | 2011-03-12 27 | 28 | * version set to 1.2b 29 | 30 | * added patch from "Allan Wirth" to avoid 31 | bison error with newer bison version (at least 2.4.1). 32 | 33 | thanks a lot for the patch! 34 | 35 | * remove gcc warning about unchecked return value of fscanf. 36 | 37 | 38 | 2010-01-27 39 | 40 | * version set to 1.2a 41 | 42 | * added cygwin windows binary version 1.2 43 | 44 | * fixed wrong named --help output about -v11 option. 45 | 46 | 2010-01-23 47 | 48 | * version set to 1.2 49 | 50 | * reworked the white codel crossing to get better trace pictures. 51 | 52 | this is based on the previous ``white_bug'' code, which was not 53 | that a bug at all ;) 54 | 55 | with v1.1 there was a noop painted from before entrance to the 56 | white codels to the exit codel. this looked quite confusing. 57 | 58 | * the old -v1 backward compatibility flag is now gone. with 59 | clarification of the execution path, it should be no longer 60 | necessary. 61 | 62 | 2009-11-15 63 | 64 | * version set to 1.1a 65 | 66 | * added fix for stack allocation bug on 64 bit platforms 67 | from Nelson Castillo : 68 | 69 | ``Stack is long and it was allocated with sizeof(int). I noticed 70 | the bug by compiling on the AMD64 arch.'' 71 | 72 | thanks a lot. 73 | 74 | * add -Wall as default option and fixed some warnings about 75 | sign of string buffers and printf character argument. 76 | 77 | 2009-10-02 78 | 79 | * version set to 1.1 80 | 81 | * npiet.c: added commandline option -v1 to get npiet version 1.0 82 | behavior. 83 | 84 | * npiet.c: added patch from Yusuke ENDOH 85 | 86 | - fixes bug printing a chacter (%c instead of %lc) 87 | 88 | - runtime behavior: 89 | 90 | ``According to `Clarification of white block behaviour 91 | (added 25 January, 2008)' in the Piet specification [1], 92 | when sliding into a black block, the interpreter must 93 | not stay in the coloured block but move to the white 94 | block. But the current behaviour of npiet is `stay'.'' 95 | 96 | thank's a lot for the patch. 97 | 98 | 99 | 2006-03-16 100 | 101 | * npiet.c: version set to 1.0a 102 | 103 | * npiet.c: added patch from Bertram Felgenhauer . 104 | the patch adds the option -dpbug to simulate the perl's 105 | interpreter behaviour. especially this allows to run the towers 106 | of hanoi example. 107 | 108 | 109 | 2004-09-27 110 | 111 | * npiet-foogol.y: fixed comment parsing (a // in the input 112 | stopped the comment parser). 113 | 114 | * version set to 0.2b 115 | 116 | 117 | 2004-08-08 118 | 119 | * npiet-foogol.y: if-then-else and while-do code added. 120 | 121 | * smart push tries harder to calculate the number 122 | instead of creating long lines (but here is lot to do). 123 | 124 | * more foogol tests created. 125 | 126 | * lots of minor fixes. 127 | 128 | * version set to 0.2a 129 | 130 | 131 | 2004-07-04 Erik Schoenfelder 132 | 133 | * npiet-foogol.y: version set to 0.1a. 134 | this initial relase can only translate output of numbers 135 | and strings. 136 | 137 | 138 | 2004-06-26 Erik Schoenfelder 139 | 140 | * stack type set to array of longs (previously int's) 141 | 142 | * core dump when having a division by zero handled by 143 | pushing a 99999999 to stack, and continuing. 144 | 145 | 146 | 2004-06-26 Erik Schoenfelder 147 | 148 | * npiet.c: version set to v0.3a 149 | 150 | * added gif format for input. 151 | if header lib_gif.h and library -lgif is found by configure, 152 | reading of gif formatted programs is compiled in. 153 | (there a some restrictions on the format, but simple gif's 154 | should be no problem). 155 | 156 | -------------------------------------------------------------------------------- /npiet.1: -------------------------------------------------------------------------------- 1 | .TH NPIET 1 "Aug 2011" "npiet v1.3" 2 | .SH NAME 3 | npiet \- an interpreter for the piet programming language 4 | .SH SYNOPSIS 5 | .B npiet 6 | [ 7 | .B \-v 8 | | 9 | .B \-q 10 | | 11 | .B \-d 12 | | 13 | .B \-dpbug 14 | | 15 | .B \-v11 16 | | 17 | .B \-t 18 | ] 19 | [ 20 | .BI "-e" " " 21 | ] 22 | [ 23 | .B \-tpic 24 | ] 25 | [ 26 | .BI "-tpf" " " 27 | ] 28 | [ 29 | .B \-tps 30 | ] 31 | [ 32 | .BI \-ts " " 33 | ] 34 | [ 35 | .BI \-te " " 36 | ] 37 | .I inputfile 38 | .SH DESCRIPTION 39 | .B npiet 40 | is an interpreter for the piet programming language. In this language 41 | the programs are pictures, build out of 18 colors and black and white, 42 | where changes in the color are stack-based commands. 43 | .br 44 | If the input (supported is ppm and optional gif and png format) includes 45 | unknown colors, they are substituted per default by white (optional by 46 | black or leading to an error). 47 | .br 48 | The input picture is per default examined, if it is zoomed (for better 49 | `readability') and the zoomfactor (the codelsize) is automatically 50 | guessed (if this failes, please specify the codelsize by the -cs 51 | option). 52 | .br 53 | Special fun gives the optional output of a trace picture. If the GD 54 | library is compiled in, the npiet interpreter can paint the trace of the 55 | program run to a png file, named npiet-trace.png. Different zoom 56 | factors and additional options lead to varying detail and readability. 57 | .SH OPTIONS 58 | .TP 59 | .B \-h 60 | print usage help and exit. 61 | .TP 62 | .B \-v 63 | be somewhat verbose. 64 | .TP 65 | .B \-q 66 | be more quiet. 67 | .TP 68 | .B \-d 69 | print debug output (lot's of more or less cryptic and mostly useless blurb). 70 | .TP 71 | .B \-dpbug 72 | changes the execution mode of the perl piet interpreter. This changes 73 | the behavior when crossing white blocks (wrong interpretation of 74 | blocking after white). 75 | .TP 76 | .B \-v11 77 | changes the execution mode to the npiet version 1.1 interpreter. This 78 | changes to the first fixed version of corrected behavior when crossing 79 | white blocks. 80 | .TP 81 | .B \-t 82 | print trace details. For every step the interpreter print some details: 83 | .nf 84 | trace: step 0 (0,0/r,l nB -> 3,0/r,l dB): 85 | action: push, value 9 86 | trace: stack (1 values): 9 87 | .fi 88 | The trace step with the codel x,y coordinates and the dp,cc values and 89 | the codel color (here: normal Blue to dark Blue). 90 | .br 91 | The action describes the command executed and the stack with its 92 | values is shown. 93 | .TP 94 | .B \-e 95 | Sets the number of execution steps. This allows to abort a erroneous program, but the default is unlimited, ie. run until program end (or forever ;-). 96 | .TP 97 | .B \-tpic 98 | Create a trace picture. The file is name 99 | .I npiet-trace.png . 100 | The picture is written on program exit, or if the normal trace options 101 | is specified too, after every step (makes execution notably slower, 102 | because this is quite expensive, but maybe helpful). (only avail if 103 | compiled with gd support). 104 | .TP 105 | .B \-tpf 106 | Sets the size of the pixel in the trace picture. For small input 107 | files, eg. 20x20 codels, the resulting trace picture is 640x640 pixel 108 | with a pizel zoom of 32. Just try different values, to get useable 109 | readability versus picture size. There are some internal values, where 110 | different information is written by different zoom factors. 111 | (only avail if compiled with gd support). 112 | .TP 113 | .B \-tps 114 | Do not include the dp/cc tries in the trace picture. This can increase 115 | readability with smaller pixel zoom factors. Additional there are some 116 | internal values too, where different information is written depending 117 | of the zoom factor. (only avail if compiled with gd support). 118 | .TP 119 | .B \-ts 120 | Please look at -te just below: 121 | .TP 122 | .B \-te 123 | Values where to start and end when painting a trace picture. To avoid 124 | clobbered output when running in loops, for better readability a start 125 | and an end step can be specified. 126 | .br 127 | Note: this does not stop or change the program execution or the textual trace output. It affects only the saved image. 128 | .br 129 | Note: this enables now tracing, so specifying -tpic is no longer necessary. 130 | .br 131 | Note: if you specify -te 0 you can easily get an bigger picture 132 | of the input saved ;-) 133 | .TP 134 | .B inputfile 135 | The picture to read. For ppm-formatted pictures this may be a - to read from 136 | . 137 | .SH EXAMPLES 138 | .B "npiet -tpic hello.gif" 139 | - run the hello.gif program and create a trace file named 140 | .I npiet-trace.png . 141 | .SH FILES 142 | .B "npiet-trace.png" 143 | - name of the trace picture file. It is overwritten if it exists. 144 | .SH AUTHOR 145 | Erik Schoenfelder . 146 | .br 147 | -dpbug option by Bertram Felgenhauer . 148 | .SH BUGS 149 | None seen - they are hidden in the oil painting ;-) 150 | .SH SEE ALSO 151 | .BR npietedit (1) 152 | .br 153 | .B "http://www.bertnase.de/npiet/" 154 | .br 155 | .B "http://www.dangermouse.net/esoteric/piet.html" 156 | -------------------------------------------------------------------------------- /install-sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # install - install a program, script, or datafile 4 | # This comes from X11R5. 5 | # 6 | # Calling this script install-sh is preferred over install.sh, to prevent 7 | # `make' implicit rules from creating a file called install from it 8 | # when there is no Makefile. 9 | # 10 | # This script is compatible with the BSD install script, but was written 11 | # from scratch. 12 | # 13 | 14 | 15 | # set DOITPROG to echo to test this script 16 | 17 | # Don't use :- since 4.3BSD and earlier shells don't like it. 18 | doit="${DOITPROG-}" 19 | 20 | 21 | # put in absolute paths if you don't have them in your path; or use env. vars. 22 | 23 | mvprog="${MVPROG-mv}" 24 | cpprog="${CPPROG-cp}" 25 | chmodprog="${CHMODPROG-chmod}" 26 | chownprog="${CHOWNPROG-chown}" 27 | chgrpprog="${CHGRPPROG-chgrp}" 28 | stripprog="${STRIPPROG-strip}" 29 | rmprog="${RMPROG-rm}" 30 | mkdirprog="${MKDIRPROG-mkdir}" 31 | 32 | tranformbasename="" 33 | transform_arg="" 34 | instcmd="$mvprog" 35 | chmodcmd="$chmodprog 0755" 36 | chowncmd="" 37 | chgrpcmd="" 38 | stripcmd="" 39 | rmcmd="$rmprog -f" 40 | mvcmd="$mvprog" 41 | src="" 42 | dst="" 43 | dir_arg="" 44 | 45 | while [ x"$1" != x ]; do 46 | case $1 in 47 | -c) instcmd="$cpprog" 48 | shift 49 | continue;; 50 | 51 | -d) dir_arg=true 52 | shift 53 | continue;; 54 | 55 | -m) chmodcmd="$chmodprog $2" 56 | shift 57 | shift 58 | continue;; 59 | 60 | -o) chowncmd="$chownprog $2" 61 | shift 62 | shift 63 | continue;; 64 | 65 | -g) chgrpcmd="$chgrpprog $2" 66 | shift 67 | shift 68 | continue;; 69 | 70 | -s) stripcmd="$stripprog" 71 | shift 72 | continue;; 73 | 74 | -t=*) transformarg=`echo $1 | sed 's/-t=//'` 75 | shift 76 | continue;; 77 | 78 | -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 79 | shift 80 | continue;; 81 | 82 | *) if [ x"$src" = x ] 83 | then 84 | src=$1 85 | else 86 | # this colon is to work around a 386BSD /bin/sh bug 87 | : 88 | dst=$1 89 | fi 90 | shift 91 | continue;; 92 | esac 93 | done 94 | 95 | if [ x"$src" = x ] 96 | then 97 | echo "install: no input file specified" 98 | exit 1 99 | else 100 | true 101 | fi 102 | 103 | if [ x"$dir_arg" != x ]; then 104 | dst=$src 105 | src="" 106 | 107 | if [ -d $dst ]; then 108 | instcmd=: 109 | else 110 | instcmd=mkdir 111 | fi 112 | else 113 | 114 | # Waiting for this to be detected by the "$instcmd $src $dsttmp" command 115 | # might cause directories to be created, which would be especially bad 116 | # if $src (and thus $dsttmp) contains '*'. 117 | 118 | if [ -f $src -o -d $src ] 119 | then 120 | true 121 | else 122 | echo "install: $src does not exist" 123 | exit 1 124 | fi 125 | 126 | if [ x"$dst" = x ] 127 | then 128 | echo "install: no destination specified" 129 | exit 1 130 | else 131 | true 132 | fi 133 | 134 | # If destination is a directory, append the input filename; if your system 135 | # does not like double slashes in filenames, you may need to add some logic 136 | 137 | if [ -d $dst ] 138 | then 139 | dst="$dst"/`basename $src` 140 | else 141 | true 142 | fi 143 | fi 144 | 145 | ## this sed command emulates the dirname command 146 | dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 147 | 148 | # Make sure that the destination directory exists. 149 | # this part is taken from Noah Friedman's mkinstalldirs script 150 | 151 | # Skip lots of stat calls in the usual case. 152 | if [ ! -d "$dstdir" ]; then 153 | defaultIFS=' 154 | ' 155 | IFS="${IFS-${defaultIFS}}" 156 | 157 | oIFS="${IFS}" 158 | # Some sh's can't handle IFS=/ for some reason. 159 | IFS='%' 160 | set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` 161 | IFS="${oIFS}" 162 | 163 | pathcomp='' 164 | 165 | while [ $# -ne 0 ] ; do 166 | pathcomp="${pathcomp}${1}" 167 | shift 168 | 169 | if [ ! -d "${pathcomp}" ] ; 170 | then 171 | $mkdirprog "${pathcomp}" 172 | else 173 | true 174 | fi 175 | 176 | pathcomp="${pathcomp}/" 177 | done 178 | fi 179 | 180 | if [ x"$dir_arg" != x ] 181 | then 182 | $doit $instcmd $dst && 183 | 184 | if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && 185 | if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && 186 | if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && 187 | if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi 188 | else 189 | 190 | # If we're going to rename the final executable, determine the name now. 191 | 192 | if [ x"$transformarg" = x ] 193 | then 194 | dstfile=`basename $dst` 195 | else 196 | dstfile=`basename $dst $transformbasename | 197 | sed $transformarg`$transformbasename 198 | fi 199 | 200 | # don't allow the sed command to completely eliminate the filename 201 | 202 | if [ x"$dstfile" = x ] 203 | then 204 | dstfile=`basename $dst` 205 | else 206 | true 207 | fi 208 | 209 | # Make a temp file name in the proper directory. 210 | 211 | dsttmp=$dstdir/#inst.$$# 212 | 213 | # Move or copy the file name to the temp name 214 | 215 | $doit $instcmd $src $dsttmp && 216 | 217 | trap "rm -f ${dsttmp}" 0 && 218 | 219 | # and set any options; do chmod last to preserve setuid bits 220 | 221 | # If any of these fail, we abort the whole thing. If we want to 222 | # ignore errors from any of these, just make sure not to ignore 223 | # errors from the above "$doit $instcmd $src $dsttmp" command. 224 | 225 | if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && 226 | if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && 227 | if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && 228 | if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && 229 | 230 | # Now rename the file to the real destination. 231 | 232 | $doit $rmcmd -f $dstdir/$dstfile && 233 | $doit $mvcmd $dsttmp $dstdir/$dstfile 234 | 235 | fi && 236 | 237 | 238 | exit 0 239 | -------------------------------------------------------------------------------- /foo/99-bottles.out: -------------------------------------------------------------------------------- 1 | 99 bottles of beer on the wall, 2 | 99 bottles of beer, 3 | take one down, pass it around, 4 | 98 bottles of beer on the wall. 5 | 6 | 98 bottles of beer on the wall, 7 | 98 bottles of beer, 8 | take one down, pass it around, 9 | 97 bottles of beer on the wall. 10 | 11 | 97 bottles of beer on the wall, 12 | 97 bottles of beer, 13 | take one down, pass it around, 14 | 96 bottles of beer on the wall. 15 | 16 | 96 bottles of beer on the wall, 17 | 96 bottles of beer, 18 | take one down, pass it around, 19 | 95 bottles of beer on the wall. 20 | 21 | 95 bottles of beer on the wall, 22 | 95 bottles of beer, 23 | take one down, pass it around, 24 | 94 bottles of beer on the wall. 25 | 26 | 94 bottles of beer on the wall, 27 | 94 bottles of beer, 28 | take one down, pass it around, 29 | 93 bottles of beer on the wall. 30 | 31 | 93 bottles of beer on the wall, 32 | 93 bottles of beer, 33 | take one down, pass it around, 34 | 92 bottles of beer on the wall. 35 | 36 | 92 bottles of beer on the wall, 37 | 92 bottles of beer, 38 | take one down, pass it around, 39 | 91 bottles of beer on the wall. 40 | 41 | 91 bottles of beer on the wall, 42 | 91 bottles of beer, 43 | take one down, pass it around, 44 | 90 bottles of beer on the wall. 45 | 46 | 90 bottles of beer on the wall, 47 | 90 bottles of beer, 48 | take one down, pass it around, 49 | 89 bottles of beer on the wall. 50 | 51 | 89 bottles of beer on the wall, 52 | 89 bottles of beer, 53 | take one down, pass it around, 54 | 88 bottles of beer on the wall. 55 | 56 | 88 bottles of beer on the wall, 57 | 88 bottles of beer, 58 | take one down, pass it around, 59 | 87 bottles of beer on the wall. 60 | 61 | 87 bottles of beer on the wall, 62 | 87 bottles of beer, 63 | take one down, pass it around, 64 | 86 bottles of beer on the wall. 65 | 66 | 86 bottles of beer on the wall, 67 | 86 bottles of beer, 68 | take one down, pass it around, 69 | 85 bottles of beer on the wall. 70 | 71 | 85 bottles of beer on the wall, 72 | 85 bottles of beer, 73 | take one down, pass it around, 74 | 84 bottles of beer on the wall. 75 | 76 | 84 bottles of beer on the wall, 77 | 84 bottles of beer, 78 | take one down, pass it around, 79 | 83 bottles of beer on the wall. 80 | 81 | 83 bottles of beer on the wall, 82 | 83 bottles of beer, 83 | take one down, pass it around, 84 | 82 bottles of beer on the wall. 85 | 86 | 82 bottles of beer on the wall, 87 | 82 bottles of beer, 88 | take one down, pass it around, 89 | 81 bottles of beer on the wall. 90 | 91 | 81 bottles of beer on the wall, 92 | 81 bottles of beer, 93 | take one down, pass it around, 94 | 80 bottles of beer on the wall. 95 | 96 | 80 bottles of beer on the wall, 97 | 80 bottles of beer, 98 | take one down, pass it around, 99 | 79 bottles of beer on the wall. 100 | 101 | 79 bottles of beer on the wall, 102 | 79 bottles of beer, 103 | take one down, pass it around, 104 | 78 bottles of beer on the wall. 105 | 106 | 78 bottles of beer on the wall, 107 | 78 bottles of beer, 108 | take one down, pass it around, 109 | 77 bottles of beer on the wall. 110 | 111 | 77 bottles of beer on the wall, 112 | 77 bottles of beer, 113 | take one down, pass it around, 114 | 76 bottles of beer on the wall. 115 | 116 | 76 bottles of beer on the wall, 117 | 76 bottles of beer, 118 | take one down, pass it around, 119 | 75 bottles of beer on the wall. 120 | 121 | 75 bottles of beer on the wall, 122 | 75 bottles of beer, 123 | take one down, pass it around, 124 | 74 bottles of beer on the wall. 125 | 126 | 74 bottles of beer on the wall, 127 | 74 bottles of beer, 128 | take one down, pass it around, 129 | 73 bottles of beer on the wall. 130 | 131 | 73 bottles of beer on the wall, 132 | 73 bottles of beer, 133 | take one down, pass it around, 134 | 72 bottles of beer on the wall. 135 | 136 | 72 bottles of beer on the wall, 137 | 72 bottles of beer, 138 | take one down, pass it around, 139 | 71 bottles of beer on the wall. 140 | 141 | 71 bottles of beer on the wall, 142 | 71 bottles of beer, 143 | take one down, pass it around, 144 | 70 bottles of beer on the wall. 145 | 146 | 70 bottles of beer on the wall, 147 | 70 bottles of beer, 148 | take one down, pass it around, 149 | 69 bottles of beer on the wall. 150 | 151 | 69 bottles of beer on the wall, 152 | 69 bottles of beer, 153 | take one down, pass it around, 154 | 68 bottles of beer on the wall. 155 | 156 | 68 bottles of beer on the wall, 157 | 68 bottles of beer, 158 | take one down, pass it around, 159 | 67 bottles of beer on the wall. 160 | 161 | 67 bottles of beer on the wall, 162 | 67 bottles of beer, 163 | take one down, pass it around, 164 | 66 bottles of beer on the wall. 165 | 166 | 66 bottles of beer on the wall, 167 | 66 bottles of beer, 168 | take one down, pass it around, 169 | 65 bottles of beer on the wall. 170 | 171 | 65 bottles of beer on the wall, 172 | 65 bottles of beer, 173 | take one down, pass it around, 174 | 64 bottles of beer on the wall. 175 | 176 | 64 bottles of beer on the wall, 177 | 64 bottles of beer, 178 | take one down, pass it around, 179 | 63 bottles of beer on the wall. 180 | 181 | 63 bottles of beer on the wall, 182 | 63 bottles of beer, 183 | take one down, pass it around, 184 | 62 bottles of beer on the wall. 185 | 186 | 62 bottles of beer on the wall, 187 | 62 bottles of beer, 188 | take one down, pass it around, 189 | 61 bottles of beer on the wall. 190 | 191 | 61 bottles of beer on the wall, 192 | 61 bottles of beer, 193 | take one down, pass it around, 194 | 60 bottles of beer on the wall. 195 | 196 | 60 bottles of beer on the wall, 197 | 60 bottles of beer, 198 | take one down, pass it around, 199 | 59 bottles of beer on the wall. 200 | 201 | 59 bottles of beer on the wall, 202 | 59 bottles of beer, 203 | take one down, pass it around, 204 | 58 bottles of beer on the wall. 205 | 206 | 58 bottles of beer on the wall, 207 | 58 bottles of beer, 208 | take one down, pass it around, 209 | 57 bottles of beer on the wall. 210 | 211 | 57 bottles of beer on the wall, 212 | 57 bottles of beer, 213 | take one down, pass it around, 214 | 56 bottles of beer on the wall. 215 | 216 | 56 bottles of beer on the wall, 217 | 56 bottles of beer, 218 | take one down, pass it around, 219 | 55 bottles of beer on the wall. 220 | 221 | 55 bottles of beer on the wall, 222 | 55 bottles of beer, 223 | take one down, pass it around, 224 | 54 bottles of beer on the wall. 225 | 226 | 54 bottles of beer on the wall, 227 | 54 bottles of beer, 228 | take one down, pass it around, 229 | 53 bottles of beer on the wall. 230 | 231 | 53 bottles of beer on the wall, 232 | 53 bottles of beer, 233 | take one down, pass it around, 234 | 52 bottles of beer on the wall. 235 | 236 | 52 bottles of beer on the wall, 237 | 52 bottles of beer, 238 | take one down, pass it around, 239 | 51 bottles of beer on the wall. 240 | 241 | 51 bottles of beer on the wall, 242 | 51 bottles of beer, 243 | take one down, pass it around, 244 | 50 bottles of beer on the wall. 245 | 246 | 50 bottles of beer on the wall, 247 | 50 bottles of beer, 248 | take one down, pass it around, 249 | 49 bottles of beer on the wall. 250 | 251 | 49 bottles of beer on the wall, 252 | 49 bottles of beer, 253 | take one down, pass it around, 254 | 48 bottles of beer on the wall. 255 | 256 | 48 bottles of beer on the wall, 257 | 48 bottles of beer, 258 | take one down, pass it around, 259 | 47 bottles of beer on the wall. 260 | 261 | 47 bottles of beer on the wall, 262 | 47 bottles of beer, 263 | take one down, pass it around, 264 | 46 bottles of beer on the wall. 265 | 266 | 46 bottles of beer on the wall, 267 | 46 bottles of beer, 268 | take one down, pass it around, 269 | 45 bottles of beer on the wall. 270 | 271 | 45 bottles of beer on the wall, 272 | 45 bottles of beer, 273 | take one down, pass it around, 274 | 44 bottles of beer on the wall. 275 | 276 | 44 bottles of beer on the wall, 277 | 44 bottles of beer, 278 | take one down, pass it around, 279 | 43 bottles of beer on the wall. 280 | 281 | 43 bottles of beer on the wall, 282 | 43 bottles of beer, 283 | take one down, pass it around, 284 | 42 bottles of beer on the wall. 285 | 286 | 42 bottles of beer on the wall, 287 | 42 bottles of beer, 288 | take one down, pass it around, 289 | 41 bottles of beer on the wall. 290 | 291 | 41 bottles of beer on the wall, 292 | 41 bottles of beer, 293 | take one down, pass it around, 294 | 40 bottles of beer on the wall. 295 | 296 | 40 bottles of beer on the wall, 297 | 40 bottles of beer, 298 | take one down, pass it around, 299 | 39 bottles of beer on the wall. 300 | 301 | 39 bottles of beer on the wall, 302 | 39 bottles of beer, 303 | take one down, pass it around, 304 | 38 bottles of beer on the wall. 305 | 306 | 38 bottles of beer on the wall, 307 | 38 bottles of beer, 308 | take one down, pass it around, 309 | 37 bottles of beer on the wall. 310 | 311 | 37 bottles of beer on the wall, 312 | 37 bottles of beer, 313 | take one down, pass it around, 314 | 36 bottles of beer on the wall. 315 | 316 | 36 bottles of beer on the wall, 317 | 36 bottles of beer, 318 | take one down, pass it around, 319 | 35 bottles of beer on the wall. 320 | 321 | 35 bottles of beer on the wall, 322 | 35 bottles of beer, 323 | take one down, pass it around, 324 | 34 bottles of beer on the wall. 325 | 326 | 34 bottles of beer on the wall, 327 | 34 bottles of beer, 328 | take one down, pass it around, 329 | 33 bottles of beer on the wall. 330 | 331 | 33 bottles of beer on the wall, 332 | 33 bottles of beer, 333 | take one down, pass it around, 334 | 32 bottles of beer on the wall. 335 | 336 | 32 bottles of beer on the wall, 337 | 32 bottles of beer, 338 | take one down, pass it around, 339 | 31 bottles of beer on the wall. 340 | 341 | 31 bottles of beer on the wall, 342 | 31 bottles of beer, 343 | take one down, pass it around, 344 | 30 bottles of beer on the wall. 345 | 346 | 30 bottles of beer on the wall, 347 | 30 bottles of beer, 348 | take one down, pass it around, 349 | 29 bottles of beer on the wall. 350 | 351 | 29 bottles of beer on the wall, 352 | 29 bottles of beer, 353 | take one down, pass it around, 354 | 28 bottles of beer on the wall. 355 | 356 | 28 bottles of beer on the wall, 357 | 28 bottles of beer, 358 | take one down, pass it around, 359 | 27 bottles of beer on the wall. 360 | 361 | 27 bottles of beer on the wall, 362 | 27 bottles of beer, 363 | take one down, pass it around, 364 | 26 bottles of beer on the wall. 365 | 366 | 26 bottles of beer on the wall, 367 | 26 bottles of beer, 368 | take one down, pass it around, 369 | 25 bottles of beer on the wall. 370 | 371 | 25 bottles of beer on the wall, 372 | 25 bottles of beer, 373 | take one down, pass it around, 374 | 24 bottles of beer on the wall. 375 | 376 | 24 bottles of beer on the wall, 377 | 24 bottles of beer, 378 | take one down, pass it around, 379 | 23 bottles of beer on the wall. 380 | 381 | 23 bottles of beer on the wall, 382 | 23 bottles of beer, 383 | take one down, pass it around, 384 | 22 bottles of beer on the wall. 385 | 386 | 22 bottles of beer on the wall, 387 | 22 bottles of beer, 388 | take one down, pass it around, 389 | 21 bottles of beer on the wall. 390 | 391 | 21 bottles of beer on the wall, 392 | 21 bottles of beer, 393 | take one down, pass it around, 394 | 20 bottles of beer on the wall. 395 | 396 | 20 bottles of beer on the wall, 397 | 20 bottles of beer, 398 | take one down, pass it around, 399 | 19 bottles of beer on the wall. 400 | 401 | 19 bottles of beer on the wall, 402 | 19 bottles of beer, 403 | take one down, pass it around, 404 | 18 bottles of beer on the wall. 405 | 406 | 18 bottles of beer on the wall, 407 | 18 bottles of beer, 408 | take one down, pass it around, 409 | 17 bottles of beer on the wall. 410 | 411 | 17 bottles of beer on the wall, 412 | 17 bottles of beer, 413 | take one down, pass it around, 414 | 16 bottles of beer on the wall. 415 | 416 | 16 bottles of beer on the wall, 417 | 16 bottles of beer, 418 | take one down, pass it around, 419 | 15 bottles of beer on the wall. 420 | 421 | 15 bottles of beer on the wall, 422 | 15 bottles of beer, 423 | take one down, pass it around, 424 | 14 bottles of beer on the wall. 425 | 426 | 14 bottles of beer on the wall, 427 | 14 bottles of beer, 428 | take one down, pass it around, 429 | 13 bottles of beer on the wall. 430 | 431 | 13 bottles of beer on the wall, 432 | 13 bottles of beer, 433 | take one down, pass it around, 434 | 12 bottles of beer on the wall. 435 | 436 | 12 bottles of beer on the wall, 437 | 12 bottles of beer, 438 | take one down, pass it around, 439 | 11 bottles of beer on the wall. 440 | 441 | 11 bottles of beer on the wall, 442 | 11 bottles of beer, 443 | take one down, pass it around, 444 | 10 bottles of beer on the wall. 445 | 446 | 10 bottles of beer on the wall, 447 | 10 bottles of beer, 448 | take one down, pass it around, 449 | 9 bottles of beer on the wall. 450 | 451 | 9 bottles of beer on the wall, 452 | 9 bottles of beer, 453 | take one down, pass it around, 454 | 8 bottles of beer on the wall. 455 | 456 | 8 bottles of beer on the wall, 457 | 8 bottles of beer, 458 | take one down, pass it around, 459 | 7 bottles of beer on the wall. 460 | 461 | 7 bottles of beer on the wall, 462 | 7 bottles of beer, 463 | take one down, pass it around, 464 | 6 bottles of beer on the wall. 465 | 466 | 6 bottles of beer on the wall, 467 | 6 bottles of beer, 468 | take one down, pass it around, 469 | 5 bottles of beer on the wall. 470 | 471 | 5 bottles of beer on the wall, 472 | 5 bottles of beer, 473 | take one down, pass it around, 474 | 4 bottles of beer on the wall. 475 | 476 | 4 bottles of beer on the wall, 477 | 4 bottles of beer, 478 | take one down, pass it around, 479 | 3 bottles of beer on the wall. 480 | 481 | 3 bottles of beer on the wall, 482 | 3 bottles of beer, 483 | take one down, pass it around, 484 | 2 bottles of beer on the wall. 485 | 486 | 2 bottles of beer on the wall, 487 | 2 bottles of beer, 488 | take one down, pass it around, 489 | 1 bottle of beer on the wall. 490 | 491 | 1 bottle of beer on the wall, 492 | 1 bottle of beer, 493 | take one down, pass it around, 494 | no more bottles of beer on the wall. 495 | 496 | Time to buy some more beer... 497 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | 2 | GNU GENERAL PUBLIC LICENSE 3 | Version 2, June 1991 4 | 5 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 6 | 675 Mass Ave, Cambridge, MA 02139, USA 7 | Everyone is permitted to copy and distribute verbatim copies 8 | of this license document, but changing it is not allowed. 9 | 10 | Preamble 11 | 12 | The licenses for most software are designed to take away your 13 | freedom to share and change it. By contrast, the GNU General Public 14 | License is intended to guarantee your freedom to share and change free 15 | software--to make sure the software is free for all its users. This 16 | General Public License applies to most of the Free Software 17 | Foundation's software and to any other program whose authors commit to 18 | using it. (Some other Free Software Foundation software is covered by 19 | the GNU Library General Public License instead.) You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | this service if you wish), that you receive source code or can get it 26 | if you want it, that you can change the software or use pieces of it 27 | in new free programs; and that you know you can do these things. 28 | 29 | To protect your rights, we need to make restrictions that forbid 30 | anyone to deny you these rights or to ask you to surrender the rights. 31 | These restrictions translate to certain responsibilities for you if you 32 | distribute copies of the software, or if you modify it. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must give the recipients all the rights that 36 | you have. You must make sure that they, too, receive or can get the 37 | source code. And you must show them these terms so they know their 38 | rights. 39 | 40 | We protect your rights with two steps: (1) copyright the software, and 41 | (2) offer you this license which gives you legal permission to copy, 42 | distribute and/or modify the software. 43 | 44 | Also, for each author's protection and ours, we want to make certain 45 | that everyone understands that there is no warranty for this free 46 | software. If the software is modified by someone else and passed on, we 47 | want its recipients to know that what they have is not the original, so 48 | that any problems introduced by others will not reflect on the original 49 | authors' reputations. 50 | 51 | Finally, any free program is threatened constantly by software 52 | patents. We wish to avoid the danger that redistributors of a free 53 | program will individually obtain patent licenses, in effect making the 54 | program proprietary. To prevent this, we have made it clear that any 55 | patent must be licensed for everyone's free use or not licensed at all. 56 | 57 | The precise terms and conditions for copying, distribution and 58 | modification follow. 59 | 60 | GNU GENERAL PUBLIC LICENSE 61 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 62 | 63 | 0. This License applies to any program or other work which contains 64 | a notice placed by the copyright holder saying it may be distributed 65 | under the terms of this General Public License. The "Program", below, 66 | refers to any such program or work, and a "work based on the Program" 67 | means either the Program or any derivative work under copyright law: 68 | that is to say, a work containing the Program or a portion of it, 69 | either verbatim or with modifications and/or translated into another 70 | language. (Hereinafter, translation is included without limitation in 71 | the term "modification".) Each licensee is addressed as "you". 72 | 73 | Activities other than copying, distribution and modification are not 74 | covered by this License; they are outside its scope. The act of 75 | running the Program is not restricted, and the output from the Program 76 | is covered only if its contents constitute a work based on the 77 | Program (independent of having been made by running the Program). 78 | Whether that is true depends on what the Program does. 79 | 80 | 1. You may copy and distribute verbatim copies of the Program's 81 | source code as you receive it, in any medium, provided that you 82 | conspicuously and appropriately publish on each copy an appropriate 83 | copyright notice and disclaimer of warranty; keep intact all the 84 | notices that refer to this License and to the absence of any warranty; 85 | and give any other recipients of the Program a copy of this License 86 | along with the Program. 87 | 88 | You may charge a fee for the physical act of transferring a copy, and 89 | you may at your option offer warranty protection in exchange for a fee. 90 | 91 | 2. You may modify your copy or copies of the Program or any portion 92 | of it, thus forming a work based on the Program, and copy and 93 | distribute such modifications or work under the terms of Section 1 94 | above, provided that you also meet all of these conditions: 95 | 96 | a) You must cause the modified files to carry prominent notices 97 | stating that you changed the files and the date of any change. 98 | 99 | b) You must cause any work that you distribute or publish, that in 100 | whole or in part contains or is derived from the Program or any 101 | part thereof, to be licensed as a whole at no charge to all third 102 | parties under the terms of this License. 103 | 104 | c) If the modified program normally reads commands interactively 105 | when run, you must cause it, when started running for such 106 | interactive use in the most ordinary way, to print or display an 107 | announcement including an appropriate copyright notice and a 108 | notice that there is no warranty (or else, saying that you provide 109 | a warranty) and that users may redistribute the program under 110 | these conditions, and telling the user how to view a copy of this 111 | License. (Exception: if the Program itself is interactive but 112 | does not normally print such an announcement, your work based on 113 | the Program is not required to print an announcement.) 114 | 115 | These requirements apply to the modified work as a whole. If 116 | identifiable sections of that work are not derived from the Program, 117 | and can be reasonably considered independent and separate works in 118 | themselves, then this License, and its terms, do not apply to those 119 | sections when you distribute them as separate works. But when you 120 | distribute the same sections as part of a whole which is a work based 121 | on the Program, the distribution of the whole must be on the terms of 122 | this License, whose permissions for other licensees extend to the 123 | entire whole, and thus to each and every part regardless of who wrote it. 124 | 125 | Thus, it is not the intent of this section to claim rights or contest 126 | your rights to work written entirely by you; rather, the intent is to 127 | exercise the right to control the distribution of derivative or 128 | collective works based on the Program. 129 | 130 | In addition, mere aggregation of another work not based on the Program 131 | with the Program (or with a work based on the Program) on a volume of 132 | a storage or distribution medium does not bring the other work under 133 | the scope of this License. 134 | 135 | 3. You may copy and distribute the Program (or a work based on it, 136 | under Section 2) in object code or executable form under the terms of 137 | Sections 1 and 2 above provided that you also do one of the following: 138 | 139 | a) Accompany it with the complete corresponding machine-readable 140 | source code, which must be distributed under the terms of Sections 141 | 1 and 2 above on a medium customarily used for software interchange; or, 142 | 143 | b) Accompany it with a written offer, valid for at least three 144 | years, to give any third party, for a charge no more than your 145 | cost of physically performing source distribution, a complete 146 | machine-readable copy of the corresponding source code, to be 147 | distributed under the terms of Sections 1 and 2 above on a medium 148 | customarily used for software interchange; or, 149 | 150 | c) Accompany it with the information you received as to the offer 151 | to distribute corresponding source code. (This alternative is 152 | allowed only for noncommercial distribution and only if you 153 | received the program in object code or executable form with such 154 | an offer, in accord with Subsection b above.) 155 | 156 | The source code for a work means the preferred form of the work for 157 | making modifications to it. For an executable work, complete source 158 | code means all the source code for all modules it contains, plus any 159 | associated interface definition files, plus the scripts used to 160 | control compilation and installation of the executable. However, as a 161 | special exception, the source code distributed need not include 162 | anything that is normally distributed (in either source or binary 163 | form) with the major components (compiler, kernel, and so on) of the 164 | operating system on which the executable runs, unless that component 165 | itself accompanies the executable. 166 | 167 | If distribution of executable or object code is made by offering 168 | access to copy from a designated place, then offering equivalent 169 | access to copy the source code from the same place counts as 170 | distribution of the source code, even though third parties are not 171 | compelled to copy the source along with the object code. 172 | 173 | 4. You may not copy, modify, sublicense, or distribute the Program 174 | except as expressly provided under this License. Any attempt 175 | otherwise to copy, modify, sublicense or distribute the Program is 176 | void, and will automatically terminate your rights under this License. 177 | However, parties who have received copies, or rights, from you under 178 | this License will not have their licenses terminated so long as such 179 | parties remain in full compliance. 180 | 181 | 5. You are not required to accept this License, since you have not 182 | signed it. However, nothing else grants you permission to modify or 183 | distribute the Program or its derivative works. These actions are 184 | prohibited by law if you do not accept this License. Therefore, by 185 | modifying or distributing the Program (or any work based on the 186 | Program), you indicate your acceptance of this License to do so, and 187 | all its terms and conditions for copying, distributing or modifying 188 | the Program or works based on it. 189 | 190 | 6. Each time you redistribute the Program (or any work based on the 191 | Program), the recipient automatically receives a license from the 192 | original licensor to copy, distribute or modify the Program subject to 193 | these terms and conditions. You may not impose any further 194 | restrictions on the recipients' exercise of the rights granted herein. 195 | You are not responsible for enforcing compliance by third parties to 196 | this License. 197 | 198 | 7. If, as a consequence of a court judgment or allegation of patent 199 | infringement or for any other reason (not limited to patent issues), 200 | conditions are imposed on you (whether by court order, agreement or 201 | otherwise) that contradict the conditions of this License, they do not 202 | excuse you from the conditions of this License. If you cannot 203 | distribute so as to satisfy simultaneously your obligations under this 204 | License and any other pertinent obligations, then as a consequence you 205 | may not distribute the Program at all. For example, if a patent 206 | license would not permit royalty-free redistribution of the Program by 207 | all those who receive copies directly or indirectly through you, then 208 | the only way you could satisfy both it and this License would be to 209 | refrain entirely from distribution of the Program. 210 | 211 | If any portion of this section is held invalid or unenforceable under 212 | any particular circumstance, the balance of the section is intended to 213 | apply and the section as a whole is intended to apply in other 214 | circumstances. 215 | 216 | It is not the purpose of this section to induce you to infringe any 217 | patents or other property right claims or to contest validity of any 218 | such claims; this section has the sole purpose of protecting the 219 | integrity of the free software distribution system, which is 220 | implemented by public license practices. Many people have made 221 | generous contributions to the wide range of software distributed 222 | through that system in reliance on consistent application of that 223 | system; it is up to the author/donor to decide if he or she is willing 224 | to distribute software through any other system and a licensee cannot 225 | impose that choice. 226 | 227 | This section is intended to make thoroughly clear what is believed to 228 | be a consequence of the rest of this License. 229 | 230 | 8. If the distribution and/or use of the Program is restricted in 231 | certain countries either by patents or by copyrighted interfaces, the 232 | original copyright holder who places the Program under this License 233 | may add an explicit geographical distribution limitation excluding 234 | those countries, so that distribution is permitted only in or among 235 | countries not thus excluded. In such case, this License incorporates 236 | the limitation as if written in the body of this License. 237 | 238 | 9. The Free Software Foundation may publish revised and/or new versions 239 | of the General Public License from time to time. Such new versions will 240 | be similar in spirit to the present version, but may differ in detail to 241 | address new problems or concerns. 242 | 243 | Each version is given a distinguishing version number. If the Program 244 | specifies a version number of this License which applies to it and "any 245 | later version", you have the option of following the terms and conditions 246 | either of that version or of any later version published by the Free 247 | Software Foundation. If the Program does not specify a version number of 248 | this License, you may choose any version ever published by the Free Software 249 | Foundation. 250 | 251 | 10. If you wish to incorporate parts of the Program into other free 252 | programs whose distribution conditions are different, write to the author 253 | to ask for permission. For software which is copyrighted by the Free 254 | Software Foundation, write to the Free Software Foundation; we sometimes 255 | make exceptions for this. Our decision will be guided by the two goals 256 | of preserving the free status of all derivatives of our free software and 257 | of promoting the sharing and reuse of software generally. 258 | 259 | NO WARRANTY 260 | 261 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 262 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 263 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 264 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 265 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 266 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 267 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 268 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 269 | REPAIR OR CORRECTION. 270 | 271 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 272 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 273 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 274 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 275 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 276 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 277 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 278 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 279 | POSSIBILITY OF SUCH DAMAGES. 280 | 281 | END OF TERMS AND CONDITIONS 282 | 283 | Appendix: How to Apply These Terms to Your New Programs 284 | 285 | If you develop a new program, and you want it to be of the greatest 286 | possible use to the public, the best way to achieve this is to make it 287 | free software which everyone can redistribute and change under these terms. 288 | 289 | To do so, attach the following notices to the program. It is safest 290 | to attach them to the start of each source file to most effectively 291 | convey the exclusion of warranty; and each file should have at least 292 | the "copyright" line and a pointer to where the full notice is found. 293 | 294 | 295 | Copyright (C) 19yy 296 | 297 | This program is free software; you can redistribute it and/or modify 298 | it under the terms of the GNU General Public License as published by 299 | the Free Software Foundation; either version 2 of the License, or 300 | (at your option) any later version. 301 | 302 | This program is distributed in the hope that it will be useful, 303 | but WITHOUT ANY WARRANTY; without even the implied warranty of 304 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 305 | GNU General Public License for more details. 306 | 307 | You should have received a copy of the GNU General Public License 308 | along with this program; if not, write to the Free Software 309 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 310 | 311 | Also add information on how to contact you by electronic and paper mail. 312 | 313 | If the program is interactive, make it output a short notice like this 314 | when it starts in an interactive mode: 315 | 316 | Gnomovision version 69, Copyright (C) 19yy name of author 317 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 318 | This is free software, and you are welcome to redistribute it 319 | under certain conditions; type `show c' for details. 320 | 321 | The hypothetical commands `show w' and `show c' should show the appropriate 322 | parts of the General Public License. Of course, the commands you use may 323 | be called something other than `show w' and `show c'; they could even be 324 | mouse-clicks or menu items--whatever suits your program. 325 | 326 | You should also get your employer (if you work as a programmer) or your 327 | school, if any, to sign a "copyright disclaimer" for the program, if 328 | necessary. Here is a sample; alter the names: 329 | 330 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 331 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 332 | 333 | , 1 April 1989 334 | Ty Coon, President of Vice 335 | 336 | This General Public License does not permit incorporating your program into 337 | proprietary programs. If your program is a subroutine library, you may 338 | consider it more useful to permit linking proprietary applications with the 339 | library. If this is what you want to do, use the GNU Library General 340 | Public License instead of this License. 341 | 342 | -------------------------------------------------------------------------------- /npietedit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ## -*- tcl -*- 3 | ## i am a tcl/tk program - launch me with a wish: \ 4 | exec wish "$0" "$@" 5 | ## 6 | ## npietedit: May 2004 7 | ## (schoenfr@web.de) 8 | ## 9 | ## npietedit is a simple editor for the piet programming language 10 | ## this file is part of npiet. 11 | ## 12 | ## more about the piet programming language and the npiet interpreter see: 13 | ## 14 | ## http://www.bertnase.de/npiet/ 15 | ## 16 | ## about the piet programming language see: 17 | ## 18 | ## http://www.dangermouse.net/esoteric/piet.html 19 | ## 20 | ## 21 | ## the default image size is about 20x20 (or 32x32) pixel or so. 22 | ## larger sizes are not very useful, because its very slow and 23 | ## looks ugly - so this is for simple playing with small programs. 24 | ## 25 | ## 26 | ## Copyright (C) 2004 Erik Schoenfelder (schoenfr@web.de) 27 | ## 28 | ## npiet is free software; you can redistribute it and/or modify it 29 | ## under the terms of the GNU General Public License as published by 30 | ## the Free Software Foundation version 2. 31 | ## 32 | ## npiet is distributed in the hope that it will be useful, but 33 | ## WITHOUT ANY WARRANTY; without even the implied warranty of 34 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 35 | ## General Public License for more details. 36 | ## 37 | ## You should have received a copy of the GNU General Public License 38 | ## along with npiet; see the file COPYING. If not, write to the Free 39 | ## Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 40 | ## 41 | ## 42 | 43 | set version "npietedit v0.9d" 44 | 45 | ## 46 | ## howto launch: 47 | ## 48 | proc usage { } { 49 | puts "\nnpietedit $version\n" 50 | puts "use: npietedit \[ \]" 51 | puts "\t - file to load / save" 52 | exit 53 | } 54 | 55 | ## 56 | ## catch broken x11 args: (hmm does not seem to work) 57 | ## 58 | if { [catch [wm title . npietedit] err] } { 59 | puts "unknown window argument: $err" 60 | exit 61 | } 62 | 63 | ## 64 | ## here we go: 65 | ## 66 | frame .top -borderwidth 10 67 | frame .cpick 68 | frame .cmd 69 | frame .paint 70 | 71 | pack .top -side top -fill x 72 | 73 | ## 74 | ## buttons: 75 | ## 76 | label .top.version -text $version 77 | button .top.quit -text quit -command exit 78 | button .top.save -text Save -command { save_cells $filename } 79 | button .top.load -text Load -command { load_cells $filename } 80 | button .top.shrink -text Shrink -command { cells_enlarge -1 } 81 | button .top.enlarge -text Enlarge -command { cells_enlarge +1 } 82 | 83 | pack .top.shrink .top.enlarge .top.save .top.load .top.quit .top.version \ 84 | -side left 85 | 86 | ## 87 | ## number of cells: 88 | ## 89 | set c_maxx 48 90 | set c_maxy 32 91 | 92 | for {set y 0} {$y < $c_maxy} {incr y} { 93 | for {set x 0} {$x < $c_maxx} {incr x} { 94 | set cells($x,$y) 19 95 | } 96 | } 97 | 98 | ## color pick pixel zoom factor: (fixed) 99 | set c_zc 20 100 | 101 | ## canvas pixel zoom factor: (may change when a pix is loaded) 102 | set c_zp 20 103 | 104 | ## default canvas width / height: 105 | set c_width [expr $c_zp * $c_maxx] 106 | set c_height [expr $c_zp * $c_maxy] 107 | 108 | ## set some default filename: 109 | set filename "npietedit-filename.ppm" 110 | 111 | 112 | ## 113 | ## 6 colors and 3 lightness values: 114 | ## 115 | set n_hue 6 116 | set n_light 3 117 | 118 | ## 119 | ## 6 light colors, 6 normal colors and 6 dark colors: 120 | ## 121 | array set colors { 122 | 123 | 0 "#FFC0C0" 1 "#FFFFC0" 2 "#C0FFC0" 124 | 3 "#C0FFFF" 4 "#C0C0FF" 5 "#FFC0FF" 125 | 126 | 6 "#FF0000" 7 "#FFFF00" 8 "#00FF00" 127 | 9 "#00FFFF" 10 "#0000FF" 11 "#FF00FF" 128 | 129 | 12 "#C00000" 13 "#C0C000" 14 "#00C000" 130 | 15 "#00C0C0" 16 "#0000C0" 17 "#C000C0" 131 | } 132 | 133 | 134 | ## 135 | ## the commands based on the color changes: 136 | ## 137 | # Commands 138 | # Lightness change 139 | # Hue change None 1 Darker 2 Darker 140 | # 141 | # None push pop 142 | # 1 Step add subtract multiply 143 | # 2 Steps divide mod not 144 | # 3 Steps greater pointer switch 145 | # 4 Steps duplicate roll in(number) 146 | # 5 Steps in(char) out(number) out(char) 147 | 148 | ## 149 | ## index is (light_change * 6 + hue_change): 150 | ## 151 | array set commands { 152 | 0 "nop" 6 "push" 12 "pop" 153 | 1 "add" 7 "sub" 13 "mul" 154 | 2 "div" 8 "mod" 14 "not" 155 | 3 "greater" 9 "pointer" 15 "switch" 156 | 4 "dup" 10 "roll" 16 "in(num)" 157 | 5 "in(char)" 11 "out(num)" 17 "out(char)" 158 | } 159 | 160 | 161 | ## 162 | ## cell info: current cell and current color index: 163 | ## (default color is white) 164 | ## 165 | set cur_x -1 166 | set cur_y -1 167 | set cur_idx 19 168 | ## last picked color: 169 | set cpick_x -1 170 | set cpick_y -1 171 | 172 | 173 | proc idx2col {idx} { 174 | global colors 175 | 176 | if {$idx == 18} { 177 | return "#000000" 178 | } elseif {$idx == 19} { 179 | return "#ffffff" 180 | } elseif {$idx >= 0 && $idx < 18} { 181 | return $colors($idx) 182 | } else { 183 | return -1 184 | } 185 | } 186 | 187 | proc col2idx {r g b} { 188 | global colors 189 | 190 | set str [string toupper [format "#%02x%02x%02x" $r $g $b]] 191 | 192 | ## special case black and white: 193 | if {$str == "#000000"} { 194 | return 18 195 | } 196 | if {$str == "#FFFFFF"} { 197 | return 19 198 | } 199 | 200 | for {set i 0} {$i < 18} {incr i} { 201 | if {$colors($i) == $str} { 202 | return $i 203 | } 204 | } 205 | ## substitute unknown color by white: 206 | return 19 207 | } 208 | 209 | ## 210 | ## 211 | ## 212 | proc paint_rect {frame x y idx zoom} { 213 | 214 | set x [expr 2 + ($x * $zoom)] 215 | set y [expr 2 + ($y * $zoom)] 216 | 217 | set col [idx2col $idx] 218 | 219 | $frame create rectangle $x $y [expr $x + $zoom - 2] \ 220 | [expr $y + $zoom - 2] -fill $col 221 | } 222 | 223 | proc paint_border {frame x y flag zoom} { 224 | 225 | set x [expr 1 + ($x * $zoom)] 226 | set y [expr 1 + ($y * $zoom)] 227 | 228 | if {$flag == 0} { 229 | set fill "" 230 | set outline "#ffffff" 231 | } else { 232 | set fill "" 233 | set outline "#000000" 234 | } 235 | $frame create rectangle $x $y [expr $x + $zoom] \ 236 | [expr $y + $zoom] -fill $fill -outline $outline 237 | } 238 | 239 | 240 | ## 241 | ## canvas click/paint callback: 242 | ## 243 | proc click_canvas {x y button} { 244 | 245 | global .paint.canvas 246 | global cells cur_x cur_y cur_idx 247 | global c_maxx c_maxy c_zp 248 | global count_col_n 249 | 250 | set x [expr $x / $c_zp] 251 | set y [expr $y / $c_zp] 252 | 253 | if {$x < 0 || $y < 0 || $x >= $c_maxx || $y >= $c_maxy} { 254 | return 255 | } 256 | 257 | if {$button != 1} { 258 | set cur_idx $cells($x,$y) 259 | pick_color $cur_idx 260 | } else { 261 | set cells($x,$y) $cur_idx 262 | paint_rect .paint.canvas $x $y $cur_idx $c_zp 263 | } 264 | 265 | if {$cur_x >= 0 && $cur_y >= 0} { 266 | ## reset old border: 267 | paint_border .paint.canvas $cur_x $cur_y 0 $c_zp 268 | } 269 | ## paint new border: 270 | paint_border .paint.canvas $x $y 1 $c_zp 271 | 272 | set cur_x $x 273 | set cur_y $y 274 | 275 | ## update display: 276 | draw_conn [count_col] 277 | draw_pos $x $y 278 | } 279 | 280 | ## 281 | ## canvas motion callback: 282 | ## 283 | proc motion_canvas {x y} { 284 | 285 | global .cpick.c c_zp c_maxx c_maxy 286 | global cells cur_x cur_y cur_idx 287 | 288 | set x [expr $x / $c_zp] 289 | set y [expr $y / $c_zp] 290 | 291 | if {$x < 0 || $y < 0 || $x >= $c_maxx || $y >= $c_maxy} { 292 | return 293 | } 294 | 295 | draw_pos $x $y 296 | } 297 | 298 | proc draw_pos {x y} { 299 | global .cpick.c cur_x cur_y 300 | 301 | .cpick.c create rectangle 150 22 340 38 -fill white -outline grey 302 | .cpick.c create text 151 24 -anchor nw -text \ 303 | "px=$cur_x py=$cur_y, x=$x y=$y" 304 | } 305 | 306 | proc draw_conn {n} { 307 | global .cpick.c 308 | 309 | ## number of currently connected cells: 310 | set n 311 | if {$n >= 32 && $n <= 127} { 312 | set n [format "$n (char: '%c')" $n] 313 | } 314 | 315 | .cpick.c create rectangle 150 2 340 18 -fill white -outline grey 316 | if {$n >= 1} { 317 | .cpick.c create text 151 4 -anchor nw -text "connected: $n" 318 | } 319 | } 320 | 321 | 322 | ## 323 | ## color pick from color table: 324 | ## 325 | canvas .cpick.c -bg white -width $c_width -height [expr $c_zc * 3 + 2] 326 | 327 | pack .cpick.c -fill both 328 | pack .cpick -fill both -side top 329 | 330 | bind .cpick.c <1> "cpick %x %y" 331 | 332 | ## 333 | ## create color palette: 334 | ## 335 | for {set i 0} {$i < 18} {incr i} { 336 | paint_rect .cpick.c [expr $i % 6] [expr $i / 6] $i $c_zc 337 | } 338 | paint_rect .cpick.c 6 0 18 $c_zc 339 | paint_rect .cpick.c 6 1 19 $c_zc 340 | 341 | ## highlite default color: (white) 342 | paint_border .cpick.c 6 1 1 $c_zc 343 | set cpick_x 6 344 | set cpick_y 1 345 | 346 | ## 347 | ## mouse callback: 348 | ## 349 | proc cpick {x y} { 350 | global .cpick.c 351 | global cpick_x cpick_y cur_idx 352 | global c_zc 353 | 354 | set x [expr ($x / $c_zc) ] 355 | set y [expr ($y / $c_zc) ] 356 | 357 | if {$x == 6 && $y == 0} { 358 | ## black 359 | set n_idx 18 360 | } elseif {$x == 6 && $y == 1} { 361 | ## white 362 | set n_idx 19 363 | } elseif {$x >= 0 && $x <= 5 && $y >= 0 && $y <=2} { 364 | set n_idx [expr ($y * 6 + $x)] 365 | } else { 366 | ## invalid click: 367 | return 368 | } 369 | 370 | set cur_idx $n_idx 371 | 372 | # puts "pick: $cur_idx" 373 | 374 | pick_color $cur_idx 375 | } 376 | 377 | ## 378 | ## pick color from color table: 379 | ## 380 | proc pick_color {idx} { 381 | 382 | global cpick_x cpick_y 383 | global c_zc 384 | 385 | if {$idx == 19} { 386 | set x 6 387 | set y 1 388 | } elseif {$idx == 18} { 389 | set x 6 390 | set y 0 391 | } else { 392 | set x [expr $idx % 6] 393 | set y [expr $idx / 6] 394 | } 395 | 396 | if {$cpick_x >= 0 && $cpick_y >= 0} { 397 | ## reset old border: 398 | paint_border .cpick.c $cpick_x $cpick_y 0 $c_zc 399 | } 400 | ## paint new border: 401 | paint_border .cpick.c $x $y 1 $c_zc 402 | 403 | set cpick_x $x 404 | set cpick_y $y 405 | 406 | 407 | } 408 | 409 | 410 | ## 411 | ## command frame: 412 | ## 413 | 414 | canvas .cmd.c -bg white -width $c_width -height [expr $c_zc * 3 + 2] 415 | 416 | pack .cmd.c -fill both 417 | pack .cmd -fill both 418 | 419 | ## 420 | ## create command strings: 421 | ## 422 | for {set i 0} {$i < 18} {incr i} { 423 | set x [expr 2 + 56 * ($i % 6)] 424 | set y [expr 2 + $c_zc * ($i / 6)] 425 | .cmd.c create text [expr $x + 2] [expr $y + 2] \ 426 | -text $commands($i) -anchor nw 427 | .cmd.c create rectangle $x $y \ 428 | [expr $x + 54] [expr $y + $c_zc - 2] -fill "" -outline black 429 | } 430 | 431 | bind .cmd.c <1> "cmd %x %y" 432 | 433 | ## 434 | ## mouse callback: 435 | ## 436 | proc cmd {x y} { 437 | global .cmd.c 438 | global cmd_x cmd_y cmd_idx cur_idx 439 | global commands colors c_zc 440 | 441 | set x [expr ($x / 56) ] 442 | set y [expr ($y / $c_zc) ] 443 | 444 | set n_idx [expr $x + $y * 6] 445 | if {$n_idx < 18 && $x < 6 && $y < 3} { 446 | set cmd_hue [expr $n_idx % 6] 447 | set cmd_light [expr (($n_idx / 6) + 3) % 3] 448 | 449 | # set cur_idx [expr ($cur_idx + (6 * $cmd_light) + $cmd_hue) % 18] 450 | set ncx [expr (($cur_idx % 6) + $cmd_hue) % 6] 451 | set ncy [expr (($cur_idx / 6) + $cmd_light) % 3] 452 | set cur_idx [expr $ncx + 6 * $ncy] 453 | 454 | # puts "pick: (cmd: $x $y) -> $n_idx -> $commands($n_idx) hue=$cmd_hue light=$cmd_light -> $cur_idx $colors($cur_idx)" 455 | 456 | pick_color $cur_idx 457 | } 458 | } 459 | 460 | 461 | ## 462 | ## paint area: 463 | ## 464 | 465 | 466 | set w "" 467 | set c .paint.canvas 468 | 469 | if {1} { 470 | ## stay with a fixed area: 471 | canvas .paint.canvas -bg white -width [expr $c_width + 1] \ 472 | -height [expr $c_height + 1] 473 | .paint.canvas create rectangle 0 0 \ 474 | [expr $c_width + 1] [expr $c_height + 1] -fill white -outline "" 475 | } else { 476 | ## 477 | ## use a scrollable area: xxx - fix me 478 | ## 479 | canvas $c -scrollregion {0 0 200p 200p} \ 480 | -xscrollc "$w.hscroll set" \ 481 | -yscrollc "$w.vscroll set" 482 | 483 | scrollbar $w.vscroll -relief sunken \ 484 | -command "$c yview" 485 | 486 | scrollbar $w.hscroll -orient horiz \ 487 | -relief sunken -command "$c xview" 488 | 489 | pack $w.vscroll -side right -fill y 490 | pack $w.hscroll -side bottom -fill x 491 | pack $c -expand yes -fill both 492 | } 493 | 494 | pack .paint.canvas -fill both 495 | pack .paint -fill both -side left 496 | 497 | bind .paint.canvas "motion_canvas %x %y" 498 | bind .paint.canvas <1> "click_canvas %x %y 1" 499 | bind .paint.canvas <2> "click_canvas %x %y 2" 500 | bind .paint.canvas "click_canvas %x %y 1" 501 | 502 | for {set y 0} {$y < $c_maxy} {incr y} { 503 | for {set x 0} {$x < $c_maxx} {incr x} { 504 | paint_rect .paint.canvas $x $y 19 $c_zp 505 | } 506 | } 507 | 508 | ## 509 | ## 510 | ## 511 | 512 | ## counter: 513 | set count_col_n -1 514 | array set count_col_arr { } 515 | 516 | proc count_col_rec {x y} { 517 | 518 | global cur_x cur_y cur_idx 519 | global count_col_n count_col_arr 520 | global c_maxx c_maxy 521 | 522 | if {$x < 0 || $x >= $c_maxx || $y < 0 || $y >= $c_maxy} { 523 | return 524 | } 525 | if {$count_col_arr($x,$y) != $cur_idx} { 526 | return 527 | } 528 | 529 | ## avoid tcl limitation: 530 | if {$count_col_n == 990} { 531 | return 532 | } 533 | 534 | ## count, mark and recurse on: 535 | incr count_col_n 536 | set count_col_arr($x,$y) 9999 537 | 538 | count_col_rec [expr $x + 1] $y 539 | count_col_rec $x [expr $y + 1] 540 | count_col_rec [expr $x - 1] $y 541 | count_col_rec $x [expr $y - 1] 542 | } 543 | 544 | proc count_col { } { 545 | 546 | global cells cur_x cur_y cur_idx 547 | global count_col_arr count_col_n 548 | 549 | ## ignore black/white/other colors: 550 | if {$cur_idx >= 18} { 551 | return 0 552 | } 553 | 554 | set count_col_n 0 555 | array set count_col_arr [array get cells] 556 | 557 | count_col_rec $cur_x $cur_y 558 | 559 | # puts "count_col: got $count_col_n" 560 | 561 | if {$count_col_n == 990} { 562 | ## avoid tcl recursion error: 563 | return "???" 564 | } else { 565 | return $count_col_n 566 | } 567 | } 568 | 569 | ## 570 | ## color index and r/g/b value: 571 | ## 572 | array set c_red { 573 | 0 255 1 255 2 192 3 192 4 192 5 255 6 255 7 255 8 0 9 0 10 0 11 255 12 192 574 | 13 192 14 0 15 0 16 0 17 192 18 0 19 255 575 | } 576 | 577 | array set c_green { 578 | 0 192 1 255 2 255 3 255 4 192 5 192 6 0 7 255 8 255 9 255 10 0 11 0 12 0 579 | 13 192 14 192 15 192 16 0 17 0 18 0 19 255 580 | } 581 | 582 | array set c_blue { 583 | 0 192 1 192 2 192 3 255 4 255 5 255 6 0 7 0 8 0 9 255 10 255 11 255 12 0 584 | 13 0 14 0 15 192 16 192 17 192 18 0 19 255 585 | } 586 | 587 | ## 588 | ## for now we write ascii readable ppm files: 589 | ## 590 | proc save_cells { filename } { 591 | 592 | global cells c_maxx c_maxy 593 | global c_red c_green c_blue 594 | 595 | set fp [open $filename "w"] 596 | if {$fp == ""} { 597 | puts "cannot save" 598 | } 599 | 600 | puts $fp "P3\n\# a piet program $filename\n$c_maxx $c_maxy\n255" 601 | 602 | for {set y 0} {$y < $c_maxy} {incr y} { 603 | for {set x 0} {$x < $c_maxx} {incr x} { 604 | set idx $cells($x,$y) 605 | puts -nonewline $fp [format "%3d %3d %3d " \ 606 | $c_red($idx) $c_green($idx) $c_blue($idx)] 607 | if {[expr ($x + $y * $c_maxx + 1) % 6] == 0} { 608 | puts $fp "" 609 | } else { 610 | puts -nonewline $fp " " 611 | } 612 | } 613 | } 614 | puts $fp "" 615 | close $fp 616 | } 617 | 618 | 619 | ## 620 | ## load a program: 621 | ## 622 | proc load_cells { filename } { 623 | 624 | global cells 625 | 626 | ## try ascii p3 first: 627 | if {[load_p3_cells $filename] >= 0} { 628 | return 629 | } 630 | 631 | ## continue with tcl builtin's: 632 | if { [catch {set img [image create photo -file $filename]} err] } { 633 | tk_messageBox -message "cannot read from $filename; reason: $err" 634 | return 635 | } 636 | 637 | set y 0 638 | set x 0 639 | set width 0 640 | set height 0 641 | set loop 1 642 | 643 | while { $loop == 1} { 644 | 645 | if { [catch {set rgb [$img get $x $y]} err] } { 646 | if {$x == 0} { 647 | set loop 0 648 | } else { 649 | set width $x 650 | set x 0 651 | incr y 652 | } 653 | } else { 654 | set idx [col2idx [lindex $rgb 0] [lindex $rgb 1] [lindex $rgb 2]] 655 | set cells($x,$y) $idx 656 | 657 | incr x 658 | } 659 | } 660 | 661 | cells_resize $width $y 662 | } 663 | 664 | ## 665 | ## Tk, at least on debian woody, can only handle P6 binary ppm 666 | ## and cannot load P3 ascii ppm; so we try to handle this on 667 | ## our own: 668 | ## 669 | proc load_p3_cells { filename } { 670 | 671 | global cells c_maxx c_maxy 672 | 673 | # puts "deb: p3 load: $filename" 674 | 675 | set fd [open $filename "r"] 676 | if {$fd == ""} { 677 | # puts "cannot open $filename for reading" 678 | return -1 679 | } 680 | 681 | ## get tag: 682 | set rc [gets $fd line] 683 | while {$rc >= 0 && [string index $line 0] == "#"} { 684 | set rc [gets $fd line] 685 | } 686 | if {$rc < 0} { 687 | # puts "cannot read $filename: no magic-tag found" 688 | close $fd 689 | return -1 690 | } 691 | 692 | if {$line != "P3"} { 693 | # puts "cannot read $filename: magic tag P3 not found" 694 | close $fd 695 | return -1 696 | } 697 | 698 | ## 699 | ## magic tag P3 found - now we can continue 700 | ## (and be somewhat more verbose): 701 | ## 702 | 703 | ## get size: 704 | set rc [gets $fd line] 705 | while {$rc >= 0 && [string index $line 0] == "#"} { 706 | set rc [gets $fd line] 707 | } 708 | 709 | if {$rc < 0 || 2 != [scan $line "%d %d" width height]} { 710 | puts "cannot read $filename: no size found" 711 | close $fd 712 | return -1 713 | } 714 | 715 | ## get #cols: 716 | set rc [gets $fd line] 717 | while {$rc >= 0 && [string index $line 0] == "#"} { 718 | set rc [gets $fd line] 719 | } 720 | 721 | if {$rc < 0 || 1 != [scan $line "%d" cols]} { 722 | puts "cannot read $filename: no color param found" 723 | close $fd 724 | return -1 725 | } 726 | if {$cols != 255} { 727 | ## warn only: 728 | puts "color param is $cols, but 255 expected - result may be wrong" 729 | } 730 | 731 | if {$width * $height > 64 * 64} { 732 | puts "info: maybe picture is too large for npietedit ($width x $height) ..." 733 | } 734 | 735 | ## read remainig data: 736 | set data [read $fd] 737 | close $fd 738 | 739 | for {set y 0} {$y < $height} {incr y} { 740 | for {set x 0} {$x < $width} {incr x} { 741 | 742 | set rc 0 743 | 744 | ## 745 | ## this is way ugly and expensive: xxx - fix me 746 | ## 747 | for {set n 0} {$n < 3} {incr n} { 748 | ## strip whites: 749 | set data [string trimleft $data] 750 | set rc [expr $rc + [scan $data "%d" rgb($n)]] 751 | ## strip number: 752 | set data [string trimleft $data "0123456789"] 753 | } 754 | 755 | if {$rc != 3} { 756 | puts "cannot read $filename: error reading rgb triples" 757 | return -1 758 | } 759 | 760 | set idx [col2idx $rgb(0) $rgb(1) $rgb(2)] 761 | set cells($x,$y) $idx 762 | } 763 | } 764 | set c_maxx $width 765 | set c_maxy $height 766 | 767 | cells_resize $c_maxx $c_maxy 768 | 769 | return 0 770 | } 771 | 772 | ## 773 | ## shrink or enlarge the number of cells by the given delta: 774 | ## 775 | proc cells_enlarge { delta } { 776 | 777 | global cells c_maxx c_maxy c_zp c_width c_height 778 | 779 | if {$delta < 0} { 780 | if {$c_maxx <= 4 || $c_maxy <= 4} { 781 | ## ignore: 782 | return 783 | } 784 | } 785 | 786 | cells_resize [expr $c_maxx + $delta] [expr $c_maxy + $delta] 787 | } 788 | 789 | 790 | ## 791 | ## shrink or enlarge the number of cells to the new size: 792 | ## 793 | proc cells_resize {width height} { 794 | 795 | global cells c_maxx c_maxy c_zp c_width c_height 796 | 797 | set c_maxx $width 798 | set c_maxy $height 799 | 800 | ## 801 | ## adjust zoom factor: 802 | ## try too keep it between 8 and 20 803 | ## 804 | set size [expr $c_maxx > $c_maxy ? $c_maxx : $c_maxy] 805 | if { $size > 0} { 806 | set c_zp [expr $c_width / $size] 807 | ## make no sense to zoom further out: 808 | if {$c_zp < 8} { 809 | set c_zp 8 810 | } 811 | } 812 | if {$c_zp > 20} { 813 | set c_zp 20 814 | } 815 | 816 | # puts "got image width $c_maxx height $c_maxy (zoom $c_zp)" 817 | 818 | ## 819 | ## paint with new zoom calculated: 820 | ## 821 | .paint.canvas create rectangle 0 0 \ 822 | [expr $c_width + 1] [expr $c_height + 1] -fill white -outline "" 823 | for {set y 0} {$y < $c_maxy} {incr y} { 824 | for {set x 0} {$x < $c_maxx} {incr x} { 825 | if {[catch {set idx $cells($x,$y)} err]} { 826 | ## set non existing cells to white: 827 | set idx 19 828 | set cells($x,$y) $idx 829 | } 830 | paint_rect .paint.canvas $x $y $idx $c_zp 831 | } 832 | } 833 | 834 | } 835 | 836 | 837 | ## 838 | ## args: 839 | ## 840 | if {$argc == 1} { 841 | if {[string index [lindex $argv 0] 0] == "-"} { 842 | usage 843 | } 844 | ## 845 | ## filename to use: 846 | ## 847 | set filename [lindex $argv 0] 848 | puts "filename: $filename" 849 | if {[file readable $filename] == 1} { 850 | load_cells $filename 851 | } 852 | } elseif {$argc > 1} { 853 | usage 854 | } 855 | -------------------------------------------------------------------------------- /examples/nhello.ppm: -------------------------------------------------------------------------------- 1 | P3 2 | # a piet program ./nhello.ppm 3 | 61 61 4 | 255 5 | 255 0 0 255 0 0 192 0 0 255 0 255 192 0 192 0 0 255 6 | 0 0 192 0 255 255 0 192 192 0 255 0 0 192 0 255 255 0 7 | 192 192 0 255 0 0 192 0 0 255 0 255 192 0 192 0 0 255 8 | 0 0 192 0 255 255 0 192 192 0 255 0 0 192 0 255 255 0 9 | 192 192 0 255 0 0 192 0 0 255 0 255 255 255 255 255 255 255 10 | 255 255 255 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 11 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 12 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 13 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 14 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 15 | 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 16 | 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 255 255 0 17 | 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 18 | 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 255 255 0 19 | 255 255 0 255 0 0 255 0 0 255 255 255 255 255 255 255 255 255 20 | 0 0 0 255 255 255 0 0 0 255 255 255 255 255 255 255 255 255 21 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 22 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 23 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 24 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 25 | 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 26 | 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 27 | 255 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 28 | 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 29 | 255 255 0 255 255 0 255 0 0 255 0 0 255 255 255 255 255 255 30 | 0 0 0 255 0 0 255 0 0 255 0 0 0 0 0 255 255 255 31 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 32 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 33 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 34 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 35 | 255 255 255 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 36 | 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 37 | 0 255 0 255 255 0 255 255 0 255 0 0 255 0 0 255 0 255 38 | 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 39 | 0 255 0 255 255 0 255 255 0 255 0 0 255 0 0 255 255 255 40 | 255 255 255 255 255 255 0 0 0 0 0 0 0 0 0 255 255 255 41 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 42 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 43 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 44 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 45 | 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 255 0 0 46 | 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 47 | 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 0 48 | 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 49 | 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 0 50 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 51 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 52 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 53 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 54 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 55 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 56 | 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 57 | 0 255 255 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 58 | 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 59 | 0 255 255 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 60 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 61 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 62 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 63 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 64 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 65 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 66 | 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 67 | 0 255 255 0 255 255 0 255 0 0 255 0 255 255 0 255 255 0 68 | 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 69 | 0 255 255 0 255 255 0 255 0 0 255 0 255 255 0 255 255 0 70 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 71 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 72 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 73 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 74 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 75 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 76 | 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 77 | 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 255 255 0 78 | 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 79 | 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 255 255 0 80 | 255 255 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 81 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 82 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 83 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 84 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 85 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 86 | 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 87 | 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 88 | 255 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 89 | 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 90 | 255 255 0 255 255 0 255 255 255 255 255 255 255 255 255 255 255 255 91 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 92 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 93 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 94 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 95 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 96 | 255 255 255 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 97 | 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 98 | 0 255 0 255 255 0 255 255 0 255 0 0 255 0 0 255 0 255 99 | 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 100 | 0 255 0 255 255 0 255 255 0 255 255 255 255 255 255 255 255 255 101 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 102 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 103 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 104 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 105 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 106 | 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 255 0 0 107 | 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 108 | 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 0 109 | 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 110 | 0 255 0 0 255 0 255 255 0 255 255 0 255 255 255 255 255 255 111 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 112 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 113 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 114 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 115 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 116 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 117 | 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 118 | 0 255 255 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 119 | 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 120 | 0 255 255 0 255 0 0 255 0 255 255 0 255 255 0 255 255 255 121 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 122 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 123 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 124 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 125 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 126 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 127 | 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 128 | 0 255 255 0 255 255 0 255 0 0 255 0 255 255 0 255 255 0 129 | 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 130 | 0 255 255 0 255 255 0 255 0 0 255 0 255 255 0 255 255 0 131 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 132 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 133 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 134 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 135 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 136 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 137 | 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 138 | 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 255 255 0 139 | 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 140 | 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 255 255 0 141 | 255 255 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 142 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 143 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 144 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 145 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 146 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 147 | 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 148 | 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 149 | 255 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 150 | 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 151 | 255 255 0 255 255 0 255 255 255 255 255 255 255 255 255 255 255 255 152 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 153 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 154 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 155 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 156 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 157 | 255 255 255 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 158 | 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 159 | 0 255 0 255 255 0 255 255 0 255 0 0 255 0 0 255 0 255 160 | 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 161 | 0 255 0 255 255 0 255 255 0 255 255 255 255 255 255 255 255 255 162 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 163 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 164 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 165 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 166 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 167 | 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 255 0 0 168 | 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 169 | 0 255 0 0 255 0 255 255 0 255 255 255 255 0 0 255 0 0 170 | 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 171 | 0 255 0 0 255 0 255 255 0 255 255 0 255 255 255 255 255 255 172 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 173 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 174 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 175 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 176 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 177 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 178 | 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 179 | 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 255 0 0 180 | 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 181 | 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 255 255 255 182 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 183 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 184 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 185 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 186 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 187 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 188 | 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 189 | 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 190 | 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 191 | 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 192 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 193 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 194 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 195 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 196 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 197 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 198 | 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 199 | 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 200 | 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 201 | 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 202 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 203 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 204 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 205 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 206 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 207 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 208 | 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 209 | 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 210 | 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 211 | 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 212 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 213 | 255 255 255 255 255 255 255 255 255 0 0 0 255 255 255 0 0 0 214 | 255 255 255 0 0 0 0 0 0 255 255 255 0 0 0 255 255 255 215 | 255 255 255 0 0 0 255 255 255 255 255 255 0 0 0 0 0 0 216 | 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 217 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 218 | 255 255 255 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 219 | 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 220 | 0 255 0 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 221 | 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 222 | 0 255 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 223 | 255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 255 255 255 224 | 0 0 0 255 255 255 0 0 0 255 255 255 255 255 255 0 0 0 225 | 255 255 255 255 255 255 0 0 0 255 255 255 255 255 255 0 0 0 226 | 255 255 255 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 227 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 228 | 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 255 0 0 229 | 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 230 | 0 255 0 0 255 0 255 255 255 255 255 255 255 0 0 255 0 0 231 | 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 232 | 0 255 0 0 255 0 255 255 255 255 255 255 255 255 255 255 255 255 233 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 234 | 0 0 0 0 0 0 255 255 255 0 0 0 0 0 0 255 255 255 235 | 0 0 0 255 255 255 255 255 255 0 0 0 255 255 255 255 255 255 236 | 0 0 0 255 255 255 0 0 0 255 255 255 255 255 255 255 255 255 237 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 238 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 239 | 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 240 | 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 255 0 0 241 | 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 242 | 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 255 255 255 243 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 244 | 0 0 0 255 255 255 0 0 0 255 255 255 0 0 0 255 255 255 245 | 255 255 255 0 0 0 255 255 255 255 255 255 0 0 0 255 255 255 246 | 255 255 255 0 0 0 255 255 255 0 0 0 255 255 255 255 255 255 247 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 248 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 249 | 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 250 | 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 251 | 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 252 | 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 253 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 | 255 255 255 0 0 0 255 255 255 0 0 0 255 255 255 0 0 0 255 | 0 0 0 255 255 255 0 0 0 0 0 0 255 255 255 0 0 0 256 | 0 0 0 255 255 255 0 0 0 0 0 0 0 0 0 255 255 255 257 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 258 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 259 | 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 260 | 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 261 | 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 262 | 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 263 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 264 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 265 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 266 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 267 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 268 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 269 | 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 270 | 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 271 | 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 272 | 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 273 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 274 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 275 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 276 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 277 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 278 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 279 | 255 255 255 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 280 | 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 281 | 0 255 0 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 282 | 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 283 | 0 255 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 284 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 285 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 286 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 287 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 288 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 289 | 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 255 0 0 290 | 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 291 | 0 255 0 0 255 0 255 255 255 255 255 255 255 0 0 255 0 0 292 | 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 293 | 0 255 0 0 255 0 255 255 255 255 255 255 255 255 255 255 255 255 294 | 255 255 255 255 255 255 255 255 255 0 0 0 255 255 255 0 0 0 295 | 255 255 255 0 0 0 255 255 255 0 0 0 0 0 0 0 0 0 296 | 255 255 255 0 0 0 0 0 0 255 255 255 255 255 255 0 0 0 297 | 255 255 255 255 255 255 0 0 0 0 0 0 255 255 255 255 255 255 298 | 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 299 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 300 | 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 301 | 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 255 0 0 302 | 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 303 | 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 255 255 255 304 | 255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 255 255 255 305 | 0 0 0 255 255 255 0 0 0 255 255 255 0 0 0 255 255 255 306 | 0 0 0 255 255 255 0 0 0 255 255 255 0 0 0 255 255 255 307 | 0 0 0 255 255 255 255 255 255 0 0 0 255 255 255 0 0 0 308 | 255 255 255 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 309 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 310 | 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 311 | 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 312 | 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 313 | 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 314 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 315 | 255 255 255 0 0 0 255 255 255 0 0 0 255 255 255 0 0 0 316 | 255 255 255 0 0 0 255 255 255 0 0 0 0 0 0 255 255 255 317 | 255 255 255 0 0 0 255 255 255 255 255 255 0 0 0 255 255 255 318 | 0 0 0 255 255 255 0 0 0 255 255 255 255 255 255 255 255 255 319 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 320 | 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 321 | 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 322 | 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 323 | 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 324 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 325 | 0 0 0 255 255 255 0 0 0 255 255 255 0 0 0 255 255 255 326 | 0 0 0 255 255 255 0 0 0 255 255 255 0 0 0 255 255 255 327 | 0 0 0 255 255 255 0 0 0 255 255 255 255 255 255 0 0 0 328 | 255 255 255 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 329 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 330 | 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 331 | 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 332 | 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 333 | 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 334 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 335 | 255 255 255 255 255 255 0 0 0 255 255 255 0 0 0 255 255 255 336 | 255 255 255 0 0 0 0 0 0 0 0 0 255 255 255 0 0 0 337 | 255 255 255 0 0 0 255 255 255 0 0 0 0 0 0 255 255 255 338 | 0 0 0 0 0 0 255 255 255 255 255 255 0 0 0 255 255 255 339 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 340 | 255 255 255 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 341 | 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 342 | 0 255 0 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 343 | 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 344 | 0 255 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 345 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 346 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 347 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 348 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 349 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 350 | 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 255 0 0 351 | 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 352 | 0 255 0 0 255 0 255 255 255 255 255 255 255 0 0 255 0 0 353 | 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 354 | 0 255 0 0 255 0 255 255 255 255 255 255 255 255 255 255 255 255 355 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 356 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 357 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 358 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 359 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 360 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 361 | 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 362 | 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 255 0 0 363 | 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 364 | 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 255 255 255 365 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 366 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 367 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 368 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 369 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 370 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 371 | 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 372 | 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 373 | 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 374 | 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 375 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 376 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 377 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 378 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 379 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 380 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 381 | 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 382 | 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 383 | 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 384 | 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 385 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 386 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 387 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 388 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 389 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 390 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 391 | 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 392 | 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 393 | 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 394 | 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 395 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 396 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 397 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 398 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 399 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 400 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 401 | 255 255 255 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 402 | 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 403 | 0 255 0 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 404 | 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 405 | 0 255 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 406 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 407 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 408 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 409 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 410 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 411 | 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 255 0 0 412 | 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 413 | 0 255 0 0 255 0 255 255 255 255 255 255 255 0 0 255 0 0 414 | 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 415 | 0 255 0 0 255 0 255 255 255 255 255 255 255 255 255 255 255 255 416 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 417 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 418 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 419 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 420 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 421 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 422 | 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 423 | 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 255 0 0 424 | 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 425 | 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 255 255 255 426 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 427 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 428 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 429 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 430 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 431 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 432 | 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 433 | 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 434 | 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 435 | 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 436 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 437 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 438 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 439 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 440 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 441 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 442 | 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 443 | 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 444 | 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 445 | 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 446 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 447 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 448 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 449 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 450 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 451 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 452 | 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 453 | 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 454 | 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 455 | 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 456 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 457 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 458 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 459 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 460 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 461 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 462 | 255 255 255 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 463 | 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 464 | 0 255 0 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 465 | 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 466 | 0 255 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 467 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 468 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 469 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 470 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 471 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 472 | 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 255 0 0 473 | 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 474 | 0 255 0 0 255 0 255 255 255 255 255 255 255 0 0 255 0 0 475 | 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 476 | 0 255 0 0 255 0 255 255 255 255 255 255 255 255 255 255 255 255 477 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 478 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 479 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 480 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 481 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 482 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 483 | 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 484 | 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 255 0 0 485 | 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 486 | 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 255 255 255 487 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 488 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 489 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 490 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 491 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 492 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 493 | 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 494 | 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 495 | 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 496 | 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 497 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 498 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 499 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 500 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 501 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 502 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 503 | 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 504 | 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 505 | 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 506 | 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 255 255 255 507 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 508 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 509 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 510 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 511 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 512 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 513 | 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 514 | 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 0 255 0 515 | 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 516 | 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 255 255 255 517 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 518 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 519 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 520 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 521 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 522 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 523 | 255 255 255 255 255 255 255 255 255 255 0 0 255 0 0 255 255 255 524 | 255 255 255 0 0 255 0 0 255 0 255 255 0 255 255 0 255 0 525 | 0 255 0 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 526 | 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 255 255 255 527 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 528 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 529 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 530 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 531 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 532 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 533 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 534 | 255 255 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 255 535 | 0 255 0 0 255 0 255 255 255 255 255 255 255 0 0 255 0 0 536 | 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 0 255 255 537 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 538 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 539 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 540 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 541 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 542 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 543 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 544 | 255 255 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 255 545 | 0 255 255 0 255 0 0 255 0 255 255 255 255 255 255 255 0 0 546 | 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 0 255 255 547 | 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 548 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 549 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 550 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 551 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 552 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 553 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 554 | 255 255 255 255 255 255 255 255 255 255 255 255 0 0 255 255 255 255 555 | 0 255 255 255 255 255 0 255 0 0 255 0 255 255 255 255 255 255 556 | 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 0 0 255 557 | 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 558 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 559 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 560 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 561 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 562 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 563 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 564 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 565 | 255 255 255 255 255 255 255 255 255 0 255 0 0 255 0 255 255 255 566 | 255 255 255 255 0 0 255 0 0 255 0 255 255 0 255 0 0 255 567 | 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 568 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 569 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 570 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 571 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 572 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 573 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 574 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 575 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 576 | 255 255 255 255 255 255 255 0 0 255 0 0 255 255 255 255 255 255 577 | 0 0 255 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 578 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 579 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 580 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 581 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 582 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 583 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 584 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 585 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 586 | 255 255 255 255 255 255 255 255 255 255 0 0 255 0 0 255 255 255 587 | 255 255 255 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 588 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 589 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 590 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 591 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 592 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 593 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 594 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 595 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 596 | 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 255 0 0 597 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 598 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 599 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 600 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 601 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 602 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 603 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 604 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 605 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 606 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 607 | 255 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 608 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 609 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 610 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 611 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 612 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 613 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 614 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 615 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 616 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 617 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 618 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 619 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 620 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 621 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 622 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 623 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 624 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 625 | 255 255 255 626 | -------------------------------------------------------------------------------- /npiet-foogol.y: -------------------------------------------------------------------------------- 1 | %{ 2 | /* 3 | * npiet-foogol.y: Jun 2004 4 | * (schoenfr@web.de) Aug 2011 5 | * 6 | * This file is part of npiet. 7 | * 8 | * Copyright (C) 2004 Erik Schoenfelder (schoenfr@web.de) 9 | * see file COPYING 10 | * 11 | * npiet-foogol translates foogol input into piet output, so it 12 | * is some kind of a picture generator ;-) 13 | * 14 | * 15 | * more about the piet programming language and the npiet interpreter see: 16 | * 17 | * http://www.bertnase.de/npiet/ 18 | * 19 | * for more about foogol see comp.sources.unix archive Volume 8 20 | * and about cfoogol see Volume 42, Issue 88 (here a copy): 21 | * 22 | * http://www.bertnase.de/html/foogol.html 23 | * 24 | * 25 | * to compile better run ./configure and make from the npiet package, 26 | * but manual compilation should work by running: 27 | * 28 | * bison -o npiet-foogol.c npiet-foogol.y 29 | * gcc -g -O -o npiet-foogol npiet-foogol.c -lgd -lpng -lm 30 | * 31 | * echo 'begin prints ("Hello World!\n") end' | npiet-foogol - 32 | * npiet npiet-foogol.png 33 | * 34 | * please note, npiet-foogol uses the libgd library. on debian it is 35 | * avail by ``apt-get install libgd2-xpm-dev'' and bison can be 36 | * installed via ``apt-get install bison''. 37 | * 38 | * Have fun. 39 | */ 40 | 41 | char *version = "v1.3"; 42 | 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | #include 53 | 54 | /* just a default: */ 55 | #define WRAP_W 64 /* default block wrap width in pixel */ 56 | 57 | /* filename for output: */ 58 | char *ofname = "npiet-foogol.png"; 59 | 60 | /* base factor for number generation: */ 61 | int smart_base = 7; /* just try a funny value */ 62 | 63 | /* codel size: */ 64 | int codel_size = 1; 65 | 66 | /* use random color at startup (opposite to pre v1.3 behavior): */ 67 | int random_color = 0; 68 | 69 | void 70 | usage (int rc) 71 | { 72 | fprintf (stderr, "npiet-foogol %s\n\n", version); 73 | 74 | fprintf (stderr, "use: npiet-foogol [] \n"); 75 | fprintf (stderr, "options:\n"); 76 | fprintf (stderr, "\t-v - be verbose (default: off)\n"); 77 | fprintf (stderr, "\t-q - be quiet (default: off)\n"); 78 | fprintf (stderr, "\t-d - print debug messages (default: off)\n"); 79 | fprintf (stderr, "\t-w - wrap pixel width (default: %d)\n", WRAP_W); 80 | fprintf (stderr, "\t-b - smart number generation base (default: %d)\n", smart_base); 81 | fprintf (stderr, "\t-cs - codel size of output (default: %d)\n", 82 | codel_size); 83 | fprintf (stderr, "\t-rnd - not only red color on startup,\n"); 84 | fprintf (stderr, "\t use a random codel (experimental)\n"); 85 | fprintf (stderr, "\t-o - output file (default: %s)\n", ofname); 86 | 87 | exit (rc); 88 | } 89 | 90 | 91 | /* be somewhat verbose: */ 92 | int verbose = 0; 93 | 94 | /* be quiet: */ 95 | int quiet = 0; 96 | 97 | /* print debugging stuff: */ 98 | int debug = 0; 99 | 100 | /* use this width as a wrap margin: */ 101 | int wrap_wm = WRAP_W; 102 | 103 | /* filename to work for: */ 104 | char *input_filename = 0; 105 | FILE *f_in; 106 | 107 | /* warning/error flag: */ 108 | int have_error = 0; 109 | int have_warning = 0; 110 | 111 | /* helper: */ 112 | #define dprintf if (debug) printf 113 | #define d2printf if (debug > 1) printf 114 | #define vprintf if (verbose) printf 115 | 116 | int 117 | parse_args (int argc, char **argv) 118 | { 119 | while (--argc > 0) { 120 | argv++; 121 | if (! strcmp (argv [0], "-v")) { 122 | verbose++; 123 | vprintf ("info: verbose set to %d\n", verbose); 124 | } else if (! strcmp (argv [0], "-q")) { 125 | quiet = 1; 126 | dprintf ("info: quiet set to %d\n", quiet); 127 | } else if (! strcmp (argv [0], "-d")) { 128 | debug++; 129 | dprintf ("info: debug set to %d\n", debug); 130 | } else if (argc > 0 && ! strcmp (argv [0], "-w")) { 131 | argc--, argv++; /* shift */ 132 | wrap_wm = atoi (argv [0]); 133 | if (wrap_wm < 10) { 134 | fprintf (stderr, 135 | "warning: wrap width %d < 10 looks a bit odd - using 10\n", 136 | wrap_wm); 137 | wrap_wm = 10; 138 | } 139 | vprintf ("info: wrap width set to %d\n", wrap_wm); 140 | } else if (argc > 0 && ! strcmp (argv [0], "-b")) { 141 | argc--, argv++; /* shift */ 142 | smart_base = atoi (argv [0]); 143 | if (smart_base < 2) { 144 | fprintf (stderr, 145 | "warning: smart_base %d < 2 looks a bit odd - using 7\n", 146 | smart_base); 147 | smart_base = 7; 148 | } 149 | vprintf ("info: smart base set to %d\n", smart_base); 150 | } else if (argc > 0 && ! strcmp (argv [0], "-cs")) { 151 | argc--, argv++; /* shift */ 152 | codel_size = atoi (argv [0]); 153 | if (codel_size < 1) { 154 | fprintf (stderr, 155 | "warning: codel size %d < 1 looks a bit odd - using 1\n", 156 | codel_size); 157 | codel_size = 1; 158 | } 159 | vprintf ("info: codel size set to %d\n", codel_size); 160 | } else if (argc > 0 && ! strcmp (argv [0], "-rnd")) { 161 | random_color = 1; 162 | vprintf ("info: using random codel colors - very experimental...\n"); 163 | /* init the random number generator - some secs should be good enough: */ 164 | srand (time ((time_t *) 0) % 32768); 165 | } else if (argc > 0 && ! strcmp (argv [0], "-o")) { 166 | argc--, argv++; /* shift */ 167 | ofname = argv [0]; 168 | vprintf ("info: output filename set to %s\n", ofname); 169 | } else if (argv [0][0] == '-' && argv [0][1]) { 170 | usage (-1); 171 | } else if (! input_filename) { 172 | input_filename = argv [0]; 173 | vprintf ("info: using input filename %s\n", input_filename); 174 | } else { 175 | usage (-1); 176 | } 177 | } 178 | 179 | return 0; 180 | } 181 | 182 | 183 | /* force code for parser debugging to be included: */ 184 | #define YYDEBUG 1 185 | /* force code for bettererror messages to be included: */ 186 | #define YYERROR_VERBOSE 1 187 | 188 | 189 | /* forward: */ 190 | void yyerror (char *s); 191 | int yylex (void); 192 | void dump_blocks (); 193 | struct _a_img * gen_block (); 194 | void gd_create_img (); 195 | int gdcol2idx (); 196 | void gen_img_push (); 197 | struct _a_decl *find_decl (); 198 | void gen_img_check_wrap (); 199 | void gen_mark (); 200 | void gen_img_push_pos (); 201 | void gen_wrap_right (); 202 | int get_pixel (); 203 | int check_fx (); 204 | 205 | 206 | 207 | /* 208 | * internals: 209 | * 210 | * we put the blocks of the code into a tree and store 211 | * references of the declarations and statements together with the 212 | * parsed expressions there too. 213 | * 214 | */ 215 | 216 | /* 217 | * a picture in an internal gd based format 218 | */ 219 | typedef struct _a_img { 220 | gdImagePtr im; 221 | int gdcol [18 + 2]; 222 | int w, h; /* width, height of the pic */ 223 | int x, y; /* paint position */ 224 | int col; /* last color used */ 225 | int dx; /* dir of code generation (1 == right, -1 == left): */ 226 | int wrap_l; /* left wrap position */ 227 | int wrap_w; /* wrap width (hint about position) */ 228 | int wrap_maxw; /* highest xpos used */ 229 | } a_img; 230 | 231 | 232 | enum e_type { e_num, e_var, e_op }; 233 | 234 | #define e_type_str(e) ((e) == e_num ? "num" : \ 235 | ((e) == e_var ? "var" : ((e) == e_op ? "op" : "???"))) 236 | 237 | 238 | typedef struct _a_expr { 239 | enum e_type type; /* eg: e_num or e_op */ 240 | int op; /* operator: eg.: '+' or '!' */ 241 | struct _a_expr *arg1, *arg2; 242 | long num; 243 | char *var; 244 | } a_expr; 245 | 246 | 247 | enum n_type { n_nop, n_block, n_assign, n_print, n_printn, n_prints, 248 | n_if, n_while }; 249 | 250 | #define n_type_str(t) ((t) == n_assign ? "assign" : \ 251 | ((t) == n_nop ? "nop" : ((t) == n_block ? "block" : \ 252 | ((t) == n_print ? "print" : \ 253 | ((t) == n_prints ? "prints" : \ 254 | ((t) == n_printn ? "printn" : \ 255 | ((t) == n_if ? "if" : \ 256 | ((t) == n_while ? "while" : "???")))))))) 257 | 258 | 259 | typedef struct _a_node { 260 | 261 | enum n_type type; /* eg: n_nop or n_assign */ 262 | char *var; /* identifier of an assignment */ 263 | struct _a_expr *arg1; /* expr of an if / assignment */ 264 | struct _a_node *stmt1; /* then / while node */ 265 | struct _a_node *stmt2; /* else node */ 266 | struct _a_block *block; /* block statement */ 267 | char *str; /* string */ 268 | 269 | struct _a_node *next; 270 | } a_node; 271 | 272 | /* current node we are parsing: */ 273 | a_node *cur_node = 0; 274 | 275 | /* 276 | * variables in use: 277 | */ 278 | typedef struct _a_decl { 279 | char *var; /* variable name */ 280 | int off; /* internal offset */ 281 | struct _a_block *block; 282 | struct _a_decl *next; 283 | } a_decl; 284 | 285 | 286 | /* 287 | * block hierarchie: 288 | */ 289 | typedef struct _a_block { 290 | a_decl *decl; 291 | int d_off; /* decl stack offsets */ 292 | a_node *node; 293 | struct _a_block *parent; 294 | a_img *img; 295 | } a_block; 296 | 297 | /* the program itself: */ 298 | a_block *root_block = 0; 299 | a_img *root_img = 0; 300 | 301 | /* block in progress: */ 302 | a_block *curr_block = 0; 303 | 304 | 305 | /* 306 | * free zone list: 307 | */ 308 | typedef struct _a_fx { 309 | int x; 310 | int y1, y2; 311 | struct _a_fx *next; 312 | } a_fx; 313 | 314 | a_fx *all_fx = 0; 315 | 316 | 317 | /* just for nicer error handling (not very accurate...): */ 318 | int lineno = 0; 319 | 320 | /* current stack depth in use (variables and expressions); */ 321 | int s_depth = 0; 322 | 323 | /* 324 | * helper: 325 | */ 326 | #define i_max(x, y) ((x) > (y) ? (x) : (y)) 327 | #define i_abs(x) ((x) < 0 ? -(x) : (x)) 328 | 329 | 330 | /* 331 | * helper: 332 | */ 333 | char * 334 | xstrdup (char *s1, char *s2) 335 | { 336 | char *s = calloc ((s1 ? strlen (s1) : 0) + (s2 ? strlen (s2) : 0) + 1, 1); 337 | if (s1) { 338 | strcat (s, s1); 339 | } 340 | if (s2) { 341 | strcat (s, s2); 342 | } 343 | return s; 344 | } 345 | 346 | /* 347 | * select new color by action (hue, light): 348 | */ 349 | #define adv_col(c, h, l) (((((c) % 6) + (h)) % 6) \ 350 | + (6 * ((((c) / 6) + (l)) % 3))) 351 | 352 | static struct c_color { 353 | int col; /* rgb color */ 354 | char *l_name; /* long color name */ 355 | char *s_name; /* short color name */ 356 | int c_idx; /* our internal color index */ 357 | } c_colors [] = { 358 | 359 | { 0xFFC0C0, "light red", "lR", 0 }, 360 | { 0xFFFFC0, "light yellow", "lY", 1 }, 361 | { 0xC0FFC0, "light green", "lG", 2 }, 362 | { 0xC0FFFF, "light cyan", "lC", 3 }, 363 | { 0xC0C0FF, "light blue", "lB", 4 }, 364 | { 0xFFC0FF, "light magenta", "lM", 5 }, 365 | 366 | { 0xFF0000, "red", "nR", 6 }, 367 | { 0xFFFF00, "yellow", "nY", 7 }, 368 | { 0x00FF00, "green", "nG", 8 }, 369 | { 0x00FFFF, "cyan", "nC", 9 }, 370 | { 0x0000FF, "blue", "nB", 10 }, 371 | { 0xFF00FF, "magenta", "nM", 11 }, 372 | 373 | { 0xC00000, "dark red", "dR", 12 }, 374 | { 0xC0C000, "dark yellow", "dY", 13 }, 375 | { 0x00C000, "dark green", "dG", 14 }, 376 | { 0x00C0C0, "dark cyan", "dC", 15 }, 377 | { 0x0000C0, "dark blue", "dB", 16 }, 378 | { 0xC000C0, "dark magenta", "dM", 17 }, 379 | 380 | { 0xFFFFFF, "white", "WW", 18 }, 381 | { 0x000000, "black", "BB", 19 } 382 | }; 383 | 384 | 385 | /* 386 | * choose 6 == red as default start color or a random value: 387 | */ 388 | int startup_color () 389 | { 390 | if (random_color == 0) { 391 | return 6; /* red */ 392 | } else { 393 | /* choose something between 6 (red) and 11 (margenta): */ 394 | return 6 + (rand () % 4); 395 | } 396 | } 397 | 398 | 399 | 400 | void 401 | img_resize (a_img *img, int w, int h) 402 | { 403 | gdImagePtr old_im = img->im; 404 | 405 | gd_create_img (img, w, h); 406 | gdImageCopy (img->im, old_im, 0, 0, 0, 0, w, h); 407 | gdImageDestroy (old_im); 408 | } 409 | 410 | 411 | void 412 | set_pixel (a_img *img, int x, int y, int col) 413 | { 414 | if (x > img->w - 1 || y > img->h - 1) { 415 | 416 | int n_w = i_max (x + 1, img->w); 417 | int n_h = i_max (y + 1, img->h); 418 | 419 | img_resize (img, n_w, n_h); 420 | } 421 | 422 | if (img->y > 0 && get_pixel (img, img->x, img->y - 1) == img->col) { 423 | /* could be ok: */ 424 | dprintf ("* set_pixel possible color clash at %d, %d\n", x, y); 425 | } 426 | 427 | if (check_fx (x, x, y)) { 428 | /* could be ok: */ 429 | dprintf ("* set_pixel possible fx clash at %d, %d\n", x, y); 430 | have_warning++; 431 | } 432 | 433 | gdImageSetPixel (img->im, x, y, img->gdcol [col]); 434 | } 435 | 436 | 437 | int 438 | get_pixel (a_img *img, int x, int y) 439 | { 440 | int col = gdImageGetPixel (img->im, x, y); 441 | col = gdcol2idx (img, col); 442 | return col; 443 | } 444 | 445 | 446 | 447 | int 448 | gdcol2idx (a_img *img, int col) 449 | { 450 | int i; 451 | 452 | for (i = 0; i < 20; i++) { 453 | if (img->gdcol [i] == col) { 454 | return i; 455 | } 456 | } 457 | 458 | return 18; /* default background */ 459 | } 460 | 461 | 462 | void 463 | gd_create_img (a_img *img, int w, int h) 464 | { 465 | int i; 466 | 467 | /* create initial image: */ 468 | img->im = gdImageCreate (w, h); 469 | 470 | img->w = w; 471 | img->h = h; 472 | 473 | /* background color: */ 474 | gdImageColorAllocate (img->im, 255, 255, 255); 475 | 476 | for (i = 0; i < 20; i++) { 477 | int r = c_colors [i].col >> 16; 478 | int g = (c_colors [i].col >> 8) & 0xff; 479 | int b = c_colors [i].col & 0xff; 480 | img->gdcol [i] = gdImageColorAllocate (img->im, r, g, b); 481 | } 482 | 483 | return; 484 | } 485 | 486 | 487 | void 488 | img_init (a_img **imgp) 489 | { 490 | a_img *img = calloc (1, sizeof (a_img)); 491 | 492 | /* save pointer: */ 493 | *imgp = img; 494 | 495 | img->w = 1; 496 | img->h = 1; 497 | 498 | gd_create_img (img, img->w, img->h); 499 | 500 | /* start image with default: */ 501 | img->dx = 1; 502 | img->wrap_l = img->wrap_maxw = 0; 503 | img->wrap_w = wrap_wm; 504 | 505 | /* initial pixel: */ 506 | img->col = startup_color (); /* random or red */ 507 | img->x = 0; 508 | img->y = 0; 509 | 510 | set_pixel (img, img->x, img->y, img->col); 511 | } 512 | 513 | 514 | void 515 | img_delete (a_img *img) 516 | { 517 | gdImageDestroy (img->im); 518 | free (img); 519 | } 520 | 521 | 522 | 523 | void 524 | save_img (a_img *img) 525 | { 526 | FILE *out; 527 | 528 | if (! (out = fopen (ofname, "wb"))) { 529 | perror ("cannot open for writing; reason"); 530 | } else { 531 | 532 | if (codel_size > 1) { 533 | /* 534 | * resize first: 535 | */ 536 | gdImagePtr im = gdImageCreate (img->w * codel_size, img->h * codel_size); 537 | 538 | gdImageCopyResized (im, img->im, 539 | 0, 0, 540 | 0, 0, 541 | img->w * codel_size, img->h * codel_size, 542 | img->w, img->h); 543 | 544 | gdImagePng (im, out); 545 | } else { 546 | gdImagePng (img->im, out); 547 | } 548 | fclose (out); 549 | if (! quiet) { 550 | fprintf (stderr, "output saved to %s\n", ofname); 551 | } 552 | } 553 | } 554 | 555 | 556 | /* 557 | * add a vertical space as a left border; 558 | */ 559 | a_fx * 560 | add_free_x (int x, int y1, int y2) 561 | { 562 | a_fx *n = calloc (1, sizeof (a_fx)); 563 | 564 | n->x = x; 565 | n->y1 = y1; 566 | n->y2 = (y2 == -1) ? INT_MAX : y2; 567 | 568 | dprintf ("* adding free x=%d (%d <= y <= %d)\n", n->x, n->y1, n->y2); 569 | 570 | n->next = all_fx; 571 | all_fx = n; 572 | 573 | return n; 574 | } 575 | 576 | 577 | int 578 | check_fx (int x1, int x2, int y) 579 | { 580 | a_fx *fx = all_fx; 581 | 582 | while (fx) { 583 | if (y >= fx->y1 && y <= fx->y2 584 | && x1 >= fx->x && x2 <= fx->x) { 585 | return 1; 586 | } 587 | fx = fx->next; 588 | } 589 | return 0; 590 | } 591 | 592 | 593 | int 594 | fx_wrap_l (int x, int y) 595 | { 596 | a_fx *fx = all_fx; 597 | int l = 0; 598 | 599 | while (fx) { 600 | if (x >= fx->x && y >= fx->y1 && y <= fx->y2) { 601 | l = i_max (l, fx->x); 602 | } 603 | fx = fx->next; 604 | } 605 | return l; 606 | } 607 | 608 | 609 | 610 | /* 611 | * alloc a node element: 612 | */ 613 | a_node * 614 | new_node (enum n_type type) 615 | { 616 | a_node *n = calloc (1, sizeof (a_node)); 617 | n->type = type; 618 | n->block = curr_block; 619 | return n; 620 | } 621 | 622 | 623 | 624 | /* 625 | * alloc a element:xpr 626 | */ 627 | a_expr * 628 | new_expr (enum e_type type) 629 | { 630 | a_expr *n = calloc (1, sizeof (a_expr)); 631 | n->type = type; 632 | return n; 633 | } 634 | 635 | 636 | void 637 | dump_expr (a_expr *expr) 638 | { 639 | if (! expr) { 640 | return; 641 | } 642 | 643 | printf (" "); 644 | if (expr->type == e_num) { 645 | printf ("%ld", expr->num); 646 | } else if (expr->type == e_var) { 647 | printf ("%s", expr->var); 648 | } else if (expr->type == e_op) { 649 | printf ("("); 650 | dump_expr (expr->arg1); 651 | printf (" %c", expr->op); 652 | dump_expr (expr->arg2); 653 | printf (" )"); 654 | } else { 655 | printf ("??? (type %s) ", e_type_str (expr->type)); 656 | } 657 | } 658 | 659 | 660 | 661 | /* 662 | * dump a decl list 663 | * 664 | * (dont care about mem leaks...) 665 | */ 666 | void 667 | dump_decls (char *off, a_decl *decl) 668 | { 669 | if (! decl) { 670 | return; 671 | } 672 | 673 | dprintf ("%s decl: %s off: %d (block 0x%08lx)\n", off, decl->var, 674 | decl->off, (unsigned long) decl->block); 675 | 676 | dump_decls (off, decl->next); 677 | } 678 | 679 | 680 | /* 681 | * dump a node list 682 | * 683 | * (dont care about mem leaks...) 684 | */ 685 | void 686 | dump_nodes (char *off, a_node *node) 687 | { 688 | if (node) { 689 | printf ("%s node: %s\n", off, n_type_str (node->type)); 690 | 691 | if (node->type == n_assign) { 692 | printf ("%s %s := ", off, node->var); 693 | dump_expr (node->arg1); 694 | printf ("\n"); 695 | } else if (node->type == n_prints) { 696 | printf ("%s str %s\n", off, node->str); 697 | } else if (node->type == n_printn) { 698 | printf ("%s ", off); 699 | dump_expr (node->arg1); 700 | printf ("\n"); 701 | } else if (node->type == n_while) { 702 | printf ("%s ", off); 703 | dump_expr (node->arg1); 704 | printf ("\n"); 705 | dump_nodes (off, node->stmt1); 706 | } else if (node->type == n_if) { 707 | printf ("%s if ", off); 708 | dump_expr (node->arg1); 709 | printf ("\n%s then\n", off); 710 | dump_nodes (xstrdup (off, " "), node->stmt1); 711 | if (node->stmt2) { 712 | printf ("%s else\n", off); 713 | dump_nodes (xstrdup (off, " "), node->stmt2); 714 | } 715 | } else if (node->type == n_block) { 716 | dump_blocks (xstrdup (off, " "), node->block); 717 | } else { 718 | printf ("???\n"); 719 | } 720 | 721 | dump_nodes (off, node->next); 722 | 723 | } 724 | } 725 | 726 | 727 | /* 728 | * dump the blocks tree 729 | * 730 | * (dont care about mem leaks...) 731 | */ 732 | void 733 | dump_blocks (char *off, a_block *block) 734 | { 735 | if (block) { 736 | printf ("%s block: 0x%08lx\n", off, (unsigned long) block); 737 | 738 | dump_decls (off, block->decl); 739 | dump_nodes (off, block->node); 740 | } 741 | } 742 | 743 | 744 | void 745 | gen_cmd_nowrap (a_img *img, int h, int l) 746 | { 747 | int c1, cc = adv_col (img->col, h, l); 748 | 749 | if (img->y > 0 && get_pixel (img, img->x + img->dx, img->y - 1) == cc) { 750 | /* color clash - set new mark and look about valid colors: */ 751 | img->x += 2 * img->dx; 752 | c1 = startup_color (); /* start cycle with random or red */ 753 | cc = adv_col (c1, h, l); 754 | 755 | while (get_pixel (img, img->x, img->y - 1) == c1 756 | || get_pixel (img, img->x + img->dx, img->y - 1) == cc) { 757 | c1 = (c1 + 1) % 18; 758 | cc = adv_col (c1, h, l); 759 | } 760 | img->col = c1; 761 | set_pixel (img, img->x, img->y, c1); 762 | } 763 | 764 | img->x += img->dx; 765 | img->col = adv_col (img->col, h, l); 766 | set_pixel (img, img->x, img->y, img->col); 767 | } 768 | 769 | 770 | /* 771 | * generate a command by the given hue and light. 772 | * 773 | * for now, put the command along the command chain. 774 | */ 775 | void 776 | gen_cmd (a_img *img, int h, int l) 777 | { 778 | gen_img_check_wrap (img); 779 | gen_cmd_nowrap (img, h, l); 780 | } 781 | 782 | 783 | /* 784 | * place a codel right here, but check about color above: 785 | */ 786 | void 787 | gen_codel (a_img *img, int col) 788 | { 789 | if (col == -1) { 790 | /* choose a color not matching the codel above: */ 791 | img->col = startup_color (); /* choose random or red */ 792 | while (img->y > 0 && get_pixel (img, img->x, img->y - 1) == img->col) { 793 | img->col++; 794 | } 795 | } else { 796 | img->col = col; 797 | if (img->y > 0 && get_pixel (img, img->x, img->y - 1) == col) { 798 | fprintf (stderr, "oops - gen_mark color clash with %d at (%d, %d)...\n", 799 | img->x, img->y , col); 800 | } 801 | } 802 | set_pixel (img, img->x, img->y, img->col); 803 | } 804 | 805 | 806 | /* 807 | * advance and create codel as a new code generation start: 808 | */ 809 | void 810 | gen_mark (a_img *img, int col) 811 | { 812 | img->x += 2 * img->dx; 813 | gen_codel (img, col); 814 | } 815 | 816 | 817 | void 818 | gen_wrap_right (a_img *img, int expand_flag) 819 | { 820 | if (img->dx > 0) { 821 | fprintf (stderr, "oops - internal error in gen_wrap_right: dx = %d\n", 822 | img->dx); 823 | } 824 | 825 | if (expand_flag) { 826 | /* expand to leftmost turn: */ 827 | while (img->dx < 0 && img->x > img->wrap_l + 4) { 828 | gen_mark (img, -1); 829 | gen_img_check_wrap (img); 830 | } 831 | if (img->dx > 0) { 832 | return; 833 | } 834 | } 835 | 836 | /* 837 | * we need minimum 6 codels and 8 if we need a new mark. 838 | * and as a worst case it will simply not work due to color clash. 839 | * xxx fix me: check harder 840 | */ 841 | gen_img_push_pos (img, 3, 0); 842 | gen_cmd_nowrap (img, 4, 0); /* dup */ 843 | gen_cmd_nowrap (img, 3, 1); /* pointer */ 844 | img->col = adv_col (img->col, 3, 1); /* pointer */ 845 | img->y++; 846 | set_pixel (img, img->x, img->y, img->col); 847 | img->wrap_maxw = i_max (img->wrap_maxw, img->x); 848 | img->dx = 1; 849 | } 850 | 851 | 852 | void 853 | gen_wrap_left (a_img *img) 854 | { 855 | if (img->dx < 0) { 856 | fprintf (stderr, "oops - internal error in gen_wrap_left: dx = %d\n", 857 | img->dx); 858 | } 859 | 860 | dprintf ("* wrapping to left at %d, %d wrap_l = %d\n", 861 | img->x, img->y, img->wrap_l); 862 | 863 | /* paint some wrap stuff: */ 864 | gen_img_push_pos (img, 1, 0); 865 | gen_cmd_nowrap (img, 4, 0); /* dup */ 866 | gen_cmd_nowrap (img, 3, 1); /* pointer */ 867 | img->col = adv_col (img->col, 3, 1); /* pointer */ 868 | img->y++; 869 | set_pixel (img, img->x, img->y, img->col); 870 | 871 | img->wrap_maxw = i_max (img->wrap_maxw, img->x); 872 | 873 | img->dx = -1; 874 | } 875 | 876 | 877 | void 878 | gen_img_check_wrap (a_img *img) 879 | { 880 | if (img->wrap_w < 8) { 881 | /* ignore: */ 882 | return; 883 | } 884 | 885 | /* yyy: */ 886 | img->wrap_l = fx_wrap_l (img->x, img->y) + 1; 887 | 888 | if (img->dx > 0 && img->x > img->wrap_l + img->wrap_w) { 889 | 890 | gen_wrap_left (img); 891 | 892 | } else if (img->dx < 0 && img->x < img->wrap_l + 11) { 893 | 894 | /* 895 | * in one case img->wrap_l + 10 was too low. gen_marks may 896 | * increase need for space to the left... 897 | */ 898 | 899 | dprintf ("deb: * do wrap: wrap_l = %d, x = %d\n", img->wrap_l, img->x); 900 | 901 | gen_wrap_right (img, 0); 902 | } 903 | } 904 | 905 | 906 | int 907 | col_clash (a_img *img, int val) 908 | { 909 | int i; 910 | 911 | for (i = 0; i < val; i++) { 912 | int x = img->x + (img->dx * i); 913 | 914 | if (get_pixel (img, x, img->y - 1) == img->col) { 915 | return 1; 916 | } 917 | } 918 | return 0; 919 | } 920 | 921 | 922 | /* 923 | * generate a push of the given positive number. 924 | * on entry we assume a single codel present and 925 | * expand this to the desired value if not equal 0. 926 | * for a 0 we create a push of 1 followed by a not. 927 | * optional we can force not to wrap. 928 | */ 929 | void 930 | gen_img_push_pos (a_img *img, long val, int w_flag) 931 | { 932 | int i; 933 | 934 | if (val < 0) { 935 | fprintf (stderr, "oops - internal error: unexpected negative value\n"); 936 | abort (); 937 | exit (-1); 938 | } 939 | 940 | if (val == 0) { 941 | if (w_flag) { 942 | gen_cmd (img, 0, 1); /* push 1 */ 943 | gen_cmd (img, 2, 2); /* not */ 944 | } else { 945 | gen_cmd_nowrap (img, 0, 1); /* push 1 */ 946 | gen_cmd_nowrap (img, 2, 2); /* not */ 947 | } 948 | /* we are done: */ 949 | return; 950 | } 951 | 952 | if (w_flag && img->dx < 0 && img->x - val <= img->wrap_l + 8) { 953 | /* 954 | * not enough space to put the push plus a wrap and some spare pixel 955 | * in. so we fill the space with noop's and head the other way: 956 | */ 957 | while (img->dx < 0 && img->x > 0) { 958 | 959 | d2printf ("* ----- fill at %d, %d (wrap_l=%d)\n", img->x, img->y, 960 | img->wrap_l); 961 | 962 | gen_mark (img, -1); 963 | gen_img_check_wrap (img); 964 | } 965 | } 966 | 967 | if (img->y > 0) { 968 | 969 | int xx = img->x + img->dx * val; 970 | int cc = adv_col (img->col, 0, 1); /* push */ 971 | int have_mark = 0; 972 | 973 | while (col_clash (img, val) || get_pixel (img, xx, img->y - 1) == cc) { 974 | 975 | d2printf ("* -- cc fill at %d, %d val=%ld (wrap_l=%d)\n", 976 | img->x, img->y, val, img->wrap_l); 977 | 978 | if (! have_mark) { 979 | gen_mark (img, -1); 980 | have_mark = 1; 981 | xx = img->x + img->dx * val; 982 | } else { 983 | /* try next color in cycle: */ 984 | img->col = (img->col + 1) % 18; 985 | } 986 | cc = adv_col (img->col, 0, 1); /* push */ 987 | } 988 | } 989 | 990 | /* the color block: */ 991 | for (i = 0; i < val; i++) { 992 | int xx = img->x + (img->dx * i); 993 | set_pixel (img, xx, img->y, img->col); 994 | } 995 | 996 | /* the push itself: */ 997 | img->x += img->dx * val; 998 | img->col = adv_col (img->col, 0, 1); 999 | 1000 | set_pixel (img, img->x, img->y, img->col); 1001 | } 1002 | 1003 | 1004 | 1005 | /* 1006 | * generate a push of zero minus the given number 1007 | */ 1008 | void 1009 | gen_img_push_neg (a_img *img, long val) 1010 | { 1011 | gen_cmd (img, 0, 1); /* push 1 */ 1012 | gen_cmd (img, 2, 2); /* not */ 1013 | gen_img_push_pos (img, val, 1); 1014 | gen_cmd (img, 1, 1); /* sub */ 1015 | } 1016 | 1017 | 1018 | 1019 | void 1020 | gen_img_push (a_img *img, long val) 1021 | { 1022 | if (val < 0) { 1023 | gen_img_push_neg (img, -1 * val); 1024 | } else { 1025 | gen_img_push_pos (img, val, 1); 1026 | } 1027 | } 1028 | 1029 | 1030 | 1031 | void 1032 | gen_img_push_smart (a_img *img, long val) 1033 | { 1034 | /* check if a wrap should be done: */ 1035 | gen_img_check_wrap (img); 1036 | 1037 | if (i_abs (val) <= smart_base) { 1038 | /* 1039 | * for now just use a straight line to the right: 1040 | */ 1041 | gen_img_push (img, val); 1042 | } else { 1043 | /* 1044 | * try to calculate the value in a smart way: 1045 | */ 1046 | if (val < 0) { 1047 | gen_img_push (img, -1); 1048 | gen_img_push_smart (img, i_abs (val)); 1049 | gen_cmd (img, 1, 2); /* mul */ 1050 | } else { 1051 | int ival = val; 1052 | if (ival > 0) { 1053 | gen_img_push_smart (img, ival % smart_base); 1054 | gen_img_push_smart (img, ival / smart_base); 1055 | gen_img_push_smart (img, smart_base); 1056 | gen_cmd (img, 1, 2); /* mul */ 1057 | gen_cmd (img, 1, 0); /* add */ 1058 | } 1059 | } 1060 | } 1061 | } 1062 | 1063 | 1064 | 1065 | void 1066 | gen_img_program_end (a_img *img) 1067 | { 1068 | if (img->dx < 0) { 1069 | gen_wrap_right (img, 0); 1070 | } 1071 | 1072 | gen_mark (img, -1); 1073 | 1074 | set_pixel (img, img->x + (img->dx * 1), img->y, 19); 1075 | set_pixel (img, img->x + (img->dx * 1), img->y + 1, 6); 1076 | set_pixel (img, img->x, img->y + 2, 6); 1077 | set_pixel (img, img->x + (img->dx * 1), img->y + 2, 6); 1078 | /* just in case: add always black blocks: */ 1079 | set_pixel (img, img->x + (img->dx * 2), img->y + 1, 19); 1080 | set_pixel (img, img->x + (img->dx * 2), img->y + 2, 19); 1081 | set_pixel (img, img->x - (img->dx * 1), img->y + 2, 19); 1082 | set_pixel (img, img->x, img->y + 3, 19); 1083 | set_pixel (img, img->x + (img->dx * 1), img->y + 3, 19); 1084 | } 1085 | 1086 | 1087 | 1088 | void 1089 | gen_expr (a_img *img, a_block *p_block, a_expr *expr, int *y_max) 1090 | { 1091 | int l_y_max = *y_max = img->y; 1092 | 1093 | if (! expr) { 1094 | return; 1095 | } 1096 | 1097 | if (expr->type == e_num) { 1098 | 1099 | dprintf (" push %ld (s_depth now %d)\n", expr->num, s_depth + 1); 1100 | 1101 | gen_img_push_smart (img, expr->num); 1102 | s_depth += 1; 1103 | 1104 | } else if (expr->type == e_var) { 1105 | 1106 | int s_off = s_depth; 1107 | a_decl *d = find_decl (expr->var, p_block); 1108 | if (! d) { 1109 | fprintf (stderr, "internal error: var %s not found ?\n", expr->var); 1110 | } 1111 | dprintf (" push var %s (d_off %d, s_off %d)\n", 1112 | expr->var, d->off, s_off); 1113 | 1114 | /* 1115 | * create a copy of the variables value: 1116 | * 1117 | * roll up, dup and roll down again (if on top, dup only) 1118 | */ 1119 | if (1 && s_off - d->off > 0) { 1120 | gen_img_push_smart (img, s_off - d->off); 1121 | gen_img_push_smart (img, -1); 1122 | gen_cmd (img, 4, 1); /* roll */ 1123 | } 1124 | gen_cmd (img, 4, 0); /* dup */ 1125 | if (1 && s_off - d->off > 0) { 1126 | gen_img_push_smart (img, s_off - d->off + 1); 1127 | gen_img_push_smart (img, 1); 1128 | gen_cmd (img, 4, 1); /* roll */ 1129 | } 1130 | 1131 | s_depth += 1; 1132 | 1133 | } else if (expr->type == e_op) { 1134 | gen_expr (img, p_block, expr->arg1, &l_y_max); 1135 | if (expr->op != '!') { 1136 | gen_expr (img, p_block, expr->arg2, &l_y_max); 1137 | } 1138 | dprintf (" op: %c\n", expr->op); 1139 | 1140 | if (expr->op == '+') { gen_cmd (img, 1, 0); } 1141 | else if (expr->op == '-') { gen_cmd (img, 1, 1); } 1142 | else if (expr->op == '*') { gen_cmd (img, 1, 2); } 1143 | else if (expr->op == '/') { gen_cmd (img, 2, 0); } 1144 | else if (expr->op == '%') { gen_cmd (img, 2, 1); } 1145 | else if (expr->op == '!') { gen_cmd (img, 2, 2); } 1146 | else if (expr->op == '>') { gen_cmd (img, 3, 0); } 1147 | else if (expr->op == '=') { 1148 | gen_cmd (img, 1, 1); /* sub */ 1149 | gen_cmd (img, 2, 2); /* not */ 1150 | } else if (expr->op == '#') { 1151 | gen_cmd (img, 1, 1); /* sub */ 1152 | } else { fprintf (stderr, "error: unknown op `%c'\n", expr->op); } 1153 | 1154 | if (expr->op != '!') { 1155 | s_depth -= 1; 1156 | } 1157 | 1158 | } else { 1159 | printf (" ??? (fix me) \n"); 1160 | } 1161 | 1162 | *y_max = i_max (l_y_max, img->y); 1163 | } 1164 | 1165 | 1166 | 1167 | void 1168 | deb_dump_img (a_img *img) 1169 | { 1170 | int i, j; 1171 | 1172 | printf ("deb: dump image (w = %d, h = %d, x = %d, y= %d, col = %d):\n", 1173 | img->w, img->h, img->x, img->y, img->col); 1174 | 1175 | printf ("----\n"); 1176 | for (j = 0; j < img->h; j++) { 1177 | for (i = 0; i < img->w; i++) { 1178 | int col = get_pixel (img, i, j); 1179 | printf (" %2d", col); 1180 | } 1181 | printf ("\n"); 1182 | } 1183 | printf ("----\n"); 1184 | } 1185 | 1186 | 1187 | 1188 | void 1189 | gen_nodes (a_img *img, a_block *p_block, a_node *node, int *y_max) 1190 | { 1191 | int l_y_max = *y_max = img->y; 1192 | 1193 | if (! node) { 1194 | return; 1195 | } 1196 | 1197 | dprintf ("gen node: %s (s_depth = %d)\n", n_type_str (node->type), 1198 | s_depth); 1199 | 1200 | if (node->type == n_assign) { 1201 | 1202 | int s_off = s_depth; 1203 | a_decl *d = find_decl (node->var, node->block); 1204 | if (!d ) { 1205 | fprintf (stderr, "internal error: var %s not found ?\n", node->var); 1206 | } 1207 | 1208 | gen_expr (img, p_block, node->arg1, &l_y_max); 1209 | dprintf ("assign %s (d_off %d, s_off %d)\n", node->var, d->off, s_off); 1210 | 1211 | /* 1212 | * move the value to the variables place on the stack: 1213 | * 1214 | * roll old value up, discard and roll down new value 1215 | */ 1216 | 1217 | gen_img_push_smart (img, s_off - d->off + 1); 1218 | gen_img_push_smart (img, -1); 1219 | gen_cmd (img, 4, 1); /* roll */ 1220 | gen_cmd (img, 0, 2); /* pop */ 1221 | gen_img_push_smart (img, s_off - d->off); 1222 | gen_img_push_smart (img, 1); 1223 | gen_cmd (img, 4, 1); /* roll */ 1224 | 1225 | s_depth -= 1; 1226 | 1227 | } else if (node->type == n_print) { 1228 | 1229 | gen_img_push_smart (img, 10); /* linefeed */ 1230 | gen_cmd (img, 5, 2); /* outchar */ 1231 | 1232 | } else if (node->type == n_prints) { 1233 | int i; 1234 | 1235 | for (i = 0; i < (int) strlen (node->str); i++) { 1236 | gen_img_push_smart (img, node->str [i]); 1237 | gen_cmd (img, 5, 2); /* outchar */ 1238 | } 1239 | 1240 | } else if (node->type == n_printn) { 1241 | 1242 | gen_expr (img, p_block, node->arg1, &l_y_max); 1243 | 1244 | gen_cmd (img, 5, 1); /* outnum */ 1245 | s_depth -= 1; 1246 | 1247 | } else if (node->type == n_block) { 1248 | 1249 | /* 1250 | * pass the same image: 1251 | */ 1252 | gen_block (node->block, img, &l_y_max); 1253 | 1254 | } else if (node->type == n_while) { 1255 | 1256 | int c, j; 1257 | int b_x, b_y, b_col; /* branch */ 1258 | int e_x, e_y; /* expr */ 1259 | int w_l_y_max = 0; 1260 | a_fx *fx; 1261 | 1262 | dprintf ("while start:\n"); 1263 | 1264 | l_y_max = img->y; 1265 | 1266 | /* lets start left to right: */ 1267 | if (img->dx < 0) { 1268 | gen_wrap_right (img, 1); 1269 | } 1270 | 1271 | /* start of expr: */ 1272 | gen_mark (img, -1); 1273 | /* return to expr: */ 1274 | c = adv_col (img->col, 3, 2); /* pointer reverse */ 1275 | set_pixel (img, img->x, img->y + 1, c); 1276 | 1277 | /* save pos; here we return from the end of the loop: */ 1278 | e_x = img->x; 1279 | e_y = img->y; 1280 | 1281 | fx = add_free_x (e_x, e_y, -1); 1282 | 1283 | img->wrap_maxw = img->x; 1284 | 1285 | /* push turn left into the while body: */ 1286 | gen_img_push (img, 3); /* pointer arg */ 1287 | s_depth += 1; 1288 | 1289 | /* condition: */ 1290 | gen_expr (img, p_block, node->arg1, &w_l_y_max); 1291 | 1292 | /* XXX */ 1293 | img->wrap_maxw = i_max (img->wrap_maxw, img->x); 1294 | 1295 | /* lets again start left to right: */ 1296 | if (img->dx < 0) { 1297 | gen_wrap_right (img, 1); 1298 | w_l_y_max = i_max (w_l_y_max, img->y); 1299 | } 1300 | 1301 | l_y_max = i_max (w_l_y_max, l_y_max); 1302 | 1303 | /* check: */ 1304 | gen_cmd_nowrap (img, 2, 2); /* not */ 1305 | gen_cmd_nowrap (img, 2, 2); /* not */ 1306 | gen_cmd_nowrap (img, 3, 1); /* pointer */ 1307 | s_depth -= 1; 1308 | 1309 | dprintf ("* while condition done; x=%d, y=%d\n", img->x, img->y); 1310 | 1311 | /* save pos; here we decide to execute the loop-body or if we are done: */ 1312 | b_x = img->x; 1313 | b_y = img->y; 1314 | b_col = img->col; 1315 | 1316 | dprintf ("deb: * wrap_l = %d\n", img->wrap_l); 1317 | 1318 | /* false path (loop exit): */ 1319 | gen_cmd_nowrap (img, 0, 2); /* pop */ 1320 | 1321 | /* and a usefull (useless ?) mark: */ 1322 | gen_mark (img, -1); 1323 | 1324 | /* set start point for while body branch: */ 1325 | b_col = adv_col (b_col, 3, 1); /* pointer */ 1326 | set_pixel (img, b_x, b_y + 1, b_col); 1327 | set_pixel (img, b_x, b_y + 2, b_col); 1328 | set_pixel (img, b_x + 1, b_y + 1, 19); 1329 | 1330 | img->x = b_x + 2; 1331 | img->y = b_y + 2; 1332 | /* 1333 | * v1.3 experimental random_color selection may fail here (at least 1334 | * withe the 99-bottels.foo test - nomen est omen ;-) 1335 | */ 1336 | #if 0 1337 | img->col = startup_color (); 1338 | #else 1339 | img->col = 6; 1340 | #endif 1341 | set_pixel (img, img->x, img->y, img->col); 1342 | 1343 | s_depth -= 1; 1344 | 1345 | /* two turns right to reenter the loop: */ 1346 | gen_img_push (img, 1); 1347 | gen_cmd (img, 4, 0); /* dup */ 1348 | s_depth += 2; 1349 | 1350 | /* create while-body statements: */ 1351 | gen_nodes (img, p_block, node->stmt1, &w_l_y_max); 1352 | 1353 | if (img->dx > 0) { 1354 | gen_wrap_left (img); 1355 | w_l_y_max = i_max (w_l_y_max, img->y); 1356 | } 1357 | 1358 | dprintf ("* w wrapw: %d (x = %d) w_l_y_max = %d (y = %d) " 1359 | "l_y_max = %d\n", 1360 | img->wrap_maxw, img->x, w_l_y_max, img->y, l_y_max); 1361 | 1362 | l_y_max = i_max (l_y_max, w_l_y_max); 1363 | 1364 | /* XXX */ 1365 | img->wrap_maxw = i_max (img->wrap_maxw, img->x); 1366 | 1367 | /* return to expression condition: */ 1368 | if (img->y <= w_l_y_max) { 1369 | for (j = img->y + 1; j <= w_l_y_max + 1; j++) { 1370 | set_pixel (img, img->x, j, img->col); 1371 | } 1372 | img->y = j - 1; 1373 | set_pixel (img, img->x - 1, img->y, img->col); 1374 | l_y_max = i_max (l_y_max, img->y); 1375 | } 1376 | 1377 | /* turn up and turn to pointer into the loop: */ 1378 | img->x = e_x; 1379 | gen_codel (img, -1); 1380 | c = adv_col (img->col, 3, 2); /* pointer reverse */ 1381 | set_pixel (img, img->x + 1, img->y, c); 1382 | 1383 | if (img->y == e_y + 1) { 1384 | printf ("internal: oops - possible color clash in while... = fix me\n"); 1385 | } 1386 | s_depth -= 2; 1387 | 1388 | /* adjust: */ 1389 | fx->y2 = img->y; 1390 | 1391 | /* add: */ 1392 | add_free_x (img->wrap_maxw + 1, e_y, img->y); 1393 | 1394 | /* end of while statement: */ 1395 | img->x = b_x + 2; 1396 | img->y = b_y; 1397 | img->dx = 1; 1398 | 1399 | /* where to continue with: */ 1400 | img->x = i_max (b_x + 2, img->wrap_maxw + 1); 1401 | gen_mark (img, -1); 1402 | 1403 | l_y_max = i_max (l_y_max, img->y); 1404 | 1405 | dprintf ("while end. (l_y_max = %d)\n", l_y_max); 1406 | 1407 | } else if (node->type == n_if) { 1408 | 1409 | int j; 1410 | int b_x, b_y, b_col; /* branch */ 1411 | int fi_y; /* final else pos */ 1412 | int el_x, el_y, el_max_y; /* else x y pos, max y */ 1413 | int old_wrap_l = img->wrap_l; 1414 | int if_l_y_max = 0; 1415 | a_fx *fx; 1416 | 1417 | dprintf ("if start: at %d, %d\n", img->x, img->y); 1418 | 1419 | l_y_max = img->y; 1420 | 1421 | if (img->dx < 0) { 1422 | gen_wrap_right (img, 1); 1423 | } 1424 | img->wrap_maxw = img->x; 1425 | 1426 | gen_img_push (img, 3); /* pointer argument */ 1427 | s_depth += 1; 1428 | 1429 | /* branch condition: */ 1430 | gen_expr (img, p_block, node->arg1, &if_l_y_max); 1431 | 1432 | l_y_max = i_max (l_y_max, if_l_y_max); 1433 | 1434 | /* lets again start left to right: */ 1435 | if (img->dx < 0) { 1436 | gen_wrap_right (img, 1); 1437 | l_y_max = i_max (l_y_max, img->y); 1438 | } 1439 | 1440 | /* branch: (first normalize with not's)*/ 1441 | gen_cmd_nowrap (img, 2, 2); /* not */ 1442 | gen_cmd_nowrap (img, 2, 2); /* not */ 1443 | gen_cmd_nowrap (img, 3, 1); /* pointer */ 1444 | s_depth -= 1; 1445 | 1446 | dprintf ("* if condition done; x=%d, y=%d\n", img->x, img->y); 1447 | 1448 | /* save pos for then branch: */ 1449 | b_x = img->x; 1450 | b_y = img->y; 1451 | b_col = img->col; 1452 | 1453 | /* init else path: */ 1454 | gen_cmd_nowrap (img, 0, 2); /* pop */ 1455 | s_depth -= 1; 1456 | 1457 | gen_mark (img, -1); 1458 | 1459 | /* 1460 | * if we have a else path, create this one first: 1461 | */ 1462 | if (node->stmt2) { 1463 | int o_maxw = img->wrap_maxw; 1464 | 1465 | img->wrap_maxw = img->x; 1466 | 1467 | /* left border: */ 1468 | fx = add_free_x (img->x, img->y, -1); 1469 | 1470 | gen_nodes (img, p_block, node->stmt2, &if_l_y_max); 1471 | 1472 | if (img->dx < 0) { 1473 | gen_wrap_right (img, 0); 1474 | if_l_y_max = i_max (if_l_y_max, img->y); 1475 | } 1476 | 1477 | l_y_max = i_max (l_y_max, if_l_y_max); 1478 | 1479 | /* adjust: */ 1480 | fx->y2 = img->y; 1481 | img->wrap_maxw = i_max (o_maxw, img->wrap_maxw); 1482 | 1483 | el_x = i_max (img->x, img->wrap_maxw); 1484 | el_y = img->y; 1485 | el_max_y = if_l_y_max; 1486 | 1487 | dprintf ("* else end: el_x = %d, el_y = %d\n", el_x, el_y); 1488 | 1489 | } else { 1490 | el_x = img->x; 1491 | el_max_y = el_y = img->y; 1492 | } 1493 | 1494 | fi_y = img->y; 1495 | 1496 | /* 1497 | * find start point for then branch: 1498 | */ 1499 | b_col = adv_col (b_col, 3, 1); /* pointer */ 1500 | dprintf ("** b_y %d, el_y %d el_max_y %d (el_x = %d)\n", 1501 | b_y, el_y, el_max_y, el_x); 1502 | for (j = b_y + 1; j < el_max_y + 3; j++) { 1503 | set_pixel (img, b_x, j, b_col); 1504 | if ( j < el_y + 2) { 1505 | set_pixel (img, b_x + 1, j, 19); 1506 | } 1507 | } 1508 | 1509 | img->x = b_x; 1510 | img->y = j - 1; 1511 | gen_mark (img, -1); 1512 | 1513 | gen_nodes (img, p_block, node->stmt1, &if_l_y_max); 1514 | 1515 | if (img->dx < 0) { 1516 | gen_wrap_right (img, 0); 1517 | } 1518 | if_l_y_max = i_max (if_l_y_max, img->y); 1519 | 1520 | dprintf ("* if wrapw: %d (x = %d) if_l_y_max = %d (y = %d) " 1521 | "l_y_max = %d\n", 1522 | img->wrap_maxw, img->x, if_l_y_max, img->y, l_y_max); 1523 | 1524 | l_y_max = i_max (l_y_max, if_l_y_max); 1525 | 1526 | /* return to end of the else path: */ 1527 | 1528 | img->x = i_max (img->x, img->wrap_maxw); 1529 | img->x = i_max (img->x, el_x); 1530 | 1531 | dprintf ("** see x %d (el_x %d)\n", img->x, el_x); 1532 | 1533 | /* at least a single mark is needed: */ 1534 | gen_mark (img, -1); 1535 | 1536 | while (img->x <= el_x) { 1537 | gen_mark (img, -1); 1538 | } 1539 | 1540 | add_free_x (img->x + 1, el_y, img->y); 1541 | 1542 | if (el_y > 0) { 1543 | while (get_pixel (img, img->x, el_y - 1) == img->col 1544 | || get_pixel (img, img->x + 1, el_y - 1) == img->col) { 1545 | img->col = (img->col + 1) % 18; 1546 | } 1547 | } 1548 | 1549 | for (j = img->y; j >= el_y; j--) { 1550 | img->y = j; 1551 | set_pixel (img, img->x, img->y, img->col); 1552 | } 1553 | 1554 | img->x++; 1555 | set_pixel (img, img->x, img->y, img->col); 1556 | 1557 | img->y = fi_y; 1558 | 1559 | /* xxx */ 1560 | gen_mark (img, -1); 1561 | 1562 | img->wrap_l = old_wrap_l; 1563 | img->wrap_maxw = i_max (old_wrap_l, img->wrap_maxw); 1564 | 1565 | dprintf ("if end.\n"); 1566 | 1567 | } else { 1568 | 1569 | fprintf (stderr, "internal error: gen %s (fix me)\n", 1570 | n_type_str (node->type)); 1571 | } 1572 | 1573 | *y_max = i_max (l_y_max, img->y); 1574 | 1575 | /* next statement in this block: */ 1576 | gen_nodes (img, p_block, node->next, &l_y_max); 1577 | 1578 | *y_max = i_max (l_y_max, *y_max); 1579 | } 1580 | 1581 | 1582 | /* 1583 | * head along the node tree and put funny color pixel into 1584 | * a picture: 1585 | */ 1586 | a_img * 1587 | gen_block (a_block *block, a_img *img, int *y_max) 1588 | { 1589 | a_decl *decl; 1590 | int pre_depth, l_y_max = 998; 1591 | 1592 | if (! block) { 1593 | *y_max = img ? img->y : 0; 1594 | return 0; 1595 | } 1596 | 1597 | dprintf ("gen block: 0x%08lx\n", (unsigned long) block); 1598 | 1599 | if (! img) { 1600 | img_init (&img); 1601 | } 1602 | 1603 | /* save stack depth: */ 1604 | pre_depth = s_depth; 1605 | 1606 | /* create variable space: */ 1607 | for (decl = block->decl; decl; decl = decl->next) { 1608 | /* for every declared variable put a 0 on the stack: */ 1609 | if (pre_depth == s_depth) { 1610 | gen_img_push_smart (img, 0); 1611 | } else { 1612 | gen_cmd (img, 4, 0); /* dup */ 1613 | } 1614 | s_depth++; 1615 | } 1616 | 1617 | gen_nodes (img, block, block->node, &l_y_max); 1618 | 1619 | /* remove variable space: */ 1620 | for (decl = block->decl; decl; decl = decl->next) { 1621 | gen_cmd (img, 0, 2); /* pop */ 1622 | s_depth--; 1623 | } 1624 | 1625 | /* restore stack depth: */ 1626 | if (s_depth != pre_depth) { 1627 | fprintf (stderr, "*** gen block oops - depth %d != %d\n", 1628 | s_depth, pre_depth); 1629 | s_depth = pre_depth; 1630 | } 1631 | 1632 | *y_max = i_max (l_y_max, img->y); 1633 | 1634 | return img; 1635 | } 1636 | 1637 | 1638 | 1639 | a_img * 1640 | gen_root_img (a_block *root_block) 1641 | { 1642 | int l_y_max = 997; 1643 | 1644 | return gen_block (root_block, 0, &l_y_max); 1645 | } 1646 | 1647 | 1648 | 1649 | a_expr * 1650 | new_biop_expr (enum e_type type, a_expr *e1, int op, a_expr *e2) 1651 | { 1652 | a_expr *n = new_expr (type); 1653 | n->op = op; 1654 | n->arg1 = e1; 1655 | n->arg2 = e2; 1656 | return n; 1657 | } 1658 | 1659 | 1660 | 1661 | void 1662 | new_decl (char *var, a_block *block) 1663 | { 1664 | a_decl *n = calloc (1, sizeof (a_decl)); 1665 | n->var = strdup (var); 1666 | n->block = block; 1667 | 1668 | /* decl offset: */ 1669 | n->off = block->d_off++; 1670 | 1671 | /* chain in: */ 1672 | n->next = block->decl; 1673 | block->decl = n; 1674 | } 1675 | 1676 | 1677 | /* 1678 | * lookup decl in current scope up to top: 1679 | */ 1680 | a_decl * 1681 | find_decl (char *var, a_block *block) 1682 | { 1683 | a_block *b = block; 1684 | 1685 | while (b) { 1686 | a_decl *d = b->decl; 1687 | 1688 | while (d) { 1689 | if (! strcmp (d->var, var)) { 1690 | return d; 1691 | } 1692 | d = d->next; 1693 | } 1694 | b = b->parent; 1695 | } 1696 | 1697 | return 0; 1698 | } 1699 | 1700 | 1701 | a_node * 1702 | new_if_stmt (a_expr *expr, a_node *node1, a_node *node2) 1703 | { 1704 | a_node *n = new_node (n_if); 1705 | n->arg1 = expr; 1706 | n->stmt1 = node1; 1707 | n->stmt2 = node2; 1708 | return n; 1709 | } 1710 | 1711 | 1712 | 1713 | %} 1714 | 1715 | /* 1716 | * grammer start: 1717 | */ 1718 | 1719 | %start foogol 1720 | 1721 | %union { 1722 | long num; 1723 | char *str; 1724 | a_expr *expr; 1725 | a_node *node; 1726 | a_block *block; 1727 | } 1728 | 1729 | %token TBEGIN TEND TINTEGER TPRINTS TPRINTN TPRINT 1730 | %token TIF TTHEN TELSE TWHILE TDO 1731 | 1732 | %token NUM 1733 | %token STR QSTR 1734 | 1735 | %type identifier 1736 | %type block program foogol begin 1737 | 1738 | %type expr 1739 | %type stmt_list stmt op_stmt cl_stmt simple_stmt 1740 | %type assign_stmt io_stmt 1741 | 1742 | %left '=' '#' 1743 | %left '>' '<' 1744 | %left '+' '-' 1745 | %left '*' '/' 1746 | %left UNARY 1747 | 1748 | %% 1749 | 1750 | foogol 1751 | : /* empty */ 1752 | { yyerror ("no vaild input found"); } 1753 | | program 1754 | { root_block = $1; } 1755 | ; 1756 | 1757 | 1758 | identifier 1759 | : STR 1760 | { $$ = $1; } 1761 | ; 1762 | 1763 | 1764 | /* expressions : */ 1765 | 1766 | expr 1767 | : NUM 1768 | { $$ = new_expr (e_num); $$->num = $1; } 1769 | | identifier 1770 | { 1771 | $$ = new_expr (e_var); 1772 | if (! find_decl ($1, curr_block)) { 1773 | yyerror ("unknown identifier"); 1774 | have_error = 1; 1775 | } 1776 | $$->var = $1; 1777 | } 1778 | | '(' expr ')' 1779 | { $$ = $2; } 1780 | | '+' expr %prec UNARY 1781 | { $$ = $2; } 1782 | | '-' expr %prec UNARY 1783 | { 1784 | a_expr *e = new_expr (e_num); 1785 | e->num = 0; 1786 | $$ = new_biop_expr (e_op, e, '-', $2); 1787 | } 1788 | | expr '*' expr 1789 | { $$ = new_biop_expr (e_op, $1, '*', $3); } 1790 | | expr '/' expr 1791 | { $$ = new_biop_expr (e_op, $1, '/', $3); } 1792 | | expr '+' expr 1793 | { $$ = new_biop_expr (e_op, $1, '+', $3); } 1794 | | expr '-' expr 1795 | { $$ = new_biop_expr (e_op, $1, '-', $3); } 1796 | | '!' expr %prec UNARY 1797 | { $$ = new_biop_expr (e_op, $2, '!', 0); } 1798 | | expr '>' expr 1799 | { $$ = new_biop_expr (e_op, $1, '>', $3); } 1800 | | expr '<' expr 1801 | { $$ = new_biop_expr (e_op, $3, '>', $1); } 1802 | | expr '=' expr 1803 | { $$ = new_biop_expr (e_op, $1, '=', $3); } 1804 | | expr '#' expr 1805 | { $$ = new_biop_expr (e_op, $1, '#', $3); } 1806 | ; 1807 | 1808 | 1809 | 1810 | /* compound statements and blocks : */ 1811 | 1812 | program 1813 | : block 1814 | { $$ = $1; } 1815 | ; 1816 | 1817 | begin 1818 | : TBEGIN 1819 | { 1820 | a_block *n = calloc (1, sizeof (a_block)); 1821 | n->parent = curr_block; 1822 | /* initialize offset with currect offset: */ 1823 | d2printf ("** curr_block 0x%08lx off %d\n", 1824 | (unsigned long) curr_block, 1825 | curr_block ? curr_block->d_off : 0); 1826 | n->d_off = curr_block ? curr_block->d_off : 0; 1827 | curr_block = n; 1828 | $$ = curr_block; 1829 | } 1830 | ; 1831 | 1832 | end 1833 | : TEND 1834 | { curr_block = curr_block->parent; } 1835 | ; 1836 | 1837 | block 1838 | : begin decl ';' stmt_list 1839 | { 1840 | curr_block->node = $4; 1841 | $$ = curr_block; 1842 | } 1843 | end 1844 | | begin stmt_list 1845 | { 1846 | curr_block->node = $2; 1847 | $$ = curr_block; 1848 | } 1849 | end 1850 | ; 1851 | 1852 | 1853 | decl 1854 | : TINTEGER id_seq ; 1855 | 1856 | id_seq 1857 | : identifier ',' id_seq /* right recursion - don't care ... */ 1858 | { new_decl ($1, curr_block); } 1859 | | identifier 1860 | { new_decl ($1, curr_block); } 1861 | ; 1862 | 1863 | 1864 | stmt_list 1865 | : stmt ';' stmt_list /* right recursion - don't care ... */ 1866 | { 1867 | $1->next = $3; 1868 | $$ = $1; 1869 | } 1870 | | stmt 1871 | { $$ = $1; } 1872 | ; 1873 | 1874 | stmt 1875 | : op_stmt 1876 | { $$ = $1; } 1877 | | cl_stmt 1878 | { $$ = $1; } 1879 | ; 1880 | 1881 | op_stmt 1882 | : TIF expr TTHEN stmt 1883 | { $$ = new_if_stmt ($2, $4, 0); } 1884 | | TIF expr TTHEN cl_stmt TELSE op_stmt 1885 | { $$ = new_if_stmt ($2, $4, $6); } 1886 | | TWHILE expr TDO op_stmt 1887 | { 1888 | a_node *n = new_node (n_while); 1889 | n->arg1 = $2; 1890 | n->stmt1 = $4; 1891 | $$ = n; 1892 | } 1893 | ; 1894 | 1895 | cl_stmt 1896 | : simple_stmt 1897 | { $$ = $1; } 1898 | | TIF expr TTHEN cl_stmt TELSE cl_stmt 1899 | { $$ = new_if_stmt ($2, $4, $6); } 1900 | | TWHILE expr TDO cl_stmt 1901 | { 1902 | a_node *n = new_node (n_while); 1903 | n->arg1 = $2; 1904 | n->stmt1 = $4; 1905 | $$ = n; 1906 | } 1907 | ; 1908 | 1909 | simple_stmt 1910 | : io_stmt 1911 | { $$ = $1; } 1912 | | assign_stmt 1913 | { $$ = $1; } 1914 | | block 1915 | { 1916 | a_node *n = new_node (n_block); 1917 | n->block = $1; 1918 | $$ = n; 1919 | } 1920 | ; 1921 | 1922 | io_stmt 1923 | : TPRINT 1924 | { $$ = new_node (n_print); } 1925 | | TPRINTS '(' QSTR ')' 1926 | { 1927 | a_node *n = new_node (n_prints); 1928 | n->str = $3; 1929 | $$ = n; 1930 | } 1931 | | TPRINTN '(' expr ')' 1932 | { 1933 | a_node *n = new_node (n_printn); 1934 | n->arg1 = $3; 1935 | $$ = n; 1936 | } 1937 | ; 1938 | 1939 | assign_stmt 1940 | : identifier ':' '=' expr 1941 | { 1942 | a_node *n = new_node (n_assign); 1943 | n->var = $1; 1944 | if (! find_decl ($1, curr_block)) { 1945 | yyerror ("unknown identifier"); 1946 | have_error = 1; 1947 | } 1948 | n->arg1 = $4; 1949 | $$ = n; 1950 | } 1951 | ; 1952 | 1953 | %% 1954 | 1955 | 1956 | /* 1957 | * lex: 1958 | * 1959 | * return number, string, word, ... 1960 | * skip white. 1961 | */ 1962 | 1963 | #include 1964 | 1965 | int 1966 | yylex () 1967 | { 1968 | int c; 1969 | 1970 | /* skip over whites */ 1971 | while ((c = getc (f_in)) == ' ' || c == '\t' || c == '\n') { 1972 | if (c == '\n') { 1973 | lineno++; 1974 | } 1975 | continue; 1976 | } 1977 | 1978 | /* skip comments: */ 1979 | if (c == '/') { 1980 | int c2 = getc (f_in); 1981 | if (c2 == '*') { 1982 | c2 = 0; 1983 | while ((c = getc (f_in)) != '/' || c2 != '*') { 1984 | if (c == EOF) { 1985 | yyerror ("EOF in comment"); 1986 | exit (1); 1987 | } else if (c == '\n') { 1988 | lineno++; 1989 | } 1990 | c2 = c; 1991 | } 1992 | /* restart: */ 1993 | return yylex (); 1994 | } 1995 | 1996 | /* no comment (tm): */ 1997 | ungetc (c2, f_in); 1998 | } 1999 | 2000 | /* number: */ 2001 | if (isdigit (c)) { 2002 | ungetc (c, f_in); 2003 | if (1 != fscanf (f_in, "%ld", &yylval.num)) { 2004 | yyerror ("cannot scan integer value"); 2005 | } 2006 | return NUM; 2007 | } 2008 | 2009 | /* quoted string: */ 2010 | if (c == '"') { 2011 | char *s = calloc (1, 1); 2012 | while ((c = getc (f_in)) > 0 && c != '"') { 2013 | if (strlen (s) > 0 && s [strlen (s) - 1] == '\\') { 2014 | if (c == 'n') { 2015 | s [strlen (s) - 1] = '\n'; 2016 | } else if (c == 't') { 2017 | s [strlen (s) - 1] = '\t'; 2018 | } else if (c == '"') { 2019 | s [strlen (s) - 1] = '"'; 2020 | } else if (c == '\\') { 2021 | s [strlen (s) - 1] = '\\'; 2022 | } else { 2023 | s [strlen (s) - 1] = c; 2024 | } 2025 | } else { 2026 | s = realloc (s, strlen (s) + 2); 2027 | s [ strlen (s) + 1] = 0; 2028 | s [ strlen (s)] = c; 2029 | } 2030 | } 2031 | yylval.str = s; 2032 | return QSTR; 2033 | } 2034 | 2035 | /* identifier / keyword: */ 2036 | if (isalpha (c)) { 2037 | char *s = calloc (2, 1); 2038 | s [0] = c; 2039 | while (isalnum ((c = getc (f_in)))) { 2040 | s = realloc (s, strlen (s) + 2); 2041 | s [ strlen (s) + 1] = 0; 2042 | s [ strlen (s)] = c; 2043 | } 2044 | if (c != EOF) { 2045 | /* so kid: put it back: */ 2046 | ungetc (c, f_in); 2047 | } 2048 | 2049 | if (! strcmp (s, "begin")) { free (s); return TBEGIN; 2050 | } else if (! strcmp (s, "end")) { free (s); return TEND; 2051 | } else if (! strcmp (s, "integer")) { free (s); return TINTEGER; 2052 | } else if (! strcmp (s, "prints")) { free (s); return TPRINTS; 2053 | } else if (! strcmp (s, "printn")) { free (s); return TPRINTN; 2054 | } else if (! strcmp (s, "print")) { free (s); return TPRINT; 2055 | } else if (! strcmp (s, "if")) { free (s); return TIF; 2056 | } else if (! strcmp (s, "then")) { free (s); return TTHEN; 2057 | } else if (! strcmp (s, "else")) { free (s); return TELSE; 2058 | } else if (! strcmp (s, "while")) { free (s); return TWHILE; 2059 | } else if (! strcmp (s, "do")) { free (s); return TDO; 2060 | } 2061 | 2062 | /* identifier: */ 2063 | yylval.str = s; 2064 | return STR; 2065 | } 2066 | 2067 | /* EOF: */ 2068 | if (c == EOF) { 2069 | return 0; 2070 | } 2071 | 2072 | /* single char: */ 2073 | return c; 2074 | } 2075 | 2076 | 2077 | 2078 | void 2079 | yyerror (char *s) 2080 | { 2081 | printf ("line %d: %s\n", lineno + 1, s); 2082 | } 2083 | 2084 | 2085 | int 2086 | main (int argc, char *argv[]) 2087 | { 2088 | int rc; 2089 | 2090 | if (parse_args (argc, argv) < 0) { 2091 | usage (-1); 2092 | } 2093 | 2094 | /* a input filename is mandatory: */ 2095 | if (! input_filename) { 2096 | usage (-1); 2097 | } else if (! strcmp (input_filename, "-")) { 2098 | vprintf ("info: reading from \n"); 2099 | input_filename = ""; 2100 | f_in = stdin; 2101 | } else if (! (f_in = fopen (input_filename, "r"))) { 2102 | fprintf (stderr, "error: cannot open `%s' for reading...\n", 2103 | input_filename); 2104 | exit (-1); 2105 | } else { 2106 | vprintf ("info: reading from `%s'\n", input_filename); 2107 | } 2108 | 2109 | /* with higher debugging level output parser messages: */ 2110 | if (debug > 1) { 2111 | yydebug = 1; 2112 | } 2113 | 2114 | /* parse input: */ 2115 | rc = yyparse (); 2116 | 2117 | if (rc || have_error) { 2118 | fprintf (stderr, "exiting...\n"); 2119 | exit (-1); 2120 | } 2121 | 2122 | if (debug > 1) { 2123 | dump_blocks ("", root_block); 2124 | } 2125 | 2126 | #if 0 2127 | if (have_warning) { 2128 | fprintf (stderr, "warning: possibly misgenerated code - " 2129 | "may not run correctly.\nwarning: try to increase" 2130 | " the wrap-width (option -w).\n"); 2131 | } 2132 | #endif 2133 | 2134 | /* save painting: */ 2135 | root_img = gen_root_img (root_block); 2136 | gen_img_program_end (root_img); 2137 | save_img (root_img); 2138 | 2139 | return 0; 2140 | } 2141 | 2142 | /* end of foogol-parse.y */ 2143 | --------------------------------------------------------------------------------