From d484f0c4e06f3dcc195ac169d5b9ff6685038720 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Sat, 31 Mar 2007 14:38:06 -0400 Subject: [PATCH] Alex Smith's 0.26 release. Nominal release date April 1st 2007. (This is a retrospective comment.) --- BUGS => BUGS.txt | 11 +- COPYING => COPYING.txt | 0 MANIFEST.txt | 186 +++ Makefile.in | 142 +- NEWS => NEWS.txt | 104 +- README | 150 --- README.txt | 218 +++ cleanick.bat | 14 + cleanick.sh | 19 + config.h.in | 94 -- config.log | 1144 ++++++++++++++++ config.status | 688 ++++++++++ configure.ac | 7 +- configure => configure.sh | 26 +- districk.bat | 9 + districk.sh | 11 + djfix.bat | 17 + djfix.sh | 17 + intercal.el => etc/intercal.el | 4 +- ickspec | 60 + intercal.spec.in => ickspec.in | 0 makeick.bat | 66 + makeick.sh | 71 + pit/tests/pictest.i | 11 + pit/tests/version.4i | 7 + pit/tests/version.doc | 14 + specgen.sh | 49 - abcess.h => src/abcess.h | 36 +- arrgghh.c => src/arrgghh.c | 0 cesspool.c => src/cesspool.c | 35 +- coopt.sh => src/coopt.sh | 0 feh.c => src/dekludge.c | 1657 +---------------------- feh.h => src/feh.h | 10 +- src/feh2.c | 2297 ++++++++++++++++++++++++++++++++ fiddle.c => src/fiddle.c | 124 ++ fiddle.h => src/fiddle.h | 8 +- ick-wrap.c => src/ick-wrap.c | 28 +- src/ick.bat | 8 + ick.h => src/ick.h | 38 +- lexer.l => src/lexer.l | 91 +- lose.c => src/lose.c | 4 +- lose.h => src/lose.h | 21 + numerals.c => src/numerals.c | 2 +- ick.y => src/parser.y | 236 +++- perpetrate.c => src/perpet.c | 564 ++++++-- src/pick1.h | 84 ++ src/pick2.h | 235 ++++ src/pickwrap.c | 46 + sizes.h => src/sizes.h | 0 unravel.c => src/unravel.c | 0 yuk.c => src/yuk.c | 12 +- yuk.h => src/yuk.h | 0 52 files changed, 6431 insertions(+), 2244 deletions(-) rename BUGS => BUGS.txt (87%) rename COPYING => COPYING.txt (100%) create mode 100644 MANIFEST.txt rename NEWS => NEWS.txt (76%) delete mode 100644 README create mode 100644 README.txt create mode 100755 cleanick.bat create mode 100755 cleanick.sh delete mode 100644 config.h.in create mode 100644 config.log create mode 100755 config.status rename configure => configure.sh (99%) create mode 100755 districk.bat create mode 100755 districk.sh create mode 100755 djfix.bat create mode 100755 djfix.sh rename intercal.el => etc/intercal.el (98%) create mode 100644 ickspec rename intercal.spec.in => ickspec.in (100%) create mode 100755 makeick.bat create mode 100755 makeick.sh create mode 100644 pit/tests/pictest.i create mode 100644 pit/tests/version.4i create mode 100644 pit/tests/version.doc delete mode 100755 specgen.sh rename abcess.h => src/abcess.h (86%) rename arrgghh.c => src/arrgghh.c (100%) rename cesspool.c => src/cesspool.c (94%) rename coopt.sh => src/coopt.sh (100%) mode change 100644 => 100755 rename feh.c => src/dekludge.c (61%) rename feh.h => src/feh.h (56%) create mode 100644 src/feh2.c rename fiddle.c => src/fiddle.c (69%) rename fiddle.h => src/fiddle.h (58%) rename ick-wrap.c => src/ick-wrap.c (74%) create mode 100755 src/ick.bat rename ick.h => src/ick.h (82%) rename lexer.l => src/lexer.l (77%) rename lose.c => src/lose.c (96%) rename lose.h => src/lose.h (90%) rename numerals.c => src/numerals.c (99%) rename ick.y => src/parser.y (60%) rename perpetrate.c => src/perpet.c (64%) create mode 100644 src/pick1.h create mode 100644 src/pick2.h create mode 100644 src/pickwrap.c rename sizes.h => src/sizes.h (100%) rename unravel.c => src/unravel.c (100%) rename yuk.c => src/yuk.c (98%) rename yuk.h => src/yuk.h (100%) diff --git a/BUGS b/BUGS.txt similarity index 87% rename from BUGS rename to BUGS.txt index 2524d44..4aabff4 100644 --- a/BUGS +++ b/BUGS.txt @@ -52,12 +52,11 @@ AIS = Alex Smith an infinite loop, because all COMING FROM a statement counts as part of that statement, and all statements are atomic. -5) (AIS) In a multithreaded backtracking program, you can't fork a thread - which has backtrack points in it. The problem is that backtracking past - the fork from one but not both of the new threads would lead to a - situation in which the fork hadn't happened in one possible route from - the fork, but had in the other. This is clearly absurd, even by the - standards of INTERCAL. +5) (AIS) Reverse assignments (those with the expression on the left) + are very unlikely to work in bases other than 2. + +6) (AIS) Most of the features new in 0.26, and many in 0.25, haven't + been documented. (This is partly because I can't get groff to work.) TO DO diff --git a/COPYING b/COPYING.txt similarity index 100% rename from COPYING rename to COPYING.txt diff --git a/MANIFEST.txt b/MANIFEST.txt new file mode 100644 index 0000000..7847e36 --- /dev/null +++ b/MANIFEST.txt @@ -0,0 +1,186 @@ +.: +BUGS.txt +COPYING.txt +MANIFEST.txt +Makefile.in +NEWS.txt +README.txt +bin +cleanick.bat +cleanick.sh +config.log +config.status +configure.ac +configure.sh +districk.bat +districk.sh +djfix.bat +djfix.sh +doc +etc +ickspec +ickspec.in +include +install.sh +lib +makeick.bat +makeick.sh +pit +src +temp + +./bin: + +./doc: +Makefile +READ.ME +THEORY +chip.spec +intercal.mm + +./etc: +intercal.el + +./include: + +./lib: + +./pit: +CATALOG +Makefile +beer.doc +beer.i +blinkers +bubble.doc +bubble.i +change.doc +change.i +delta.fft +fft.doc +fft.i +flonck.doc +flonck.i +glider +gun +hail_mary.3i +hail_mary.doc +icat.i +iching.doc +iching1.i +iching2.i +ins.doc +ins.i +lib +life.doc +life.i +life2.doc +life2.i +pass.i +pi.doc +pi.i +pow.i +primes.doc +primes.i +quine.i +random.doc +random.i +random2.i +rot13.doc +rot13.i +rot13b.doc +rot13b.i +sample.i +sort.i +syslib.i +t_tet +tests +tophat.fft +tpk.doc +tpk.i +yapp.doc +yapp.i + +./pit/lib: +1910.doc +floatlib.doc +floatlib.i +lib2.doc +lib2.i +numio.doc +numio.i +plus.i +syslib-orig.i +syslib.3i +syslib.4i +syslib.5i +syslib.6i +syslib.7i +syslib.doc +syslib.i +syslib3-7.doc + +./pit/tests: +ais1.i +ais2.i +arrtest.doc +arrtest.i +compucome.i +count.3i +count.doc +hello.i +iogerunds.doc +iogerunds.i +knuth.i +limits.3i +limits.i +onceagain.i +permute.doc +permute.i +pictest.i +sink.doc +sink.i +test1.i +test16bit.i +test2.i +testarray.i +testcf.i +testi18n.i +testlib2.i +testonce.i +testops.3i +testops.5i +testsplat.i +version.4i +version.doc + +./src: +abcess.h +arrgghh.c +cesspool.c +coopt.sh +dekludge.c +feh.h +feh2.c +fiddle.c +fiddle.h +ick-wrap.c +ick.bat +ick.h +lexer.l +lose.c +lose.h +numerals.c +parser.y +perpet.c +pick1.h +pick2.h +pickwrap.c +sizes.h +unravel.c +yuk.c +yuk.h + +./temp: +lexer.c +parser.c +parser.h diff --git a/Makefile.in b/Makefile.in index 9a68945..6acd911 100644 --- a/Makefile.in +++ b/Makefile.in @@ -34,10 +34,10 @@ DESTDIR= # If you want to delete or move the distribution files, then you will have to move COPYING # to another directory; otherwise, you can aim this at COPYING. # It's also possible to aim this at a copy of COPYING from another GPL program. -copyloc = ${DESTDIR}${datadir}/COPYING +copyloc = ${DESTDIR}${datadir}/COPYING.txt CC = @CC@ -CFLAGS = @CFLAGS@ -DICKINCLUDEDIR=\"$(incdir)\" -DICKLIBDIR=\"$(datadir)\" -DICKBINDIR=\"$(bindir)\" -DYYDEBUG -DYUKCOPYLOC=\"$(copyloc)\" +CFLAGS = @CFLAGS@ -DICKINCLUDEDIR=\"$(incdir)\" -DICKLIBDIR=\"$(datadir)\" -DICKBINDIR=\"$(bindir)\" -DYYDEBUG -DYUKCOPYLOC=\"$(copyloc)\" -O2 -W -Wall -I./src -I./temp LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXFLAGS= @@ -46,74 +46,103 @@ YACCFLAGS = -d # -t LOADLIBS = @LIBS@ @INTLLIBS@ @LEXLIB@ -CSOURCES = ick.y lexer.l feh.c lose.c fiddle.c perpetrate.c unravel.c -ISOURCES = cesspool.c arrgghh.c ick-wrap.c numerals.c -YSOURCES = yuk.c -HEADERS = ick.h lose.h sizes.h abcess.h fiddle.h feh.h yuk.h +CSOURCES = src/parser.y src/lexer.l src/feh2.c src/dekludge.c src/lose.c src/fiddle.c src/perpet.c src/unravel.c +ISOURCES = src/cesspool.c src/arrgghh.c src/ick-wrap.c src/numerals.c +YSOURCES = src/yuk.c +HEADERS = src/ick.h src/lose.h src/sizes.h src/abcess.h src/fiddle.h src/feh.h src/yuk.h BUILD = Makefile.in Makefile configure.ac configure config.h.in intercal.spec.in intercal.spec install.sh -MISC = intercal.el coopt.sh -DOCS = BUGS COPYING NEWS README +MISC = etc/intercal.el src/coopt.sh +DOCS = BUGS.txt COPYING.txt NEWS.txt README.txt SOURCES = $(CSOURCES) $(ISOURCES) $(YSOURCES) $(HEADERS) $(BUILD) $(MISC) $(DOCS) pit doc -all: ick libick.a libickmt.a libyuk.a +all: bin/ick lib/libick.a lib/libickmt.a lib/libyuk.a ial -copycopy: COPYING +ial: src/fiddle.h src/abcess.h src/lose.h src/yuk.h src/ick-wrap.c src/pickwrap.c src/coopt.sh pit/lib/syslib.i + -cp src/fiddle.h include/fiddle.h + -cp src/abcess.h include/abcess.h + -cp src/lose.h include/lose.h + -cp src/yuk.h include/yuk.h + -cp pit/lib/syslib.i pit/lib/syslib.?i include + -cp src/ick-wrap.c lib/ick-wrap.c + -cp src/pickwrap.c lib/pickwrap.c + -cp src/coopt.sh lib/coopt.sh + +copycopy: COPYING.txt -mkdir $(DESTDIR)$(datadir) - -if cp $(copyloc) /dev/null ; then : ; else cp COPYING $(copyloc) ; fi + -if cp $(copyloc) /dev/null ; then : ; else cp COPYING.txt $(copyloc) ; fi checkcopy: @echo If the following line fails, change \"copyloc\" in your makefile. cp $(copyloc) /dev/null -ick: ick.o lexer.o feh.o lose.o fiddle.o perpetrate.o - $(CC) perpetrate.o ick.o lexer.o feh.o lose.o fiddle.o $(LDFLAGS) -o ick +bin/ick: temp/parser.o temp/lexer.o temp/feh2.o temp/dekludge.o temp/lose.o temp/fiddle.o temp/perpet.o + $(CC) temp/perpet.o temp/ick.o temp/lexer.o temp/feh2.o temp/dekludge.o temp/lose.o temp/fiddle.o $(LDFLAGS) -o bin/ick -y.tab.h ick.c: ick.y ick.h sizes.h feh.h lose.h - $(YACC) -d $(YACCFLAGS) ick.y - mv y.tab.c ick.c +temp/parser.h temp/parser.c: src/parser.y src/ick.h src/sizes.h src/feh.h src/lose.h + $(YACC) -d $(YACCFLAGS) src/parser.y + -rm temp/parser.c + mv y.tab.c temp/parser.c + -rm temp/parser.h + mv y.tab.h temp/parser.h -lexer.c: lexer.l ick.h lose.h - $(LEX) $(LEXFLAGS) lexer.l - mv lex.yy.c lexer.c +temp/lexer.c: src/lexer.l src/ick.h src/lose.h + $(LEX) $(LEXFLAGS) src/lexer.l + -rm temp/lexer.c + mv lex.yy.c temp/lexer.c # Uncomment the following if using a stock lex # LEXLIBS = -ll -lextest: y.tab.h lexer.c ick.h lose.o - $(CC) -DMAIN lexer.c lose.o $(LEXLIBS) -o lextest - -ick.o: ick.c ick.h feh.h lose.h sizes.h -lexer.o: lexer.c y.tab.h ick.h lose.h -feh.o: feh.c feh.h y.tab.h ick.h fiddle.h lose.h sizes.h -perpetrate.o: perpetrate.c y.tab.h ick.h lose.h sizes.h -cesspool.o: cesspool.c numerals.c abcess.h lose.h sizes.h -unravel.o: unravel.c abcess.h lose.h sizes.h -lose.o: lose.h -fiddle.o: fiddle.h sizes.h -yuk.o: checkcopy yuk.h lose.h sizes.h abcess.h - -libick.a: cesspool.o lose.o fiddle.o arrgghh.o - ar cr libick.a cesspool.o lose.o fiddle.o arrgghh.o - -ranlib libick.a - -libickmt.a: cesspool.o unravel.o lose.o fiddle.o arrgghh.o - ar cr libickmt.a cesspool.o unravel.o lose.o fiddle.o arrgghh.o +bin/lextest: temp/parser.h src/lexer.c src/ick.h temp/lose.o + $(CC) -DMAIN src/lexer.c src/lose.o $(LEXLIBS) -o bin/lextest + +temp/parser.o: temp/parser.c src/ick.h src/feh.h src/lose.h src/sizes.h + $(CC) $(CFLAGS) -c -o temp/ick.o temp/parser.c +temp/lexer.o: temp/lexer.c temp/parser.h src/ick.h src/lose.h + $(CC) $(CFLAGS) -c -o temp/lexer.o temp/lexer.c +temp/feh2.o: src/feh2.c src/feh.h temp/parser.h src/ick.h src/fiddle.h src/lose.h src/sizes.h + $(CC) $(CFLAGS) -c -o temp/feh2.o src/feh2.c +temp/dekludge.o: src/dekludge.c src/feh.h temp/parser.h src/ick.h src/fiddle.h src/lose.h src/sizes.h + $(CC) $(CFLAGS) -c -o temp/dekludge.o src/dekludge.c +temp/perpet.o: src/perpet.c temp/parser.h src/ick.h src/lose.h src/sizes.h + $(CC) $(CFLAGS) -c -o temp/perpet.o src/perpet.c +temp/cesspool.o: src/cesspool.c src/abcess.h src/lose.h src/sizes.h + $(CC) $(CFLAGS) -c -o temp/cesspool.o src/cesspool.c +temp/numerals.o: src/numerals.c src/abcess.h src/lose.h src/sizes.h + $(CC) $(CFLAGS) -c -o temp/numerals.o src/numerals.c +temp/unravel.o: src/unravel.c src/abcess.h src/lose.h src/sizes.h + $(CC) $(CFLAGS) -c -o temp/unravel.o src/unravel.c +temp/lose.o: src/lose.c src/lose.h + $(CC) $(CFLAGS) -c -o temp/lose.o src/lose.c +temp/fiddle.o: src/fiddle.c src/fiddle.h src/sizes.h + $(CC) $(CFLAGS) -c -o temp/fiddle.o src/fiddle.c +temp/arrgghh.o: src/arrgghh.c + $(CC) $(CFLAGS) -c -o temp/arrgghh.o src/arrgghh.c +temp/yuk.o: checkcopy src/yuk.h src/lose.h src/sizes.h src/abcess.h + $(CC) $(CFLAGS) -c -o temp/yuk.o src/yuk.c + +lib/libick.a: temp/cesspool.o temp/numerals.o temp/lose.o temp/fiddle.o temp/arrgghh.o + ar cr lib/libick.a temp/cesspool.o temp/numerals.o temp/lose.o temp/fiddle.o temp/arrgghh.o + -ranlib lib/libick.a + +lib/libickmt.a: temp/cesspool.o temp/numerals.o temp/unravel.o temp/lose.o temp/fiddle.o temp/arrgghh.o + ar cr lib/libickmt.a temp/cesspool.o temp/numerals.o temp/unravel.o temp/lose.o temp/fiddle.o temp/arrgghh.o -ranlib libickmt.a -libyuk.a: yuk.o - ar cr libyuk.a yuk.o - -ranlib libyuk.a +lib/libyuk.a: temp/yuk.o + ar cr lib/libyuk.a temp/yuk.o + -ranlib lib/libyuk.a install: copycopy all - cp ick $(DESTDIR)$(bindir) - cp libick.a $(DESTDIR)$(libdir) - cp libickmt.a $(DESTDIR)$(libdir) - cp libyuk.a $(DESTDIR)$(libdir) + cp bin/ick $(DESTDIR)$(bindir) + cp lib/libick.a $(DESTDIR)$(libdir) + cp lib/libickmt.a $(DESTDIR)$(libdir) + cp lib/libyuk.a $(DESTDIR)$(libdir) -mkdir -p $(DESTDIR)$(incdir) - cp lose.h abcess.h fiddle.h yuk.h $(DESTDIR)$(incdir) + cp src/lose.h src/abcess.h src/fiddle.h src/yuk.h $(DESTDIR)$(incdir) -mkdir $(DESTDIR)$(datadir) (cp -r pit $(DESTDIR)$(datadir)) - cp ick-wrap.c $(DESTDIR)$(datadir) - cp coopt.sh $(DESTDIR)$(bindir) + cp src/ick-wrap.c $(DESTDIR)$(datadir) + cp etc/coopt.sh $(DESTDIR)$(bindir) uninstall: rm -f $(DESTDIR)$(bindir)/ick $(DESTDIR)$(libdir)/libick.a @@ -124,15 +153,16 @@ uninstall: TAGS: $(SOURCES) etags $(SOURCES) -dist: intercal-@PACKAGE_VERSION@.tar.gz +dist: ick-@PACKAGE_VERSION@.tgz -intercal-@PACKAGE_VERSION@.tar.gz: $(SOURCES) - @find $(SOURCES) -type f -print | grep -v RCS | sed s:^:intercal-@PACKAGE_VERSION@/: >MANIFEST - @(cd ..; ln -s intercal intercal-@PACKAGE_VERSION@) - (cd ..; tar -czvf intercal/intercal-@PACKAGE_VERSION@.tar.gz `cat intercal/MANIFEST`) - @(cd ..; rm intercal-@PACKAGE_VERSION@) +ick-@PACKAGE_VERSION@.tgz: $(SOURCES) + @find $(SOURCES) -type f -print | grep -v RCS | sed s:^:ick-@PACKAGE_VERSION@/: >MANIFEST.txt + @(cd ..; ln -s intercal ick-@PACKAGE_VERSION@) + (cd ..; tar -czvf intercal/ick-@PACKAGE_VERSION@.tgz `cat intercal/MANIFEST.txt`) + @(cd ..; rm ick-@PACKAGE_VERSION@) clean: - rm -f yacc.* y.tab.* y.output *~ *.[oa] lexer.c ick.c lextest ick - rm -f intercal-@PACKAGE_VERSION@.tar.gz intercal.spec core + rm -f temp/* bin/* lib/* include/* +distr: + rm -f temp/*.o bin/* lib/* include/* diff --git a/NEWS b/NEWS.txt similarity index 76% rename from NEWS rename to NEWS.txt index bcacb53..14c66b3 100644 --- a/NEWS +++ b/NEWS.txt @@ -1,8 +1,102 @@ NEW IN THIS RELEASE - Release ? (by ?) ? + Release 0.26 (by Alex Smith) +   +1. Fixed a few bugs in the previous release (some bugfixed by Joris Huizer). -(All these changes were by AIS) +2. Ported to DJGPP. The compiler now works on both POSIX and DJGPP systems. + +3. Reorganized the directory structure. + +4. Added support for cross-compiling to the PIC microcontroller. + +5. Added a simple test program for PIC cross-compilation. + +6. Improved further searching for skeletons and executables. + +7. Delinted some of the code, and turned up the default gcc warning level. + +8. Reformatted some of the documentation. + +9. Renamed and split files; all files used in the build now have 8.3 + filenames, to prevent any problems using DJGPP on 8.3 systems. The + optimizer was split from the code degeneration into dekludge.c (optimizer) + and feh2.c (degeneration), because feh.c was getting too large. + +10. The text documentation (README, COPYING, NEWS, and BUGS) was renamed to + end .txt (again for DJGPP compatibility); formatting changes were made to + README in addition to the addition of extra readme information. + +11. Included precompiled-to-C versions of the parser and the lexer so that + DJGPP (or I suppose, POSIX if you hacked the makefile) implementations + without bison or flex could still compile the rest of C-INTERCAL and give + a running program. + +12. Fixed a bug involving optimization of Tri-INTERCAL programs. + +13. Added to the lexer, so that it supports CLC-INTERCAL syntax for operators + that were already present in C-INTERCAL, as long as they don't conflict + with C-INTERCAL syntax. (Using the -X switch will support CLC-INTERCAL + syntax for operators that were already present in C-INTERCAL even if they + conflict with C-INTERCAL syntax.) For the symbols present in the + CLC-INTERCAL character set but not in ASCII, ISO-8859-1 is supported as an + encoding as well as UTF-8 (to increase the chance that CLC-INTERCAL + programs will run without modification); it was meant to be supported to + some extent before, but seemed not to be working. + +14. Added the COMMENT gerund, with the same semantics as in CLC-INTERCAL. + +15. Added COME FROM gerund. This suffers from the same restrictions as + computed COME FROM, in that it can't be used in PIC programs and causes + the program to end up substantially less efficient. + +16. Added support for prefix as well as infix unary operators. The rule is + that any number of prefix unary operators, but only one infix unary + operator, is allowed on each group, variable, and/or mesh. (Previously, + only infix operators were supported, and then only one per mesh.) + +17. Added positional precedences to the parser. INTERCAL still doesn't have + operator precedences (that would be completely contrary to the spirit of + INTERCAL) but it now has rules for deciding on the meaning of previously + ambiguous expressions. Chains of select and mingle operations right- + associate, and when a unary operator could legitimately be in either a + prefix or infix position, the infix position is assumed (although remember + that only one infix operator is allowed for each group, variable, and/or + mesh). + +18. Added ¬ as a synonym for NOT. + +19. Added operand overloading, for onespot and twospot variables. This uses + the slat operator in almost, but not quite, the same way as + CLC-INTERCAL. Note that the width of unary operations will mostly depend + on the type a variable appears to have in an expression, rather than on + its actual bitwidth (if a onespot is overloaded to a twospot or vice + versa). Note that meshes won't change as the result of operand overloading + unless the -v option is used (an error will be generated instead). + +20. Added an option for generalised assignments. With the -v option, + expressions (rather than just variables) can appear on the left of an + assignment. Any meshes on the left of an assignment (even if in apparently + inoccuous positions) may change value as a result. (Note that such + assignments aren't always possible.) If the left-hand-side of an + expression is anything other than simply a variable or a constant, the + compiler will try to change the values of meshes and non-ignored variables + in the expression to make it fit. (In bases other than 2, it will nearly + always fail.) Unlike CLC-INTERCAL, assigning to a mesh only changes that + mesh, not line labels or other uses of the number. + +21. Restricted the compiler to just one input file at a time (it used to break + if this wasn't done anyway). + +22. Fixed a nonportability involving stdin and stdout in cesspool.c. + +23. Added support for the NEXT FROM command, with the same semantics as COME + FROM (including computed NEXT FROM and NEXT FROM gerund), except that it + saves the line that was NEXTed FROM on the choicepoint stack. + +24. Fixed a bug where the yuk debugger accessed unallocated memory. + + Release 0.25 (by Alex Smith) 1. Added support for computed ABSTAIN and TRY AGAIN. @@ -48,9 +142,9 @@ possible for multithreading, backtracking, computed ABSTAIN, and computed COME FROM to all be used simultaneously in the same program, to help maximize obfuscation. -11. Added an option (-l) for generating warnings. To prevent this actually being -useful, it is designed to generate far too many warnings, which all have to be -trawled through to find the important ones, and has no way to turn the +11. Added an option (-l) for generating warnings. To prevent this actually +being useful, it is designed to generate far too many warnings, which all have +to be trawled through to find the important ones, and has no way to turn the unimportant ones off. 12. Added the +printflow and +mystery options for executing INTERCAL programs. diff --git a/README b/README deleted file mode 100644 index bc44f1c..0000000 --- a/README +++ /dev/null @@ -1,150 +0,0 @@ - Release Notes for C-INTERCAL - - DISCREDITS - -This package is an implementation of the language INTERCAL designed by Don -Woods and James Lyon, who have since spent more than twenty years trying to -live it down. - -This implementation was created by Eric S. Raymond -during a fit of lunacy from which he has since mostly recovered. It has -been considerably hacked upon and improved by Steve Swales, Michael Ernst, -Louis Howell, Brian Raiter, and others. For detailed credits see NEWS. - - FILES - -The compiler itself is in the src directory. Setting a symbol in the -makefile will allow you to install it and its libraries and support files -in a directory of your choice. The doc directory contains (surprise!) -documentation, and pit contains various examples of INTERCAL source code, -writhing in agony. - -The files included are: - -README -- this file -BUGS -- current bug and to-do list -NEWS -- info on features and fixes new in this release -intercal.el -- elisp for editing INTERCAL code under GNU Emacs - -doc/READ.ME -- historical notes on the docs -doc/intercal.mm -- the manual in groffable form -doc/THEORY -- some notes on the internals of the INTERCAL compiler - -Makefile.in -- makefile for the INTERCAL compiler -lexer.l -- the lexical analyzer specification (in LEX) -ick.y -- the grammar specification (in YACC) -ick.h -- compilation types and defines -perpetrate.c -- main routine for compiler -feh.c -- INTERCAL-to-C code generator -feh.h -- interface to INTERCAL-to-C code generator -fiddle.c -- the INTERCAL operators -lose.[ch] -- INTERCAL compile- and run-time error handling -ick-wrap.c -- the driver for generated C-from-INTERCAL code -arrgghh.c -- option argument parsing for generated programs -abcess.h -- interface to functions linked with programs -cesspool.c -- the INTERCAL runtime support code -numerals.c -- numerals table for INTERCAL input -sizes.h -- variables defining the numeric base -unravel.c -- multithreading functions -yuk.[ch] -- INTERCAL debugger and profiler -coopt.sh -- shell-script to help out the -F optimizer - -pit/* -- sample INTERCAL code; see pit/CATALOG - - HOW TO GET STARTED - -You want a man page? Man pages are for wimps. To compile an INTERCAL -program `foo.i' to executable code, just do - - ick foo.i - -There's a -c option that leaves the generated `foo.c' in place for -inspection (suppressing compilation to machine code), a -d option that -enables verbose parse reporting from the yacc/bison parser, a -t -option that requires strict INTERCAL-72 compliance (rejecting COME -FROM and the extensions for bases other than two), a -b option that -disables the INTERCAL-72 random-bug feature, and an -O option that -enables the (hah!) optimizer (which can be invoked at higher levels -with -Of or -F). Invoking ick -? prints a usage message. The -m -option enables multithreading extensions. If you need to debug code, -you can use -y to invoke the debugger immediately after compilation, --p to invoke the profiler immediately after compilation, or -g to -generate the C code in such a way that it can be debugged with a C -debugger. -h, -H, and -hH generate debugging output from the -optimizer, which is useful if you need to understand an INTERCAL -program, and -l turns on warnings (far too many warnings!). If ick -itself needs debugging, the -U option will cause it to dump core on -E778. Other than that, yer on yer own. - -Another switch affects C-INTERCAL's runtime behavior. The `-C' -option forces output in "clockface" mode, for superstitious users who -believe writing "IV" upside-down offends IVPITER and would rather -see IIII. - -Every INTERCAL runtime also accepts certain options at runtime (code by -Steve Swales). These include [+/-]help, [+/-]traditional, and [+/-]wimpmode. -The help option (with either + or -) triggers a 'usage' message. The -+traditional option is presently a no-op. Also available are [+/-] printflow, -which gives information that may or may not be helpful for debugging a program, -and [+/-] mystery, which is undocumented. Note that these options are not -necessarily available if the program is compiled with -F. - -Steve writes: "The wimpmode option is the most interesting. I found myself -always running my test programs with filters on both ends to work around the -'nifty' INTERCAL number representations. This was so painful that I decided it -would be LESS painful (and a lot less code) if I added a 'wimp' option. With -the +wimpmode option, the user is subjected to a humiliating message about what -a wimp he or she is to use this mode, but after that is allowed to use -conventional numerical notation. While such a mode doubtless violates to some -extent the INTERCAL philosophy, the fact that a 'unbutcher' command has been -posted clearly indicates the need for it. Anyway... if you don't like it, don't -use it... the default is -wimpmode (i.e. NOT wimp mode)." - - SPREADING THE BLAME - -There is an INTERCAL Resource Page at http://www.catb.org/intercal - -The latest version of INTERCAL is also kept available at the -Retrocomputing Museun, http://www.catb.org/retro. - -There is, in addition, an occasionally active USENET newsgroup devoted to the -language: alt.lang.intercal. - - NOTES ON THE LINUX BUILD - -At the top of ick.h are two defines that you may need to remove if you -are using lex instead of flex. - -Many lexes export a yylineno variable, an undocumented feature that is -not in flex (by default). If your build fails because of redecleration -of yylineno, comment out the define of YYLINENO_BY_HAND. - -Some lexes also supply a yyrestart function to begin parsing a second -file, while others automatically restart after seeing an EOF. (This is -the case with flex.) If your build fails at link time because -yyrestart is not defined, comment out the define of USE_YYRESTART. - -If you are using gcc in an non-ANSI environment, such as SunOS, it is -strongly recommended that you add "-Wno-unused -Wimplicit" to the gcc -command in the makefile. If you are in an ANSI environment and are -using the current versions of gcc, flex, and bison, C-INTERCAL should -build with no warnings. - -As the debugger is interactive, it needs to be able to find the GNU GPL. -The Makefile attempts to copy the GPL to /dev/null to prove it exists. If -this fails, you will have to point the Makefile to a copy of the GPL -yourself. You can always copy the one included with this distribution -somewhere safe and use that (what the Makefile will try to do by default). - - LICENSING - -C-INTERCAL is now distributed under the General Public License, -except for the C skeleton file which is explicitly *not* GPLed -in order to avoid the (possibly mythical) "license virus" effect. -See the file COPYING for details on the General Public License. - - APOCALYPSE - -INTERCAL is fully Y2K-compliant. Indeed, it is Y2K-obsequious, and -loves nothing better than to be punished by relays of leather-clad and -spike-heeled calendricists. Bite me and go buy your own shotgun. diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..927ff81 --- /dev/null +++ b/README.txt @@ -0,0 +1,218 @@ + Release Notes for C-INTERCAL + + DISCREDITS + +This package is an implementation of the language INTERCAL designed by Don +Woods and James Lyon, who have since spent more than twenty years trying to +live it down. + +This implementation was created by Eric S. Raymond +during a fit of lunacy from which he has since mostly recovered. It has been +considerably hacked upon and improved by Steve Swales, Michael Ernst, Louis +Howell, Brian Raiter, and others. For detailed credits see NEWS. + + FILES + +The compiler itself is in the src directory. Setting a symbol in the makefile +will allow you to install it and its libraries and support files in a directory +of your choice. The doc directory contains (surprise!) documentation, and pit +contains various examples of INTERCAL source code, writhing in agony. + +The files included are: + +README.txt -- this file +BUGS.txt -- current bug and to-do list +NEWS.txt -- info on features and fixes new in this release +COPYING.txt -- copyright and licence information +MANIFEST.txt -- a list of all files in the distribution + +etc/intercal.el -- elisp for editing INTERCAL code under GNU Emacs + +doc/READ.ME -- historical notes on the docs +doc/intercal.mm -- the manual in groffable form +doc/THEORY -- some notes on the internals of the INTERCAL compiler + +src/lexer.l -- the lexical analyzer specification (in LEX) +src/parser.y -- the grammar specification (in YACC) +src/ick.h -- compilation types and defines +src/perpet.c -- main routine for compiler +src/feh2.c -- INTERCAL-to-C code generator +src/feh2.h -- interface to INTERCAL-to-C code generator +src/dekludge.c -- INTERCAL parse tree optimizer +src/fiddle.c -- the INTERCAL operators +src/lose.[ch] -- INTERCAL compile- and run-time error handling +src/ick-wrap.c -- the driver for generated C-from-INTERCAL code +src/pickwrap.c -- the driver for generated PIC C-from-INTERCAL code +src/arrgghh.c -- option argument parsing for generated programs +src/abcess.h -- interface to functions linked with programs +src/cesspool.c -- the INTERCAL runtime support code +src/numerals.c -- numerals table for INTERCAL input +src/sizes.h -- variables defining the numeric base +src/unravel.c -- multithreading functions +src/yuk.[ch] -- INTERCAL debugger and profiler (POSIX only) +src/pick1.h -- template for compiler-dependent PIC C headers +src/pick2.h -- runtime support for compiled PIC-INTERCAL +src/coopt.sh -- script to help out the -F optimizer (POSIX only) +src/ick.bat -- wrapper around the compiler (DJGPP only) + +temp/parser.[ch] -- Prebuilt parser (for DJGPP systems without bison) +temp/lexer.c -- Prebuilt lexer (for DJGPP systems without flex) + +Makefile.in -- makefile input for the INTERCAL compiler (POSIX) +makeick.bat -- script to compile under DJGPP +districk.bat -- script to remove files not distributed (DJGPP) +cleanick.bat -- script to remove all non-source files (DJGPP) +djfix.bat -- script to remove ^Ms that may have got in by mistake +makeick.sh --\ +districk.sh --|the same as above, but in sh format +cleanick.sh --| +djfix.sh --/ + +configure.sh -- GNU Autoconf script that generates a makefile + from Makefile.in +ickspec.in -- Input to configure.sh +configure.ac -- Source from which configure.sh was generated +install.sh -- Helper file for 'make install' + +bin/* -- Directory that holds binaries after the build +include/* -- Directory that holds header files after the build +lib/* -- Directory that holds library files after the build + +pit/* -- sample INTERCAL code; see pit/CATALOG + + HOW TO GET STARTED + +You want a man page? Man pages are for wimps. To compile an INTERCAL program +`foo.i' to executable code, just do + + ick foo.i + +There's a -c option that leaves the generated `foo.c' in place for inspection +(suppressing compilation to machine code), a -d option that enables verbose +parse reporting from the yacc/bison parser, a -t option that requires strict +INTERCAL-72 compliance (rejecting COME FROM and the extensions for bases other +than two), a -b option that disables the INTERCAL-72 random-bug feature, and an +-O option that enables the (hah!) optimizer (which can be invoked at higher +levels with -Of or -F). Invoking ick -? prints a usage message. The -m +option enables multithreading extensions. If you need to debug code, -g +generates the C code in such a way that it can be debugged with a C +debugger. -h, -H, and -hH generate debugging output from the optimizer, which +is useful if you need to understand an INTERCAL program, and -l turns on +warnings (far too many warnings!). If ick itself needs debugging, the -U option +will cause it to dump core on E778. Other than that, yer on yer own. + +-t has been mentioned above as a compatibility option; -X is also permitted, +and causes the program to treat the ambiguous characters ? and @ as having the +meanings that they have in CLC-INTERCAL rather than their traditional +C-INTERCAL meanings. + +Another switch affects C-INTERCAL's runtime behavior. The `-C' option forces +output in "clockface" mode, for superstitious users who believe writing "IV" +upside-down offends IVPITER and would rather see IIII. + +Every INTERCAL runtime also accepts certain options at runtime (code by Steve +Swales). These include [+/-]help, [+/-]traditional, and [+/-]wimpmode. The +help option (with either + or -) triggers a 'usage' message. The +traditional +option is presently a no-op. Also available are [+/-] printflow, which gives +information that may or may not be helpful for debugging a program, and [+/-] +mystery, which is deliberately undocumented. + +Steve writes: "The wimpmode option is the most interesting. I found myself +always running my test programs with filters on both ends to work around the +'nifty' INTERCAL number representations. This was so painful that I decided it +would be LESS painful (and a lot less code) if I added a 'wimp' option. With +the +wimpmode option, the user is subjected to a humiliating message about what +a wimp he or she is to use this mode, but after that is allowed to use +conventional numerical notation. While such a mode doubtless violates to some +extent the INTERCAL philosophy, the fact that a 'unbutcher' command has been +posted clearly indicates the need for it. Anyway... if you don't like it, don't +use it... the default is -wimpmode (i.e. NOT wimp mode)." + + SPREADING THE BLAME + +There is an INTERCAL Resource Page at http://www.catb.org/intercal + +The latest version of INTERCAL is also kept available at the Retrocomputing +Museun, http://www.catb.org/retro. + +There is, in addition, an occasionally active USENET newsgroup devoted to the +language: alt.lang.intercal. + + NOTES ON THE POSIX BUILD + +At the top of ick.h are two defines that you may need to remove if you are +using lex instead of flex. + +Many lexes export a yylineno variable, an undocumented feature that is not in +flex (by default). If your build fails because of redecleration of yylineno, +comment out the define of YYLINENO_BY_HAND. + +Some lexes also supply a yyrestart function to begin parsing a second file, +while others automatically restart after seeing an EOF. (This is the case with +flex.) If your build fails at link time because yyrestart is not defined, +comment out the define of USE_YYRESTART. + +If you are using gcc in an non-ANSI environment, such as SunOS, it is strongly +recommended that you add "-Wno-unused -Wimplicit" to the gcc command in the +makefile. If you are in an ANSI environment and are using the current versions +of gcc, flex, and bison, C-INTERCAL should build with no warnings. + +As the debugger is interactive, it needs to be able to find the GNU GPL. The +Makefile attempts to copy the GPL to /dev/null to prove it exists. If this +fails, you will have to point the Makefile to a copy of the GPL yourself. You +can always copy the one included with this distribution somewhere safe and use +that (what the Makefile will try to do by default). + + NOTES ON THE DJGPP BUILD + +This distribution needs prebuilding; you can use the makeick.bat or makeick.sh +file provided to compile the program if you can't compile using the usual +POSIX methods via configure and make. Once the implementation has been built, +you can install it by adding the \bin subdirectory to your PATH environment +variable (at either end). The temporary output from bison and flex is included +in the distribution (for those people who don't have bison and flex, makeick +will give error messages, but succeed anyway using the prebuilt versions). The +districk.bat file will remove all generated files that weren't in the +distribution, and the cleanick.bat file will remove all files that aren't +needed for a build (including the temporary bison/flex output). Note that +makeick.bat and makeick.sh produce DJGPP-specific output; and if you're +running DJGPP under bash under Windows XP, you'll need to either set your +default command interpreter for batch files to cmd rather than command.com, or +explicitly invoke the compiler as cmd /c ick rather than just ick. + +Some distributions of DJGPP have a bug where they complain that they can't find +'m4.exe'. You can solve this problem by copying m4.exe into the \temp +subdirectory before running makeick.bat. + +Some features (for instance, -F) are unavailable at the moment under DJGPP +(they are documented, but have no effect). + +Note that for copyright reasons, the compilation needs to know a location of +the GNU GPL on your system. There is one provided as COPYING.txt. You will +need to edit makeick.sh or makeick.bat to change the location given, if the +default (/DJGPP/COPYING) is incorrect. + +You can get a copy of DJGPP at . + + NOTES ON COMPILING PIC-INTERCAL + +PIC C compilers tend to differ substantially in the way they handle various +language constructs. As a result, this compiler will only compile to C (not to +hex or asm) when compiling a PIC-INTERCAL program. There are two header files, +pick1.h and pick2.h in the /src directory; these need to be placed somewhere +your compiler can find them, and pick1.h will need to be modified to contain +compiler-specific data (like the names of data types and the syntax for +specifying the device type, fuses, and various commands). + + LICENSING + +C-INTERCAL is now distributed under the General Public License, except for the +C skeleton file which is explicitly *not* GPLed in order to avoid the (possibly +mythical) "license virus" effect. See the file COPYING.txt for details on the +General Public License. + + APOCALYPSE + +INTERCAL is fully Y2K-compliant. Indeed, it is Y2K-obsequious, and loves +nothing better than to be punished by relays of leather-clad and spike-heeled +calendricists. Bite me and go buy your own shotgun. diff --git a/cleanick.bat b/cleanick.bat new file mode 100755 index 0000000..c5cc758 --- /dev/null +++ b/cleanick.bat @@ -0,0 +1,14 @@ +@echo off +rem This batch file removes all files that aren't needed to recompile. +del /q bin\*.* +del /q lib\*.* +del /q include\*.* +del /q temp\*.h +del /q temp\*.c +del /q temp\*.o +del /q temp\*.a +del /q temp\*.y +del /q temp\*.l +del /q temp\*.bat +del /q temp\*.sh +del /q temp\ickmain.exe diff --git a/cleanick.sh b/cleanick.sh new file mode 100755 index 0000000..2c459fd --- /dev/null +++ b/cleanick.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# make cleanick as a shell-script, for the benefit of DJGPP systems with broken +# versions of make. +# This batch file removes all files that weren't in the distribution. +rm -f bin/*.* +rm -f lib/*.* +rm -f include/*.* +rm -f temp/*.h +rm -f temp/*.c +rm -f temp/*.o +rm -f temp/*.a +rm -f temp/*.y +rm -f temp/*.l +rm -f temp/*.bat +rm -f temp/*.sh +rm -f temp/ickmain.exe +rm -f temp/*~ +rm -f src/*~ +rm -f *~ \ No newline at end of file diff --git a/config.h.in b/config.h.in deleted file mode 100644 index 5551add..0000000 --- a/config.h.in +++ /dev/null @@ -1,94 +0,0 @@ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if your system has a GNU libc compatible `malloc' function, and - to 0 otherwise. */ -#undef HAVE_MALLOC - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* Define to 1 if you have the `memset' function. */ -#undef HAVE_MEMSET - -/* Define to 1 if your system has a GNU libc compatible `realloc' function, - and to 0 otherwise. */ -#undef HAVE_REALLOC - -/* Define to 1 if stdbool.h conforms to C99. */ -#undef HAVE_STDBOOL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDDEF_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the `strrchr' function. */ -#undef HAVE_STRRCHR - -/* Define to 1 if you have the `strtol' function. */ -#undef HAVE_STRTOL - -/* Define to 1 if you have the `strtoul' function. */ -#undef HAVE_STRTOUL - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Define to 1 if the system has the type `_Bool'. */ -#undef HAVE__BOOL - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* Define as the return type of signal handlers (`int' or `void'). */ -#undef RETSIGTYPE - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a - `char[]'. */ -#undef YYTEXT_POINTER - -/* Define to empty if `const' does not conform to ANSI C. */ -#undef const - -/* Define to rpl_malloc if the replacement function should be used. */ -#undef malloc - -/* Define to rpl_realloc if the replacement function should be used. */ -#undef realloc - -/* Define to `unsigned' if does not define. */ -#undef size_t diff --git a/config.log b/config.log new file mode 100644 index 0000000..75ff729 --- /dev/null +++ b/config.log @@ -0,0 +1,1144 @@ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by intercal configure.sh 0.26, which was +generated by GNU Autoconf 2.57. Invocation command line was + + $ configure.sh + +## --------- ## +## Platform. ## +## --------- ## + +hostname = chillingi +uname -m = sun4u +uname -r = 5.9 +uname -s = SunOS +uname -v = Generic_118558-34 + +/usr/bin/uname -p = sparc +/bin/uname -X = System = SunOS +Node = chillingi +Release = 5.9 +KernelID = Generic_118558-34 +Machine = sun4u +BusType = +Serial = +Users = +OEM# = 0 +Origin# = 1 +NumCPU = 2 + +/bin/arch = sun4 +/usr/bin/arch -k = sun4u +/usr/convex/getsysinfo = unknown +hostinfo = unknown +/bin/machine = unknown +/usr/bin/oslevel = unknown +/bin/universe = unknown + +PATH: . +PATH: /home/ais523/bin +PATH: /home/ais523 +PATH: /opt/SUNWspro/bin +PATH: /usr/local/bin +PATH: /usr/sbin +PATH: /usr/ucb +PATH: /usr/bin +PATH: /usr/ccs/bin +PATH: /usr/etc +PATH: /usr/dt/bin +PATH: /usr/openwin/bin +PATH: /apps7/bin +PATH: /apps7/script + + +## ----------- ## +## Core tests. ## +## ----------- ## + +configure.sh:1275: checking for bison +configure.sh:1304: result: no +configure.sh:1275: checking for byacc +configure.sh:1304: result: no +configure.sh:1358: checking for gcc +configure.sh:1374: found /usr/local/bin/gcc +configure.sh:1384: result: gcc +configure.sh:1628: checking for C compiler version +configure.sh:1631: gcc --version &5 +2.95.2 +configure.sh:1634: $? = 0 +configure.sh:1636: gcc -v &5 +Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.7/2.95.2/specs +gcc version 2.95.2 19991024 (release) +configure.sh:1639: $? = 0 +configure.sh:1641: gcc -V &5 +gcc: argument to `-V' is missing +configure.sh:1644: $? = 1 +configure.sh:1668: checking for C compiler default output +configure.sh:1671: gcc conftest.c >&5 +configure.sh:1674: $? = 0 +configure.sh:1720: result: a.out +configure.sh:1725: checking whether the C compiler works +configure.sh:1731: ./a.out +configure.sh:1734: $? = 0 +configure.sh:1751: result: yes +configure.sh:1758: checking whether we are cross compiling +configure.sh:1760: result: no +configure.sh:1763: checking for suffix of executables +configure.sh:1765: gcc -o conftest conftest.c >&5 +configure.sh:1768: $? = 0 +configure.sh:1793: result: +configure.sh:1799: checking for suffix of object files +configure.sh:1821: gcc -c conftest.c >&5 +configure.sh:1824: $? = 0 +configure.sh:1846: result: o +configure.sh:1850: checking whether we are using the GNU C compiler +configure.sh:1875: gcc -c conftest.c >&5 +configure.sh:1878: $? = 0 +configure.sh:1881: test -s conftest.o +configure.sh:1884: $? = 0 +configure.sh:1897: result: yes +configure.sh:1903: checking whether gcc accepts -g +configure.sh:1925: gcc -c -g conftest.c >&5 +configure.sh:1928: $? = 0 +configure.sh:1931: test -s conftest.o +configure.sh:1934: $? = 0 +configure.sh:1945: result: yes +configure.sh:1962: checking for gcc option to accept ANSI C +configure.sh:2023: gcc -c -g -O2 conftest.c >&5 +configure.sh:2026: $? = 0 +configure.sh:2029: test -s conftest.o +configure.sh:2032: $? = 0 +configure.sh:2050: result: none needed +configure.sh:2068: gcc -c -g -O2 conftest.c >&5 +conftest.c:2: parse error before `me' +configure.sh:2071: $? = 1 +configure.sh: failed program was: +| #ifndef __cplusplus +| choke me +| #endif +configure.sh:2185: checking for flex +configure.sh:2214: result: no +configure.sh:2185: checking for lex +configure.sh:2201: found /usr/ccs/bin/lex +configure.sh:2211: result: lex +configure.sh:2224: checking for yywrap in -lfl +configure.sh:2255: gcc -o conftest -g -O2 conftest.c -lfl >&5 +ld: fatal: library -lfl: not found +ld: fatal: File processing errors. No output written to conftest +collect2: ld returned 1 exit status +configure.sh:2258: $? = 1 +configure.sh: failed program was: +| #line 2231 "configure" +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "intercal" +| #define PACKAGE_TARNAME "intercal" +| #define PACKAGE_VERSION "0.26" +| #define PACKAGE_STRING "intercal 0.26" +| #define PACKAGE_BUGREPORT "esr@thyrsus.com" +| /* end confdefs.h. */ +| +| /* Override any gcc2 internal prototype to avoid an error. */ +| #ifdef __cplusplus +| extern "C" +| #endif +| /* We use char because int might match the return type of a gcc2 +| builtin and then its argument prototype would still apply. */ +| char yywrap (); +| int +| main () +| { +| yywrap (); +| ; +| return 0; +| } +configure.sh:2276: result: no +configure.sh:2281: checking for yywrap in -ll +configure.sh:2312: gcc -o conftest -g -O2 conftest.c -ll >&5 +configure.sh:2315: $? = 0 +configure.sh:2318: test -s conftest +configure.sh:2321: $? = 0 +configure.sh:2333: result: yes +configure.sh:2344: checking lex output file root +configure.sh:2355: lex conftest.l +configure.sh:2358: $? = 0 +configure.sh:2370: result: lex.yy +configure.sh:2375: checking whether yytext is a pointer +configure.sh:2391: gcc -o conftest -g -O2 conftest.c -ll >&5 +conftest.c:418: conflicting types for `yytext' +conftest.c:71: previous declaration of `yytext' +configure.sh:2394: $? = 1 +configure.sh: failed program was: +| #include +| #include +| #include +| # define U(x) x +| # define NLSTATE yyprevious=YYNEWLINE +| # define BEGIN yybgin = yysvec + 1 + +| # define INITIAL 0 +| # define YYLERR yysvec +| # define YYSTATE (yyestate-yysvec-1) +| # define YYOPTIM 1 +| # ifndef YYLMAX +| # define YYLMAX BUFSIZ +| # endif +| #ifndef __cplusplus +| # define output(c) (void)putc(c,yyout) +| #else +| # define lex_output(c) (void)putc(c,yyout) +| #endif +| +| #if defined(__cplusplus) || defined(__STDC__) +| +| #if defined(__cplusplus) && defined(__EXTERN_C__) +| extern "C" { +| #endif +| int yyback(int *, int); +| int yyinput(void); +| int yylook(void); +| void yyoutput(int); +| int yyracc(int); +| int yyreject(void); +| void yyunput(int); +| int yylex(void); +| #ifdef YYLEX_E +| void yywoutput(wchar_t); +| wchar_t yywinput(void); +| #endif +| #ifndef yyless +| int yyless(int); +| #endif +| #ifndef yywrap +| int yywrap(void); +| #endif +| #ifdef LEXDEBUG +| void allprint(char); +| void sprint(char *); +| #endif +| #if defined(__cplusplus) && defined(__EXTERN_C__) +| } +| #endif +| +| #ifdef __cplusplus +| extern "C" { +| #endif +| void exit(int); +| #ifdef __cplusplus +| } +| #endif +| +| #endif +| # define unput(c) {yytchar= (c);if(yytchar=='\n')yylineno--;*yysptr++=yytchar;} +| # define yymore() (yymorfg=1) +| #ifndef __cplusplus +| # define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):getc(yyin))==10?(yylineno++,yytchar):yytchar)==EOF?0:yytchar) +| #else +| # define lex_input() (((yytchar=yysptr>yysbuf?U(*--yysptr):getc(yyin))==10?(yylineno++,yytchar):yytchar)==EOF?0:yytchar) +| #endif +| #define ECHO fprintf(yyout, "%s",yytext) +| # define REJECT { nstr = yyreject(); goto yyfussy;} +| int yyleng; +| #define YYISARRAY +| char yytext[YYLMAX]; +| int yymorfg; +| extern char *yysptr, yysbuf[]; +| int yytchar; +| FILE *yyin = {stdin}, *yyout = {stdout}; +| extern int yylineno; +| struct yysvf { +| struct yywork *yystoff; +| struct yysvf *yyother; +| int *yystops;}; +| struct yysvf *yyestate; +| extern struct yysvf yysvec[], *yybgin; +| # define YYNEWLINE 10 +| yylex(){ +| int nstr; extern int yyprevious; +| #ifdef __cplusplus +| /* to avoid CC and lint complaining yyfussy not being used ...*/ +| static int __lex_hack = 0; +| if (__lex_hack) goto yyfussy; +| #endif +| while((nstr = yylook()) >= 0) +| yyfussy: switch(nstr){ +| case 0: +| if(yywrap()) return(0); break; +| case -1: +| break; +| default: +| (void)fprintf(yyout,"bad switch yylook %d",nstr); +| } return(0); } +| /* end of yylex */ +| int yyvstop[] = { +| 0, +| 0}; +| # define YYTYPE unsigned char +| struct yywork { YYTYPE verify, advance; } yycrank[] = { +| 0,0, 0,0, 0,0, 0,0, +| 0,0}; +| struct yysvf yysvec[] = { +| 0, 0, 0, +| yycrank+0, 0, 0, +| yycrank+0, 0, 0, +| 0, 0, 0}; +| struct yywork *yytop = yycrank+0; +| struct yysvf *yybgin = yysvec+1; +| char yymatch[] = { +| 0, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 0}; +| char yyextra[] = { +| 0,0,0,0,0,0,0,0, +| 0}; +| /* Copyright (c) 1989 AT&T */ +| /* All Rights Reserved */ +| +| /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */ +| /* The copyright notice above does not evidence any */ +| /* actual or intended publication of such source code. */ +| +| #pragma ident "@(#)ncform 6.12 97/12/08 SMI" +| +| int yylineno =1; +| # define YYU(x) x +| # define NLSTATE yyprevious=YYNEWLINE +| struct yysvf *yylstate [YYLMAX], **yylsp, **yyolsp; +| char yysbuf[YYLMAX]; +| char *yysptr = yysbuf; +| int *yyfnd; +| extern struct yysvf *yyestate; +| int yyprevious = YYNEWLINE; +| #if defined(__cplusplus) || defined(__STDC__) +| int yylook(void) +| #else +| yylook() +| #endif +| { +| register struct yysvf *yystate, **lsp; +| register struct yywork *yyt; +| struct yysvf *yyz; +| int yych, yyfirst; +| struct yywork *yyr; +| # ifdef LEXDEBUG +| int debug; +| # endif +| char *yylastch; +| /* start off machines */ +| # ifdef LEXDEBUG +| debug = 0; +| # endif +| yyfirst=1; +| if (!yymorfg) +| yylastch = yytext; +| else { +| yymorfg=0; +| yylastch = yytext+yyleng; +| } +| for(;;){ +| lsp = yylstate; +| yyestate = yystate = yybgin; +| if (yyprevious==YYNEWLINE) yystate++; +| for (;;){ +| # ifdef LEXDEBUG +| if(debug)fprintf(yyout,"state %d\n",yystate-yysvec-1); +| # endif +| yyt = yystate->yystoff; +| if(yyt == yycrank && !yyfirst){ /* may not be any transitions */ +| yyz = yystate->yyother; +| if(yyz == 0)break; +| if(yyz->yystoff == yycrank)break; +| } +| #ifndef __cplusplus +| *yylastch++ = yych = input(); +| #else +| *yylastch++ = yych = lex_input(); +| #endif +| #ifdef YYISARRAY +| if(yylastch > &yytext[YYLMAX]) { +| fprintf(yyout,"Input string too long, limit %d\n",YYLMAX); +| exit(1); +| } +| #else +| if (yylastch >= &yytext[ yytextsz ]) { +| int x = yylastch - yytext; +| +| yytextsz += YYTEXTSZINC; +| if (yytext == yy_tbuf) { +| yytext = (char *) malloc(yytextsz); +| memcpy(yytext, yy_tbuf, sizeof (yy_tbuf)); +| } +| else +| yytext = (char *) realloc(yytext, yytextsz); +| if (!yytext) { +| fprintf(yyout, +| "Cannot realloc yytext\n"); +| exit(1); +| } +| yylastch = yytext + x; +| } +| #endif +| yyfirst=0; +| tryagain: +| # ifdef LEXDEBUG +| if(debug){ +| fprintf(yyout,"char "); +| allprint(yych); +| putchar('\n'); +| } +| # endif +| yyr = yyt; +| if ( (uintptr_t)yyt > (uintptr_t)yycrank){ +| yyt = yyr + yych; +| if (yyt <= yytop && yyt->verify+yysvec == yystate){ +| if(yyt->advance+yysvec == YYLERR) /* error transitions */ +| {unput(*--yylastch);break;} +| *lsp++ = yystate = yyt->advance+yysvec; +| if(lsp > &yylstate[YYLMAX]) { +| fprintf(yyout,"Input string too long, limit %d\n",YYLMAX); +| exit(1); +| } +| goto contin; +| } +| } +| # ifdef YYOPTIM +| else if((uintptr_t)yyt < (uintptr_t)yycrank) { /* r < yycrank */ +| yyt = yyr = yycrank+(yycrank-yyt); +| # ifdef LEXDEBUG +| if(debug)fprintf(yyout,"compressed state\n"); +| # endif +| yyt = yyt + yych; +| if(yyt <= yytop && yyt->verify+yysvec == yystate){ +| if(yyt->advance+yysvec == YYLERR) /* error transitions */ +| {unput(*--yylastch);break;} +| *lsp++ = yystate = yyt->advance+yysvec; +| if(lsp > &yylstate[YYLMAX]) { +| fprintf(yyout,"Input string too long, limit %d\n",YYLMAX); +| exit(1); +| } +| goto contin; +| } +| yyt = yyr + YYU(yymatch[yych]); +| # ifdef LEXDEBUG +| if(debug){ +| fprintf(yyout,"try fall back character "); +| allprint(YYU(yymatch[yych])); +| putchar('\n'); +| } +| # endif +| if(yyt <= yytop && yyt->verify+yysvec == yystate){ +| if(yyt->advance+yysvec == YYLERR) /* error transition */ +| {unput(*--yylastch);break;} +| *lsp++ = yystate = yyt->advance+yysvec; +| if(lsp > &yylstate[YYLMAX]) { +| fprintf(yyout,"Input string too long, limit %d\n",YYLMAX); +| exit(1); +| } +| goto contin; +| } +| } +| if ((yystate = yystate->yyother) && (yyt= yystate->yystoff) != yycrank){ +| # ifdef LEXDEBUG +| if(debug)fprintf(yyout,"fall back to state %d\n",yystate-yysvec-1); +| # endif +| goto tryagain; +| } +| # endif +| else +| {unput(*--yylastch);break;} +| contin: +| # ifdef LEXDEBUG +| if(debug){ +| fprintf(yyout,"state %d char ",yystate-yysvec-1); +| allprint(yych); +| putchar('\n'); +| } +| # endif +| ; +| } +| # ifdef LEXDEBUG +| if(debug){ +| fprintf(yyout,"stopped at %d with ",*(lsp-1)-yysvec-1); +| allprint(yych); +| putchar('\n'); +| } +| # endif +| while (lsp-- > yylstate){ +| *yylastch-- = 0; +| if (*lsp != 0 && (yyfnd= (*lsp)->yystops) && *yyfnd > 0){ +| yyolsp = lsp; +| if(yyextra[*yyfnd]){ /* must backup */ +| while(yyback((*lsp)->yystops,-*yyfnd) != 1 && lsp > yylstate){ +| lsp--; +| unput(*yylastch--); +| } +| } +| yyprevious = YYU(*yylastch); +| yylsp = lsp; +| yyleng = yylastch-yytext+1; +| yytext[yyleng] = 0; +| # ifdef LEXDEBUG +| if(debug){ +| fprintf(yyout,"\nmatch "); +| sprint(yytext); +| fprintf(yyout," action %d\n",*yyfnd); +| } +| # endif +| return(*yyfnd++); +| } +| unput(*yylastch); +| } +| if (yytext[0] == 0 /* && feof(yyin) */) +| { +| yysptr=yysbuf; +| return(0); +| } +| #ifndef __cplusplus +| yyprevious = yytext[0] = input(); +| if (yyprevious>0) +| output(yyprevious); +| #else +| yyprevious = yytext[0] = lex_input(); +| if (yyprevious>0) +| lex_output(yyprevious); +| #endif +| yylastch=yytext; +| # ifdef LEXDEBUG +| if(debug)putchar('\n'); +| # endif +| } +| } +| #if defined(__cplusplus) || defined(__STDC__) +| int yyback(int *p, int m) +| #else +| yyback(p, m) +| int *p; +| #endif +| { +| if (p==0) return(0); +| while (*p) { +| if (*p++ == m) +| return(1); +| } +| return(0); +| } +| /* the following are only used in the lex library */ +| #if defined(__cplusplus) || defined(__STDC__) +| int yyinput(void) +| #else +| yyinput() +| #endif +| { +| #ifndef __cplusplus +| return(input()); +| #else +| return(lex_input()); +| #endif +| } +| #if defined(__cplusplus) || defined(__STDC__) +| void yyoutput(int c) +| #else +| yyoutput(c) +| int c; +| #endif +| { +| #ifndef __cplusplus +| output(c); +| #else +| lex_output(c); +| #endif +| } +| #if defined(__cplusplus) || defined(__STDC__) +| void yyunput(int c) +| #else +| yyunput(c) +| int c; +| #endif +| { +| unput(c); +| } +| extern char *yytext; +configure.sh:2413: result: no +configure.sh:2461: checking for a BSD-compatible install +configure.sh:2515: result: ./install.sh -c +configure.sh:2526: checking whether ln -s works +configure.sh:2530: result: yes +configure.sh:2537: checking whether make sets $(MAKE) +configure.sh:2557: result: yes +configure.sh:2575: checking how to run the C preprocessor +configure.sh:2611: gcc -E conftest.c +configure.sh:2617: $? = 0 +configure.sh:2649: gcc -E conftest.c +configure:2648: ac_nonexistent.h: No such file or directory +configure.sh:2655: $? = 1 +configure.sh: failed program was: +| #line 2640 "configure" +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "intercal" +| #define PACKAGE_TARNAME "intercal" +| #define PACKAGE_VERSION "0.26" +| #define PACKAGE_STRING "intercal 0.26" +| #define PACKAGE_BUGREPORT "esr@thyrsus.com" +| /* end confdefs.h. */ +| #include +configure.sh:2693: result: gcc -E +configure.sh:2718: gcc -E conftest.c +configure.sh:2724: $? = 0 +configure.sh:2756: gcc -E conftest.c +configure:2755: ac_nonexistent.h: No such file or directory +configure.sh:2762: $? = 1 +configure.sh: failed program was: +| #line 2747 "configure" +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "intercal" +| #define PACKAGE_TARNAME "intercal" +| #define PACKAGE_VERSION "0.26" +| #define PACKAGE_STRING "intercal 0.26" +| #define PACKAGE_BUGREPORT "esr@thyrsus.com" +| /* end confdefs.h. */ +| #include +configure.sh:2805: checking for egrep +configure.sh:2815: result: egrep +configure.sh:2820: checking for ANSI C header files +configure.sh:2846: gcc -c -g -O2 conftest.c >&5 +configure.sh:2849: $? = 0 +configure.sh:2852: test -s conftest.o +configure.sh:2855: $? = 0 +configure.sh:2944: gcc -o conftest -g -O2 conftest.c >&5 +configure.sh:2947: $? = 0 +configure.sh:2949: ./conftest +configure.sh:2952: $? = 0 +configure.sh:2967: result: yes +configure.sh:2991: checking for sys/types.h +configure.sh:3008: gcc -c -g -O2 conftest.c >&5 +configure.sh:3011: $? = 0 +configure.sh:3014: test -s conftest.o +configure.sh:3017: $? = 0 +configure.sh:3028: result: yes +configure.sh:2991: checking for sys/stat.h +configure.sh:3008: gcc -c -g -O2 conftest.c >&5 +configure.sh:3011: $? = 0 +configure.sh:3014: test -s conftest.o +configure.sh:3017: $? = 0 +configure.sh:3028: result: yes +configure.sh:2991: checking for stdlib.h +configure.sh:3008: gcc -c -g -O2 conftest.c >&5 +configure.sh:3011: $? = 0 +configure.sh:3014: test -s conftest.o +configure.sh:3017: $? = 0 +configure.sh:3028: result: yes +configure.sh:2991: checking for string.h +configure.sh:3008: gcc -c -g -O2 conftest.c >&5 +configure.sh:3011: $? = 0 +configure.sh:3014: test -s conftest.o +configure.sh:3017: $? = 0 +configure.sh:3028: result: yes +configure.sh:2991: checking for memory.h +configure.sh:3008: gcc -c -g -O2 conftest.c >&5 +configure.sh:3011: $? = 0 +configure.sh:3014: test -s conftest.o +configure.sh:3017: $? = 0 +configure.sh:3028: result: yes +configure.sh:2991: checking for strings.h +configure.sh:3008: gcc -c -g -O2 conftest.c >&5 +configure.sh:3011: $? = 0 +configure.sh:3014: test -s conftest.o +configure.sh:3017: $? = 0 +configure.sh:3028: result: yes +configure.sh:2991: checking for inttypes.h +configure.sh:3008: gcc -c -g -O2 conftest.c >&5 +configure.sh:3011: $? = 0 +configure.sh:3014: test -s conftest.o +configure.sh:3017: $? = 0 +configure.sh:3028: result: yes +configure.sh:2991: checking for stdint.h +configure.sh:3008: gcc -c -g -O2 conftest.c >&5 +configure:3047: stdint.h: No such file or directory +configure.sh:3011: $? = 1 +configure.sh: failed program was: +| #line 2996 "configure" +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "intercal" +| #define PACKAGE_TARNAME "intercal" +| #define PACKAGE_VERSION "0.26" +| #define PACKAGE_STRING "intercal 0.26" +| #define PACKAGE_BUGREPORT "esr@thyrsus.com" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| /* end confdefs.h. */ +| #include +| #if HAVE_SYS_TYPES_H +| # include +| #endif +| #if HAVE_SYS_STAT_H +| # include +| #endif +| #if STDC_HEADERS +| # include +| # include +| #else +| # if HAVE_STDLIB_H +| # include +| # endif +| #endif +| #if HAVE_STRING_H +| # if !STDC_HEADERS && HAVE_MEMORY_H +| # include +| # endif +| # include +| #endif +| #if HAVE_STRINGS_H +| # include +| #endif +| #if HAVE_INTTYPES_H +| # include +| #else +| # if HAVE_STDINT_H +| # include +| # endif +| #endif +| #if HAVE_UNISTD_H +| # include +| #endif +| +| #include +configure.sh:3028: result: no +configure.sh:2991: checking for unistd.h +configure.sh:3008: gcc -c -g -O2 conftest.c >&5 +configure.sh:3011: $? = 0 +configure.sh:3014: test -s conftest.o +configure.sh:3017: $? = 0 +configure.sh:3028: result: yes +configure.sh:3049: checking for memory.h +configure.sh:3054: result: yes +configure.sh:3058: checking stddef.h usability +configure.sh:3071: gcc -c -g -O2 conftest.c >&5 +configure.sh:3074: $? = 0 +configure.sh:3077: test -s conftest.o +configure.sh:3080: $? = 0 +configure.sh:3090: result: yes +configure.sh:3094: checking stddef.h presence +configure.sh:3105: gcc -E conftest.c +configure.sh:3111: $? = 0 +configure.sh:3130: result: yes +configure.sh:3166: checking for stddef.h +configure.sh:3173: result: yes +configure.sh:3049: checking for stdlib.h +configure.sh:3054: result: yes +configure.sh:3049: checking for string.h +configure.sh:3054: result: yes +configure.sh:3049: checking for unistd.h +configure.sh:3054: result: yes +configure.sh:3188: checking for stdbool.h that conforms to C99 +configure.sh:3242: gcc -c -g -O2 conftest.c >&5 +configure:3218: #error bool is not defined +configure:3230: #error true is not 1 +configure.sh:3245: $? = 1 +configure.sh: failed program was: +| #line 3193 "configure" +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "intercal" +| #define PACKAGE_TARNAME "intercal" +| #define PACKAGE_VERSION "0.26" +| #define PACKAGE_STRING "intercal 0.26" +| #define PACKAGE_BUGREPORT "esr@thyrsus.com" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_UNISTD_H 1 +| /* end confdefs.h. */ +| +| #include +| #ifndef bool +| # error bool is not defined +| #endif +| #ifndef false +| # error false is not defined +| #endif +| #if false +| # error false is not 0 +| #endif +| #ifndef true +| # error true is not defined +| #endif +| #if true != 1 +| # error true is not 1 +| #endif +| #ifndef __bool_true_false_are_defined +| # error __bool_true_false_are_defined is not defined +| #endif +| +| struct s { _Bool s: 1; _Bool t; } s; +| +| char a[true == 1 ? 1 : -1]; +| char b[false == 0 ? 1 : -1]; +| char c[__bool_true_false_are_defined == 1 ? 1 : -1]; +| char d[(bool) -0.5 == true ? 1 : -1]; +| bool e = &s; +| char f[(_Bool) -0.0 == false ? 1 : -1]; +| char g[true]; +| char h[sizeof (_Bool)]; +| char i[sizeof s.t]; +| +| int +| main () +| { +| return !a + !b + !c + !d + !e + !f + !g + !h + !i; +| ; +| return 0; +| } +configure.sh:3262: result: no +configure.sh:3264: checking for _Bool +configure.sh:3289: gcc -c -g -O2 conftest.c >&5 +configure: In function `main': +configure:3328: `_Bool' undeclared (first use in this function) +configure:3328: (Each undeclared identifier is reported only once +configure:3328: for each function it appears in.) +configure:3328: parse error before `)' +configure.sh:3292: $? = 1 +configure.sh: failed program was: +| #line 3269 "configure" +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "intercal" +| #define PACKAGE_TARNAME "intercal" +| #define PACKAGE_VERSION "0.26" +| #define PACKAGE_STRING "intercal 0.26" +| #define PACKAGE_BUGREPORT "esr@thyrsus.com" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_UNISTD_H 1 +| /* end confdefs.h. */ +| #include +| #if HAVE_SYS_TYPES_H +| # include +| #endif +| #if HAVE_SYS_STAT_H +| # include +| #endif +| #if STDC_HEADERS +| # include +| # include +| #else +| # if HAVE_STDLIB_H +| # include +| # endif +| #endif +| #if HAVE_STRING_H +| # if !STDC_HEADERS && HAVE_MEMORY_H +| # include +| # endif +| # include +| #endif +| #if HAVE_STRINGS_H +| # include +| #endif +| #if HAVE_INTTYPES_H +| # include +| #else +| # if HAVE_STDINT_H +| # include +| # endif +| #endif +| #if HAVE_UNISTD_H +| # include +| #endif +| int +| main () +| { +| if ((_Bool *) 0) +| return 0; +| if (sizeof (_Bool)) +| return 0; +| ; +| return 0; +| } +configure.sh:3309: result: no +configure.sh:3328: checking for an ANSI C-conforming const +configure.sh:3396: gcc -c -g -O2 conftest.c >&5 +configure.sh:3399: $? = 0 +configure.sh:3402: test -s conftest.o +configure.sh:3405: $? = 0 +configure.sh:3416: result: yes +configure.sh:3426: checking for size_t +configure.sh:3451: gcc -c -g -O2 conftest.c >&5 +configure.sh:3454: $? = 0 +configure.sh:3457: test -s conftest.o +configure.sh:3460: $? = 0 +configure.sh:3471: result: yes +configure.sh:3490: checking for stdlib.h +configure.sh:3495: result: yes +configure.sh:3627: checking for GNU libc compatible malloc +configure.sh:3657: gcc -o conftest -g -O2 conftest.c >&5 +configure.sh:3660: $? = 0 +configure.sh:3662: ./conftest +configure.sh:3665: $? = 0 +configure.sh:3679: result: yes +configure.sh:3707: checking for stdlib.h +configure.sh:3712: result: yes +configure.sh:3844: checking for GNU libc compatible realloc +configure.sh:3874: gcc -o conftest -g -O2 conftest.c >&5 +configure.sh:3877: $? = 0 +configure.sh:3879: ./conftest +configure.sh:3882: $? = 0 +configure.sh:3896: result: yes +configure.sh:3919: checking return type of signal handlers +configure.sh:3951: gcc -c -g -O2 conftest.c >&5 +configure.sh:3954: $? = 0 +configure.sh:3957: test -s conftest.o +configure.sh:3960: $? = 0 +configure.sh:3971: result: void +configure.sh:3986: checking for memset +configure.sh:4036: gcc -o conftest -g -O2 conftest.c >&5 +configure:4034: warning: conflicting types for built-in function `memset' +configure.sh:4039: $? = 0 +configure.sh:4042: test -s conftest +configure.sh:4045: $? = 0 +configure.sh:4056: result: yes +configure.sh:3986: checking for strrchr +configure.sh:4036: gcc -o conftest -g -O2 conftest.c >&5 +configure.sh:4039: $? = 0 +configure.sh:4042: test -s conftest +configure.sh:4045: $? = 0 +configure.sh:4056: result: yes +configure.sh:3986: checking for strtol +configure.sh:4036: gcc -o conftest -g -O2 conftest.c >&5 +configure.sh:4039: $? = 0 +configure.sh:4042: test -s conftest +configure.sh:4045: $? = 0 +configure.sh:4056: result: yes +configure.sh:3986: checking for strtoul +configure.sh:4036: gcc -o conftest -g -O2 conftest.c >&5 +configure.sh:4039: $? = 0 +configure.sh:4042: test -s conftest +configure.sh:4045: $? = 0 +configure.sh:4056: result: yes +configure.sh:4067: Version is 0.26 +configure.sh:4196: creating ./config.status + +## ---------------------- ## +## Running config.status. ## +## ---------------------- ## + +This file was extended by intercal config.status 0.26, which was +generated by GNU Autoconf 2.57. Invocation command line was + + CONFIG_FILES = + CONFIG_HEADERS = + CONFIG_LINKS = + CONFIG_COMMANDS = + $ ./config.status + +on chillingi + +config.status:614: creating Makefile +config.status:614: creating ickspec + +## ---------------- ## +## Cache variables. ## +## ---------------- ## + +ac_cv_c_compiler_gnu=yes +ac_cv_c_const=yes +ac_cv_env_CC_set= +ac_cv_env_CC_value= +ac_cv_env_CFLAGS_set= +ac_cv_env_CFLAGS_value= +ac_cv_env_CPPFLAGS_set= +ac_cv_env_CPPFLAGS_value= +ac_cv_env_CPP_set= +ac_cv_env_CPP_value= +ac_cv_env_LDFLAGS_set= +ac_cv_env_LDFLAGS_value= +ac_cv_env_build_alias_set= +ac_cv_env_build_alias_value= +ac_cv_env_host_alias_set= +ac_cv_env_host_alias_value= +ac_cv_env_target_alias_set= +ac_cv_env_target_alias_value= +ac_cv_exeext= +ac_cv_func_malloc_0_nonnull=yes +ac_cv_func_memset=yes +ac_cv_func_realloc_0_nonnull=yes +ac_cv_func_strrchr=yes +ac_cv_func_strtol=yes +ac_cv_func_strtoul=yes +ac_cv_header_inttypes_h=yes +ac_cv_header_memory_h=yes +ac_cv_header_stdbool_h=no +ac_cv_header_stdc=yes +ac_cv_header_stddef_h=yes +ac_cv_header_stdint_h=no +ac_cv_header_stdlib_h=yes +ac_cv_header_string_h=yes +ac_cv_header_strings_h=yes +ac_cv_header_sys_stat_h=yes +ac_cv_header_sys_types_h=yes +ac_cv_header_unistd_h=yes +ac_cv_lib_fl_yywrap=no +ac_cv_lib_l_yywrap=yes +ac_cv_objext=o +ac_cv_prog_CPP=$'gcc -E' +ac_cv_prog_LEX=lex +ac_cv_prog_ac_ct_CC=gcc +ac_cv_prog_cc_g=yes +ac_cv_prog_cc_stdc= +ac_cv_prog_egrep=egrep +ac_cv_prog_lex_root=lex.yy +ac_cv_prog_lex_yytext_pointer=no +ac_cv_prog_make_make_set=yes +ac_cv_type__Bool=no +ac_cv_type_signal=void +ac_cv_type_size_t=yes + +## ----------------- ## +## Output variables. ## +## ----------------- ## + +CC='gcc' +CFLAGS='-g -O2' +CPP='gcc -E' +CPPFLAGS='' +DEFS='-DPACKAGE_NAME=\"intercal\" -DPACKAGE_TARNAME=\"intercal\" -DPACKAGE_VERSION=\"0.26\" -DPACKAGE_STRING=\"intercal\ 0.26\" -DPACKAGE_BUGREPORT=\"esr@thyrsus.com\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_UNISTD_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STDDEF_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_STDLIB_H=1 -DHAVE_REALLOC=1 -DRETSIGTYPE=void -DHAVE_MEMSET=1 -DHAVE_STRRCHR=1 -DHAVE_STRTOL=1 -DHAVE_STRTOUL=1 ' +ECHO_C='' +ECHO_N='-n' +ECHO_T='' +EGREP='egrep' +EXEEXT='' +INSTALL_DATA='${INSTALL} -m 644' +INSTALL_PROGRAM='${INSTALL}' +INSTALL_SCRIPT='${INSTALL}' +LDFLAGS='' +LEX='lex' +LEXLIB='-ll' +LEX_OUTPUT_ROOT='lex.yy' +LIBOBJS='' +LIBS='' +LN_S='ln -s' +LTLIBOBJS='' +OBJEXT='o' +PACKAGE_BUGREPORT='esr@thyrsus.com' +PACKAGE_NAME='intercal' +PACKAGE_STRING='intercal 0.26' +PACKAGE_TARNAME='intercal' +PACKAGE_VERSION='0.26' +PATH_SEPARATOR=':' +SET_MAKE='' +SHELL='/bin/bash' +YACC='yacc' +ac_ct_CC='gcc' +bindir='${exec_prefix}/bin' +build_alias='' +datadir='${prefix}/share' +exec_prefix='${prefix}' +host_alias='' +includedir='${prefix}/include' +infodir='${prefix}/info' +libdir='${exec_prefix}/lib' +libexecdir='${exec_prefix}/libexec' +localstatedir='${prefix}/var' +mandir='${prefix}/man' +oldincludedir='/usr/include' +prefix='/usr/local' +program_transform_name='s,x,x,' +sbindir='${exec_prefix}/sbin' +sharedstatedir='${prefix}/com' +sysconfdir='${prefix}/etc' +target_alias='' + +## ----------- ## +## confdefs.h. ## +## ----------- ## + +#define HAVE_INTTYPES_H 1 +#define HAVE_MALLOC 1 +#define HAVE_MEMORY_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_MEMSET 1 +#define HAVE_REALLOC 1 +#define HAVE_STDDEF_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_STRING_H 1 +#define HAVE_STRING_H 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_UNISTD_H 1 +#define HAVE_UNISTD_H 1 +#define PACKAGE_BUGREPORT "esr@thyrsus.com" +#define PACKAGE_NAME "intercal" +#define PACKAGE_STRING "intercal 0.26" +#define PACKAGE_TARNAME "intercal" +#define PACKAGE_VERSION "0.26" +#define RETSIGTYPE void +#define STDC_HEADERS 1 + +configure.sh: exit 0 diff --git a/config.status b/config.status new file mode 100755 index 0000000..9ee60a8 --- /dev/null +++ b/config.status @@ -0,0 +1,688 @@ +#! /bin/bash +# Generated by configure.sh. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=${CONFIG_SHELL-/bin/bash} +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by intercal $as_me 0.26, which was +generated by GNU Autoconf 2.57. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +config_files=" Makefile ickspec" + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Report bugs to ." +ac_cs_version="\ +intercal config.status 0.26 +configured by configure.sh, generated by GNU Autoconf 2.57, + with options \"\" + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=. +INSTALL="./install.sh -c" +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +if $ac_cs_recheck; then + echo "running /bin/bash configure.sh " $ac_configure_extra_args " --no-create --no-recursion" >&6 + exec /bin/bash configure.sh $ac_configure_extra_args --no-create --no-recursion +fi + +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "ickspec" ) CONFIG_FILES="$CONFIG_FILES ickspec" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t$/@;t t/; /@;t t$/s/[\\&,]/\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t$/,;t t/' >$tmp/subs.sed <<\CEOF +s,@SHELL@,/bin/bash,;t t +s,@PATH_SEPARATOR@,:,;t t +s,@PACKAGE_NAME@,intercal,;t t +s,@PACKAGE_TARNAME@,intercal,;t t +s,@PACKAGE_VERSION@,0.26,;t t +s,@PACKAGE_STRING@,intercal 0.26,;t t +s,@PACKAGE_BUGREPORT@,esr@thyrsus.com,;t t +s,@exec_prefix@,${prefix},;t t +s,@prefix@,/usr/local,;t t +s,@program_transform_name@,s,x,x,,;t t +s,@bindir@,${exec_prefix}/bin,;t t +s,@sbindir@,${exec_prefix}/sbin,;t t +s,@libexecdir@,${exec_prefix}/libexec,;t t +s,@datadir@,${prefix}/share,;t t +s,@sysconfdir@,${prefix}/etc,;t t +s,@sharedstatedir@,${prefix}/com,;t t +s,@localstatedir@,${prefix}/var,;t t +s,@libdir@,${exec_prefix}/lib,;t t +s,@includedir@,${prefix}/include,;t t +s,@oldincludedir@,/usr/include,;t t +s,@infodir@,${prefix}/info,;t t +s,@mandir@,${prefix}/man,;t t +s,@build_alias@,,;t t +s,@host_alias@,,;t t +s,@target_alias@,,;t t +s,@DEFS@,-DPACKAGE_NAME=\"intercal\" -DPACKAGE_TARNAME=\"intercal\" -DPACKAGE_VERSION=\"0.26\" -DPACKAGE_STRING=\"intercal\ 0.26\" -DPACKAGE_BUGREPORT=\"esr@thyrsus.com\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_UNISTD_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STDDEF_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_STDLIB_H=1 -DHAVE_REALLOC=1 -DRETSIGTYPE=void -DHAVE_MEMSET=1 -DHAVE_STRRCHR=1 -DHAVE_STRTOL=1 -DHAVE_STRTOUL=1 ,;t t +s,@ECHO_C@,,;t t +s,@ECHO_N@,-n,;t t +s,@ECHO_T@,,;t t +s,@LIBS@,,;t t +s,@YACC@,yacc,;t t +s,@CC@,gcc,;t t +s,@CFLAGS@,-g -O2,;t t +s,@LDFLAGS@,,;t t +s,@CPPFLAGS@,,;t t +s,@ac_ct_CC@,gcc,;t t +s,@EXEEXT@,,;t t +s,@OBJEXT@,o,;t t +s,@LEX@,lex,;t t +s,@LEXLIB@,-ll,;t t +s,@LEX_OUTPUT_ROOT@,lex.yy,;t t +s,@INSTALL_PROGRAM@,${INSTALL},;t t +s,@INSTALL_SCRIPT@,${INSTALL},;t t +s,@INSTALL_DATA@,${INSTALL} -m 644,;t t +s,@LN_S@,ln -s,;t t +s,@SET_MAKE@,,;t t +s,@CPP@,gcc -E,;t t +s,@EGREP@,egrep,;t t +s,@LIBOBJS@,,;t t +s,@LTLIBOBJS@,,;t t +CEOF + + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + sed "/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +} + +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done + +{ (exit 0); exit 0; } diff --git a/configure.ac b/configure.ac index 63b3af1..37da6fb 100644 --- a/configure.ac +++ b/configure.ac @@ -2,9 +2,8 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.57) -AC_INIT(intercal, 0.25, esr@thyrsus.com) -AC_CONFIG_SRCDIR([lose.h]) -#AC_CONFIG_HEADER([config.h]) +AC_INIT(intercal, 0.26, esr@thyrsus.com) +AC_CONFIG_SRCDIR([src/lose.h]) # Checks for programs. AC_PROG_YACC @@ -32,4 +31,4 @@ AC_TYPE_SIGNAL AC_CHECK_FUNCS([memset strrchr strtol strtoul]) AC_MSG_NOTICE(Version is $PACKAGE_VERSION) -AC_OUTPUT(Makefile intercal.spec) +AC_OUTPUT(Makefile ickspec) diff --git a/configure b/configure.sh similarity index 99% rename from configure rename to configure.sh index c78c49a..9609f29 100755 --- a/configure +++ b/configure.sh @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.57 for intercal 0.25. +# Generated by GNU Autoconf 2.57 for intercal 0.26. # # Report bugs to . # @@ -268,11 +268,11 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='intercal' PACKAGE_TARNAME='intercal' -PACKAGE_VERSION='0.25' -PACKAGE_STRING='intercal 0.25' +PACKAGE_VERSION='0.26' +PACKAGE_STRING='intercal 0.26' PACKAGE_BUGREPORT='esr@thyrsus.com' -ac_unique_file="lose.h" +ac_unique_file="src/lose.h" # Factoring default headers for most tests. ac_includes_default="\ #include @@ -779,7 +779,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures intercal 0.25 to adapt to many kinds of systems. +\`configure' configures intercal 0.26 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -836,7 +836,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of intercal 0.25:";; + short | recursive ) echo "Configuration of intercal 0.26:";; esac cat <<\_ACEOF @@ -915,7 +915,7 @@ fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF -intercal configure 0.25 +intercal configure 0.26 generated by GNU Autoconf 2.57 Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 @@ -930,7 +930,7 @@ cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by intercal $as_me 0.25, which was +It was created by intercal $as_me 0.26, which was generated by GNU Autoconf 2.57. Invocation command line was $ $0 $@ @@ -1266,8 +1266,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu - -#AC_CONFIG_HEADER([config.h]) # Checks for programs. for ac_prog in 'bison -y' byacc @@ -4071,7 +4069,7 @@ done { echo "$as_me:$LINENO: Version is $PACKAGE_VERSION" >&5 echo "$as_me: Version is $PACKAGE_VERSION" >&6;} - ac_config_files="$ac_config_files Makefile intercal.spec" + ac_config_files="$ac_config_files Makefile ickspec" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure @@ -4463,7 +4461,7 @@ _ASBOX } >&5 cat >&5 <<_CSEOF -This file was extended by intercal $as_me 0.25, which was +This file was extended by intercal $as_me 0.26, which was generated by GNU Autoconf 2.57. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4518,7 +4516,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -intercal config.status 0.25 +intercal config.status 0.26 configured by $0, generated by GNU Autoconf 2.57, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" @@ -4623,7 +4621,7 @@ do case "$ac_config_target" in # Handling of arguments. "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "intercal.spec" ) CONFIG_FILES="$CONFIG_FILES intercal.spec" ;; + "ickspec" ) CONFIG_FILES="$CONFIG_FILES ickspec" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; diff --git a/districk.bat b/districk.bat new file mode 100755 index 0000000..9a593ef --- /dev/null +++ b/districk.bat @@ -0,0 +1,9 @@ +@echo off +rem This batch file removes all files that weren't in the distribution. +ren temp\parser.c parser.tmp +ren temp\parser.h parserh.tmp +ren temp\lexer.c lexer.tmp +call cleanick +ren temp\parser.tmp parser.c +ren temp\parserh.tmp parser.h +ren temp\lexer.tmp lexer.c diff --git a/districk.sh b/districk.sh new file mode 100755 index 0000000..7df8992 --- /dev/null +++ b/districk.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# make districk as a shell-script, for the benefit of DJGPP systems with broken +# versions of make. +# This batch file removes all files that weren't in the distribution. +mv temp/parser.c temp/parser.tmp +mv temp/parser.h temp/parserh.tmp +mv temp/lexer.c temp/lexer.tmp +sh cleanick.sh +mv temp/parser.tmp temp/parser.c +mv temp/parserh.tmp temp/parser.h +mv temp/lexer.tmp temp/lexer.c diff --git a/djfix.bat b/djfix.bat new file mode 100755 index 0000000..c05cd75 --- /dev/null +++ b/djfix.bat @@ -0,0 +1,17 @@ +@echo off +rem This is a script to remove trailing ^Ms that might otherwise get into files +rem when running under DJGPP, to prevent the files being unusable on Unix. + +dtou *.txt +dtou etc\intercal.el +dtou src\*.c +dtou src\*.h +dtou src\*.l +dtou src\*.y +dtou src\*.sh +dtou pit\*.doc +dtou pit\*.i +dtou pit\tests\*.doc +dtou pit\tests\*.i +dtou pit\lib\*.doc +dtou pit\lib\*.i diff --git a/djfix.sh b/djfix.sh new file mode 100755 index 0000000..cc8e946 --- /dev/null +++ b/djfix.sh @@ -0,0 +1,17 @@ +#!/bin/sh +# This is a script to remove trailing ^Ms that might otherwise get into files +# when running under DJGPP, to prevent the files being unusable on Unix. + +dtou *.txt +dtou etc/intercal.el +dtou src/*.c +dtou src/*.h +dtou src/*.l +dtou src/*.y +dtou src/*.sh +dtou pit/*.doc +dtou pit/*.i +dtou pit/tests/*.doc +dtou pit/tests/*.i +dtou pit/lib/*.doc +dtou pit/lib/*.i diff --git a/intercal.el b/etc/intercal.el similarity index 98% rename from intercal.el rename to etc/intercal.el index b5ab3a6..7c3c93d 100644 --- a/intercal.el +++ b/etc/intercal.el @@ -321,8 +321,8 @@ a good idea in long files, which take a long time to update." ;; be abstained from all program. (defvar intercal-font-lock-keywords '(("^\\(([0-9]+)\\|\\)[ \t]*\\(PLEASE DO\\|DO\\|PLEASE\\)[ \t]*\\(NOT\\|N'T\\).*$" . font-lock-comment-face) - ("\\<\\(ABSTAIN\\|GIVE UP\\|READ OUT\\|RESUME\\|WRITE IN\\|COME\\|FROM\\|IGNORE\\|REINSTATE\\|RETRIEVE\\|PLEASE\\|DO\\|MAYBE\\|ONCE\\|AGAIN\\|FORGET\\|NEXT\\|REMEMBER\\|STASH\\|DON'T\\|NOT\\|TRY AGAIN\\|GO AHEAD\\|GO BACK\\)\\>" . font-lock-keyword-face) - ("\\<\\(ABSTAINING\\|GIVING UP\\|READING OUT\\|RESUMING\\|WRITING IN\\|COMING\\|IGNORING\\|REINSTATING\\|RETRIEVING\\|FORGETTING\\|NEXTING\\|REMEMBERING\\|STASHING\\|TRYING AGAIN\\|CALCULATING\\|GOING AHEAD\\|GOING BACK\\)\\>" . font-lock-builtin-face) + ("\\<\\(ABSTAIN\\|GIVE UP\\|READ OUT\\|RESUME\\|WRITE IN\\|PIN\\|COME\\|FROM\\|IGNORE\\|REINSTATE\\|RETRIEVE\\|PLEASE\\|DO\\|MAYBE\\|ONCE\\|AGAIN\\|FORGET\\|NEXT\\|REMEMBER\\|STASH\\|DON'T\\|NOT\\|TRY AGAIN\\|GO AHEAD\\|GO BACK\\)\\>" . font-lock-keyword-face) + ("\\<\\(ABSTAINING\\|GIVING UP\\|READING OUT\\|RESUMING\\|WRITING IN\\|PINNING\\|COMING\\|IGNORING\\|REINSTATING\\|RETRIEVING\\|FORGETTING\\|NEXTING\\|REMEMBERING\\|STASHING\\|TRYING AGAIN\\|CALCULATING\\|GOING AHEAD\\|GOING BACK\\)\\>" . font-lock-builtin-face) ("[.,:;][0-9]+" . font-lock-variable-name-face) ("#[0-9]+\\(\\$#[0-9]+\\|\\)" . font-lock-constant-face)) "Default expressions to highlight in Intercal mode.") diff --git a/ickspec b/ickspec new file mode 100644 index 0000000..704c76f --- /dev/null +++ b/ickspec @@ -0,0 +1,60 @@ +Name: intercal +Version: 0.26 +Release: 1 +URL: http://www.catb.org/~esr/intercal/ +Source: intercal-0.26.tar.gz +License: GPL +Group: Development/Languages +Summary: the language that kills the weak and drives mad the strong +BuildRoot: %{_tmppath}/%{name}-root + +%description +An implementation of the language INTERCAL, legendary for +its perversity and horribleness (this version adds COME FROM +for extra flavor). Comes with language manual and examples +including possibly the entire extant body of INTERCAL code. +Now supports i18n and l14n (to Ancient Roman locale only) +Now with fix patch by Donald Knuth. + +%prep +%setup -q + +%build +configure --prefix=/usr +make + +%clean +[ "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT" + +%install +[ "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT" +mkdir -p "$RPM_BUILD_ROOT"%{_bindir} +cp ick coopt.sh "$RPM_BUILD_ROOT"%{_bindir} +mkdir -p "$RPM_BUILD_ROOT"%{_libdir} +cp libick.a "$RPM_BUILD_ROOT"%{_libdir} +cp libickmt.a "$RPM_BUILD_ROOT"%{_libdir} +cp libyuk.a "$RPM_BUILD_ROOT"%{_libdir} +mkdir -p "$RPM_BUILD_ROOT"%{_includedir}/intercal-0.26 +cp lose.h abcess.h fiddle.h yuk.h "$RPM_BUILD_ROOT"%{_includedir}/intercal-0.26 + +%files +%doc README BUGS NEWS +%{_bindir}/ick +%{_libdir}/libick.a +%{_libdir}/libickmt.a +%{_libdir}/libyuk.a +%{_includedir}/intercal-0.26/lose.h +%{_includedir}/intercal-0.26/abcess.h +%{_includedir}/intercal-0.26/fiddle.h +%{_includedir}/intercal-0.26/yuk.h + +%changelog +* Wed Dec 31 2003 Eric S. Raymond 0.24-1 +- Non-root users can now build RPMs. + +# The following sets edit modes for GNU EMACS +# Local Variables: +# mode:rpm-spec +# End: + + diff --git a/intercal.spec.in b/ickspec.in similarity index 100% rename from intercal.spec.in rename to ickspec.in diff --git a/makeick.bat b/makeick.bat new file mode 100755 index 0000000..08d6b7b --- /dev/null +++ b/makeick.bat @@ -0,0 +1,66 @@ +@echo off + +rem C-INTERCAL 0.25 compilation batch file for DJGPP. + +rem This code will attempt to recompile the parser and lexer using +rem bison and flex. If you don't have them, you will get an error +rem message and the parser and lexer included with the distribution +rem will be used. My DJGPP distribution seems to require that you +rem copy DJDIR\bin\m4.exe to the temp subdir of the INTERCAL +rem distribution or bison won't work; YMMV. + +copy /y src\*.* temp +cd temp +bison -d -oparser.c parser.y +flex -olexer.c lexer.l + +rem If you don't care about being able to debug ick, use +rem set CFLAGS=-s -O2 -DICKNOSEARCH -W -Wall +set CFLAGS=-gstabs+ -O2 -DICKNOSEARCH -W -Wall + +rem Set this to a location of the GNU GPL on your system... +set COPYLOC=C:\DJGPP\COPYING +rem ...and this to the same thing, but within "s and with backslashes doubled. +set COPYLOCC="C:\\DJGPP\\COPYING" + +if not exist %COPYLOC% goto :error +echo Compiling... + +gcc -c %CFLAGS% parser.c +gcc -c %CFLAGS% lexer.c +gcc -c %CFLAGS% feh2.c +gcc -c %CFLAGS% dekludge.c +gcc -c %CFLAGS% perpet.c +gcc -c %CFLAGS% cesspool.c +gcc -c %CFLAGS% numerals.c +gcc -c %CFLAGS% unravel.c +gcc -c %CFLAGS% fiddle.c +gcc -c %CFLAGS% arrgghh.c +gcc -c %CFLAGS% lose.c +gcc -c %CFLAGS% -DYUKCOPYLOC=\"%COPYLOCC%\" yuk.c +ar cr libick.a cesspool.o numerals.o fiddle.o arrgghh.o lose.o +ranlib libick.a +ar cr libickmt.a cesspool.o numerals.o fiddle.o arrgghh.o lose.o unravel.o +ranlib libickmt.a +ar cr libyuk.a yuk.o +ranlib libyuk.a +gcc %CFLAGS% -oickmain.exe parser.o lexer.o perpet.o feh2.o dekludge.o lose.o fiddle.o +copy /y ickmain.exe ..\bin +copy /y *.a ..\lib +cd .. +copy /y src\ick-wrap.c lib +copy /y src\pickwrap.c lib +copy /y pit\lib\syslib.i lib +copy /y pit\lib\syslib.?i lib +copy /y src\fiddle.h include +copy /y src\abcess.h include +copy /y src\lose.h include +copy /y src\yuk.h include +copy /y src\ick.bat bin +echo Compilation complete unless there were errors. +goto :end +:error +echo You need to tell this batch file where the GNU GPL is on your system. +echo Please edit this batch file and set COPYLOC to a correct location. +echo (You can point it to the copy of COPYING.txt provided.) +:end \ No newline at end of file diff --git a/makeick.sh b/makeick.sh new file mode 100755 index 0000000..f9ba3a6 --- /dev/null +++ b/makeick.sh @@ -0,0 +1,71 @@ +#!/bin/sh + +# C-INTERCAL 0.25 compilation batch file for sh and bash. + +# This code will attempt to recompile the parser and lexer using +# bison and flex. If you don't have them, you will get an error +# message and the parser and lexer included with the distribution +# will be used. My DJGPP distribution seems to require that you +# copy DJDIR/bin/m4.exe to the temp subdir of the INTERCAL +# distribution or bison won't work; YMMV. + +# Using configure.sh and make is recommended; this script is a fallback for +# when you can't get configure.sh and/or make to work on your system; make +# is broken on my DJGPP distribution, so I use this file instead. + +# This file is meant to contain the same content as makeick.bat; it's simply +# written for sh rather than COMMAND.COM (and doesn't make use of all its +# features, as it's meant to be exactly analogous). + +# Run this file from the directory in which this script is installed. + +cp src/* temp +cd temp +bison -d -oparser.c parser.y +flex -olexer.c lexer.l + +# If you don't care about being able to debug ick, use +# CFLAGS=-s -O2 -DICKNOSEARCH -W -Wall +CFLAGS='-gstabs+ -O2 -DICKNOSEARCH -W -Wall' + +# Set this to a location of the GNU GPL on your system. +# Please use forward-slash notation! +COPYLOC=c:/djgpp/copying + +echo If the following line fails, edit makeick.sh to point COPYLOC at a +echo location of the GNU GPL on your system. You can point it to the copy of +echo COPYING.txt provided. +cp ${COPYLOC} /dev/null || exit +echo Compiling... +gcc -c ${CFLAGS} parser.c +gcc -c ${CFLAGS} lexer.c +gcc -c ${CFLAGS} feh2.c +gcc -c ${CFLAGS} dekludge.c +gcc -c ${CFLAGS} perpet.c +gcc -c ${CFLAGS} cesspool.c +gcc -c ${CFLAGS} numerals.c +gcc -c ${CFLAGS} unravel.c +gcc -c ${CFLAGS} fiddle.c +gcc -c ${CFLAGS} arrgghh.c +gcc -c ${CFLAGS} lose.c +gcc -c ${CFLAGS} "-DYUKCOPYLOC=\"${COPYLOC}\"" yuk.c +ar cr libick.a cesspool.o numerals.o fiddle.o arrgghh.o lose.o +ranlib libick.a +ar cr libickmt.a cesspool.o numerals.o fiddle.o arrgghh.o lose.o unravel.o +ranlib libickmt.a +ar cr libyuk.a yuk.o +ranlib libyuk.a +gcc ${CFLAGS} -oickmain.exe parser.o lexer.o perpet.o feh2.o dekludge.o lose.o fiddle.o +cp ickmain.exe ../bin +cp *.a ../lib +cd .. +cp src/ick-wrap.c lib +cp src/pickwrap.c lib +cp pit/lib/syslib.i lib +cp pit/lib/syslib.?i lib +cp src/fiddle.h include +cp src/abcess.h include +cp src/lose.h include +cp src/yuk.h include +cp src/ick.bat bin +echo Compilation complete unless there were errors. \ No newline at end of file diff --git a/pit/tests/pictest.i b/pit/tests/pictest.i new file mode 100644 index 0000000..95918b8 --- /dev/null +++ b/pit/tests/pictest.i @@ -0,0 +1,11 @@ +PLEASE NOTE This continuously copies PORTA to PORTB + (PORTA is always input, PORTB is always output) + DO .2 <- #0 + DO .1 <- #65280 + PLEASE COME FROM (11) + DO (1520) NEXT + DO PIN :1 + DO .1 <- :1~#255 + PLEASE DO .2 <- #257 + DO (1030) NEXT +(11) DO .1 <- .3 diff --git a/pit/tests/version.4i b/pit/tests/version.4i new file mode 100644 index 0000000..f18b9bc --- /dev/null +++ b/pit/tests/version.4i @@ -0,0 +1,7 @@ +(1) DO .1 <- #?6 + DOING DETECTION... YOU ARE USING INTERCAL-72 +(5) PLEASE COME FROM (1) + DOING DETECTION... YOU ARE USING C-INTERCAL + PLEASE COME FROM .1 + DOING DETECTION... YOU ARE USING CLC-INTERCAL + diff --git a/pit/tests/version.doc b/pit/tests/version.doc new file mode 100644 index 0000000..60ce346 --- /dev/null +++ b/pit/tests/version.doc @@ -0,0 +1,14 @@ +version.4i is a simple program that tests what version of INTERCAL you are +running. + +Under INTERCAL-72, the .4i suffix is ignored, and the COME FROM lines are +splatted. So execution flows to the first splat line, where an error is +reported that prints out the required message. + +Under C-INTERCAL (or CLC-INTERCAL faking it), the ? is interpreted as XOR, +leaving a hugely large value in .1. So the second COME FROM doesn't match, +and the second splat line generates the error. + +Under CLC-INTERCAL (or C-INTERCAL using the -X option), the ? is interpreted +as BUT, leaving #5 in .1. So the second COME FROM finds the required line +label, and the third splat line generates the error. diff --git a/specgen.sh b/specgen.sh deleted file mode 100755 index bc73394..0000000 --- a/specgen.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh - -version=$1 - -cat < #include +/* AIS: Make this work with DJGPP's stdarg.h */ +#ifdef __DJGPP__ +#define _POSIX_SOURCE +#endif + #ifdef _POSIX_SOURCE #include #else @@ -34,14 +39,19 @@ LICENSE TERMS #endif #include "sizes.h" +/* AIS: To avoid a separate overloaded/nonoverloaded library, we import + the overloading defines here and ignore them if we don't need them. */ +#define MULTITHREAD 0 +#define OVEROPUSED 1 #include "abcess.h" #include "lose.h" #include "numerals.c" -FILE* cesspoolin = stdin; -FILE* cesspoolout = stdout; -/* AIS: In a future version of ick or yuk, these might not be constants */ +/* AIS: These will be set to stdin/stdout at the first opportunity, + which is not necessarily here. */ +FILE* cesspoolin=0; +FILE* cesspoolout=0; /********************************************************************** * @@ -98,6 +108,8 @@ unsigned int pin(void) int n; extern int wimp_mode; + if(!cesspoolin) cesspoolin=stdin; /* AIS */ + if (fgets(buf, BUFSIZ, cesspoolin) == (char *)NULL) lose(E562, lineno, (char *)NULL); n = strlen(buf) - 1; @@ -274,6 +286,8 @@ void pout(unsigned int val) char result[2*MAXROMANS+1]; extern int wimp_mode; + if(!cesspoolout) cesspoolout=stdout; /* AIS */ + if(wimp_mode) { (void) fprintf(cesspoolout,"%u\n",val); } @@ -300,6 +314,8 @@ void binin(unsigned int type, array *a, bool forget) if (a->rank != 1) lose(E241, lineno, (char *)NULL); + + if(!cesspoolin) cesspoolin=stdin; /* AIS */ for (i = 0 ; i < a->dims[0] ; i++) { v = ((c=fgetc(cesspoolin)) == EOF) ? 256 : (c - lastin) % 256; @@ -321,6 +337,8 @@ void binout(unsigned int type, array *a) if (a->rank != 1) lose(E241, lineno, (char *)NULL); + if(!cesspoolout) cesspoolout=stdout; /* AIS */ + for (i = 0 ; i < a->dims[0] ; i++) { if (type == TAIL) c = lastout - a->data.tail[i]; @@ -345,7 +363,7 @@ void binout(unsigned int type, array *a) unsigned int assign(char *dest, unsigned int type, bool forget, unsigned int value) { - unsigned int retval; + unsigned int retval = 0; if (type == ONESPOT || type == TAIL) { if (value > (unsigned int)Max_small) lose(E275, lineno, (char *)NULL); @@ -512,7 +530,7 @@ static stashbox *fetch(unsigned int type, unsigned int index) return (sp); } -void stash(unsigned int type, unsigned int index, void *from) +void stash(unsigned int type, unsigned int index, void *from, overop* oo) /* stash away the variable's value */ { /* create a new stashbox and push it onto the stack */ @@ -524,8 +542,11 @@ void stash(unsigned int type, unsigned int index, void *from) /* store the variable in it */ sp->type = type; sp->index = index; + if(oo) sp->overloadinfo=oo[index]; /* AIS */ if (type == ONESPOT) + { memcpy((char *)&sp->save.onespot, from, sizeof(type16)); + } else if (type == TWOSPOT) memcpy((char *)&sp->save.twospot, from, sizeof(type32)); else if (type == TAIL || type == HYBRID) { @@ -561,7 +582,7 @@ void stash(unsigned int type, unsigned int index, void *from) return; } -void retrieve(void *to, int type, unsigned int index, bool forget) +void retrieve(void *to, int type, unsigned int index, bool forget, overop* oo) /* restore the value of a variable from the save stack */ { stashbox *sp; @@ -569,6 +590,7 @@ void retrieve(void *to, int type, unsigned int index, bool forget) if ((sp = fetch(type, index)) == (stashbox *)NULL) lose(E436, lineno, (char *)NULL); else if (!forget) { + if(oo) oo[index]=sp->overloadinfo; /* AIS */ if (type == ONESPOT) memcpy(to, (char *)&sp->save.onespot, sizeof(type16)); else if (type == TWOSPOT) @@ -623,6 +645,7 @@ unsigned int roll(unsigned int n) int multicome0(int errlineno, jmp_buf pc) { + (void) pc; /* it's ignored by this function */ lose(E555, errlineno, (char *) NULL); /* this line number is quite possibly going to be wildly inaccurate */ return 0; diff --git a/coopt.sh b/src/coopt.sh old mode 100644 new mode 100755 similarity index 100% rename from coopt.sh rename to src/coopt.sh diff --git a/feh.c b/src/dekludge.c similarity index 61% rename from feh.c rename to src/dekludge.c index be39609..f42004c 100644 --- a/feh.c +++ b/src/dekludge.c @@ -1,11 +1,10 @@ /**************************************************************************** Name - feh.c -- code-generator back-end for ick parser + dekludge.c -- C-INTERCAL expression and flow optimizers DESCRIPTION - This module provides storage manglement, code degeneration, -and optimizations of dubious value for the INTERCAL compiler. + This file contains optimizations used by the C-INTERCAL compiler. LICENSE TERMS Copyright (C) 1996 Eric S. Raymond @@ -31,11 +30,13 @@ LICENSE TERMS #include #include "sizes.h" #include "ick.h" -#include "y.tab.h" +#include "parser.h" #include "fiddle.h" #include "lose.h" #include "feh.h" +extern int emitlineno; /* AIS: From feh2.c */ + /* AIS: The following macro produces optimization debug data. I added all occurences of it in this source file. It also keeps track of whether optimizations have taken place. */ @@ -49,37 +50,8 @@ LICENSE TERMS if(optdebug >= 2) putc('\n',stderr);\ opted = 1; -static int emitlineno; /* line number for errors encountered during emit */ - static void checknodeactbits(node *np); /* AIS: This prototype needed early */ - -int mark112 = 0; /* AIS: Mark the next generated tuple for W112 */ - -/************************************************************************* - * - * Node allocation functions. - * - * Nodes are used to represent expression trees. The emit() function - * deallocates them. - * - **************************************************************************/ - -node *newnode(void) -/* allocate and zero out a new expression node */ -{ - return((node *)calloc(sizeof(node), 1)); -} - -node *cons(int type, node *car, node *cdr) -{ - node *np = newnode(); - - np->opcode = type; - np->lval = car; - np->rval = cdr; - - return(np); -} +extern void prexpr(node *np, FILE* fp, int freenode); /* AIS */ /* By AIS. This function looks remarkably like a C++ copy-constructor to me, just with extra arrows in. */ @@ -121,268 +93,6 @@ static bool nodessame(node* n1, node* n2) } } -/************************************************************************* - * - * Variable-name mapping - * - * This permits us to optimize use of variable storage at runtime - * - **************************************************************************/ - -unsigned int intern(int type, int index) -{ - atom *x; - - if (index < 1 || index > 65535) - lose(E200, yylineno, (char *)NULL); - - if (!oblist) - { - /* initialize oblist and obdex */ - oblist = malloc(ALLOC_CHUNK * sizeof(atom)); - if (!oblist) - lose(E778, yylineno, (char *)NULL); - obdex = oblist; - obcount = ALLOC_CHUNK; - } - - /* if it's already on the oblist, return its intindex */ - for (x = oblist; x < obdex; x++) - if (x->type == type && x->extindex == index) - return(x->intindex); - - /* else we must intern a new symbol */ - if (obdex >= oblist + obcount) - { - obcount += ALLOC_CHUNK; - x = realloc(oblist, obcount * sizeof(atom)); - if (!x) - lose(E333, yylineno, (char *)NULL); - obdex = x + (obdex - oblist); - oblist = x; - } - obdex->type = type; - obdex->extindex = index; - if (type == ONESPOT) - obdex->intindex = nonespots++; - if (type == TWOSPOT) - obdex->intindex = ntwospots++; - if (type == TAIL) - obdex->intindex = ntails++; - if (type == HYBRID) - obdex->intindex = nhybrids++; - ++obdex; - - return(obdex[-1].intindex); -} - -/************************************************************************* - * - * This function insures a label is valid. - * - **************************************************************************/ - -void checklabel(int label) -{ - if (label < 1 || label > 65535) - lose(E197, yylineno, (char *)NULL); -} - -/************************************************************************* - * - * AIS: Search for the indexth COME_FROM sucking in the given tuple. - * Return an int representing the COME_FROM's tn-tuples+1, or -1. - * index is based at 1, not 0 as is usual for C. - * - ***************************************************************************/ - -int comefromsearch(tuple* tn, unsigned int index) -{ - tuple* tp; - for (tp = tuples; tp < tuples + lineno; tp++) - { - if(tp->type == COME_FROM && tp->u.target == tn-tuples+1) index--; - if(!index) return tp-tuples+1; - } - return -1; -} - -/************************************************************************* - * - * Tuple allocation functions. - * - **************************************************************************/ - -void treset(void) -{ - tuplecount = 0; - if (tuples) - { - free(tuples); - tuples = NULL; - } - nonespots = ntwospots = ntails = nhybrids = 0; - obdex = oblist; - lineno = 0; -} - -tuple *newtuple(void) -/* allocate and zero out a new expression tuple */ -{ - if (lineno >= tuplecount) - { - tuplecount += ALLOC_CHUNK; - if (tuples) - tuples = realloc(tuples, tuplecount * sizeof(tuple)); - else - tuples = malloc(tuplecount * sizeof(tuple)); - if (!tuples) - { - lose(E666, yylineno, (char *)NULL); - return NULL; - } - memset(tuples + lineno, 0, (tuplecount - lineno) * sizeof(tuple)); - } - if(mark112) tuples[lineno].warn112 = 1; mark112 = 0; /* AIS */ - return(tuples + lineno++); -} - -/************************************************************************* - * - * The typecaster - * - * The theory here is that we associate a type with each node in order to - * know what widths of unary-logical operator to use. - * - **************************************************************************/ - -void typecast(node *np) -{ - /* recurse so we typecast each node after all its subnodes */ - if (np == (node *)NULL) - return; - else if (np->lval != (node *)NULL) - typecast(np->lval); - if (np->rval != (node *)NULL) - typecast(np->rval); - - /* - * This is an entire set of type-deducing machinery right here. - */ - if (np->opcode == MESH || np->opcode == ONESPOT || np->opcode == TAIL) - np->width = 16; - else if (np->opcode == TWOSPOT || np->opcode == HYBRID - || np->opcode == MINGLE || np->opcode == MESH32) - np->width = 32; - else if (np->opcode == AND || np->opcode == OR || np->opcode == XOR || - np->opcode == FIN || - (np->opcode >= WHIRL && np->opcode <= WHIRL5)) - np->width = np->rval->width; - else if (np->opcode == SELECT) - np->width = np->rval->width; /* n-bit select has an n-bit result */ - else if (np->opcode == SUB) - np->width = np->lval->width; /* type of the array */ -} - -/************************************************************************* - * - * The codechecker - * - * This checks for nasties like mismatched types in assignments that - * can be detected at compile time -- also for errors that could cause - * the compilation of the generated C to fail, like generated gotos to - * nonexistent labels or duplicate labels. - * - * AIS: codecheck has another important job, that of filling in information - * about COME FROM suckpoints and ABSTAIN/REINSTATE command numbers - * into the tuples. - * - **************************************************************************/ - -void codecheck(void) -{ - tuple *tp, *up; - int notpast1900; /* AIS */ - - /* check for assignment type mismatches */ - /* This check can't be done at compile time---RTFM. [LHH] */ -/* - for (tp = tuples; tp < tuples + lineno; tp++) - if (tp->type == GETS) - if (tp->u.node->lval->width == 16 && tp->u.node->rval->width == 32) - lose(E275, tp - tuples + 1, (char *)NULL); -*/ - - /* check for duplicate labels */ - for (tp = tuples; tp < tuples + lineno; tp++) - if (tp->label) - for (up = tuples; up < tuples + lineno; up++) - if (tp != up && tp->label == up->label) - lose(E182, tp - tuples + 1, (char *)NULL); - - /* - * Check that every NEXT, ABSTAIN, REINSTATE and COME_FROM actually has a - * legitimate target label. - */ - notpast1900 = TRUE; - for (tp = tuples; tp < tuples + lineno; tp++) - { - if (tp->label == 1900) notpast1900 = FALSE; /* AIS */ - if (tp->type == NEXT - || tp->type == ABSTAIN || tp->type == REINSTATE - || tp->type == COME_FROM || tp->type == FROM) /* AIS: added FROM. */ - { - bool foundit = FALSE; - - if (tp->u.target >= 1900 && tp->u.target <= 1998) - { - /* AIS: This program uses syslib.i's random number feature... or are - we in syslib already? */ - if(notpast1900) coopt = 0; - } - - for (up = tuples; up < tuples + lineno; up++) - if (tp->u.target == up->label) - { - foundit = TRUE; - break; - } - - if (!foundit) - { - if (tp->type == NEXT) - lose(E129, tp - tuples + 1, (char *)NULL); - else if (tp->type == COME_FROM) - lose(E444, tp - tuples + 1, (char *)NULL); - else - lose(E139, tp - tuples + 1, (char *)NULL); - } - /* tell the other tuple if it is a COME FROM target */ - else if (tp->type == COME_FROM) - { - if (up->ncomefrom && !multithread) /* AIS: multithread check */ - lose(E555, yylineno, (char *)NULL); - else - up->ncomefrom++; /* AIS: to handle multiple COME FROMs */ - } - /* this substitutes line numbers for label numbers - AIS: COME FROM now uses this too. This changes the logic - slightly so that an !foundit condition would fall through, - but as long as lose doesn't return, it's not a problem. - (I removed the else before the if.) */ - if (tp->type != NEXT) - { - tp->u.target = up - tuples + 1; - } - else /* AIS */ - { - tp->nexttarget = up - tuples + 1; - up->nextable = TRUE; - } - } - } -} - /* AIS: Checks if an abstention could affect a tuple. */ int abstainmatch(int npconstant, int tptype) { @@ -394,11 +104,6 @@ int abstainmatch(int npconstant, int tptype) return 0; } -/* AIS: Added the third argument to prexpr and prvar. It specifies - whether the node should be freed or not. I added the third - argument in all calls of prexpr/prvar. This protoype has been moved - up through the file so it can be used earlier. */ -static void prexpr(node *np, FILE *fp, int freenode); /************************************************************************* * @@ -466,7 +171,7 @@ void optimizef(void) if(tpa->exechance < 0) tpa->abstainable = 1; } } - if(tp->type == GETS) + if(tp->type == GETS && Base == 2 && !opoverused) checknodeactbits(tp->u.node->rval); /* If optdata shows that the value must always fit in the variable, and the variable cannot be ignored, assign can be replaced by the @@ -477,7 +182,7 @@ void optimizef(void) { for (op = oblist; op < obdex; op++) { - if(op->type == np->opcode && op->intindex == np->constant) + if(op->type == np->opcode && (unsigned)op->intindex == np->constant) op->ignorable = 1; } } @@ -519,7 +224,7 @@ void optimizef(void) relevant variable needs to be checked for also. The checks are done partly in optimizef() and partly in emit(). */ - if(compucomesused) return; /* That's one check out of the way! */ + if(compucomesused||Base!=2||opoverused) return; np = (node*) NULL; for (tp = tuples; tp < tuples + lineno; tp++) @@ -528,9 +233,9 @@ void optimizef(void) { if(tp->u.node->rval->opcode == C_AND1ADD1 || tp->u.node->rval->opcode == C_2SUBAND1 || - (tp->u.node->rval->opcode == C_1PLUS || - tp->u.node->rval->opcode == C_2MINUS) && - tp->u.node->rval->rval->optdata == 1) + ((tp->u.node->rval->opcode == C_1PLUS || + tp->u.node->rval->opcode == C_2MINUS) && + tp->u.node->rval->rval->optdata == 1)) { /* This won't catch all <1-or-2-expressions>, but will get most of them. */ @@ -547,7 +252,7 @@ void optimizef(void) for(op = oblist; op < obdex; op++) { if(op->type == np->opcode && - op->intindex == np->constant) + (unsigned)op->intindex == np->constant) { ignorable &= op->ignorable; } @@ -572,11 +277,12 @@ void optimizef(void) tpb = tuples + tpa->nexttarget - 1; if(tpb->type == RESUME && ((tpb->u.node->opcode == C_AND1ADD1 || tpb->u.node->opcode == C_2SUBAND1 || - (tpb->u.node->opcode == C_1PLUS || - tpb->u.node->opcode == C_2MINUS) && - tpb->u.node->rval->optdata == 1) || - np&&nodessame(tpb->u.node,np))&& - !tpb->abstainable) /* No COMING FROM a nonabstainable RESUME line! */ + ((tpb->u.node->opcode == C_1PLUS || + tpb->u.node->opcode == C_2MINUS) && + tpb->u.node->rval->optdata == 1)) || + (np&&nodessame(tpb->u.node,np))) && + !tpb->abstainable) + /* No COMING FROM a nonabstainable RESUME line! */ { tp->optversion = TRUE; tp->u.node = nodecopy(tpb->u.node); @@ -622,9 +328,13 @@ static node* optdebugnode; void optimize(node *np) { int optflag; - checknodeactbits(np); - checkW534(np); /* This must be done before optimization, and depends on - checknodeactbits. */ + if(opoverused) return; /* what chance do we have of optimizing this? */ + if(Base==2) + { + checknodeactbits(np); + checkW534(np); /* This must be done before optimization, and depends on + checknodeactbits. */ + } if(optdebug == 1) explexpr(np,stderr); if(optdebug == 1) fprintf(stderr," becomes "); if(optdebug >= 2) optdebugnode = np; @@ -652,9 +362,10 @@ void optimize(node *np) } /* By AIS. This relies on free'd pointers being NULLed. */ -static void nodefree(node *np) +void nodefree(node *np) { if(!np) return; + if(np->opcode==SLAT) return; /* mustn't be freed yet */ nodefree(np->lval); nodefree(np->rval); free(np); @@ -768,6 +479,10 @@ static void checknodeactbits(node *np) np->optdata = np->width == 16 ? 0xffff : 0xffffffffLU; break; + case C_A: + np->optdata = 0xffffffffLU; + break; + case C_NOTEQUAL: case C_NNAND: case C_ISNONZERO: @@ -949,8 +664,8 @@ static int optimize_pass1(node *np) /* AIS: was 'optimize'. Recursive calls in here have been updated. */ { node *mingleop, *op, *op2; - unsigned long temp; - int temp2; + unsigned long temp = 0; + int temp2 = 0; int opted = 0; /* recurse so we simplify each node after all its subnodes @@ -1555,7 +1270,7 @@ static int optimize_pass1(node *np) /* AIS: was 'optimize'. Recursive calls in np->rval->rval->opcode==TWOSPOT&& np->lval->rval->constant== np->rval->rval->constant) temp=np->lval->rval->constant; - if(temp==0xfffffffff) break; + if(temp==0xffffffff) break; /* Patched by Joris Huizer */ /* recognized a 32-bit leftshift */ OPTING(lshift32by1) free(np->lval->lval); @@ -1610,7 +1325,7 @@ static int optimize_pass1(node *np) /* AIS: was 'optimize'. Recursive calls in free(mingleop->rval); free(mingleop); free(np->lval); - free(mingleop->rval); + /*free(mingleop->rval);*/ np->lval=(node*)NULL; /* np->rval could be an iselect of a variable with itself, @@ -2481,1303 +2196,3 @@ static int optimize_pass1(node *np) /* AIS: was 'optimize'. Recursive calls in return opted; } -/************************************************************************* - * - * Code degeneration - * - * The theory behind this crock is that we've been handed a pointer to - * a tuple representing a single INTERCAL statement, possibly with an - * expression tree hanging off it and twisting slowly, slowly in the wind. - * - * Our mission, should we choose to accept it, is to emit C code which, - * when linked to the INTERCAL run-time support, will do something - * resembling the right thing. - * - **************************************************************************/ - -/* - * If the order of statement-token defines in ick.y ever changes, - * this will need to be reordered. - */ -char *enablers[MAXTYPES] = -{ - "GETS", - "RESIZE", - "NEXT", - "GO_AHEAD", /* AIS: Added for backtracking */ - "GO_BACK", /* AIS: Added for backtracking */ - "FORGET", - "RESUME", - "STASH", - "RETRIEVE", - "IGNORE", - "REMEMBER", - "ABSTAIN", - "REINSTATE", - "DISABLE", - "ENABLE", - "MANYFROM", /* AIS: Added ABSTAIN expr FROM gerunds */ - "GIVE_UP", - "READ_OUT", - "WRITE_IN", - "COME_FROM", - "COMPUCOME", /* AIS: Added COMPUCOME */ - "TRY_AGAIN", /* AIS: Added TRY AGAIN */ - "FROM", /* AIS: ABSTAIN expr FROM LABEL */ -}; - -assoc vartypes[] = -{ - { ONESPOT, "ONESPOT" }, - { TWOSPOT, "TWOSPOT" }, - { TAIL, "TAIL" }, - { HYBRID, "HYBRID" }, - { 0, (char *)NULL } -}; - -static assoc forgetbits[] = -{ - { ONESPOT, "oneforget" }, - { TWOSPOT, "twoforget" }, - { TAIL, "tailforget" }, - { HYBRID, "hyforget" }, - { 0, (char *)NULL } -}; - -static assoc varstores[] = -{ - { ONESPOT, "onespots" }, - { TWOSPOT, "twospots" }, - { TAIL, "tails" }, - { HYBRID, "hybrids" }, - { 0, (char *)NULL } -}; - -static assoc typedefs[] = -{ - { ONESPOT, "type16" }, - { TWOSPOT, "type32" }, - { TAIL, "type16" }, - { HYBRID, "type32" }, - { 0, (char *)NULL } -}; - -char *nameof(int value, assoc table[]) -/* return string corresponding to value in table */ -{ - assoc *ap; - - for (ap = table; ap->name; ap++) - if (ap->value == value) - return(ap->name); - return((char *)NULL); -} - -/* AIS: Code for printing explanations (mixed C/INTERCAL code that lets - the user know what the meaning of an expression is). This is paraphrased - from the prexpr/prvar code lower down. It's passed to yuk so that the - explain ('e') command works. It's also included in the degenerated C - code when the option -c is used, so the person looking at the code can - debug both the INTERCAL and ick itself more effectively, and used by - -h to produce its optimizer-debug output. */ - -unsigned long varextern(unsigned long intern, int vartype) -{ - atom *x; - if(!oblist) lose(E778, emitlineno, (char*) NULL); - for (x = oblist; x < obdex; x++) - if (x->type == vartype && x->intindex == intern) - return(x->extindex); - lose(E778, emitlineno, (char*) NULL); -} - -static void explvar(node* np, FILE* fp) -{ - node *sp; - switch(np->opcode) - { - case ONESPOT: - (void) fprintf(fp, ".%lu", varextern(np->constant,ONESPOT)); - break; - case TWOSPOT: - (void) fprintf(fp, ":%lu", varextern(np->constant,TWOSPOT)); - break; - case TAIL: - (void) fprintf(fp, ",%lu", varextern(np->constant,TAIL)); - break; - case HYBRID: - (void) fprintf(fp, ";%lu", varextern(np->constant,HYBRID)); - break; - case SUB: - (void) fprintf(fp, "("); - explvar(np->lval, fp); - (void) fprintf(fp, " SUB "); - for (sp = np->rval ; sp ; sp = sp->rval) - explexpr(sp->lval, fp); - (void) fprintf(fp, ")"); - break; - default: - lose(E778, emitlineno, (char*) NULL); - } -} - -/* unlike prexpr, this doesn't free its operands */ -void explexpr(node* np, FILE* fp) -{ - if(!np) return; - switch (np->opcode) - { - case MINGLE: - (void) fprintf(fp, "("); - explexpr(np->lval, fp); - (void) fprintf(fp, " $ "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case SELECT: - (void) fprintf(fp, "("); - explexpr(np->lval, fp); - (void) fprintf(fp, " ~ "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case AND: - (void) fprintf(fp, "(& "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case OR: - (void) fprintf(fp, "(V "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case XOR: - (void) fprintf(fp, "(? "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case FIN: - if (Base < 3) - lose(E997, emitlineno, (char *)NULL); - (void) fprintf(fp, "(^ "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case WHIRL: - case WHIRL2: - case WHIRL3: - case WHIRL4: - case WHIRL5: - if (np->opcode - WHIRL + 3 > Base) - lose(E997, emitlineno, (char *)NULL); - if(np->opcode == WHIRL) - (void) fprintf(fp, "(@ "); - else - (void) fprintf(fp, "(%d@ ", np->opcode - WHIRL + 1); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case MESH: - (void) fprintf(fp, "0x%lx", np->constant); - break; - - case MESH32: - (void) fprintf(fp, "0x%lx", np->constant); - break; - - case ONESPOT: - case TWOSPOT: - case TAIL: - case HYBRID: - case SUB: - explvar(np, fp); - break; - - /* cases from here down are generated by the optimizer */ - case C_AND: - (void) fprintf(fp, "("); - explexpr(np->lval, fp); - (void) fprintf(fp, " & "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case C_OR: - (void) fprintf(fp, "("); - explexpr(np->lval, fp); - (void) fprintf(fp, " | "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case C_XOR: - (void) fprintf(fp, "("); - explexpr(np->lval, fp); - (void) fprintf(fp, " ^ "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case C_NOT: - (void) fprintf(fp, "(~ "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case C_NOTEQUAL: - (void) fprintf(fp, "("); - explexpr(np->lval, fp); - (void) fprintf(fp, " != "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case C_NNAND: - (void) fprintf(fp, "(!!("); - explexpr(np->lval, fp); - (void) fprintf(fp, " & "); - explexpr(np->rval, fp); - (void) fprintf(fp, "))"); - break; - - case C_AND1ADD1: - (void) fprintf(fp, "(("); - explexpr(np->rval,fp); - (void) fprintf(fp, " & 0x1) + 0x1)"); - break; - - case C_1PLUS: - (void) fprintf(fp, "("); - explexpr(np->rval,fp); - (void) fprintf(fp, " + 0x1)"); - break; - - case C_2MINUS: - (void) fprintf(fp, "(0x2 - "); - explexpr(np->rval,fp); - (void) fprintf(fp, ")"); - break; - - case C_2SUBAND1: - (void) fprintf(fp, "(0x2 - ("); - explexpr(np->rval,fp); - (void) fprintf(fp, " & 0x1))"); - break; - - case C_LSHIFT: - (void) fprintf(fp, "(("); - explexpr(np->lval, fp); - (void) fprintf(fp, " & "); - explexpr(np->rval, fp); - (void) fprintf(fp, ") << 0x1)"); - break; - - case C_LSHIFTIN1: - (void) fprintf(fp, "((("); - explexpr(np->lval, fp); - (void) fprintf(fp, " & "); - explexpr(np->rval, fp); - (void) fprintf(fp, ") << 0x1) | 0x1)"); - break; - - case C_LSHIFT2: - (void) fprintf(fp, "(("); - explexpr(np->lval, fp); - (void) fprintf(fp, " & "); - explexpr(np->rval, fp); - (void) fprintf(fp, ") << 0x2)"); - break; - - case C_LSHIFT8: - (void) fprintf(fp, "(("); - explexpr(np->lval, fp); - (void) fprintf(fp, " & "); - explexpr(np->rval, fp); - (void) fprintf(fp, ") << 0x8)"); - break; - - case C_RSHIFTBY: - (void) fprintf(fp, "("); - explexpr(np->lval, fp); - (void) fprintf(fp, " >> "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case C_RSHIFT: - (void) fprintf(fp, "(("); - explexpr(np->lval, fp); - (void) fprintf(fp, " & "); - explexpr(np->rval, fp); - (void) fprintf(fp, ") >> 0x1)"); - break; - - case C_XORGREATER: - (void) fprintf(fp, "("); - explexpr(np->lval, fp); - (void) fprintf(fp, " > ("); - explexpr(np->rval, fp); - (void) fprintf(fp, " ^ "); - explexpr(np->lval, fp); - (void) fprintf(fp, "))"); - break; - - case C_ISNONZERO: - (void) fprintf(fp, "(!!"); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case INTERSECTION: - explexpr(np->lval, fp); - (void) fprintf(fp, " + "); - explexpr(np->rval, fp); - break; - - case GETS: - case RESIZE: - explexpr(np->lval, fp); - (void) fprintf(fp, " <- "); - explexpr(np->rval, fp); - break; - - case BY: - explexpr(np->lval, fp); - (void) fprintf(fp, " BY "); - explexpr(np->rval, fp); - break; - - default: - lose(E778, emitlineno, (char*) NULL); - break; - } -} - -/* AIS: Added the third argument to prexpr and prvar. It specifies - whether the node should be freed or not. I added the third - argument in all calls of prexpr/prvar. */ - -/* AIS: I moved prexpr's prototype higher in the file. */ - -static void prvar(node *np, FILE *fp, int freenode) -/* print out args to pass to storage manager for reference */ -{ - node *sp; - int dim; - - switch (np->opcode) - { - case ONESPOT: - (void) fprintf(fp, "onespots[%lu]", np->constant); - break; - - case TWOSPOT: - (void) fprintf(fp, "twospots[%lu]", np->constant); - break; - - case TAIL: - (void) fprintf(fp, "TAIL, &tails[%lu]", np->constant); - break; - - case HYBRID: - (void) fprintf(fp, "HYBRID, &hybrids[%lu]", np->constant); - break; - - case SUB: - { - (void) fprintf(fp, "aref("); - prvar(np->lval, fp, freenode); - - dim = 0; - for (sp = np->rval ; sp ; sp = sp->rval) - dim++; - (void) fprintf(fp, ", %d", dim); - - for (sp = np->rval ; sp ; sp = sp->rval) { - (void) fprintf(fp, ", "); - prexpr(sp->lval, fp, freenode); - } - (void) fprintf(fp, ")"); - } - break; - default: /* Added by AIS */ - lose(E778, emitlineno, (char*) NULL); - break; - } -} - -static void prexpr(node *np, FILE *fp, int freenode) -/* print out C-function equivalent of an expression */ -{ - switch (np->opcode) - { - case MINGLE: - (void) fprintf(fp, "mingle("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, ", "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case SELECT: - (void) fprintf(fp, "iselect("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, ", "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case AND: - (void) fprintf(fp, "and%d(", np->width); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case OR: - (void) fprintf(fp, "or%d(", np->width); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case XOR: - (void) fprintf(fp, "xor%d(", np->width); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case FIN: - if (Base < 3) - lose(E997, emitlineno, (char *)NULL); - (void) fprintf(fp, "fin%d(", np->width); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case WHIRL: - case WHIRL2: - case WHIRL3: - case WHIRL4: - case WHIRL5: - if (np->opcode - WHIRL + 3 > Base) - lose(E997, emitlineno, (char *)NULL); - (void) fprintf(fp, "whirl%d(%d, ", np->width, np->opcode - WHIRL + 1); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case MESH: - (void) fprintf(fp, "0x%lx", np->constant); - break; - - case MESH32: - (void) fprintf(fp, "0x%lx", np->constant); - break; - - case ONESPOT: - case TWOSPOT: - case TAIL: - case HYBRID: - prvar(np, fp, freenode); - break; - - case SUB: - (void) fprintf(fp, "*(%s*)", nameof(np->lval->opcode, typedefs)); - prvar(np, fp, freenode); - break; - - /* cases from here down are generated by the optimizer */ - case C_AND: - (void) fprintf(fp, "("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " & "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case C_OR: - (void) fprintf(fp, "("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " | "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case C_XOR: - (void) fprintf(fp, "("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " ^ "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case C_NOT: - (void) fprintf(fp, "(~"); - prexpr(np->rval, fp, freenode); - if (np->rval->width == Small_digits) - (void) fprintf(fp, " & Max_small)"); - else - (void) fprintf(fp, " & Max_large)"); - break; - - /* AIS: I added the rest of the cases */ - case C_NOTEQUAL: - (void) fprintf(fp, "("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " != "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case C_NNAND: - (void) fprintf(fp, "(!!("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " & "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, "))"); - break; - - case C_AND1ADD1: - (void) fprintf(fp, "(("); - prexpr(np->rval,fp, freenode); - (void) fprintf(fp, " & 0x1) + 0x1)"); - break; - - case C_1PLUS: - (void) fprintf(fp, "("); - prexpr(np->rval,fp, freenode); - (void) fprintf(fp, " + 0x1)"); - break; - - case C_2MINUS: - (void) fprintf(fp, "(0x2 - "); - prexpr(np->rval,fp, freenode); - (void) fprintf(fp, ")"); - break; - - case C_2SUBAND1: - (void) fprintf(fp, "(0x2 - ("); - prexpr(np->rval,fp, freenode); - (void) fprintf(fp, " & 0x1))"); - break; - - case C_LSHIFT: - (void) fprintf(fp, "(("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " & "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ") << 0x1)"); - break; - - case C_LSHIFTIN1: - (void) fprintf(fp, "((("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " & "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ") << 0x1) | 0x1)"); - break; - - case C_LSHIFT2: - (void) fprintf(fp, "(("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " & "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ") << 0x2)"); - break; - - case C_LSHIFT8: - (void) fprintf(fp, "(("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " & "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ") << 0x8)"); - break; - - case C_RSHIFTBY: - (void) fprintf(fp, "(("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, ") >> "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case C_RSHIFT: - (void) fprintf(fp, "(("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " & "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ") >> 0x1)"); - break; - - case C_XORGREATER: - (void) fprintf(fp, "("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " > ("); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, " ^ "); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, "))"); - break; - - case C_ISNONZERO: - (void) fprintf(fp, "(!!("); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, "))"); - break; - - case GETS: /* AIS: this is used only if freenode == 0 */ - if(freenode) lose(E778, emitlineno, (char*) NULL); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " = "); - prexpr(np->rval, fp, freenode); - break; - - default: /* Added by AIS */ - if(!freenode) break; /* Be less careful when not freeing, because - this is used by -hH to print out its - intermediate optimization stages */ - lose(E778, emitlineno, (char*) NULL); - break; - } - - if(freenode) (void) free(np); -} - -static char *nice_text(char *texts[], int lines) -{ -#define MAXNICEBUF 512 - static char buf[MAXNICEBUF]; - char *cp, *text; - int i; - - if (lines < 1) - lines = 1; - for (cp = buf, i = 0 ; i < lines ; ++i) { - if (cp>buf+MAXNICEBUF-10) goto abort; - if (i) { - (*cp++) = '\\'; - (*cp++) = 'n'; - (*cp++) = '\\'; - (*cp++) = '\n'; - (*cp++) = '\t'; - } - for (text = texts[i] ; text&&*text ; cp++, text++) { - if (cp>buf+MAXNICEBUF-10) goto abort; - if(*text == '"' || *text == '\\') { - (*cp++) = '\\'; - } - *cp = *text; - } - } - *cp = '\0'; - return buf; -abort: (*cp++) = '.'; - (*cp++) = '.'; - (*cp++) = '.'; - *cp = '\0'; - return buf; -} - -static void emit_guard(tuple *tn, FILE *fp) -/* emit execution guard for giiven tuple (note the unbalanced trailing {!) */ -{ - if(tn->maybe) /* AIS */ - { - if(!multithread) lose(E405, emitlineno, (char *)NULL); - (void) fprintf(fp, " gonebackto = setjmp(btjb); choicepoint();\n"); - } - if(!flowoptimize || tn->abstainable) /* This condition by AIS */ - { - (void) fprintf(fp, " if ("); - if (tn->maybe) /* AIS */ - (void) fprintf(fp, "gonebackto == !("); - if (tn->exechance < 100) - (void) fprintf(fp, "roll(%d) && ", tn->exechance); - if ((tn->type != NEXT && tn->type != GO_BACK && tn->type != COME_FROM) - || tn->onceagainflag == onceagain_NORMAL) - (void) fprintf(fp, "!abstained[%d])%s {\n", (int)(tn - tuples), - /* AIS */ tn->maybe?")":""); - else /* AIS: [NEXT, GO_BACK, COME_FROM] ONCE needs specially - handled abstentions */ - (void) fprintf(fp, "!oldabstain)%s {\n", - /* AIS */ tn->maybe?")":""); - } - else - { /* AIS */ - if(tn->maybe) lose(E778, emitlineno, (char*) NULL); - if(!tn->initabstain) - { - if(tn->type != COMPUCOME) (void) fprintf(fp, " {\n"); - else (void) fprintf(fp, " if(1) {\n"); /* COMPUCOME specifically needs - an if() so it can have - an else. */ - } - else (void) fprintf(fp, " if(0) {\n"); /* for exceptional cases like - DON'T COME FROM #1 where we - need a label or an else. */ - } -} - -void emittextlines(FILE *fp) -{ - int i=-1; - while(i++lineno); - if (tn->label) - (void) fprintf(fp, "L%d:", tn->label); - if (yydebug || compile_only) - { - (void) fprintf(fp, "\t/* %s */", textlines[tn->lineno]); - /* AIS: grind out an expression explanation */ - if (tn->type == GETS || tn->type == FORGET || tn->type == RESUME - || tn->type == FROM || tn->type == COMPUCOME - || tn->type == MANYFROM) - { - (void) fprintf(fp, "\n\t/* Expression is "); - explexpr(tn->type == MANYFROM ? tn->u.node->lval : - tn->type == GETS ? tn->u.node->rval : tn->u.node, fp); - (void) fprintf(fp, " */"); - } - } - (void) fputc('\n', fp); - - /* set up the "next" lexical line number for error messages */ - if (tn->type == NEXT) { - tuple *up; - for (up = tuples; up < tuples + lineno; up++) - if (tn->u.target == up->label) { - emitlineno = up->lineno; - break; - } - } else if (tn->ncomefrom) - emitlineno = comefromsearch(tn,1); /* AIS: For multithreading. - Return the 1st if we're forking. */ - else if (tn < tuples + lineno - 1) - emitlineno = tn[1].lineno; - else - emitlineno = yylineno; - (void) fprintf(fp, " lineno = %d;\n", emitlineno); - - /* print warnings on -l */ - if(checkforbugs) - { - if(tn->warn112) lwarn(W112, emitlineno, (char*) NULL); - if(tn->warn128) lwarn(W128, emitlineno, (char*) NULL); - if(tn->warn534) lwarn(W534, emitlineno, (char*) NULL); - if(tn->warn018) lwarn(W018, emitlineno, (char*) NULL); - if(tn->warn016) lwarn(W016, emitlineno, (char*) NULL); - if(tn->warn276) lwarn(W276, emitlineno, (char*) NULL); - if(tn->warn239) lwarn(W239, emitlineno, (char*) NULL); - if(tn->warn622) lwarn(W622, emitlineno, (char*) NULL); - } - - /* emit debugging information */ - if (yukdebug||yukprofile) - { - (void) fprintf(fp, " YUK(%d,%d);\n", - (int)(tn-tuples),emitlineno); - } - - /* AIS: The +mystery option on degenerated code causes the code to - unexpectedly terminate after 4 billion commands are run, thus - preventing an infinite loop. Of course, it will enhance the fun - if we don't tell the user that. (This is necessary for the - constant-output optimizer to work properly.) */ - (void) fprintf(fp, " MYSTERYLINE;\n"); - - /* AIS: If the tuple is ONCE/AGAIN flagged, we need a delayed-action - set of its abstention status to the AGAIN-flagged status. The - problem is that some statements, like COME FROM, need to set after - the command has finished, and some, like NEXT, need it before the - command has started. At the moment, only NEXT and GO_BACK have a - ONCE/AGAIN before it, rather than after (because neither of them - continue in the normal fashion). */ - if ((tn->type == NEXT || tn->type == GO_BACK) && - tn->onceagainflag != onceagain_NORMAL) - { - /* ONCE/AGAIN has already been swapped by perpetrate.c in the case - of a preabstained statement ('DO NOT'...). So if currently have - a ONCE, it means that being abstained is the attractive state, - and if we currently have an AGAIN, it means that being - reinstated is the attractive state. Semantics with computed - ABSTAIN: Don't change the abstention count unless necessary, in - which case change it to 0 or 1. */ - fprintf(fp," oldabstain = abstained[%d];\n", (int)(tn - tuples)); - fprintf(fp," abstained[%d] = %s;\n", - (int)(tn - tuples), - tn->onceagainflag==onceagain_ONCE ? "oldabstain ? oldabstain : 1" - : "0"); - /* This test-and-set must be atomic. As all statements are atomic anyway - in the current version of ick, that isn't a problem, but if anyone - wants to try using POSIX's multithreading features, the above two - lines need to be a critical section. */ - } - - /* in the case of COMPUCOME, we need an extra guard */ - if (tn->type == COMPUCOME) - { - fprintf(fp," if(0)\n {\n"); - fprintf(fp,"CCF%d:\n",compucomecount++); - fprintf(fp," if(skipto=="); - prexpr(tn->u.node, fp, 1); - fprintf(fp,") {\n"); - } - - /* AIS: With this block placed here, you can't even have a comment - after a TRY AGAIN line. Move it below the next check if this seems - to be undesirable behaviour. */ - if(pasttryagain) /* AIS */ - { - lose(E993, emitlineno, (char*)NULL); - } - - if(flowoptimize && tn->initabstain && !tn->abstainable - && tn->type != COMPUCOME && tn->type != COME_FROM && - tn->type != NEXT) /* AIS */ - goto skipcomment; /* Look, a comment! We can completely skip all - degeneration of this statement (although with - -c, comments will appear in the degenerated - code in its place). The COMPUCOME condition is - because it is so weird. COME_FROM and NEXT are - exempted so labels are generated. */ - - /* emit conditional-execution prefixes */ - if (tn->type != COME_FROM) - emit_guard(tn, fp); - - /* now emit the code for the statement body */ - switch(tn->type) - { - case GETS: - /* Start of AIS optimization */ - np = tn->u.node; - if(np->lval->opcode == SUB) np = np->lval; - if(flowoptimize && - (np->lval->opcode == TWOSPOT - || np->lval->opcode == HYBRID - || !(tn->u.node->lval->optdata & ~0xffffLU))) - { - atom* op; - int ignorable = 1; - for(op = oblist; op < obdex; op++) - { - if(op->type == np->lval->opcode && - op->intindex == np->lval->constant) - { - ignorable &= op->ignorable; - } - } - if(!ignorable) - { /* Variable can't be ignored, and expression must be in range */ - (void) fprintf(fp,"\t"); - prexpr(tn->u.node->lval, fp, 1); - (void) fprintf(fp, " = "); - prexpr(tn->u.node->rval, fp, 1); - (void) fprintf(fp, ";\n"); - break; - } - } - /* End of AIS optimization */ - - np = tn->u.node; - - if (np->lval->opcode != SUB) { - sp = np->lval; - (void) fprintf(fp,"\t(void) assign((char*)&"); - } - else { - sp = np->lval->lval; - (void) fprintf(fp,"\t(void) assign("); - } - prvar(np->lval, fp, 1); - (void) fprintf(fp,", %s", nameof(sp->opcode, vartypes)); - (void) fprintf(fp,", %s[%lu], ", nameof(sp->opcode, forgetbits), - sp->constant); - prexpr(np->rval, fp, 1); - (void) fprintf(fp,");\n"); - break; - - case RESIZE: - np = tn->u.node; - dim = 0; - for (sp = np->rval; sp; sp = sp->rval) - dim++; - (void) fprintf(fp, "\tresize("); - prvar(np->lval, fp, 1); - (void) fprintf(fp, ", %s[%lu]", nameof(np->lval->opcode, forgetbits), - np->lval->constant); - (void) fprintf(fp, ", %d", dim); - for (sp = np->rval; sp; sp = sp->rval) { - (void) fprintf(fp, ", "); - prexpr(sp->lval, fp, 1); - } - (void) fprintf(fp, ");\n"); - break; - - case NEXT: - /* Start of AIS optimization */ - if(tn->optversion) - { /* optimizef has checked that this is a valid optimization */ - (void) fprintf(fp, "\tif(1 == "); - prexpr(tn->u.node, fp, 1); /* frees optimizef's nodecopy */ - (void) fprintf(fp, ") {pushnext(%d); goto N%d;} N%d:;\n", - (int)(tn - tuples + 1), tn->nexttarget, (int)(tn - tuples + 1)); - break; - } - /* End of AIS optimization */ - (void) fprintf(fp, - "\tpushnext(%d); goto L%d; N%d:;\n", - (int)(tn - tuples + 1), tn->u.target, (int)(tn - tuples + 1)); - break; - - case GO_BACK: /* By AIS */ - if(!multithread) lose(E405, emitlineno, (char*) NULL); - (void) fprintf(fp, "\tchoiceback();\n"); - break; - - case GO_AHEAD: /* By AIS */ - if(!multithread) lose(E405, emitlineno, (char*) NULL); - (void) fprintf(fp, "\tchoiceahead();\n"); - break; - - case RESUME: - (void) fprintf(fp, "\tskipto = resume("); - prexpr(tn->u.node, fp, 1); - (void) fprintf(fp, "); goto top;\n"); - break; - - case FORGET: - (void) fprintf(fp, "\tpopnext("); - prexpr(tn->u.node, fp, 1); - (void) fprintf(fp, ");\n"); - break; - - case STASH: - for (np = tn->u.node; np; np = np->rval) - (void) fprintf(fp, "\tstash(%s, %lu, %s+%lu);\n", - nameof(np->opcode, vartypes), - np->constant, - nameof(np->opcode, varstores), np->constant); - break; - - case RETRIEVE: - for (np = tn->u.node; np; np = np->rval) - (void) fprintf(fp, "\tretrieve(%s+%lu, %s, %lu, %s[%lu]);\n", - nameof(np->opcode, varstores), np->constant, - nameof(np->opcode, vartypes), - np->constant, - nameof(np->opcode, forgetbits), - np->constant); - break; - - case IGNORE: - for (np = tn->u.node; np; np = np->rval) - (void) fprintf(fp,"\t%s[%lu] = TRUE;\n", - nameof(np->opcode, forgetbits), - np->constant); - break; - - case REMEMBER: - for (np = tn->u.node; np; np = np->rval) - (void) fprintf(fp,"\t%s[%lu] = FALSE;\n", - nameof(np->opcode, forgetbits), - np->constant); - break; - - /* All abstention code has been edited by AIS to allow for the new abstention rules */ - case ABSTAIN: - (void) fprintf(fp, "\tif(!abstained[%d]) abstained[%d] = 1;\n", tn->u.target - 1, tn->u.target-1); - break; - - case FROM: - (void) fprintf(fp, "\tabstained[%d]+=", tn->u.target-1); - tn->u.node->width = 32; - prexpr(tn->u.node,fp, 1); - (void) fprintf(fp, ";\n"); - break; - - case REINSTATE: - (void) fprintf(fp, "\tif(abstained[%d]) abstained[%d]--;\n", tn->u.target - 1, tn->u.target-1); - break; - - case ENABLE: - (void) fprintf(fp, - "\tint i;\n"); - for (np = tn->u.node; np; np = np->rval) - { - (void) fprintf(fp, - "\n\tfor (i = 0; i < (int)(sizeof(linetype)/sizeof(int)); i++)\n"); - if (np->constant == ABSTAIN) { - (void) fprintf(fp, - "\t if (linetype[i] == %s || linetype[i] == %s || linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2], enablers[FROM-GETS], enablers[MANYFROM-GETS]); - } else if (np->constant == REINSTATE) { - (void) fprintf(fp, - "\t if (linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2]); - } else { - (void) fprintf(fp, - "\t if (linetype[i] == %s)\n", enablers[np->constant-GETS]); - } - (void) fprintf(fp, - "\t\tif(abstained[i]) abstained[i]--;\n"); - } - break; - - case DISABLE: - (void) fprintf(fp, - "\tint i;\n"); - for (np = tn->u.node; np; np = np->rval) - { - (void) fprintf(fp, - "\n\tfor (i = 0; i < (int)(sizeof(linetype)/sizeof(int)); i++)\n"); - if (np->constant == ABSTAIN) { - (void) fprintf(fp, - "\t if (linetype[i] == %s || linetype[i] == %s || linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2], enablers[FROM-GETS], enablers[MANYFROM-GETS]); - } else if (np->constant == REINSTATE) { - (void) fprintf(fp, - "\t if (linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2]); - } else { - (void) fprintf(fp, - "\t if (linetype[i] == %s)\n", enablers[np->constant-GETS]); - } - (void) fprintf(fp, - "\t\tif(!abstained[i]) abstained[i] = 1;\n"); - } - break; - - case MANYFROM: - (void) fprintf(fp, - "\tint i;\n\tint j;\n\tj="); - tn->u.node->lval->width=32; - prexpr(tn->u.node->lval,fp, 1); - (void) fprintf(fp, - ";\n"); - for (np = tn->u.node->rval; np; np = np->rval) - { - (void) fprintf(fp, - "\n\tfor (i = 0; i < (int)(sizeof(linetype)/sizeof(int)); i++)\n"); - if (np->constant == ABSTAIN) { - (void) fprintf(fp, - "\t if (linetype[i] == %s || linetype[i] == %s || linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2], enablers[FROM-GETS], enablers[MANYFROM-GETS]); - } else if (np->constant == REINSTATE) { - (void) fprintf(fp, - "\t if (linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2]); - } else { - (void) fprintf(fp, - "\t if (linetype[i] == %s)\n", enablers[np->constant-GETS]); - } - (void) fprintf(fp, - "\t\tabstained[i] += j;\n"); - } - break; - - case COMPUCOME: /* By AIS. Note that this doesn't even have balanced - braces; it's designed to work with COMPUCOME's - crazy guarding arrangements */ - fprintf(fp,"\t;} else goto CCF%d;\n",compucomecount); - break; - - case GIVE_UP: /* AIS: Edited to allow for yuk */ - if(yukprofile||yukdebug) fprintf(fp, "\tYUKTERM;\n"); - if(multithread) fprintf(fp, "\tkillthread();\n"); - (void) fprintf(fp, "\treturn(0);\n"); - break; - - case TRY_AGAIN: /* By AIS */ - (void) fprintf(fp, "\tgoto ick_restart;\n }\n"); - if(yukprofile||yukdebug) fprintf(fp, " if(yukloop) goto ick_restart;\n"); - if(yukprofile||yukdebug) fprintf(fp, " YUKTERM;\n"); - if(multithread) fprintf(fp, "\tkillthread();\n"); - (void) fprintf(fp, " {\n\treturn(0);\n"); - /* because if TRY AGAIN is the last line, falling off the end isn't an error */ - pasttryagain=1; /* flag an error if we try any more commands */ - break; - - case WRITE_IN: - for (np = tn->u.node; np; np = np->rval) { - if (np->lval->opcode == TAIL || np->lval->opcode == HYBRID) { - (void) fprintf(fp,"\tbinin("); - prvar(np->lval, fp, 1); - (void) fprintf(fp, ", %s[%lu]", - nameof(np->lval->opcode, forgetbits), - np->lval->constant); - (void) fprintf(fp,");\n"); - } - else { - if (np->lval->opcode != SUB) { - sp = np->lval; - (void) fprintf(fp,"\t(void) assign((char*)&"); - } - else { - sp = np->lval->lval; - (void) fprintf(fp,"\t(void) assign("); - } - prvar(np->lval, fp, 1); - (void) fprintf(fp,", %s", nameof(sp->opcode, vartypes)); - (void) fprintf(fp,", %s[%lu]", nameof(sp->opcode, forgetbits), - sp->constant); - (void) fprintf(fp,", pin());\n"); - } - } - break; - - case READ_OUT: - for (np = tn->u.node; np; np = np->rval) - { - if (np->lval->opcode == TAIL || np->lval->opcode == HYBRID) { - (void) fprintf(fp,"\tbinout("); - prvar(np->lval, fp, 1); - (void) fprintf(fp,");\n"); - } - else { - (void) fprintf(fp, "\tpout("); - prexpr(np->lval, fp, 1); - (void) fprintf(fp, ");\n"); - } - } - break; - - case SPLATTERED: - dim = emitlineno - tn->lineno; - if (tn->sharedline) - ++dim; - (void) fprintf(fp, "\tlose(E000, %d, \"%s\");\n", - emitlineno, nice_text(textlines + tn->lineno, dim)); - break; - - case COME_FROM: - (void) fprintf(fp, "C%ld:\n", (long)(tn-tuples+1)); - /* AIS: Changed so all COME_FROMs have unique labels even if two - of them aim at the same line. */ - break; - - default: - lose(E778, emitlineno, (char *)NULL); - break; - } - - if (tn->type != COME_FROM) - (void) fprintf(fp, " }\n"); - - skipcomment: - - if (tn->type == COMPUCOME) - { /* By AIS */ - (void) fprintf(fp," else goto CCF%d;\n",compucomecount); - (void) fprintf(fp," ccfc++;\n"); - /* Note that due to the semantics of setjmp, this has to be written as 2 - separate ifs. The MULTICOME macro expands to a non-multithreaded or - multithreaded function for handling a COME FROM clash. */ - (void) fprintf(fp," if(ccfc==1||MULTICOME(%d,cjb))\n" - "\tif(setjmp(cjb) == 0) goto CCF%d;\n", - emitlineno, compucomecount); - /* Of course, emitlineno is unlikely to be helpful! */ - (void) fprintf(fp," }\n"); - } - - /* AIS: Before any COMING FROM this line is done, we need to sort out - ONCE and AGAIN situations, unless this line was a NEXT or GO_BACK. - COME FROM is also excluded because it acts at the suckpoint, not - at the place it's written in the program. */ - if (tn->onceagainflag != onceagain_NORMAL && - (tn->type != NEXT && tn->type != GO_BACK && tn->type != COME_FROM)) - { - /* See my comments against the NEXT code for more information. - This code is placed here so COME FROM ... ONCE constructs work - properly (the line is abstained if the COME FROM is reached in - execution, or its suckpoint is reached in execution). */ - fprintf(fp," oldabstain = abstained[%d];\n", (int)(tn - tuples)); - fprintf(fp," abstained[%d] = %s;\n", - (int)(tn - tuples), - tn->onceagainflag==onceagain_ONCE ? "oldabstain ? oldabstain : 1" - : "0"); - } - - /* AIS: This is where we start the COME FROM suckpoint code. */ - - /* AIS: We need to keep track of how many COME FROMs are aiming here - at runtime, if we don't have the very simple situation of no - COMPUCOMEs and a single-thread program (in which case the check - is done at compile-time by codecheck). Even without COMPUCOME, - this can change in a multithread program due to abstentions. */ - if((tn->ncomefrom && multithread) || (tn->label && compucomesused)) - (void) fprintf(fp, " ccfc = 0;\n"); - - /* - * If the statement that was just degenerated was a COME FROM target, - * emit the code for the jump to the COME FROM. - * AIS: Changed most of this to allow for multithreading. - */ - while(tn->ncomefrom) /* acts as an if if singlethreading */ - { - tuple* cf; /* local to this block */ - if(multithread || compucomesused) generatecfjump = 1; - cf = tuples+comefromsearch(tn,tn->ncomefrom)-1; - if (yydebug || compile_only) - (void) fprintf(fp, - " /* line %03d is a suck point for the COME FROM " - "at line %03d */\n", tn->lineno, cf->lineno); - if (cf->onceagainflag != onceagain_NORMAL) - { /* Calculate ONCE/AGAIN when the suckpoint is passed */ - fprintf(fp," oldabstain = abstained[%d];\n", (int)(cf - tuples)); - fprintf(fp," abstained[%d] = %s;\n", - (int)(cf - tuples), - cf->onceagainflag==onceagain_ONCE ? "oldabstain ? oldabstain : 1" - : "0"); - } - emit_guard(cf, fp); - if(multithread || compucomesused) - (void) fprintf(fp, - "\tccfc++;\tif(ccfc==1||MULTICOME(%d,cjb)) " - "if(setjmp(cjb) == 1) goto C%ld;\n }\n", - emitlineno, (long)(cf-tuples+1)); - else /* optimize for the simple case */ - (void) fprintf(fp, "\tgoto C%ld;\n }\n", (long)(cf-tuples+1)); - tn->ncomefrom--; - } - - /* AIS: If the statement has a label, it might be a - computed COME FROM target. Also check the flag that says this - code is needed in a multithread non-COMPUCOME program. - If (at runtime) ccfc is nonzero, we know cjb has already been set; - otherwise, set it now. In the case of a multithread non-COMPUCOME - program, the goto will just jump to a longjmp, switching to the - one and only one COME FROM that hasn't been given its own thread. */ - if ((tn->label && compucomesused) || generatecfjump) - { - if(compucomesused) (void) fprintf(fp, " skipto = %d;\n", tn->label); - if(generatecfjump) (void) fprintf(fp, " if(ccfc) goto CCF0;\n"); - if(compucomesused) - { /* check all the COMPUCOMES */ - (void) fprintf(fp, " %sif(setjmp(cjb) == 0) goto CCF0;\n", - generatecfjump?"else ":""); - } - generatecfjump = 0; - } - - /* AIS: Now we've finished the statement, let's switch to the next - thread in a multithread program. */ - if(multithread) (void) fputs(" NEXTTHREAD;\n", fp); -} - -/* feh.c ends here */ diff --git a/feh.h b/src/feh.h similarity index 56% rename from feh.h rename to src/feh.h index ae55dc5..582364a 100644 --- a/feh.h +++ b/src/feh.h @@ -2,7 +2,7 @@ extern node *newnode(void); extern node *cons(int type, node *car, node *cdr); -extern unsigned int intern(int type, int index); +extern unsigned int intern(int type, unsigned int index); extern void checklabel(int label); extern void treset(void); extern tuple *newtuple(void); @@ -12,11 +12,17 @@ extern void optimize(node *np); extern char *nameof(int value, assoc table[]); extern void emit(tuple *tn, FILE *fp); extern void emittextlines(FILE *fp); +extern void emitslatproto(FILE *fp); /* AIS: emit prototypes for /-functions */ +extern void emitslat(FILE* fp); /* AIS: emit bodies of /-functions */ extern int comefromsearch(tuple *tn, unsigned int index); /* AIS */ extern void explexpr(node* np, FILE* fp); /* AIS */ extern void optimizef(); /* AIS */ +extern void nodefree(node* np); /* AIS */ +extern unsigned long varextern(unsigned long intern, int vartype); /* AIS */ -extern char *enablers[MAXTYPES]; +extern char **enablers; /* AIS: so that there can be an element before the + first element of the array (UNKNOWN is element + -1, just to cause a bit more confusion) */ extern assoc vartypes[]; /* feh.h ends here */ diff --git a/src/feh2.c b/src/feh2.c new file mode 100644 index 0000000..576ae2d --- /dev/null +++ b/src/feh2.c @@ -0,0 +1,2297 @@ +/**************************************************************************** + +Name + feh2.c -- code-generator back-end for ick parser + +DESCRIPTION + This module provides storage manglement and code degeneration + for the INTERCAL compiler. Optimizations (formerly in this file) + were split into dekludge.c. + +LICENSE TERMS + Copyright (C) 1996 Eric S. Raymond + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +****************************************************************************/ +/*LINTLIBRARY */ +#include +#include +#include +#include "sizes.h" +#include "ick.h" +#include "parser.h" +#include "fiddle.h" +#include "lose.h" +#include "feh.h" + +/* AIS: Destaticed for dekludge.c */ +int emitlineno; /* line number for errors encountered during emit */ + +int mark112 = 0; /* AIS: Mark the next generated tuple for W112 */ + +/* AIS: From perpet.c */ +extern int pickcompile; + +/************************************************************************* + * + * Node allocation functions. + * + * Nodes are used to represent expression trees. The emit() function + * deallocates them. + * + **************************************************************************/ + +node *newnode(void) +/* allocate and zero out a new expression node */ +{ + return((node *)calloc(sizeof(node), 1)); +} + +node *cons(int type, node *car, node *cdr) +{ + node *np = newnode(); + + np->opcode = type; + np->lval = car; + np->rval = cdr; + + return(np); +} + +/************************************************************************* + * + * Variable-name mapping + * + * This permits us to optimize use of variable storage at runtime + * + **************************************************************************/ + +unsigned int intern(int type, unsigned int index) +{ + atom *x; + + /* AIS: Allow use of a modifiable constant 0. */ + if ((index < 1 || index > 65535) && type!=MESH) + lose(E200, yylineno, (char *)NULL); + + if (!oblist) + { + /* initialize oblist and obdex */ + oblist = malloc(ALLOC_CHUNK * sizeof(atom)); + if (!oblist) + lose(E778, yylineno, (char *)NULL); + obdex = oblist; + obcount = ALLOC_CHUNK; + } + + /* if it's already on the oblist, return its intindex */ + for (x = oblist; x < obdex; x++) + if (x->type == type && x->extindex == index) + return(x->intindex); + + /* else we must intern a new symbol */ + if (obdex >= oblist + obcount) + { + obcount += ALLOC_CHUNK; + x = realloc(oblist, obcount * sizeof(atom)); + if (!x) + lose(E333, yylineno, (char *)NULL); + obdex = x + (obdex - oblist); + oblist = x; + } + obdex->type = type; + obdex->extindex = index; + obdex->memloc = 0; /* AIS: not placed in memory yet */ + if (type == ONESPOT) + obdex->intindex = nonespots++; + if (type == TWOSPOT) + obdex->intindex = ntwospots++; + if (type == TAIL) + obdex->intindex = ntails++; + if (type == HYBRID) + obdex->intindex = nhybrids++; + if (type == MESH) /* AIS: count meshes too */ + obdex->intindex = nmeshes++; + ++obdex; + + return(obdex[-1].intindex); +} + +/************************************************************************* + * + * This function insures a label is valid. + * + **************************************************************************/ + +void checklabel(int label) +{ + if (label < 1 || label > 65535) + lose(E197, yylineno, (char *)NULL); +} + +/************************************************************************* + * + * AIS: Search for the indexth COME_FROM sucking in the given tuple. + * Return an int representing the COME_FROM's tn-tuples+1, or -1. + * index is based at 1, not 0 as is usual for C. + * + ***************************************************************************/ + +int comefromsearch(tuple* tn, unsigned int index) +{ + tuple* tp; + for (tp = tuples; tp < tuples + lineno; tp++) + { + if((tp->type == COME_FROM || tp->type == NEXTFROMLABEL) + && tp->u.target == (unsigned)(tn-tuples+1)) + index--; + if(!index) return tp-tuples+1; + } + return -1; +} + +/************************************************************************* + * + * Tuple allocation functions. + * + **************************************************************************/ + +void treset(void) +{ + tuplecount = 0; + if (tuples) + { + free(tuples); + tuples = NULL; + } + nonespots = ntwospots = ntails = nhybrids = 0; + obdex = oblist; + lineno = 0; +} + +tuple *newtuple(void) +/* allocate and zero out a new expression tuple */ +{ + if (lineno >= tuplecount) + { + tuplecount += ALLOC_CHUNK; + if (tuples) + tuples = realloc(tuples, tuplecount * sizeof(tuple)); + else + tuples = malloc(tuplecount * sizeof(tuple)); + if (!tuples) + { + lose(E666, yylineno, (char *)NULL); + return NULL; + } + memset(tuples + lineno, 0, (tuplecount - lineno) * sizeof(tuple)); + } + if(mark112) tuples[lineno].warn112 = 1; mark112 = 0; /* AIS */ + return(tuples + lineno++); +} + +/************************************************************************* + * + * The typecaster + * + * The theory here is that we associate a type with each node in order to + * know what widths of unary-logical operator to use. + * + **************************************************************************/ + +void typecast(node *np) +{ + /* recurse so we typecast each node after all its subnodes */ + if (np == (node *)NULL) + return; + else if (np->lval != (node *)NULL) + typecast(np->lval); + if (np->rval != (node *)NULL) + typecast(np->rval); + + /* + * This is an entire set of type-deducing machinery right here. + */ + if (np->opcode == MESH || np->opcode == ONESPOT || np->opcode == TAIL) + np->width = 16; + else if (np->opcode == TWOSPOT || np->opcode == HYBRID + || np->opcode == MINGLE || np->opcode == MESH32) + np->width = 32; + else if (np->opcode == AND || np->opcode == OR || np->opcode == XOR || + np->opcode == FIN || + (np->opcode >= WHIRL && np->opcode <= WHIRL5)) + np->width = np->rval->width; + else if (np->opcode == SELECT) + np->width = np->rval->width; /* n-bit select has an n-bit result */ + else if (np->opcode == SUB) + np->width = np->lval->width; /* type of the array */ + else if (np->opcode == SLAT || np->opcode == BACKSLAT) + np->width = np->lval->width; /* AIS: \ and / return their left arg */ +} + +/************************************************************************* + * + * The codechecker + * + * This checks for nasties like mismatched types in assignments that + * can be detected at compile time -- also for errors that could cause + * the compilation of the generated C to fail, like generated gotos to + * nonexistent labels or duplicate labels. + * + * AIS: codecheck has another important job, that of filling in information + * about COME FROM suckpoints and ABSTAIN/REINSTATE command numbers + * into the tuples. + * + **************************************************************************/ + +void codecheck(void) +{ + tuple *tp, *up; + int notpast1900; /* AIS */ + + /* check for assignment type mismatches */ + /* This check can't be done at compile time---RTFM. [LHH] */ +/* + for (tp = tuples; tp < tuples + lineno; tp++) + if (tp->type == GETS) + if (tp->u.node->lval->width == 16 && tp->u.node->rval->width == 32) + lose(E275, tp - tuples + 1, (char *)NULL); +*/ + + /* check for duplicate labels */ + for (tp = tuples; tp < tuples + lineno; tp++) + if (tp->label) + for (up = tuples; up < tuples + lineno; up++) + if (tp != up && tp->label == up->label) + lose(E182, tp - tuples + 1, (char *)NULL); + + /* + * Check that every NEXT, ABSTAIN, REINSTATE and COME_FROM actually has a + * legitimate target label. + */ + notpast1900 = TRUE; + for (tp = tuples; tp < tuples + lineno; tp++) + { + if (tp->label == 1900) notpast1900 = FALSE; /* AIS */ + if (tp->type == NEXT + || tp->type == ABSTAIN || tp->type == REINSTATE + || tp->type == COME_FROM || tp->type == FROM + || tp->type == NEXTFROMLABEL) /* AIS: added FROM, NEXTFROMLABEL. */ + { + bool foundit = FALSE; + + if (tp->u.target >= 1900 && tp->u.target <= 1998) + { + /* AIS: This program uses syslib.i's random number feature... or are + we in syslib already? */ + if(notpast1900) coopt = 0; + } + + for (up = tuples; up < tuples + lineno; up++) + if (tp->u.target == up->label) + { + foundit = TRUE; + break; + } + + if (!foundit) + { + /* AIS: Added the pickcompile check. Syslib has to be optimized + for PICs, so syslib.i isn't imported and so none of the lables + in it will appear in the program. */ + if (tp->type == NEXT && + (!pickcompile||tp->u.target<1000||tp->u.target>1999)) + lose(E129, tp - tuples + 1, (char *)NULL); + else if (tp->type == NEXT) /* AIS */ + {tp->nexttarget=0; continue;} + /* AIS: NEXTFROMLABEL's basically identical to COME_FROM */ + else if (tp->type == COME_FROM || tp->type == NEXTFROMLABEL) + lose(E444, tp - tuples + 1, (char *)NULL); + else + lose(E139, tp - tuples + 1, (char *)NULL); + } + /* tell the other tuple if it is a COME FROM target */ + /* AIS: NEXTFROMLABEL again */ + else if (tp->type == COME_FROM || tp->type == NEXTFROMLABEL) + { + if (up->ncomefrom && !multithread) /* AIS: multithread check */ + lose(E555, yylineno, (char *)NULL); + else + up->ncomefrom++; /* AIS: to handle multiple COME FROMs */ + } + /* this substitutes line numbers for label numbers + AIS: COME FROM now uses this too. This changes the logic + slightly so that an !foundit condition would fall through, + but as long as lose doesn't return, it's not a problem. + (I removed the else before the if.) */ + if (tp->type != NEXT) + { + tp->u.target = up - tuples + 1; + } + else /* AIS */ + { + tp->nexttarget = up - tuples + 1; + up->nextable = TRUE; + } + } + } +} + +/* AIS: Added the third argument to prexpr and prvar. It specifies + whether the node should be freed or not. I added the third + argument in all calls of prexpr/prvar. This protoype has been moved + up through the file so it can be used earlier. Destaticed so it can + be referenced by dekludge.c. */ +void prexpr(node *np, FILE *fp, int freenode); +/************************************************************************* + * + * Code degeneration + * + * The theory behind this crock is that we've been handed a pointer to + * a tuple representing a single INTERCAL statement, possibly with an + * expression tree hanging off it and twisting slowly, slowly in the wind. + * + * Our mission, should we choose to accept it, is to emit C code which, + * when linked to the INTERCAL run-time support, will do something + * resembling the right thing. + * + **************************************************************************/ + +/* + * If the order of statement-token defines in parser.y ever changes, + * this will need to be reordered. + */ +char *enablersm1[MAXTYPES+1] = +{ + "UNKNOWN", /* AIS: so comments can be ABSTAINED/REINSTATED */ + "GETS", + "RESIZE", + "NEXT", + "GO_AHEAD", /* AIS: Added for backtracking */ + "GO_BACK", /* AIS: Added for backtracking */ + "FORGET", + "RESUME", + "STASH", + "RETRIEVE", + "IGNORE", + "REMEMBER", + "ABSTAIN", + "REINSTATE", + "DISABLE", + "ENABLE", + "MANYFROM", /* AIS: Added ABSTAIN expr FROM gerunds */ + "GIVE_UP", + "READ_OUT", + "WRITE_IN", + "PIN", + "COME_FROM", + "NEXTFROMLABEL", /* AIS */ + "NEXTFROMEXPR", /* AIS */ + "NEXTFROMGERUND", /* AIS */ + "COMPUCOME", /* AIS: Added COMPUCOME */ + "GERUCOME", /* AIS: This is COME FROM gerunds */ + "TRY_AGAIN", /* AIS: Added TRY AGAIN */ + "FROM", /* AIS: ABSTAIN expr FROM LABEL */ +}; +char** enablers = enablersm1+1; + +assoc vartypes[] = +{ + { ONESPOT, "ONESPOT" }, + { TWOSPOT, "TWOSPOT" }, + { TAIL, "TAIL" }, + { HYBRID, "HYBRID" }, + { 0, (char *)NULL } +}; + +static assoc forgetbits[] = +{ + { ONESPOT, "oneforget" }, + { TWOSPOT, "twoforget" }, + { TAIL, "tailforget" }, + { HYBRID, "hyforget" }, + { 0, (char *)NULL } +}; + +/* AIS: Destatic. This is now needed in perpet.c. */ +assoc varstores[] = +{ + { ONESPOT, "onespots" }, + { TWOSPOT, "twospots" }, + { TAIL, "tails" }, + { HYBRID, "hybrids" }, + { 0, (char *)NULL } +}; + +static assoc typedefs[] = +{ + { ONESPOT, "type16" }, + { TWOSPOT, "type32" }, + { TAIL, "type16" }, + { HYBRID, "type32" }, + { 0, (char *)NULL } +}; + +char *nameof(int value, assoc table[]) +/* return string corresponding to value in table */ +{ + assoc *ap; + + for (ap = table; ap->name; ap++) + if (ap->value == value) + return(ap->name); + return((char *)NULL); +} + +/* AIS: Code for printing explanations (mixed C/INTERCAL code that lets + the user know what the meaning of an expression is). This is paraphrased + from the prexpr/prvar code lower down. It's passed to yuk so that the + explain ('e') command works. It's also included in the degenerated C + code when the option -c is used, so the person looking at the code can + debug both the INTERCAL and ick itself more effectively, and used by + -h to produce its optimizer-debug output. */ + +unsigned long varextern(unsigned long intern, int vartype) +{ + atom *x; + if(!oblist) lose(E778, emitlineno, (char*) NULL); + for (x = oblist; x < obdex; x++) + if (x->type == vartype && (unsigned)x->intindex == intern) + return(x->extindex); + if(vartype==MESH) return 0; /* the mesh wasn't used after all */ + lose(E778, emitlineno, (char*) NULL); + return 0; /* never reached */ +} + +void explvar(node* np, FILE* fp) +{ + node *sp; + switch(np->opcode) + { + case ONESPOT: + (void) fprintf(fp, ".%lu", varextern(np->constant,ONESPOT)); + break; + case TWOSPOT: + (void) fprintf(fp, ":%lu", varextern(np->constant,TWOSPOT)); + break; + case TAIL: + (void) fprintf(fp, ",%lu", varextern(np->constant,TAIL)); + break; + case HYBRID: + (void) fprintf(fp, ";%lu", varextern(np->constant,HYBRID)); + break; + case SUB: + (void) fprintf(fp, "("); + explvar(np->lval, fp); + (void) fprintf(fp, " SUB "); + for (sp = np->rval ; sp ; sp = sp->rval) + explexpr(sp->lval, fp); + (void) fprintf(fp, ")"); + break; + default: + lose(E778, emitlineno, (char*) NULL); + } +} + +/* unlike prexpr, this doesn't free its operands */ +void explexpr(node* np, FILE* fp) +{ + if(!np) return; + switch (np->opcode) + { + case MINGLE: + (void) fprintf(fp, "("); + explexpr(np->lval, fp); + (void) fprintf(fp, " $ "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case SELECT: + (void) fprintf(fp, "("); + explexpr(np->lval, fp); + (void) fprintf(fp, " ~ "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case SLAT: + (void) fprintf(fp, "("); + explexpr(np->lval, fp); + (void) fprintf(fp, " / "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case BACKSLAT: + (void) fprintf(fp, "("); + explexpr(np->lval, fp); + (void) fprintf(fp, " \\ "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case AND: + (void) fprintf(fp, "(& "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case OR: + (void) fprintf(fp, "(V "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case XOR: + (void) fprintf(fp, "(? "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case FIN: + if (Base < 3) + lose(E997, emitlineno, (char *)NULL); + (void) fprintf(fp, "(^ "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case WHIRL: + case WHIRL2: + case WHIRL3: + case WHIRL4: + case WHIRL5: + if (np->opcode - WHIRL + 3 > Base) + lose(E997, emitlineno, (char *)NULL); + if(np->opcode == WHIRL) + (void) fprintf(fp, "(@ "); + else + (void) fprintf(fp, "(%d@ ", np->opcode - WHIRL + 1); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case MESH: + if(variableconstants) /* AIS */ + (void) fprintf(fp, "meshes[%lu]", np->constant); + else + (void) fprintf(fp, "0x%lx", np->constant); + break; + + case MESH32: + (void) fprintf(fp, "0x%lx", np->constant); + break; + + case ONESPOT: + case TWOSPOT: + case TAIL: + case HYBRID: + case SUB: + explvar(np, fp); + break; + + /* cases from here down are generated by the optimizer */ + case C_AND: + (void) fprintf(fp, "("); + explexpr(np->lval, fp); + (void) fprintf(fp, " & "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case C_OR: + (void) fprintf(fp, "("); + explexpr(np->lval, fp); + (void) fprintf(fp, " | "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case C_XOR: + (void) fprintf(fp, "("); + explexpr(np->lval, fp); + (void) fprintf(fp, " ^ "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case C_NOT: + (void) fprintf(fp, "(~ "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case C_NOTEQUAL: + (void) fprintf(fp, "("); + explexpr(np->lval, fp); + (void) fprintf(fp, " != "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case C_A: + (void) fprintf(fp, "a"); + break; + + case C_NNAND: + (void) fprintf(fp, "(!!("); + explexpr(np->lval, fp); + (void) fprintf(fp, " & "); + explexpr(np->rval, fp); + (void) fprintf(fp, "))"); + break; + + case C_AND1ADD1: + (void) fprintf(fp, "(("); + explexpr(np->rval,fp); + (void) fprintf(fp, " & 0x1) + 0x1)"); + break; + + case C_1PLUS: + (void) fprintf(fp, "("); + explexpr(np->rval,fp); + (void) fprintf(fp, " + 0x1)"); + break; + + case C_2MINUS: + (void) fprintf(fp, "(0x2 - "); + explexpr(np->rval,fp); + (void) fprintf(fp, ")"); + break; + + case C_2SUBAND1: + (void) fprintf(fp, "(0x2 - ("); + explexpr(np->rval,fp); + (void) fprintf(fp, " & 0x1))"); + break; + + case C_LSHIFT: + (void) fprintf(fp, "(("); + explexpr(np->lval, fp); + (void) fprintf(fp, " & "); + explexpr(np->rval, fp); + (void) fprintf(fp, ") << 0x1)"); + break; + + case C_LSHIFTIN1: + (void) fprintf(fp, "((("); + explexpr(np->lval, fp); + (void) fprintf(fp, " & "); + explexpr(np->rval, fp); + (void) fprintf(fp, ") << 0x1) | 0x1)"); + break; + + case C_LSHIFT2: + (void) fprintf(fp, "(("); + explexpr(np->lval, fp); + (void) fprintf(fp, " & "); + explexpr(np->rval, fp); + (void) fprintf(fp, ") << 0x2)"); + break; + + case C_LSHIFT8: + (void) fprintf(fp, "(("); + explexpr(np->lval, fp); + (void) fprintf(fp, " & "); + explexpr(np->rval, fp); + (void) fprintf(fp, ") << 0x8)"); + break; + + case C_RSHIFTBY: + (void) fprintf(fp, "("); + explexpr(np->lval, fp); + (void) fprintf(fp, " >> "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case C_RSHIFT: + (void) fprintf(fp, "(("); + explexpr(np->lval, fp); + (void) fprintf(fp, " & "); + explexpr(np->rval, fp); + (void) fprintf(fp, ") >> 0x1)"); + break; + + case C_XORGREATER: + (void) fprintf(fp, "("); + explexpr(np->lval, fp); + (void) fprintf(fp, " > ("); + explexpr(np->rval, fp); + (void) fprintf(fp, " ^ "); + explexpr(np->lval, fp); + (void) fprintf(fp, "))"); + break; + + case C_ISNONZERO: + (void) fprintf(fp, "(!!"); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case INTERSECTION: + explexpr(np->lval, fp); + (void) fprintf(fp, " + "); + explexpr(np->rval, fp); + break; + + case GETS: + case RESIZE: + explexpr(np->lval, fp); + (void) fprintf(fp, " <- "); + explexpr(np->rval, fp); + break; + + case BY: + explexpr(np->lval, fp); + (void) fprintf(fp, " BY "); + explexpr(np->rval, fp); + break; + + default: + lose(E778, emitlineno, (char*) NULL); + break; + } +} + +/* AIS: Added the third argument to prexpr and prvar. It specifies + whether the node should be freed or not. I added the third + argument in all calls of prexpr/prvar. */ + +/* AIS: I moved prexpr's prototype higher in the file. + Destaticed so the optimizer can access it. */ + +void prvar(node *np, FILE *fp, int freenode) +/* print out args to pass to storage manager for reference */ +{ + node *sp; + int dim; + + switch (np->opcode) + { + case ONESPOT: + (void) fprintf(fp, "onespots[%lu]", np->constant); + break; + + case TWOSPOT: + (void) fprintf(fp, "twospots[%lu]", np->constant); + break; + + case TAIL: + (void) fprintf(fp, "TAIL, &tails[%lu]", np->constant); + break; + + case HYBRID: + (void) fprintf(fp, "HYBRID, &hybrids[%lu]", np->constant); + break; + + case SUB: + { + (void) fprintf(fp, "aref("); + prvar(np->lval, fp, freenode); + + dim = 0; + for (sp = np->rval ; sp ; sp = sp->rval) + dim++; + (void) fprintf(fp, ", %d", dim); + + for (sp = np->rval ; sp ; sp = sp->rval) { + (void) fprintf(fp, ", "); + prexpr(sp->lval, fp, freenode); + } + (void) fprintf(fp, ")"); + } + break; + default: /* Added by AIS */ + lose(E778, emitlineno, (char*) NULL); + break; + } +} + +void ooprvar(node *np, FILE *fp, int freenode) +/* AIS: Print out the overloaded version */ +{ + node *sp; + int dim; + + switch (np->opcode) + { + case ONESPOT: + (void) fprintf(fp, "oo_onespots[%lu]", np->constant); + break; + + case TWOSPOT: + (void) fprintf(fp, "oo_twospots[%lu]", np->constant); + break; + + case TAIL: + case HYBRID: + /* This should never be reached */ + lose(E778, emitlineno, (char*) NULL); + break; + + case SUB: + { + (void) fprintf(fp, "aref("); + prvar(np->lval, fp, freenode); + + dim = 0; + for (sp = np->rval ; sp ; sp = sp->rval) + dim++; + (void) fprintf(fp, ", %d", dim); + + for (sp = np->rval ; sp ; sp = sp->rval) { + (void) fprintf(fp, ", "); + prexpr(sp->lval, fp, freenode); + } + (void) fprintf(fp, ")"); + } + break; + default: + lose(E778, emitlineno, (char*) NULL); + break; + } +} + +/* AIS: Give us a mesh with value x */ +static unsigned long meshval(unsigned long x) +{ + if(variableconstants) + return intern(MESH, x); + else + return x; +} + +/* AIS: This is the reverse of prexpr, in a way. + It degenerates an expression that causes *np to become equal to *target. + If this is impossible at any point, it degenerates code that causes + error 277 (and itself causes error 278 if the situation is inevitable). */ +void revprexpr(node *np, FILE *fp, node *target) +{ + node* temp; + switch (np->opcode) + { + case MINGLE: + /* We can use select to determine what np->lval and np->rval have + to become equal to, as long as we're in base 2. */ + if(Base!=2) + { + fprintf(fp, " lose(E277, lineno, (char*) NULL);\n"); + lwarn(W278, emitlineno, (char*) NULL); + break; + } + temp=cons(MESH,0,0); + temp->constant=meshval(0xAAAAAAAALU); + temp->width=32; + temp=cons(SELECT,target,temp); + temp->width=target->width; + revprexpr(np->lval, fp, temp); + free(temp->rval); + free(temp); + temp=cons(MESH,0,0); + temp->constant=meshval(0x55555555LU); + temp->width=32; + temp=cons(SELECT,target,temp); + temp->width=target->width; + revprexpr(np->rval, fp, temp); + free(temp->rval); + free(temp); + break; + + case SELECT: + /* Set the left of the select to the target, and the right + to 0xffffffff or 0xffff. This only works in base 2. */ + if(Base!=2) + { + fprintf(fp, " lose(E277, lineno, (char*) NULL);\n"); + lwarn(W278, emitlineno, (char*) NULL); + break; + } + temp=cons(MESH,0,0); + temp->constant=meshval(target->width==32?0xFFFFFFFFLU:0xFFFFLU); + temp->width=target->width; + revprexpr(np->lval, fp, target); + revprexpr(np->rval, fp, temp); + free(temp); + break; + + case BACKSLAT: + /* Unimplemented. This isn't even in the parser yet, so it's a + mystery how we got here. */ + lose(E778, emitlineno, (char*) NULL); + break; + + case SLAT: + /* We need to set the true value of the LHS... */ + + /* Copied and modified from the GETS code */ + if(!pickcompile) + { + (void) fprintf(fp," (void) assign((char*)&"); + prvar(np->lval, fp, 0); + (void) fprintf(fp,", %s", nameof(np->lval->opcode, vartypes)); + (void) fprintf(fp,", %s[%lu], ", nameof(np->lval->opcode, forgetbits), + np->lval->constant); + prexpr(target, fp, 0); + (void) fprintf(fp,"); \n"); + } + else /* AIS: Added this case for the simpler PIC assignment rules */ + { + (void) fprintf(fp,"\tif(ignore%s%lu) ", + nameof(np->lval->opcode,varstores), + np->lval->constant); + prexpr(np->lval, fp, 0); + (void) fprintf(fp, " = "); + prexpr(target, fp, 0); + (void) fprintf(fp, "; \n"); + } + + /* ... and we need to cause overloading to happen. This is a copy + of part of the code for SLAT, modified to work in this context. */ + ooprvar(np->lval, fp, 0); + /* Do something highly non-portable with pointers that should work + anyway. Each pointer needs to be given a unique code; so we use + the hex representation of np casted to an unsigned long. + Technically speaking, np->rval could be casted to anything; but + all implementations I've ever seen cast unique pointers to unique + numbers, which is good enough for our purposes. */ + (void) fprintf(fp, ".get=og%lx;\n ", (unsigned long)np); + ooprvar(np->lval, fp, 0); + (void) fprintf(fp, ".set=os%lx;\n", (unsigned long)np); + break; + + case AND: + case OR: + case XOR: + case FIN: + case WHIRL: + case WHIRL2: + case WHIRL3: + case WHIRL4: + case WHIRL5: + temp=cons(np->opcode-AND+REV_AND,0,target); + temp->width=temp->rval->width=np->width; + revprexpr(np->rval, fp, temp); + free(temp); + break; + + case MESH: + if(!variableconstants) + { + /* Can't set a mesh in this case */ + fprintf(fp, " lose(E277, lineno, (char*) NULL);\n"); + lwarn(W278, emitlineno, (char*) NULL); + break; + } + (void) fprintf(fp," meshes[%lu] = ",np->constant); + prexpr(target, fp, 0); + (void) fprintf(fp,";\n"); + break; + + case ONESPOT: + case TWOSPOT: + case TAIL: + case HYBRID: + case SUB: + /* Copy the code for the GETS statement; this is almost the same + thing. Modified because we're assigning target to np, not + np->lval to np->rval, and to not free(). */ + if(opoverused&& + (np->opcode==ONESPOT||np->opcode==TWOSPOT)) /* AIS */ + { + (void) fprintf(fp," "); + ooprvar(np, fp, 0); + (void) fprintf(fp,".set("); + prexpr(target, fp, 0); + (void) fprintf(fp,",(void(*)())os%dspot%lu);\n", + (np->opcode==TWOSPOT)+1, np->constant); + } + else if(!pickcompile) + { + node* sp; + + if (np->opcode != SUB) { + sp = np; + (void) fprintf(fp," (void) assign((char*)&"); + } + else { + sp = np->lval; + (void) fprintf(fp," (void) assign("); + } + prvar(np, fp, 0); + (void) fprintf(fp,", %s", nameof(sp->opcode, vartypes)); + (void) fprintf(fp,", %s[%lu], ", nameof(sp->opcode, forgetbits), + sp->constant); + prexpr(target, fp, 0); + (void) fprintf(fp,");\n"); + } + else /* AIS: Added this case for the simpler PIC assignment rules */ + { + (void) fprintf(fp," if(ignore%s%lu) ", + nameof(np->opcode,varstores), + np->constant); + prexpr(np, fp, 0); + (void) fprintf(fp, " = "); + prexpr(target, fp, 0); + (void) fprintf(fp, ";\n"); + } + break; + + /* cases from here down are generated by the optimizer, and so + should never come up here and are errors. The exception is + C_A, which should only ever appear in a target expression, + so is also an error. */ + case MESH32: + case C_AND: + case C_OR: + case C_XOR: + case C_NOT: + case C_NOTEQUAL: + case C_A: + case C_NNAND: + case C_AND1ADD1: + case C_1PLUS: + case C_2MINUS: + case C_2SUBAND1: + case C_LSHIFT: + case C_LSHIFTIN1: + case C_LSHIFT2: + case C_LSHIFT8: + case C_RSHIFTBY: + case C_RSHIFT: + case C_XORGREATER: + case C_ISNONZERO: + case GETS: /* should never come up */ + default: + lose(E778, emitlineno, (char*) NULL); + break; + } +} + +/* AIS: Destaticed */ +void prexpr(node *np, FILE *fp, int freenode) +/* print out C-function equivalent of an expression */ +{ + int tempint; + switch (np->opcode) + { + case MINGLE: + (void) fprintf(fp, "mingle("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, ", "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case SELECT: + (void) fprintf(fp, "iselect("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, ", "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case BACKSLAT: /* AIS */ + /* Unimplemented. This isn't even in the parser yet, so it's a + mystery how we got here. */ + lose(E778, emitlineno, (char*) NULL); + break; + + case SLAT: /* AIS */ + (void) fprintf(fp,"(("); + ooprvar(np->lval, fp, 0); + /* Do something highly non-portable with pointers that should work + anyway. Each pointer needs to be given a unique code; so we use + the hex representation of np casted to an unsigned long. + Technically speaking, np->rval could be casted to anything; but + all implementations I've ever seen cast unique pointers to unique + numbers, which is good enough for our purposes. */ + (void) fprintf(fp, ".get=og%lx),(", (unsigned long)np); + ooprvar(np->lval, fp, 0); + (void) fprintf(fp, ".set=os%lx),(", (unsigned long)np); + prvar(np->lval, fp, freenode); + /* np->rval will be freed later, when its expression is printed */ + (void) fprintf(fp, "))"); + return; /* mustn't be freed */ + + case AND: + (void) fprintf(fp, "and%d(", np->width); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case OR: + (void) fprintf(fp, "or%d(", np->width); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case XOR: + (void) fprintf(fp, "xor%d(", np->width); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case FIN: + if (Base < 3) + lose(E997, emitlineno, (char *)NULL); + (void) fprintf(fp, "fin%d(", np->width); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case WHIRL: + case WHIRL2: + case WHIRL3: + case WHIRL4: + case WHIRL5: + if (np->opcode - WHIRL + 3 > Base) + lose(E997, emitlineno, (char *)NULL); + (void) fprintf(fp, "whirl%d(%d, ", np->width, np->opcode - WHIRL + 1); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + /* AIS: Reversed operations */ + case REV_AND: + (void) fprintf(fp, "rev_and%d(", np->width); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case REV_OR: + (void) fprintf(fp, "rev_or%d(", np->width); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case REV_XOR: + (void) fprintf(fp, "rev_xor%d(", np->width); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case REV_FIN: + if (Base < 3) + lose(E997, emitlineno, (char *)NULL); + (void) fprintf(fp, "rev_fin%d(", np->width); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case REV_WHIRL: + case REV_WHIRL2: + case REV_WHIRL3: + case REV_WHIRL4: + case REV_WHIRL5: + if (np->opcode - WHIRL + 3 > Base) + lose(E997, emitlineno, (char *)NULL); + (void) fprintf(fp, + "rev_whirl%d(%d, ", np->width, np->opcode - WHIRL + 1); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case MESH: + if(variableconstants) /* AIS */ + (void) fprintf(fp, "meshes[%lu]", np->constant); + else + (void) fprintf(fp, "0x%lx", np->constant); + break; + + case MESH32: + (void) fprintf(fp, "0x%lx", np->constant); + break; + + case ONESPOT: + case TWOSPOT: + case TAIL: + case HYBRID: + if(!opoverused||np->opcode==TAIL||np->opcode==HYBRID) + prvar(np, fp, freenode); + else /* AIS */ + { + ooprvar(np, fp, freenode); + fprintf(fp, ".get("); + prvar(np, fp, freenode); + fprintf(fp,")"); + } + break; + + case SUB: + (void) fprintf(fp, "*(%s*)", nameof(np->lval->opcode, typedefs)); + prvar(np, fp, freenode); + break; + + /* cases from here down are generated by the optimizer */ + case C_AND: + (void) fprintf(fp, "("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " & "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case C_OR: + (void) fprintf(fp, "("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " | "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case C_XOR: + (void) fprintf(fp, "("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " ^ "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case C_NOT: + (void) fprintf(fp, "(~"); + tempint=np->rval->width; /* AIS */ + prexpr(np->rval, fp, freenode); + if (tempint == Small_digits) + (void) fprintf(fp, " & Max_small)"); + else + (void) fprintf(fp, " & Max_large)"); + break; + + /* AIS: I added the rest of the cases */ + case C_NOTEQUAL: + (void) fprintf(fp, "("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " != "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case C_A: + (void) fprintf(fp, "a"); + break; + + case C_NNAND: + (void) fprintf(fp, "(!!("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " & "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, "))"); + break; + + case C_AND1ADD1: + (void) fprintf(fp, "(("); + prexpr(np->rval,fp, freenode); + (void) fprintf(fp, " & 0x1) + 0x1)"); + break; + + case C_1PLUS: + (void) fprintf(fp, "("); + prexpr(np->rval,fp, freenode); + (void) fprintf(fp, " + 0x1)"); + break; + + case C_2MINUS: + (void) fprintf(fp, "(0x2 - "); + prexpr(np->rval,fp, freenode); + (void) fprintf(fp, ")"); + break; + + case C_2SUBAND1: + (void) fprintf(fp, "(0x2 - ("); + prexpr(np->rval,fp, freenode); + (void) fprintf(fp, " & 0x1))"); + break; + + case C_LSHIFT: + (void) fprintf(fp, "(("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " & "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ") << 0x1)"); + break; + + case C_LSHIFTIN1: + (void) fprintf(fp, "((("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " & "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ") << 0x1) | 0x1)"); + break; + + case C_LSHIFT2: + (void) fprintf(fp, "(("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " & "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ") << 0x2)"); + break; + + case C_LSHIFT8: + (void) fprintf(fp, "(("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " & "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ") << 0x8)"); + break; + + case C_RSHIFTBY: + (void) fprintf(fp, "(("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, ") >> "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case C_RSHIFT: + (void) fprintf(fp, "(("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " & "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ") >> 0x1)"); + break; + + case C_XORGREATER: + (void) fprintf(fp, "("); + prexpr(np->lval, fp, 0); /* Patched by Joris Huizer */ + (void) fprintf(fp, " > ("); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, " ^ "); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, "))"); + break; + + case C_ISNONZERO: + (void) fprintf(fp, "(!!("); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, "))"); + break; + + case GETS: /* AIS: this is used only if freenode == 0 */ + if(freenode) lose(E778, emitlineno, (char*) NULL); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " = "); + prexpr(np->rval, fp, freenode); + break; + + default: /* Added by AIS */ + if(!freenode) break; /* Be less careful when not freeing, because + this is used by -hH to print out its + intermediate optimization stages */ + lose(E778, emitlineno, (char*) NULL); + break; + } + + if(freenode) (void) free(np); +} + +static char *nice_text(char *texts[], int lines) +{ +#define MAXNICEBUF 512 + static char buf[MAXNICEBUF]; + char *cp, *text; + int i; + + if (lines < 1) + lines = 1; + for (cp = buf, i = 0 ; i < lines ; ++i) { + if (cp>buf+MAXNICEBUF-10) goto abort; + if (i) { + (*cp++) = '\\'; + (*cp++) = 'n'; + (*cp++) = '\\'; + (*cp++) = '\n'; + (*cp++) = '\t'; + } + for (text = texts[i] ; text&&*text ; cp++, text++) { + if (cp>buf+MAXNICEBUF-10) goto abort; + if(*text == '"' || *text == '\\') { + (*cp++) = '\\'; + } + *cp = *text; + } + } + *cp = '\0'; + return buf; +abort: (*cp++) = '.'; + (*cp++) = '.'; + (*cp++) = '.'; + *cp = '\0'; + return buf; +} + +static void emit_guard(tuple *tn, FILE *fp) +/* emit execution guard for giiven tuple (note the unbalanced trailing {!) */ +{ + if(tn->maybe) /* AIS */ + { + if(!multithread) lose(E405, emitlineno, (char *)NULL); + (void) fprintf(fp, " gonebackto = setjmp(btjb); choicepoint();\n"); + } + if(!flowoptimize || tn->abstainable) /* This condition by AIS */ + { + (void) fprintf(fp, " if ("); + if (tn->maybe) /* AIS */ + (void) fprintf(fp, "gonebackto == !("); + if (tn->exechance < 100) + (void) fprintf(fp, "roll(%d) && ", tn->exechance); + if ((tn->type != NEXT && tn->type != GO_BACK && tn->type != COME_FROM + && /* AIS */ tn->type != NEXTFROMLABEL) + || tn->onceagainflag == onceagain_NORMAL) + (void) fprintf(fp, "!ICKABSTAINED(%d))%s {\n", (int)(tn - tuples), + /* AIS */ tn->maybe?")":""); + else /* AIS: [NEXT, GO_BACK, COME_FROM] ONCE needs specially + handled abstentions */ + (void) fprintf(fp, "!oldabstain)%s {\n", + /* AIS */ tn->maybe?")":""); + } + else + { /* AIS */ + if(tn->maybe) lose(E778, emitlineno, (char*) NULL); + if(!tn->initabstain) + { + if(tn->type != COMPUCOME && tn->type != GERUCOME + && tn->type != NEXTFROMEXPR && tn->type != NEXTFROMGERUND) + (void) fprintf(fp, " {\n"); + else (void) fprintf(fp, " if(1) {\n"); /* COMPUCOME specifically needs + an if() so it can have + an else. */ + } + else (void) fprintf(fp, " if(0) {\n"); /* for exceptional cases like + DON'T COME FROM #1 where we + need a label or an else. */ + } +} + +void emittextlines(FILE *fp) +{ + int i=0; /* The first textline is line 1 */ + (void) fprintf(fp, "\"\",\n"); + while(++ilineno); + if (tn->label) + (void) fprintf(fp, "L%d:", tn->label); + if (yydebug || compile_only) + { + (void) fprintf(fp, "\t/* %s */", textlines[tn->lineno]); + /* AIS: grind out an expression explanation */ + if (tn->type == GETS || tn->type == FORGET || tn->type == RESUME + || tn->type == FROM || tn->type == COMPUCOME + || tn->type == MANYFROM || tn->type == NEXTFROMEXPR) + { + (void) fprintf(fp, "\n\t/* Expression is "); + explexpr(tn->type == MANYFROM ? tn->u.node->lval : + tn->type == GETS ? tn->u.node->rval : tn->u.node, fp); + (void) fprintf(fp, " */"); + } + } + (void) fputc('\n', fp); + + /* set up the "next" lexical line number for error messages */ + if (tn->type == NEXT) { + tuple *up; + for (up = tuples; up < tuples + lineno; up++) + if (tn->u.target == up->label) { + emitlineno = up->lineno; + break; + } + } else if (tn->ncomefrom) + emitlineno = comefromsearch(tn,1); /* AIS: For multithreading. + Return the 1st if we're forking. */ + else if (tn < tuples + lineno - 1) + emitlineno = tn[1].lineno; + else + emitlineno = yylineno; + if(!pickcompile) /* AIS: PICs can't report errors, so don't bother with lineno */ + (void) fprintf(fp, " lineno = %d;\n", emitlineno); + + /* print warnings on -l */ + if(checkforbugs) + { + if(tn->warn112) lwarn(W112, emitlineno, (char*) NULL); + if(tn->warn128) lwarn(W128, emitlineno, (char*) NULL); + if(tn->warn534) lwarn(W534, emitlineno, (char*) NULL); + if(tn->warn018) lwarn(W018, emitlineno, (char*) NULL); + if(tn->warn016) lwarn(W016, emitlineno, (char*) NULL); + if(tn->warn276) lwarn(W276, emitlineno, (char*) NULL); + if(tn->warn239) lwarn(W239, emitlineno, (char*) NULL); + if(tn->warn622) lwarn(W622, emitlineno, (char*) NULL); + } + + /* emit debugging information */ + if (yukdebug||yukprofile) + { + (void) fprintf(fp, " YUK(%d,%d);\n", + (int)(tn-tuples),emitlineno); + } + + /* AIS: The +mystery option on degenerated code causes the code to + unexpectedly terminate after 4 billion commands are run, thus + preventing an infinite loop. Of course, it will enhance the fun + if we don't tell the user that. (This is necessary for the + constant-output optimizer to work properly.) */ + if(coopt) (void) fprintf(fp, " MYSTERYLINE;\n"); + + /* AIS: If the tuple is ONCE/AGAIN flagged, we need a delayed-action + set of its abstention status to the AGAIN-flagged status. The + problem is that some statements, like COME FROM, need to set after + the command has finished, and some, like NEXT, need it before the + command has started. At the moment, only NEXT and GO_BACK have a + ONCE/AGAIN before it, rather than after (because neither of them + continue in the normal fashion). */ + if ((tn->type == NEXT || tn->type == GO_BACK) && + tn->onceagainflag != onceagain_NORMAL) + { + /* ONCE/AGAIN has already been swapped by perpetrate.c in the case + of a preabstained statement ('DO NOT'...). So if currently have + a ONCE, it means that being abstained is the attractive state, + and if we currently have an AGAIN, it means that being + reinstated is the attractive state. Semantics with computed + ABSTAIN: Don't change the abstention count unless necessary, in + which case change it to 0 or 1. */ + fprintf(fp," oldabstain = ICKABSTAINED(%d);\n", (int)(tn - tuples)); + fprintf(fp," ICKABSTAINED(%d) = %s;\n", + (int)(tn - tuples), + tn->onceagainflag==onceagain_ONCE ? "oldabstain ? oldabstain : 1" + : "0"); + /* This test-and-set must be atomic. As all statements are atomic anyway + in the current version of ick, that isn't a problem, but if anyone + wants to try using POSIX's multithreading features, the above two + lines need to be a critical section. */ + } + + /* in the case of COMPUCOME, we need an extra guard */ + if (tn->type == COMPUCOME || tn->type == GERUCOME + || tn->type == NEXTFROMEXPR || tn->type == NEXTFROMGERUND) + { + fprintf(fp," if(0)\n {\n"); + fprintf(fp,"CCF%d:\n",compucomecount++); + if(tn->type == COMPUCOME || tn->type == NEXTFROMEXPR) + { + fprintf(fp," if(skipto&&skipto=="); + prexpr(tn->u.node, fp, 1); + } + else if(tn->type == GERUCOME || tn->type == NEXTFROMGERUND) + { + fprintf(fp," if("); + for (np = tn->u.node; np; np = np->rval) + { + if (np->constant == ABSTAIN) { + (void) fprintf(fp, +"linetype[truelineno] == %s || linetype[truelineno] == %s || " +"linetype[truelineno] == %s || linetype[truelineno] == %s || ", + enablers[np->constant-GETS], + enablers[np->constant-GETS+2], + enablers[FROM-GETS], enablers[MANYFROM-GETS]); + } else if (np->constant == REINSTATE) { + (void) fprintf(fp, +"linetype[truelineno] == %s || linetype[truelineno] == %s || ", + enablers[np->constant-GETS], + enablers[np->constant-GETS+2]); + } else if (np->constant == COME_FROM) { + (void) fprintf(fp, +"linetype[truelineno] == %s || linetype[truelineno] == %s || " +"linetype[truelineno] == %s || ", + enablers[COME_FROM-GETS], + enablers[COMPUCOME-GETS], + enablers[GERUCOME-GETS]); + } else if (np->constant == NEXTFROMLABEL) { + (void) fprintf(fp, +"linetype[truelineno] == %s || linetype[truelineno] == %s || " +"linetype[truelineno] == %s || ", + enablers[NEXTFROMLABEL-GETS], + enablers[NEXTFROMEXPR-GETS], + enablers[NEXTFROMGERUND-GETS]); + } else { + (void) fprintf(fp, "linetype[truelineno] == %s || ", + enablers[np->constant-GETS]); + } + } + fprintf(fp, "0"); + } + fprintf(fp,") {\n"); + } + + /* AIS: With this block placed here, you can't even have a comment + after a TRY AGAIN line. Move it below the next check if this seems + to be undesirable behaviour. */ + if(pasttryagain) /* AIS */ + { + lose(E993, emitlineno, (char*)NULL); + } + + if(flowoptimize && tn->initabstain && !tn->abstainable + && tn->type != COMPUCOME && tn->type != COME_FROM && + tn->type != NEXT && tn->type != GERUCOME && + tn->type != NEXTFROMLABEL && tn->type != NEXTFROMEXPR && + tn->type != NEXTFROMGERUND) /* AIS */ + goto skipcomment; /* Look, a comment! We can completely skip all + degeneration of this statement (although with + -c, comments will appear in the degenerated + code in its place). The COMPUCOME condition is + because it is so weird. COME_FROM and NEXT are + exempted so labels are generated. */ + + /* emit conditional-execution prefixes */ + if (tn->type != COME_FROM && tn->type != NEXTFROMLABEL) + emit_guard(tn, fp); + + /* now emit the code for the statement body */ + switch(tn->type) + { + case GETS: + /* AIS: variableconstants means GETS has been generalised */ + if(variableconstants) + { + revprexpr(tn->u.node->lval, fp, tn->u.node->rval); + nodefree(tn->u.node); + break; + } + + /* Start of AIS optimization */ + np = tn->u.node; + if(np->lval->opcode == SUB) np = np->lval; + if(flowoptimize && Base == 2 && !opoverused && !variableconstants && + (np->lval->opcode == TWOSPOT + || np->lval->opcode == HYBRID + || !(tn->u.node->lval->optdata & ~0xffffLU))) + { + atom* op; + int ignorable = 1; + for(op = oblist; op < obdex; op++) + { + if(op->type == np->lval->opcode && + (unsigned)op->intindex == np->lval->constant) + { + ignorable &= op->ignorable; + } + } + if(!ignorable) + { /* Variable can't be ignored, and expression must be in range */ + (void) fprintf(fp,"\t"); + prexpr(tn->u.node->lval, fp, 1); + (void) fprintf(fp, " = "); + prexpr(tn->u.node->rval, fp, 1); + (void) fprintf(fp, ";\n"); + break; + } + } + /* End of AIS optimization */ + if(opoverused&& + (tn->u.node->lval->opcode==ONESPOT|| + tn->u.node->lval->opcode==TWOSPOT)) /* AIS */ + { + (void) fprintf(fp,"\t"); + ooprvar(tn->u.node->lval, fp, 1); + (void) fprintf(fp,".set("); + prexpr(tn->u.node->rval, fp, 1); + (void) fprintf(fp,",(void(*)())os%dspot%lu);\n", + (tn->u.node->rval->opcode==TWOSPOT)+1, + tn->u.node->rval->constant); + } + else if(!pickcompile) + { + np = tn->u.node; + + if (np->lval->opcode != SUB) { + sp = np->lval; + (void) fprintf(fp,"\t(void) assign((char*)&"); + } + else { + sp = np->lval->lval; + (void) fprintf(fp,"\t(void) assign("); + } + prvar(np->lval, fp, 1); + (void) fprintf(fp,", %s", nameof(sp->opcode, vartypes)); + (void) fprintf(fp,", %s[%lu], ", nameof(sp->opcode, forgetbits), + sp->constant); + prexpr(np->rval, fp, 1); + (void) fprintf(fp,");\n"); + } + else /* AIS: Added this case for the simpler PIC assignment rules */ + { + (void) fprintf(fp,"\tif(ignore%s%lu) ", + nameof(tn->u.node->lval->opcode,varstores), + tn->u.node->lval->constant); + prexpr(tn->u.node->lval, fp, 1); + (void) fprintf(fp, " = "); + prexpr(tn->u.node->rval, fp, 1); + (void) fprintf(fp, ";\n"); + } + break; + + case RESIZE: + if(pickcompile) lose(E256, emitlineno, (char*) NULL); /* AIS */ + np = tn->u.node; + dim = 0; + for (sp = np->rval; sp; sp = sp->rval) + dim++; + (void) fprintf(fp, "\tresize("); + prvar(np->lval, fp, 1); + (void) fprintf(fp, ", %s[%lu]", nameof(np->lval->opcode, forgetbits), + np->lval->constant); + (void) fprintf(fp, ", %d", dim); + for (sp = np->rval; sp; sp = sp->rval) { + (void) fprintf(fp, ", "); + prexpr(sp->lval, fp, 1); + } + (void) fprintf(fp, ");\n"); + break; + + case NEXT: + /* Start of AIS optimization */ + if(tn->u.target>=1000 && tn->u.target<=1999 && pickcompile) + { + /* optimize syslib call on a PIC */ + (void) fprintf(fp, "\tsyslibopt%d();\n", tn->u.target); + break; + } + if(tn->optversion) + { /* optimizef has checked that this is a valid optimization */ + (void) fprintf(fp, "\tif(1 == "); + prexpr(tn->u.node, fp, 1); /* frees optimizef's nodecopy */ + /* AIS: Everything now in one giant switch(), with some very strange + constructs (including ;{;} as a null statement; this makes + degenerating the code slightly easier) */ + (void) fprintf(fp, ") {pushnext(%d); skipto=%d; goto top;}} case %d:;{;\n", + (int)(tn - tuples + 1), tn->nexttarget, (int)(tn - tuples + 1)); + break; + } + /* End of AIS optimization */ + (void) fprintf(fp, /* same change as above (case rather than a label) */ + "\tpushnext(%d); goto L%d;} case %d:;{;\n", + (int)(tn - tuples + 1), tn->u.target, (int)(tn - tuples + 1)); + break; + + case GO_BACK: /* By AIS */ + if(!multithread) lose(E405, emitlineno, (char*) NULL); + (void) fprintf(fp, "\tchoiceback();\n"); + break; + + case GO_AHEAD: /* By AIS */ + if(!multithread) lose(E405, emitlineno, (char*) NULL); + (void) fprintf(fp, "\tchoiceahead();\n"); + break; + + case RESUME: + (void) fprintf(fp, "\tskipto = resume("); + prexpr(tn->u.node, fp, 1); + (void) fprintf(fp, "); goto top;\n"); + break; + + case FORGET: + (void) fprintf(fp, "\tpopnext("); + prexpr(tn->u.node, fp, 1); + (void) fprintf(fp, ");\n"); + break; + + case STASH: + for (np = tn->u.node; np; np = np->rval) + (void) fprintf(fp, "\tICKSTASH(%s, %lu, %s, %s%s);\n", + nameof(np->opcode, vartypes), + np->constant, + nameof(np->opcode, varstores), + /* AIS */(opoverused&&(np->opcode==ONESPOT|| + np->opcode==TWOSPOT)? + "oo_":"0"), + /* AIS */(opoverused&&(np->opcode==ONESPOT|| + np->opcode==TWOSPOT)? + nameof(np->opcode, varstores):"0")); + break; + + case RETRIEVE: + for (np = tn->u.node; np; np = np->rval) + (void) fprintf(fp, "\tICKRETRIEVE(%s, %lu, %s, %s, %s%s);\n", + nameof(np->opcode, varstores), np->constant, + nameof(np->opcode, vartypes), + nameof(np->opcode, forgetbits), + /* AIS */(opoverused&&(np->opcode==ONESPOT|| + np->opcode==TWOSPOT)? + "oo_":"0"), + /* AIS */(opoverused&&(np->opcode==ONESPOT|| + np->opcode==TWOSPOT)? + nameof(np->opcode, varstores):"0")); + + break; + + case IGNORE: + for (np = tn->u.node; np; np = np->rval) + (void) fprintf(fp,"\tICKIGNORE(%s,%lu,%s) = TRUE;\n", + nameof(np->opcode, forgetbits), + np->constant, + nameof(np->opcode, varstores)); + break; + + case REMEMBER: + for (np = tn->u.node; np; np = np->rval) + (void) fprintf(fp,"\tICKIGNORE(%s,%lu,%s) = FALSE;\n", + nameof(np->opcode, forgetbits), + np->constant, + nameof(np->opcode, varstores)); + break; + + /* All abstention code has been edited by AIS to allow for the new + abstention rules */ + case ABSTAIN: + if(!pickcompile) + (void) fprintf(fp, "\tif(!ICKABSTAINED(%d)) ICKABSTAINED(%d) = 1;\n", tn->u.target - 1, tn->u.target-1); + else + (void) fprintf(fp, "ICKABSTAINED(%d) = 1;\n", tn->u.target-1); + break; + + case FROM: + if(pickcompile) lose(E256, emitlineno, (char*) NULL); + (void) fprintf(fp, "\tICKABSTAINED(%d)+=", tn->u.target-1); + tn->u.node->width = 32; + prexpr(tn->u.node,fp, 1); + (void) fprintf(fp, ";\n"); + break; + + case REINSTATE: + if(!pickcompile) + (void) fprintf(fp, "\tif(ICKABSTAINED(%d)) ICKABSTAINED(%d)--;\n", tn->u.target - 1, tn->u.target-1); + else + (void) fprintf(fp, "\tICKABSTAINED(%d)=0;\n", tn->u.target - 1); + break; + + case ENABLE: + if(pickcompile) lose(E256, emitlineno, (char*) NULL); /* AIS */ + (void) fprintf(fp, + "\tint i;\n"); + for (np = tn->u.node; np; np = np->rval) + { + (void) fprintf(fp, + "\n\tfor (i = 0; i < (int)(sizeof(linetype)/sizeof(int)); i++)\n"); + if (np->constant == ABSTAIN) { + (void) fprintf(fp, + "\t if (linetype[i] == %s || linetype[i] == %s || linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2], enablers[FROM-GETS], enablers[MANYFROM-GETS]); + } else if (np->constant == REINSTATE) { + (void) fprintf(fp, + "\t if (linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2]); + } else if (np->constant == COME_FROM) { + (void) fprintf(fp, + "\t if (linetype[i] == %s || linetype[i] == %s || linetype[i] == %s)\n", enablers[COME_FROM-GETS], enablers[COMPUCOME-GETS], enablers[GERUCOME-GETS]); + } else if (np->constant == NEXTFROMLABEL) { + (void) fprintf(fp, + "\t if (linetype[i] == %s || linetype[i] == %s || linetype[i] == %s)\n", enablers[NEXTFROMLABEL-GETS], enablers[NEXTFROMGERUND-GETS], enablers[NEXTFROMEXPR-GETS]); + } else { + (void) fprintf(fp, + "\t if (linetype[i] == %s)\n", enablers[np->constant-GETS]); + } + (void) fprintf(fp, + "\t\tif(abstained[i]) abstained[i]--;\n"); + } + break; + + case DISABLE: + if(pickcompile) lose(E256, emitlineno, (char*) NULL); /* AIS */ + (void) fprintf(fp, + "\tint i;\n"); + for (np = tn->u.node; np; np = np->rval) + { + (void) fprintf(fp, + "\n\tfor (i = 0; i < (int)(sizeof(linetype)/sizeof(int)); i++)\n"); + if (np->constant == ABSTAIN) { + (void) fprintf(fp, + "\t if (linetype[i] == %s || linetype[i] == %s || linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2], enablers[FROM-GETS], enablers[MANYFROM-GETS]); + } else if (np->constant == REINSTATE) { + (void) fprintf(fp, + "\t if (linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2]); + } else if (np->constant == COME_FROM) { + (void) fprintf(fp, + "\t if (linetype[i] == %s || linetype[i] == %s || linetype[i] == %s)\n", enablers[COME_FROM-GETS], enablers[COMPUCOME-GETS], enablers[GERUCOME-GETS]); + } else if (np->constant == NEXTFROMLABEL) { + (void) fprintf(fp, + "\t if (linetype[i] == %s || linetype[i] == %s || linetype[i] == %s)\n", enablers[NEXTFROMLABEL-GETS], enablers[NEXTFROMGERUND-GETS], enablers[NEXTFROMEXPR-GETS]); + } else { + (void) fprintf(fp, + "\t if (linetype[i] == %s)\n", enablers[np->constant-GETS]); + } + (void) fprintf(fp, + "\t\tif(!abstained[i]) abstained[i] = 1;\n"); + } + break; + + case MANYFROM: + if(pickcompile) lose(E256, emitlineno, (char*) NULL); /* AIS */ + (void) fprintf(fp, + "\tint i;\n\tint j;\n\tj="); + tn->u.node->lval->width=32; + prexpr(tn->u.node->lval,fp, 1); + (void) fprintf(fp, + ";\n"); + for (np = tn->u.node->rval; np; np = np->rval) + { + (void) fprintf(fp, + "\n\tfor (i = 0; i < (int)(sizeof(linetype)/sizeof(int)); i++)\n"); + if (np->constant == ABSTAIN) { + (void) fprintf(fp, + "\t if (linetype[i] == %s || linetype[i] == %s || linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2], enablers[FROM-GETS], enablers[MANYFROM-GETS]); + } else if (np->constant == REINSTATE) { + (void) fprintf(fp, + "\t if (linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2]); + } else { + (void) fprintf(fp, + "\t if (linetype[i] == %s)\n", enablers[np->constant-GETS]); + } + (void) fprintf(fp, + "\t\tabstained[i] += j;\n"); + } + break; + + case NEXTFROMEXPR: + case NEXTFROMGERUND: + case GERUCOME: + case COMPUCOME: /* By AIS. Note that this doesn't even have balanced + braces; it's designed to work with COMPUCOME's + crazy guarding arrangements */ + if(pickcompile) lose(E256, emitlineno, (char*) NULL); /* AIS */ + fprintf(fp,"\t;} else goto CCF%d;\n",compucomecount); + break; + + case GIVE_UP: /* AIS: Edited to allow for yuk */ + if(yukprofile||yukdebug) fprintf(fp, "\tYUKTERM;\n"); + if(multithread) fprintf(fp, "\tkillthread();\n"); + (void) fprintf(fp, "\treturn(0);\n"); + break; + + case TRY_AGAIN: /* By AIS */ + (void) fprintf(fp, "\tgoto ick_restart;\n }\n"); + if(yukprofile||yukdebug) fprintf(fp, " if(yukloop) goto ick_restart;\n"); + if(yukprofile||yukdebug) fprintf(fp, " YUKTERM;\n"); + if(multithread) fprintf(fp, "\tkillthread();\n"); + (void) fprintf(fp, " {\n\treturn(0);\n"); + /* because if TRY AGAIN is the last line, falling off the end isn't an error */ + pasttryagain=1; /* flag an error if we try any more commands */ + break; + + case WRITE_IN: + if(pickcompile) lose(E256, emitlineno, (char*) NULL); /* AIS */ + for (np = tn->u.node; np; np = np->rval) { + if (np->lval->opcode == TAIL || np->lval->opcode == HYBRID) { + (void) fprintf(fp,"\tbinin("); + prvar(np->lval, fp, 1); + (void) fprintf(fp, ", %s[%lu]", + nameof(np->lval->opcode, forgetbits), + np->lval->constant); + (void) fprintf(fp,");\n"); + } + else { + if (np->lval->opcode != SUB) { + sp = np->lval; + (void) fprintf(fp,"\t(void) assign((char*)&"); + } + else { + sp = np->lval->lval; + (void) fprintf(fp,"\t(void) assign("); + } + prvar(np->lval, fp, 1); + (void) fprintf(fp,", %s", nameof(sp->opcode, vartypes)); + (void) fprintf(fp,", %s[%lu]", nameof(sp->opcode, forgetbits), + sp->constant); + (void) fprintf(fp,", pin());\n"); + } + } + break; + + case READ_OUT: + if(pickcompile) lose(E256, emitlineno, (char*) NULL); /* AIS */ + for (np = tn->u.node; np; np = np->rval) + { + if (np->lval->opcode == TAIL || np->lval->opcode == HYBRID) { + (void) fprintf(fp,"\tbinout("); + prvar(np->lval, fp, 1); + (void) fprintf(fp,");\n"); + } + else { + (void) fprintf(fp, "\tpout("); + prexpr(np->lval, fp, 1); + (void) fprintf(fp, ");\n"); + } + } + break; + + case PIN: /* AIS, with some code borrowed from the GETS code */ + np = tn->u.node; + (void) fprintf(fp, "\tTRISA = seq(~(("); + prexpr(np, fp, 0); + (void) fprintf(fp, " >> 16) & 255));\n"); + (void) fprintf(fp, "\tTRISB = seq(~("); + prexpr(np, fp, 0); + (void) fprintf(fp, " >> 24));\n"); + (void) fprintf(fp, "\tPORTA = seq(~("); + prexpr(np, fp, 0); + (void) fprintf(fp, " & 255));\n"); + (void) fprintf(fp, "\tPORTB = seq(~(("); + prexpr(np, fp, 0); + (void) fprintf(fp, " >> 8) & 255));\n"); + { + atom* op; + int ignorable = 1; + for(op = oblist; op < obdex; op++) + { + if(op->type == np->opcode && + (unsigned)op->intindex == np->constant) + { + ignorable &= op->ignorable; + } + } + if(!ignorable) + { /* Variable can't be ignored, and expression must be in range */ + (void) fprintf(fp,"\t"); + prexpr(np, fp, 1); + (void) fprintf(fp, " = "); + } + else + { + np = tn->u.node; + (void) fprintf(fp,"\tif(ignore%s%lu) ", + nameof(np->opcode,varstores), + np->constant); + prexpr(np, fp, 1); + (void) fprintf(fp, " = "); + } + } + (void) fprintf(fp,"(TRISB<<24) | (TRISA<<16) | (PORTB<<8) | PORTA;\n"); + break; + + case SPLATTERED: + dim = emitlineno - tn->lineno; + if (tn->sharedline) + ++dim; + (void) fprintf(fp, "\tlose(E000, %d, \"%s\");\n", + emitlineno, nice_text(textlines + tn->lineno, dim)); + break; + + case COME_FROM: + case NEXTFROMLABEL: /* AIS */ + (void) fprintf(fp, "if(0) {C%ld: %s;}\n", (long)(tn-tuples+1), + tn->type==NEXTFROMLABEL ? "pushnext(truelineno+1)":""); + /* AIS: Changed so all COME_FROMs have unique labels even if two + of them aim at the same line, and added the NEXT FROM case (which + invloves hiding COME FROM labels in an unreachable if()). */ + break; + + default: + lose(E778, emitlineno, (char *)NULL); + break; + } + + if (tn->type != COME_FROM && tn->type != NEXTFROMLABEL) + (void) fprintf(fp, " }\n"); + + skipcomment: + + if (tn->type == COMPUCOME || tn->type == GERUCOME || + tn->type == NEXTFROMEXPR || tn->type == NEXTFROMGERUND) + { /* By AIS */ + (void) fprintf(fp," else goto CCF%d;\n",compucomecount); + (void) fprintf(fp," ccfc++;\n"); + /* Note that due to the semantics of setjmp, this has to be written as 2 + separate ifs. The MULTICOME macro expands to a non-multithreaded or + multithreaded function for handling a COME FROM clash. */ + (void) fprintf(fp," if(ccfc==1||MULTICOME(%d,cjb))\n" + "\tif(setjmp(cjb) == 0) goto CCF%d;\n", + emitlineno, compucomecount); + /* Of course, emitlineno is unlikely to be helpful! */ + if(tn->type == NEXTFROMEXPR || tn->type == NEXTFROMGERUND) + { + /* Stack up the statement we've NEXTed from */ + (void) fprintf(fp," pushnext(truelineno+1);\n"); + } + (void) fprintf(fp," }\n"); + } + + /* AIS: Before any COMING FROM this line is done, we need to sort out + ONCE and AGAIN situations, unless this line was a NEXT or GO_BACK. + COME FROM is also excluded because it acts at the suckpoint, not + at the place it's written in the program. */ + if (tn->onceagainflag != onceagain_NORMAL && + (tn->type != NEXT && tn->type != GO_BACK && tn->type != COME_FROM && + tn->type != NEXTFROMLABEL)) + { + /* See my comments against the NEXT code for more information. + This code is placed here so COME FROM ... ONCE constructs work + properly (the line is abstained if the COME FROM is reached in + execution, or its suckpoint is reached in execution). */ + fprintf(fp," oldabstain = ICKABSTAINED(%d);\n", (int)(tn - tuples)); + fprintf(fp," ICKABSTAINED(%d) = %s;\n", + (int)(tn - tuples), + tn->onceagainflag==onceagain_ONCE ? "oldabstain ? oldabstain : 1" + : "0"); + } + + /* AIS: This is where we start the COME FROM suckpoint code. */ + + /* AIS: We need to keep track of how many COME FROMs are aiming here + at runtime, if we don't have the very simple situation of no + COMPUCOMEs and a single-thread program (in which case the check + is done at compile-time by codecheck). Even without COMPUCOME, + this can change in a multithread program due to abstentions. */ + if((tn->ncomefrom && multithread) || (tn->label && compucomesused) + || gerucomesused) + (void) fprintf(fp, " ccfc = 0;\n"); + /* AIS: For NEXTING FROM this line */ + if(nextfromsused && tn->ncomefrom) + { + (void) fprintf(fp, " truelineno = %d;\n", (int)(tn-tuples)); + } + /* + * If the statement that was just degenerated was a COME FROM target, + * emit the code for the jump to the COME FROM. + * AIS: Changed most of this to allow for multithreading. + */ + while(tn->ncomefrom) /* acts as an if if singlethreading */ + { + tuple* cf; /* local to this block */ + if(multithread || compucomesused) generatecfjump = 1; + cf = tuples+comefromsearch(tn,tn->ncomefrom)-1; + if (yydebug || compile_only) + (void) fprintf(fp, + " /* line %03d is a suck point for the COME FROM " + "at line %03d */\n", tn->lineno, cf->lineno); + if (cf->onceagainflag != onceagain_NORMAL) + { /* Calculate ONCE/AGAIN when the suckpoint is passed */ + fprintf(fp," oldabstain = ICKABSTAINED(%d);\n", (int)(cf - tuples)); + fprintf(fp," ICKABSTAINED(%d) = %s;\n", + (int)(cf - tuples), + cf->onceagainflag==onceagain_ONCE ? "oldabstain ? oldabstain : 1" + : "0"); + } + emit_guard(cf, fp); + if(multithread || compucomesused) + (void) fprintf(fp, + "\tccfc++;\tif(ccfc==1||MULTICOME(%d,cjb)) " + "if(setjmp(cjb) == 1) goto C%ld;\n }\n", + emitlineno, (long)(cf-tuples+1)); + else /* optimize for the simple case */ + (void) fprintf(fp, "\tgoto C%ld;\n }\n", (long)(cf-tuples+1)); + tn->ncomefrom--; + } + + /* AIS: If the statement has a label, it might be a + computed COME FROM target. Also check the flag that says this + code is needed in a multithread non-COMPUCOME program. + If (at runtime) ccfc is nonzero, we know cjb has already been set; + otherwise, set it now. In the case of a multithread non-COMPUCOME + program, the goto will just jump to a longjmp, switching to the + one and only one COME FROM that hasn't been given its own thread. */ + if ((tn->label && compucomesused) || generatecfjump || gerucomesused) + { + if(compucomesused) + { + (void) fprintf(fp, " skipto = %d;\n", tn->label); + } + if(gerucomesused || nextfromsused) + { + (void) fprintf(fp, " truelineno = %d;\n", (int)(tn-tuples)); + } + if(generatecfjump) (void) fprintf(fp, " if(ccfc) goto CCF0;\n"); + if(compucomesused || gerucomesused) + { /* check all the COMPUCOMES */ + (void) fprintf(fp, " %sif(setjmp(cjb) == 0) goto CCF0;\n", + generatecfjump?"else ":""); + } + generatecfjump = 0; + /* AIS: If NEXT FROM's used, this might be a NEXT return target. + Don't generate case labels for NEXT, as it has them already. */ + if(nextfromsused && tn->type != NEXT) + { + (void) fprintf(fp, " case %u:;\n", (unsigned)(tn-tuples+1)); + } + } + + /* AIS: Now we've finished the statement, let's switch to the next + thread in a multithread program. */ + if(multithread) (void) fputs(" NEXTTHREAD;\n", fp); +} + +/* AIS: Generate prototypes for slat expressions */ +void emitslatproto(FILE* fp) +{ + node* np=firstslat; + char* t="type32"; + while(np) + { + fprintf(fp,"%s og%lx(%s);\nvoid os%lx(%s, void(*)());\n", + t,(unsigned long)np,t,(unsigned long)np,t); + np=np->nextslat; + } +} + +/* AIS: Generate bodies for slat expressions */ +void emitslat(FILE* fp) +{ + node* np=firstslat; + node* temp, *temp2; + char* t="type32"; + while(np) + { + fprintf(fp, + "void os%lx(%s a, void(*f)())\n{\n static int l=0;\n" + " if(l)\n {\n if(!f)lose(E778, lineno, (char *)NULL);\n" + " ((void(*)(%s,void(*)()))f)(a,0);\n return;\n }\n l=1;\n", + (unsigned long)np,t,t); + temp=cons(C_A, 0, 0); + revprexpr(np->rval, fp, temp); /* revprexpr can't free */ + fprintf(fp," l=0;\n}\n"); + fprintf(fp,"%s og%lx(%s t)\n{\n %s a;\n static int l=0;\n" + " if(l) return t;\n l=1;\n a=", + t,(unsigned long)np,t,t); + prexpr(np->rval, fp, 0); + fprintf(fp,";\n l=0;\n return a;\n}\n"); + np=np->nextslat; + } + np=firstslat; + /* Note that the order in which the parser assembles nodes means + that we have to free the nodes in reverse order so we don't + free child nodes twice. */ + temp2=0; + while(np) + { + temp=np->nextslat; + np->nextslat=temp2; /* reverse the chain */ + temp2=np; + np=temp; + } + np=temp2; + while(np) + { + temp=np->nextslat; + nodefree(np->rval); + free(np); + np=temp; + } +} + +/* feh.c ends here */ diff --git a/fiddle.c b/src/fiddle.c similarity index 69% rename from fiddle.c rename to src/fiddle.c index 2f6a9e5..239e02f 100644 --- a/fiddle.c +++ b/src/fiddle.c @@ -251,4 +251,128 @@ unsigned int fin32(unsigned int n) } } +/* AIS: Reversed operations, for operand overloading */ + +static unsigned int rotleft16(unsigned int n) +{ + return !!(n&0x8000)|((n&0x7FFF)<<1); +} +static unsigned int rotleft32(unsigned int n) +{ + return !!(n&0x80000000)|((n&0x7FFFFFFF)<<1); +} + +/* For the time being, just work out the answer in binary, and test using + the base-whatever operation. This means that there'll nearly always be + a failure in reversing in bases other than 2. */ +unsigned int rev_or16(unsigned int n) +{ + if(or16(rotleft16(and16(n)))==n) return rotleft16(and16(n)); + lose(E277, lineno, (char*) NULL); + return 0; +} + +unsigned int rev_or32(unsigned int n) +{ + if(or32(rotleft32(and32(n)))==n) return rotleft32(and32(n)); + lose(E277, lineno, (char*) NULL); + return 0; +} + +unsigned int rev_and16(unsigned int n) +{ + if(and16(rotleft16(or16(n)))==n) return rotleft16(or16(n)); + lose(E277, lineno, (char*) NULL); + return 0; +} + +unsigned int rev_and32(unsigned int n) +{ + if(and32(rotleft32(or32(n)))==n) return rotleft32(or32(n)); + lose(E277, lineno, (char*) NULL); + return 0; +} + +unsigned int rev_xor16(unsigned int n) +{ + unsigned int a=0, l=1, t=0; + while(l<=0x4000) + { + if(n&l) + t^=1; + if(t) + a+=l*2; + l*=2; + } + if(xor16(a)==n) return a; + lose(E277, lineno, (char*) NULL); + return 0; +} + + +unsigned int rev_xor32(unsigned int n) +{ + unsigned int a=0, l=1, t=0; + while(l<=0x4000000) + { + if(n&l) + t^=1; + if(t) + a+=l*2; + l*=2; + } + if(xor32(a)==n) return a; + lose(E277, lineno, (char*) NULL); + return 0; +} + +unsigned int rev_fin16(unsigned int n) +{ + unsigned int a=0, l=1, t=0; + while(l<=0x4000) + { + if(n&l) + t^=1; + if(t) + a+=l*2; + l*=2; + } + if(fin16(a)==n) return a; + lose(E277, lineno, (char*) NULL); + return 0; +} + + +unsigned int rev_fin32(unsigned int n) +{ + unsigned int a=0, l=1, t=0; + while(l<=0x4000000) + { + if(n&l) + t^=1; + if(t) + a+=l*2; + l*=2; + } + if(fin32(a)==n) return a; + lose(E277, lineno, (char*) NULL); + return 0; +} + +unsigned int rev_whirl16(unsigned int p, unsigned int n) +{ + /* Only reverse if all digits are the same. */ + if(whirl16(p,n)==n) return n; + lose(E277, lineno, (char*) NULL); + return 0; +} + +unsigned int rev_whirl32(unsigned int p, unsigned int n) +{ + /* Only reverse if all digits are the same. */ + if(whirl32(p,n)==n) return n; + lose(E277, lineno, (char*) NULL); + return 0; +} + /* fiddle.c */ diff --git a/fiddle.h b/src/fiddle.h similarity index 58% rename from fiddle.h rename to src/fiddle.h index b01346f..a68d3d2 100644 --- a/fiddle.h +++ b/src/fiddle.h @@ -8,5 +8,11 @@ extern unsigned int whirl16(unsigned int p, unsigned int n); extern unsigned int and32(unsigned int n), or32(unsigned int n), xor32(unsigned int n), fin32(unsigned int n); extern unsigned int whirl32(unsigned int p, unsigned int n); - +/* AIS: Reversed operators */ +extern unsigned int rev_and16(unsigned int n), rev_or16(unsigned int n), + rev_xor16(unsigned int n), rev_fin16(unsigned int n); +extern unsigned int rev_whirl16(unsigned int p, unsigned int n); +extern unsigned int rev_and32(unsigned int n), rev_or32(unsigned int n), + rev_xor32(unsigned int n), rev_fin32(unsigned int n); +extern unsigned int rev_whirl32(unsigned int p, unsigned int n); /* fiddle.h ends here */ diff --git a/ick-wrap.c b/src/ick-wrap.c similarity index 74% rename from ick-wrap.c rename to src/ick-wrap.c index a3dc7ae..50ce9c6 100644 --- a/ick-wrap.c +++ b/src/ick-wrap.c @@ -14,7 +14,10 @@ $M #include "lose.h" $K -#define OK(d) !abstained[d] +#define ICKABSTAINED(d) abstained[d] +#define ICKSTASH(a,b,c,d) stash(a, b, c+b, d) +#define ICKRETRIEVE(a,b,c,d,e) retrieve(a+b, c, b, d[b], e) +#define ICKIGNORE(a,b,c) a[b] extern int printflow; @@ -22,13 +25,14 @@ int lineno; jmp_buf cjb; int ccfc; -int skipto; +unsigned skipto=0; +$O int oldabstain; int abstained[$B]$C; $D $E - +$P int main(int argc, char *argv[]) { parseargs(argc,argv); @@ -44,9 +48,9 @@ $N #endif /* set seed for random error generation */ #ifdef USG - srand48(time((long *)0) + getpid()); + srand48(time(0) + getpid()); #else - srand(time((long *)0)); + srand(time(0)); #endif /* UNIX */ #if MULTITHREAD == 1 @@ -60,17 +64,21 @@ $N /* degenerated code */ ick_restart: - ; + top: + switch(skipto) + { + case 0: + $G + } -$G - #ifdef YUK if(yukloop) goto ick_restart; #endif lose(E633, $J, (char *)0); -$H + $H + return 0; } - +$Q /* Generated code for $A.i ends here */ diff --git a/src/ick.bat b/src/ick.bat new file mode 100755 index 0000000..0e246b8 --- /dev/null +++ b/src/ick.bat @@ -0,0 +1,8 @@ +@rem Wrapper for ickmain.exe that gets around the 126-byte system() limit + +@echo off +ickmain %* +if exist ickgcc.rsp gcc @ickgcc.rsp +if exist ickgcc.rsp del ickgcc.rsp +if exist ickyuk.bat call ickyuk.bat +if exist ickyuk.bat del ickyuk.bat diff --git a/ick.h b/src/ick.h similarity index 82% rename from ick.h rename to src/ick.h index 1f0cafe..85e0581 100644 --- a/ick.h +++ b/src/ick.h @@ -1,10 +1,22 @@ /* ick.h -- compilation types for intercal parser */ +/* AIS: Changes for DJGPP */ +#ifdef __DJGPP__ +#define _POSIX_SOURCE +#endif + +#ifdef ICKNOSEARCH +#define ICKINCLUDEDIR "." +#define ICKLIBDIR "." +#define ICKBINDIR "." +#define YYDEBUG 1 +#endif + /* Comment this out if your version of lex automatically supplies yylineno. */ -/*#define YYLINENO_BY_HAND*/ +#define YYLINENO_BY_HAND /* Comment this out if your version of lex doesn't use yyrestart(). */ -/*#define USE_YYRESTART*/ +#define USE_YYRESTART #define YY_NO_UNPUT @@ -25,7 +37,7 @@ typedef int bool; * Maximum supported statement types; should be equal to (FROM - GETS + 1) * AIS: Changed this when I added new statements. */ -#define MAXTYPES 23 +#define MAXTYPES 28 /* AIS: Maximum supported spark/ears nesting, divided by 32. The value given allows for 256 nested spark/ears groupings, which should be enough. */ @@ -40,6 +52,7 @@ typedef struct node_t unsigned long optdata; /* AIS: Temp used by the optimizer */ int width; /* is this 32-bit data? */ struct node_t *lval, *rval; /* attached expression nodes */ + struct node_t *nextslat; /* AIS: The next node with a slat */ } node; typedef struct tuple_t @@ -80,10 +93,11 @@ typedef struct tuple_t /* this maps the `external' name of a variable to an internal array index */ typedef struct { - int type; - int extindex; - int intindex; - int ignorable; /* AIS: Can this variable be IGNOREd? */ + int type; + unsigned int extindex; + unsigned int intindex; + int ignorable; /* AIS: Can this variable be IGNOREd? */ + int memloc; /* AIS: Where does a PIC store this in memory? */ } atom; @@ -96,13 +110,15 @@ assoc; extern atom *oblist, *obdex; extern int obcount, nonespots, ntwospots, ntails, nhybrids; +extern int nmeshes; /* AIS */ extern tuple *tuples; extern int tuplecount; extern tuple *optuple; /* AIS: The tuple currently being optimized */ -extern char *enablers[MAXTYPES]; +extern char **enablers; +extern char *enablersm1[MAXTYPES+1]; extern assoc vartypes[]; /* the lexical analyzer keeps copies of the source logical lines */ @@ -128,7 +144,13 @@ extern int yukdebug; /* debug the code with yuk */ extern int yukprofile; /* profile the code with yuk */ extern int compucomecount; /* number of computed COME FROMs */ extern int compucomesused; /* are computed COME FROMs used? */ +extern int nextfromsused; /* is NEXT FROM used? */ +extern int gerucomesused; /* is COME FROM gerund used? */ +extern int opoverused; /* is operand overloading used? */ +extern node* firstslat; /* the first node with a slat */ +extern node* prevslat; /* the last node so far with a slat */ extern int multithread; /* is the program multithreaded? */ +extern int variableconstants; /* is any assignment allowed? */ extern int coreonerr; /* dump core on E778? */ extern int optdebug; /* debug the optimizer */ extern int flowoptimize; /* optimize program flow */ diff --git a/lexer.l b/src/lexer.l similarity index 77% rename from lexer.l rename to src/lexer.l index 4fabe88..aee2b40 100644 --- a/lexer.l +++ b/src/lexer.l @@ -1,3 +1,6 @@ +%e 2000 +%p 4000 +%n 1000 %{ /* * NAME @@ -25,7 +28,7 @@ LICENSE TERMS #include #include #include "ick.h" -#include "y.tab.h" +#include "parser.h" #include "lose.h" /*#undef wchar_t*/ @@ -55,6 +58,16 @@ int stbeginline = 0; unsigned long sparkearsstack[SENESTMAX] = {0}; int sparkearslev = 0; +/* AIS: Some symbols are ambiguous between C-INTERCAL and CLC-INTERCAL: + Symbol C-INTERCAL CLC-INTERCAL + NOSPOT _ @ + WHIRL @ ? + XOR ? yen, or bookworm (bookworm's also C-INTERCAL legal) + By default, the C-INTERCAL meanings are used; the extern variable clclex + causes CLC-INTERCAL interpretations to be put on the ambiguous symbols. + Otherwise, mixing syntaxes freely is allowed. */ +extern int clclex; + #ifdef FLEX_SCANNER static char linebuf[YY_BUF_SIZE]; #else /* FLEX_SCANNER */ @@ -116,9 +129,10 @@ int getc(FILE *fp) char c_char; /*fprintf(stderr,"about to fgetc(\045p)",(void*)fp);*/ + c_char=0; /* AIS */ (void)fread(&c_char,1,1,fp); c = c_char; - /*fputc(c,stderr);*/ + /*if(!c) c=' '; AIS */ if(feof(fp)) c=EOF; /*fprintf(stderr,"getc input a character: %c\n",c);*/ @@ -211,12 +225,17 @@ D [0-9][\ \t\n0-9]* %% {D} {yylval.numval = myatoi(yytext); return(NUMBER);} +\_ {return(NOSPOT);} \. {return(ONESPOT);} \: {return(TWOSPOT);} \, {return(TAIL);} \; {return(HYBRID);} \# {return(MESH);} +\xBD | +"c^H/" | +"c^H|" {return(MINGLE); /* AIS: CLC-INTERCAL mingle symbols. + The \xBD is ISO-8859-1 for cent. */} \$ | \xA2 | \xA3 | @@ -243,13 +262,26 @@ D [0-9][\ \t\n0-9]* \~ {return(SELECT);} +\/ {return(SLAT); /* AIS: Operand overloading */} +\\ {return(BACKSLAT); /* ditto */} + \& {yylval.numval = AND; return(UNARY);} V {yylval.numval = OR; return(UNARY);} +\xA5 | +\xBE | "V^H-" | -\xE2\x88\x80 | -\? {yylval.numval = XOR; return(UNARY);} -\^ {yylval.numval = FIN; return(UNARY);} -@ {yylval.numval = WHIRL; return(UNARY);} +\xE2\x88\x80 {yylval.numval = XOR; return(UNARY); + /* AIS: CLC-INTERCAL uses \xBE, ISO-8859-1 for yen; + for some reason, \xA5 is what was detected by the compiler + during my tests, so that's here too */} +\? {if(clclex) yylval.numval = WHIRL; + else yylval.numval = XOR; return(UNARY); + /* AIS: ? is a unary operator in both C-INTERCAL and + CLC-INTERCAL, but with different meanings. */} +\| | +\^ {yylval.numval = FIN; return(UNARY); /* AIS: | is CLC */} +@ {if(clclex) return(NOSPOT); /* AIS: a C/CLC ambiguity */ + else {yylval.numval = WHIRL; return(UNARY);}} [2-5]{W}@ {yylval.numval = WHIRL + myatoi(yytext) - 1; return(UNARY);} \' {char temp = sparkearsstack[sparkearslev/32]&1; @@ -280,6 +312,10 @@ MAYBE{W}PLEASE{W}DO {SETLINENO; CLEARSPARKEARSTACK; politesse++; return(MAYBE); NOT {return(NOT);} N\'T {return(NOT);} NON {return(NOT);} +\xAA {return(NOT); /* AIS: CLC-INTERCAL again, this time it's + ISO-8859-1 for the logical NOT symbol... */} +\xAC {return(NOT); /* ... but my computer translates it to \xAC */} + ONCE {return(ONCE);} QUONDAM {return(ONCE);} AGAIN {return(AGAIN);} @@ -298,10 +334,6 @@ BY {return(BY);} CALCULANDUM | CALCULATING {yylval.numval = GETS; return(GERUND);} -DEINDE | -NEXT {stbeginline = 0; return(NEXT);} -PROXIMANDUM | -NEXTING {yylval.numval = NEXT; return(GERUND);} ALIENERE | FORGET {return(FORGET);} ALIENENDUM | @@ -328,8 +360,6 @@ MEMINISSENDUM | REMEMBERING {yylval.numval = REMEMBER; return(GERUND);} ABSTINERE | ABSTAIN {return(ABSTAIN);} -FROM | -A {return(FROM);} ABSTINENDUM | ABSTAINING {yylval.numval = ABSTAIN; return(GERUND);} REINSTARE | @@ -344,13 +374,34 @@ SCRIBERE{W}IN | WRITE{W}IN {return(WRITE_IN);} SCRIBENDUM | WRITING{W}IN {yylval.numval = WRITE_IN; return(GERUND);} +COMMEMERO | +COMMENT {yylval.numval = UNKNOWN; return(GERUND); + /* AIS: An idea stolen from CLC-INTERCAL. + The Latin means literally 'remind' or 'mention'. */} +PIN {/* By AIS. I can't find a Latin translation for this. */ + return(PIN);} +PINNING {/* By AIS */ yylval.numval = PIN; return(GERUND);} +DEINDERE{W}A{W}\({W}{D}\) | +NEXT{W}FROM{W}\({W}{D}\) {/* AIS */ yylval.numval = myatoi(yytext); + return(NEXTFROMLABEL);} +DEINDERE{W}A | +NEXT{W}FROM {/* AIS: 'next' is not a verb, so the Latin is invented */ + return(NEXTFROMEXPR);} +DEINDENDUM | +NEXTING{W}FROM {/* AIS */ yylval.numval = NEXTFROMLABEL; return(GERUND);} ADVENIRE{W}DE{W}\({W}{D}\) | -COME{W}FROM{W}\({W}{D}\) {/* By AIS */ yylval.numval = myatoi(yytext); +COME{W}FROM{W}\({W}{D}\) {/* AIS */ yylval.numval = myatoi(yytext); return(COME_FROM);} ADVENIRE{W}DE | -COME{W}FROM {/* By AIS */ return(COMPUCOME);} +COME{W}FROM {/* AIS */ return(COMPUCOME);} ADVENENDUM | COMING{W}FROM {yylval.numval = COME_FROM; return(GERUND);} +DEINDE | +NEXT {stbeginline = 0; return(NEXT);} +PROXIMANDUM | +NEXTING {yylval.numval = NEXT; return(GERUND);} +FROM | +A {return(FROM);} CONCEDERE | DESPERARE | GIVE{W}UP {return(GIVE_UP);} @@ -372,7 +423,9 @@ GOING{W}AHEAD {yylval.numval = GO_AHEAD; return(GERUND); \+ {return(INTERSECTION);} {W} ; -. {yylval.numval = yytext[0]; return(BADCHAR);} +. {yylval.numval = yytext[0]; /* AIS: The line below for debug */ + if(yydebug) fprintf(stdout, "yylex: bad char %#x\n",(unsigned char)yytext[0]); + return(BADCHAR);} %% @@ -399,7 +452,7 @@ int lexer(void) return(tok); } -static int myatoi(char *text) /* Alex edit! */ +static int myatoi(char *text) /* AIS */ { #define MAXTEXT 100 static char buf[MAXTEXT]; @@ -415,8 +468,10 @@ static int myatoi(char *text) /* Alex edit! */ } buf[i] = '\0'; bp=buf; tp=thinbuf; - while(*tp++=*bp++); /* thinbuf code added by an Alex edit, - in case we want to work with wchar_t */ + while(((*tp++=*bp++))); /* thinbuf code added by an AIS + in case we want to work with wchar_t; + the extra brackets tell GCC that this is + intended and not a mistaken assignment */ return atoi(thinbuf); } diff --git a/lose.c b/src/lose.c similarity index 96% rename from lose.c rename to src/lose.c index 23cbee3..adf751d 100644 --- a/lose.c +++ b/src/lose.c @@ -59,8 +59,10 @@ void lwarn(char *m, int n, char *s) m[0],m[1],m[2]); if (s) (void) fprintf(stderr, m + 4, s, n); - else + else if(m[0]!='2'||m[1]!='7'||m[2]!='8') (void) fprintf(stderr, m + 4, n); + else + (void) fprintf(stderr, m + 4); (void) fprintf(stderr, " RECONSIDER SOURCE AND RESUBNIT\n\n"); /* Don't exit. This is not any error except one not causing immediate termination of program execution. */ diff --git a/lose.h b/src/lose.h similarity index 90% rename from lose.h rename to src/lose.h index a249fd4..c613054 100644 --- a/lose.h +++ b/src/lose.h @@ -92,6 +92,10 @@ /* Out of stash space */ #define E222 "222 BUMMER, DUDE!\n\ ON THE WAY TO %d\n" +/* (AIS) Can't reverse an expression in an assignment. This is the + same error number as in CLC-INTERCAL, but the message is different. */ +#define E277 "277 YOU CAN ONLY DISTORT THE LAWS OF MATHEMATICS SO FAR\n\ + ON THE WAY TO %d\n" /* (AIS) The spark/ears nesting is too deep. */ #define E281 "281 THAT MUCH QUOTATION AMOUNTS TO PLAGIARISM\n\ ON THE WAY TO %d\n" @@ -135,6 +139,19 @@ /* (AIS) Memory allocation failure during multithreading */ #define E991 "991 YOU HAVE TOO MUCH ROPE TO HANG YOURSELF\n\ ON THE WAY TO %d\n" +/* (AIS) Unimplemented feature used. This should never come up, hopefully. */ +#define E995 "995 DO YOU REALLY EXPECT ME TO HAVE IMPLEMENTED THAT?\n\ + ON THE WAY TO %d\n" +/* + * AIS: These errors are specific to PIC-INTERCAL + */ +/* (AIS) Attempted to use an unsupported language feature. */ +#define E256 "256 THAT'S TOO HARD FOR MY TINY BRAIN\n\ + ON THE WAY TO %d\n" + +/* (AIS) Attempted to use a PIC feature in a non-PIC program. */ +#define E652 "652 HOW DARE YOU INSULT ME!\n\ + ON THE WAY TO %d\n" /* * AIS: These errors are generated by the yuk debugger @@ -195,6 +212,10 @@ #define W276 "276 YOU CAN'T EXPECT ME TO CHECK BACK THAT FAR\n\ ON THE WAY TO %d\n" +/* (AIS) A line will inevitably cause an expression-reversal failure. */ +#define W278 "278 FROM A CONTRADICTION, ANYTHING FOLLOWS\n\ + ON THE WAY TO A HUGE DISASTER\n" + /* (AIS) The two following warnings are both compile-time traps for near-certain runtime errors. As such, they have similar numbers and similar messages. In fact, they're a shameless ripoff of the diff --git a/numerals.c b/src/numerals.c similarity index 99% rename from numerals.c rename to src/numerals.c index c4a200e..d6c9584 100644 --- a/numerals.c +++ b/src/numerals.c @@ -43,7 +43,7 @@ typedef struct } numeral; -static numeral numerals[] = +numeral numerals[] = { /* English */ { "OH", 0 }, diff --git a/ick.y b/src/parser.y similarity index 60% rename from ick.y rename to src/parser.y index 391674c..97807d7 100644 --- a/ick.y +++ b/src/parser.y @@ -5,10 +5,8 @@ NAME DESCRIPTION This YACC grammar parses the INTERCAL language by designed by Don R. Woods -and James M. Lyon. There are five syntax extensions over the original -INTERCAL-72 language; the COME FROM statement, the prefixed forms of the -WHIRL operator, and (AIS) the ABSTAIN FROM, COME FROM , -and ONCE/AGAIN forms. +and James M. Lyon. There are several syntax extensions over the original +INTERCAL-72 language. LICENSE TERMS Copyright (C) 1996 Eric S. Raymond @@ -85,22 +83,30 @@ static tuple *splat(void); /* * Don't change this statement token list gratuitously! - * Some code in feh.c depends on GETS being the least + * Some code in feh2.c depends on GETS being the least * statement type and on the order of the ones following. - * AIS: Added FROM, MANYFROM, TRY_AGAIN, COMPUCOME. + * AIS: Note that although GETS is the lowest statement type (with index 0 + * in feh2.c), UNKNOWN (i.e. a line that causes error 000) is an even + * lower statement type, with index -1. perpet.c uses indexes 1 higher. + * AIS: Added FROM, MANYFROM, TRY_AGAIN, COMPUCOME, GERUCOME, and + * three NEXT FROM cases. * AIS: COME_FROM now merged with the label following it, - * to distinguish it from COMPUCOME, in the lexer. This changes - * the parser somewhat. + * to distinguish it from COMPUCOME, in the lexer. This changes + * the parser somewhat. */ +%token UNKNOWN /* AIS: This is so comments can be REINSTATED */ %token GETS RESIZE NEXT GO_AHEAD GO_BACK FORGET RESUME STASH RETRIEVE IGNORE %token REMEMBER ABSTAIN REINSTATE -%token DISABLE ENABLE MANYFROM GIVE_UP READ_OUT WRITE_IN -%token COME_FROM -%token COMPUCOME TRY_AGAIN FROM +%token DISABLE ENABLE MANYFROM GIVE_UP READ_OUT WRITE_IN /* AIS: */PIN +%token COME_FROM NEXTFROMLABEL +%token NEXTFROMEXPR NEXTFROMGERUND COMPUCOME GERUCOME TRY_AGAIN FROM -/* AIS: ONCE and AGAIN added, for multithread support */ -%token MAYBE DO PLEASE NOT ONCE AGAIN MESH ONESPOT TWOSPOT TAIL HYBRID +/* AIS: ONCE and AGAIN added, for multithread support; also, NOSPOT added, + so that I can reserve _ for future use (it's nowhere in the grammar yet) */ +%token MAYBE DO PLEASE NOT ONCE AGAIN MESH NOSPOT ONESPOT TWOSPOT TAIL HYBRID %token MINGLE SELECT /* AIS: SPARK EARS */ SUB BY BADCHAR +/* AIS: For operand overloading */ +%token SLAT BACKSLAT %token NUMBER UNARY OHOHSEVEN GERUND LABEL %token INTERSECTION @@ -112,21 +118,30 @@ static tuple *splat(void); * WHIRL through WHIRL5 be a continuous sequence. */ /* AIS: Added new tokens for optimizer output */ -%token SPLATTERED +%token SPLATTERED MESH32 %token C_AND C_OR C_XOR C_NOT C_NNAND C_ISNONZERO C_LSHIFT C_LSHIFT2 %token C_LSHIFT8 C_LSHIFTIN1 C_RSHIFT C_AND1ADD1 C_2SUBAND1 C_1PLUS C_2MINUS -%token C_XORGREATER C_RSHIFTBY C_NOTEQUAL -%token AND OR XOR FIN MESH32 WHIRL WHIRL2 WHIRL3 WHIRL4 WHIRL5 - -%type expr varlist variable constant lvalue inlist outlist -%type subscr byexpr scalar array initem outitem sublist -%type unambig subscr1 sublist1 oparray osubscr osubscr1 +%token C_XORGREATER C_RSHIFTBY C_NOTEQUAL C_A +/* The reverse unary operators have to be in the same order as the forward + unary operators. */ +%token AND OR XOR FIN WHIRL WHIRL2 WHIRL3 WHIRL4 WHIRL5 +%token REV_AND REV_OR REV_XOR REV_FIN +%token REV_WHIRL REV_WHIRL2 REV_WHIRL3 REV_WHIRL4 REV_WHIRL5 + +%type expr limexpr varlist variable constant lvalue inlist outlist +%type subscr byexpr scalar scalar2s array initem outitem sublist +%type unambig limunambig subscr1 sublist1 oparray osubscr osubscr1 +%type notanlvalue nlunambig lunambig %type perform mtperform %type please preftype %nonassoc OPENEARS OPENSPARK CLOSEEARS CLOSESPARK %nonassoc HIGHPREC -/* AIS: I reversed this precedence, to sort out the near-ambiguity */ +%nonassoc UNARYPREC +%nonassoc LOWPREC +/* AIS: I reversed this precedence, to sort out the near-ambiguity. + UNARYPREC and LOWPREC are to give the C-INTERCAL meaning of a statement + precedence above its CLC-INTERCAL meaning. */ %% /* beginning of rules section */ @@ -161,22 +176,26 @@ command : please mtperform */ mtperform : perform - {$1->onceagainflag = onceagain_NORMAL; $$ = $1;} - | perform ONCE - {NEWFANGLED {$1->onceagainflag = onceagain_ONCE; $$ = $1;}} - | perform AGAIN - {NEWFANGLED {$1->onceagainflag = onceagain_AGAIN; $$ = $1;}} + {$1->onceagainflag = onceagain_NORMAL; $$ = $1;} + | perform ONCE + {NEWFANGLED {$1->onceagainflag = onceagain_ONCE; $$ = $1;}} + | perform AGAIN + {NEWFANGLED {$1->onceagainflag = onceagain_AGAIN; $$ = $1;}} /* There are two (AIS: now four) forms of preamble returned by the lexer */ please : DO {GETLINENO; $$ = 1;} | DO NOT {GETLINENO; $$ = -1;} - | MAYBE {NEWFANGLED {GETLINENO; $$ = 101;}} - | MAYBE NOT {NEWFANGLED {GETLINENO; $$ = -101;}} + | MAYBE {NEWFANGLED {GETLINENO; $$ = 101;}} + | MAYBE NOT {NEWFANGLED {GETLINENO; $$ = -101;}} ; /* Here's how to parse statement bodies */ perform : lvalue GETS expr {ACTION($$, GETS, cons(GETS,$1,$3));} | array GETS byexpr {ACTION($$, RESIZE, cons(RESIZE,$1,$3));} + | notanlvalue GETS expr %prec LOWPREC + {/* AIS: This is for variableconstants, and an error otherwise.*/ + if(variableconstants) ACTION($$, GETS, cons(GETS,$1,$3)) + else {yyclearin; $$=splat();}} | LABEL NEXT {TARGET($$, NEXT, $1);} | FORGET expr {ACTION($$, FORGET, $2);} | RESUME expr {ACTION($$, RESUME, $2);} @@ -186,19 +205,33 @@ perform : lvalue GETS expr {ACTION($$, GETS, cons(GETS,$1,$3));} | REMEMBER varlist {ACTION($$, REMEMBER, rlist);} | ABSTAIN FROM LABEL {stbeginline=0; TARGET($$, ABSTAIN, $3);} | ABSTAIN FROM gerunds {ACTION($$, DISABLE, rlist);} - | ABSTAIN expr FROM LABEL {/* AIS */ NEWFANGLED {stbeginline=0; ACTARGET($$, FROM, $2, $4);}} - | ABSTAIN expr FROM gerunds {/* AIS */ NEWFANGLED {$$ = newtuple(); $$->type = MANYFROM; $$->lineno = thisline; \ + | ABSTAIN expr FROM LABEL {/* AIS */ NEWFANGLED {stbeginline=0; ACTARGET($$, FROM, $2, $4);}} + | ABSTAIN expr FROM gerunds {/* AIS */ NEWFANGLED {$$ = newtuple(); $$->type = MANYFROM; $$->lineno = thisline; \ {node* tempnode=newnode(); $$->u.node = tempnode; tempnode->lval=$2; tempnode->rval=rlist; tempnode->opcode=MANYFROM;}}} | REINSTATE LABEL {stbeginline=0; TARGET($$, REINSTATE, $2);} | REINSTATE gerunds {ACTION($$, ENABLE, rlist);} | WRITE_IN inlist {ACTION($$, WRITE_IN, $2);} | READ_OUT outlist {ACTION($$, READ_OUT, $2);} + | PIN scalar2s {ACTION($$, PIN, $2);} | GIVE_UP {ACTION($$, GIVE_UP, 0);} - | GO_AHEAD {/* AIS */ NEWFANGLED {ACTION($$, GO_AHEAD, 0);}} - | GO_BACK {/* AIS */ NEWFANGLED {ACTION($$, GO_BACK, 0);}} - | TRY_AGAIN {/* AIS */ NEWFANGLED {ACTION($$,TRY_AGAIN,0);}} - | COME_FROM {/* AIS: Modified this */ NEWFANGLED {TARGET($$,COME_FROM,$1);}} - | COMPUCOME expr {/* AIS */NEWFANGLED {ACTION($$,COMPUCOME,$2); compucomesused=1;}} + | GO_AHEAD {/* AIS */ NEWFANGLED {ACTION($$, GO_AHEAD, 0);}} + | GO_BACK {/* AIS */ NEWFANGLED {ACTION($$, GO_BACK, 0);}} + | TRY_AGAIN {/* AIS */ NEWFANGLED {ACTION($$,TRY_AGAIN,0);}} + | COME_FROM {/* AIS: Modified */ NEWFANGLED {TARGET($$,COME_FROM,$1);}} + | COMPUCOME gerunds {/* AIS: COME FROM gerund */ + NEWFANGLED{ACTION($$,GERUCOME,rlist); + compucomesused=1; gerucomesused=1;}} + | COMPUCOME expr {/* AIS */NEWFANGLED {ACTION($$,COMPUCOME,$2); + compucomesused=1;}} +/* AIS: NEXT FROM works along the same lines as COME FROM */ + | NEXTFROMLABEL {NEWFANGLED {TARGET($$,NEXTFROMLABEL,$1);} + nextfromsused=1;} + | NEXTFROMEXPR gerunds{NEWFANGLED{ACTION($$,NEXTFROMGERUND,rlist); + compucomesused=1; gerucomesused=1;} + nextfromsused=1;} + | NEXTFROMEXPR expr {NEWFANGLED {ACTION($$,NEXTFROMEXPR,$2); + compucomesused=1; nextfromsused=1;}} + | BADCHAR {yyclearin; $$ = splat();} | error {yyclearin; $$ = splat();} ; @@ -219,6 +252,12 @@ variable: scalar | array; lvalue : scalar | subscr; +scalar2s: TWOSPOT NUMBER /* AIS: for TWOSPOTs only */ + { + $$ = newnode(); + $$->opcode = TWOSPOT; + $$->constant = intern(TWOSPOT, $2); + } scalar : ONESPOT NUMBER { $$ = newnode(); @@ -249,7 +288,7 @@ array : TAIL NUMBER /* Array with unary operator is a special intermediate case; these nodes will be rearranged when the subscript list is added */ -oparray : TAIL UNARY NUMBER +oparray : TAIL UNARY NUMBER %prec UNARYPREC { $$ = newnode(); $$->opcode = $2; @@ -257,7 +296,7 @@ oparray : TAIL UNARY NUMBER $$->rval->opcode = TAIL; $$->rval->constant = intern(TAIL, $3); } - | HYBRID UNARY NUMBER + | HYBRID UNARY NUMBER %prec UNARYPREC { $$ = newnode(); $$->opcode = $2; @@ -265,7 +304,7 @@ oparray : TAIL UNARY NUMBER $$->rval->opcode = HYBRID; $$->rval->constant = intern(HYBRID, $3); } - ; + ; /* And a constant looks like this */ constant: MESH NUMBER @@ -275,7 +314,10 @@ constant: MESH NUMBER lose(E017, yylineno, (char *)NULL); $$ = newnode(); $$->opcode = MESH; - $$->constant = $2; + if(variableconstants) /* AIS */ + $$->constant = intern(MESH, $2); + else + $$->constant = $2; } ; @@ -307,22 +349,22 @@ byexpr : expr BY byexpr {$$ = cons(BY, $1, $3);} ; /* Support array subscripts (as lvalues) */ -subscr : subscr1 {$$ = $1;} - | array SUB sublist {$$ = cons(SUB, $1, $3);} +subscr : subscr1 {$$ = $1;} + | array SUB sublist {$$ = cons(SUB, $1, $3);} ; subscr1 : array SUB sublist1 {$$ = cons(SUB, $1, $3);} ; -sublist : unambig sublist {$$ = cons(INTERSECTION, $1, $2);} - | unambig sublist1 {$$ = cons(INTERSECTION, $1, $2);} +sublist : unambig sublist {$$ = cons(INTERSECTION, $1, $2);} + | unambig sublist1 {$$ = cons(INTERSECTION, $1, $2);} + ; +sublist1: subscr1 {$$ = cons(INTERSECTION, $1, 0);} + | osubscr1 {$$ = cons(INTERSECTION, $1, 0);} + | unambig %prec HIGHPREC {$$ = cons(INTERSECTION, $1, 0);} ; -sublist1: subscr1 {$$ = cons(INTERSECTION, $1, 0);} - | osubscr1 {$$ = cons(INTERSECTION, $1, 0);} - | unambig %prec HIGHPREC {$$ = cons(INTERSECTION, $1, 0);} - ; /* Unary operators with arrays act like arrays only in expressions */ -osubscr : osubscr1 {$$ = $1;} - | oparray SUB sublist +osubscr : osubscr1 {$$ = $1;} + | oparray SUB sublist {$$ = $1; $$->rval = cons(SUB, $$->rval, $3);} ; osubscr1: oparray SUB sublist1 @@ -330,24 +372,55 @@ osubscr1: oparray SUB sublist1 ; /* here goes the general expression syntax */ -expr : unambig {$$ = $1;} - | unambig SELECT unambig {$$ = cons(SELECT, $1, $3);} - | unambig SELECT subscr {$$ = cons(SELECT, $1, $3);} - | unambig SELECT osubscr {$$ = cons(SELECT, $1, $3);} - | unambig MINGLE unambig {$$ = cons(MINGLE, $1, $3);} - | unambig MINGLE subscr {$$ = cons(MINGLE, $1, $3);} - | unambig MINGLE osubscr {$$ = cons(MINGLE, $1, $3);} +expr : unambig {$$ = $1;} +/* AIS: CLC-INTERCAL allows right-association of SELECT and MINGLE. + (Strangely, that simplifies this section somewhat.) */ + | unambig SELECT expr {$$ = cons(SELECT, $1, $3);} + | unambig MINGLE expr {$$ = cons(MINGLE, $1, $3);} +/* AIS: Operand overloading */ + | scalar SLAT expr {NEWFANGLED{$$ = cons(SLAT, $1, $3); + opoverused=1; if(!firstslat) + firstslat=$$; else + prevslat->nextslat=$$; prevslat=$$; + $$->nextslat=0;}} | subscr {$$ = $1;} | osubscr {$$ = $1;} - ; + ; -preftype: MESH {$$=MESH; } | ONESPOT {$$=ONESPOT;} | TWOSPOT {$$=TWOSPOT;}; +/* AIS: Any expression that isn't an lvalue */ +notanlvalue:nlunambig {$$ = $1;} + | osubscr {$$ = $1;} + | unambig SELECT expr {$$ = cons(SELECT, $1, $3);} + | unambig MINGLE expr {$$ = cons(MINGLE, $1, $3);} + | scalar SLAT expr {NEWFANGLED{$$ = cons(SLAT, $1, $3); + opoverused=1; if(!firstslat) + firstslat=$$; else + prevslat->nextslat=$$; prevslat=$$; + $$->nextslat=0;}} + ; -unambig : variable {$$ = $1;} - | constant {$$ = $1;} +/* AIS: an expr that doesn't start with a unary operator */ +limexpr : limunambig {$$ = $1;} + | limunambig SELECT expr {$$ = cons(SELECT, $1, $3);} + | limunambig MINGLE expr {$$ = cons(MINGLE, $1, $3);} + | scalar SLAT expr {NEWFANGLED{$$ = cons(SLAT, $1, $3); + opoverused=1; if(!firstslat) + firstslat=$$; else + prevslat->nextslat=$$; prevslat=$$; + $$->nextslat=0;}} + | subscr {$$ = $1;} + | osubscr {$$ = $1;} + ; + + +preftype: MESH {$$=MESH; } | ONESPOT {$$=ONESPOT;} | TWOSPOT {$$=TWOSPOT;}; +/* AIS: unambig split into limunambig (unambigs that don't start with a + unary operator), nlunambig (unambigs that aren't lvalues), + lunambig (both), and unambig (the general case) */ +lunambig: constant {$$ = $1;} /* deal with the bizarre unary-op syntax */ - | preftype UNARY NUMBER + | preftype UNARY NUMBER %prec UNARYPREC { $$ = newnode(); $$->opcode = $2; @@ -357,7 +430,7 @@ unambig : variable {$$ = $1;} /* enforce the 16-bit constant constraint */ if ((unsigned int)$3 > Max_small) lose(E017, yylineno, (char *)NULL); - $$->rval->constant = $3; + $$->rval->constant = intern(MESH, $3); } else { $$->rval->constant = intern($1, $3); @@ -365,33 +438,54 @@ unambig : variable {$$ = $1;} } /* Now deal with the screwy unary-op interaction with grouping */ - /* AIS: Modified to allow for maintenance of the SPARK/EARS stack */ - | eitherspark UNARY expr CLOSESPARK + /* AIS: Modified to allow for maintenance of the SPARK/EARS stack */ + | eitherspark UNARY expr CLOSESPARK %prec UNARYPREC { $$ = newnode(); $$->opcode = $2; $$->rval = $3; DESTACKSPARKEARS; } - | eitherears UNARY expr CLOSEEARS + | eitherears UNARY expr CLOSEEARS %prec UNARYPREC { $$ = newnode(); $$->opcode = $2; $$->rval = $3; DESTACKSPARKEARS; } +/* AIS: limexpr, a limited expression that isn't allowed to start with a + unary operator, is used here to avoid a reduce/reduce conflict. */ + | eitherspark limexpr CLOSESPARK {$$ = $2; DESTACKSPARKEARS;} + | eitherears limexpr CLOSEEARS {$$ = $2; DESTACKSPARKEARS;} + ; + +limunambig: lunambig {$$ = $1;} + | scalar {$$ = $1;} + ; + +nlunambig: lunambig {$$ = $1;} + | UNARY unambig %prec LOWPREC + {$$=newnode(); $$->opcode = $1; $$->rval = $2;} + ; - | eitherspark expr CLOSESPARK {$$ = $2; DESTACKSPARKEARS;} - | eitherears expr CLOSEEARS {$$ = $2; DESTACKSPARKEARS;} +/* AIS: A bit of CLC-INTERCAL compatibility here. + The syntax now allows any number of unary operators before, and one inside, + an expression. In ambiguous cases like '&VV#1~#5', the & applies to the + whole expression (one operator inside is allowed, and inside takes + precedence), but the Vs apply just to the #1, because only one operator + inside is allowed. */ +unambig : limunambig {$$ = $1;} + | UNARY unambig %prec LOWPREC + {$$=newnode(); $$->opcode = $1; $$->rval = $2;} ; eitherspark : OPENSPARK ; - | CLOSESPARK ; - ; + | CLOSESPARK ; + ; eitherears : OPENEARS ; - | CLOSEEARS ; - ; + | CLOSEEARS ; + ; %% diff --git a/perpetrate.c b/src/perpet.c similarity index 64% rename from perpetrate.c rename to src/perpet.c index 5acec59..6adeebc 100644 --- a/perpetrate.c +++ b/src/perpet.c @@ -1,7 +1,7 @@ /**************************************************************************** NAME - perpetrate.c -- main routine for C-INTERCAL compiler. + perpet.c -- main routine for C-INTERCAL compiler. DESCRIPTION This is where all the dirty work begins and ends. @@ -33,7 +33,7 @@ LICENSE TERMS #include #include "ick.h" #include "feh.h" -#include "y.tab.h" +#include "parser.h" #include "sizes.h" #include "lose.h" @@ -50,6 +50,8 @@ LICENSE TERMS #define CC "gcc" #endif +#define ARGSTRING "bcdfghlmptuvyCFHOPUX@" + #ifdef USE_YYRESTART /* function supplied by lex */ extern void yyrestart(FILE*); @@ -69,22 +71,35 @@ int yukdebug; /* AIS: Use the yuk debugger. */ int yukprofile; /* AIS: Use the yuk profiler. */ extern int coreonerr; /* AIS: Dump core on E778. (defined in lose.c) */ int multithread; /* AIS: Allow multithreading and backtracking. */ +int variableconstants; /* AIS: Allow anything on the left of an assignment. */ int cdebug; /* AIS: Pass -g to our C compiler, and leave C code. */ int optdebug; /* AIS: Debug the optimizer. Value is 0, 1, 2, or 3. */ int flowoptimize; /* AIS: Do flow optimizations (in INTERCAL!). */ int coopt; /* AIS: The constant-output optimization. This should mean that INTERCAL will beat any other language at many benchmark programs (!) */ +int printfopens; /* AIS: Print messages whenever attempting to open a + file */ extern int checkforbugs;/* AIS: Try to find possible bugs in the source code */ - -int compucomecount=0; /* AIS: Computed COME FROM count */ -int compucomesused=0; /* AIS: Are computed COME FROMs used? */ +int pickcompile; /* AIS: Compile for PIC? */ +int clclex; /* AIS: 1 means use CLC-INTERCAL meanings for @, ? */ +int outtostdout; /* AIS: Output on stdout rather than the output file */ + +/* AIS: Autodetected compilation options */ +int compucomecount=0; /* Computed COME FROM count */ +int compucomesused=0; /* Are computed COME FROMs used? */ +int gerucomesused=0; /* Is COME FROM gerund used? */ +int nextfromsused=0; /* Is NEXT FROM used? */ +int opoverused=0; /* Is operand overloading used? */ +node* firstslat=0; /* The first slat expression in the program */ +node* prevslat=0; /* The last slat expression used so far */ static bool dooptimize; /* do optimizations? (controlled by -O) */ static bool clockface; /* set up output to do IIII for IV */ -#define SKELETON "ick-wrap.c" -#define SYSLIB "pit/lib/syslib" +#define SKELETON "ick-wrap.c" +#define PSKELETON "pickwrap.c" +#define SYSLIB "syslib" /* numeric base defaults, exported to other files */ @@ -113,12 +128,15 @@ static char *compiler; atom *oblist = NULL, *obdex; int obcount = 0; int nonespots, ntwospots, ntails, nhybrids; +int nmeshes; /* AIS */ tuple *tuples = NULL; int tuplecount = 0; tuple *optuple = NULL; /* AIS: Tuple being optimized */ +extern assoc varstores[]; /* AIS: Need to know this for PIC compilation */ + static int myfgetc(FILE* in) { char c; @@ -127,13 +145,21 @@ static int myfgetc(FILE* in) return (int)c; } +static FILE* debfopen(char* fname, char* mode) +{ + FILE* t; + if(printfopens) fprintf(stderr,"Trying to open '%s'...\n",fname); + t=fopen(fname,mode); + if(printfopens&&t) fprintf(stderr,"Success!\n"); + if(printfopens&&!t) fprintf(stderr,"Failed!\n"); + return t; +} static void abend(int signim) { lose(E778, yylineno, (char *)NULL); (void) signim; } - static void print_usage(char *prog, char *options) { fprintf(stderr,"Usage: %s [-%s] [ ... ]\n",prog,options); @@ -161,6 +187,14 @@ static void print_usage(char *prog, char *options) fprintf(stderr,"\t-p\t:run the yuk profiler on the code (prevents -fm)\n"); fprintf(stderr,"\t-m\t:allow multithreading and backtracking " "(prevents -yp)\n"); + fprintf(stderr,"\t-v\t:allow anything on the left of an assignment. This " + "is required\n\t\tif you want operand overloading. " + "(prevents -fFOP)\n"); + fprintf(stderr,"\t-P\t:compile PIC-INTERCAL rather than INTERCAL\n"); + fprintf(stderr,"\t-o\t:output to stdout rather than .c (implies -c)"); + fprintf(stderr,"\t-X\t:interpret ? and @ with CLC-INTERCAL meanings\n"); + fprintf(stderr,"\t-u\t:print a message whenever the compiler tries to " + "open a file\n"); fprintf(stderr,"\t-U\t:dump core on E778 rather than printing an error\n"); fprintf(stderr,"\t-g\t:compile to both debuggable executable and C\n"); fprintf(stderr,"\t-l\t:attempt to report likely bugs " @@ -174,7 +208,8 @@ static void print_usage(char *prog, char *options) path they should be in, then the current directory, then argv[0]'s directory (if one was given). This function avoids possible buffer overflows, instead truncating filenames (and if that manages to find them, - I'll be incredibly surprised). */ + I'll be incredibly surprised). It also tries argv[0]/../lib and + argv[0]/../include (where they are when running without installing). */ static FILE* findandfopen(char* file, char* guessdir, char* mode, char* argv0) { char buf2[BUFSIZ], *fileiter; @@ -185,18 +220,42 @@ static FILE* findandfopen(char* file, char* guessdir, char* mode, char* argv0) fileiter = file; while(*fileiter&&itype; tp++) { - /* - * If some label in the (1000)-(2000) range is defined, - * then clearly the syslib is already there, so we - * can stop searching and won't need the syslib. - */ - if (tp->label >= 1000 && tp->label <= 1999) { - needsyslib = FALSE; - break; + if(!pickcompile) /* AIS: We never need syslib when compiling + for PIC, because it's preoptimized. */ + { + for (tp = tuples; tp->type; tp++) + { + /* + * If some label in the (1000)-(2000) range is defined, + * then clearly the syslib is already there, so we + * can stop searching and won't need the syslib. + */ + if (tp->label >= 1000 && tp->label <= 1999) { + needsyslib = FALSE; + break; + } + /* + * If some label in the (1000)-(2000) range is being + * called, we might need the system library. + */ + if (tp->type == NEXT && tp->u.target >= 1000 && + tp->u.target <= 1999) + needsyslib = TRUE; } - /* - * If some label in the (1000)-(2000) range is being - * called, we might need the system library. - */ - if (tp->type == NEXT && tp->u.target >= 1000 && - tp->u.target <= 1999) - needsyslib = TRUE; } if ( needsyslib ) { /* AIS: modified to use findandfreopen */ if (Base == 2) /* see code for opening the skeleton */ @@ -489,7 +614,6 @@ int main(int argc, char *argv[]) (void) sprintf(buf2, "%s.%di", SYSLIB, Base); if (findandfreopen(buf2, libdir, "r", argv[0], stdin) == 0) lose(E127, 1, (char*) NULL); - #ifdef USE_YYRESTART yyrestart(stdin); #endif /* USE_YYRESTART */ @@ -547,7 +671,8 @@ int main(int argc, char *argv[]) /* set up the generated C output file name */ (void) strcpy(buf, argv[optind]); (void) strcat(buf, ".c"); - if ((ofp = fopen(buf, "w")) == (FILE *)NULL) + if(outtostdout) ofp=stdout; /* AIS */ + else if((ofp = debfopen(buf, "w")) == (FILE *)NULL) lose(E888, 1, (char *)NULL); fseek(ifp,0L,0); /* rewind skeleton file */ @@ -563,9 +688,15 @@ int main(int argc, char *argv[]) else strcpy(argv[0],"."); (void) sprintf(buf2, - "%s %s%s-I%s -I%s -L%s -L%s -o %s -lick%s%s", - compiler, buf, yukdebug||yukprofile?" -lyuk ":" ", - includedir, argv[0], libdir, argv[0], + "%s %s%s-I%s -I%s -I%s/../include -L%s -L%s -L%s/../lib -O%c -o %s" +#ifdef __DJGPP__ + ".exe -lick%s%s","", +#else + " -lick%s%s",compiler, +#endif + buf, yukdebug||yukprofile?" -lyuk ":" ", + includedir, argv[0], argv[0], libdir, argv[0], argv[0], + coopt?'3':'2', /* AIS: If coopting, optimize as much as possible */ argv[optind], multithread?"mt":"", cdebug?" -g":""); /* AIS: Possibly link in the debugger yuk and/or libickmt.a here. */ /* AIS: Added -g support. */ @@ -585,15 +716,16 @@ int main(int argc, char *argv[]) break; case 'C': /* initial abstentions */ - /* AIS: Modified to check for coopt */ + /* AIS: Modified to check for coopt, pickcompile */ maxabstain = 0; for (tp = tuples; tp->type; tp++) if (((tp->exechance <= 0 || tp->exechance >= 101) - && tp - tuples + 1 > maxabstain) || coopt) + && tp - tuples + 1 > maxabstain) + || coopt || pickcompile) maxabstain = tp - tuples + 1; if (maxabstain) { - (void) fprintf(ofp, " = {"); + if(!pickcompile) (void) fprintf(ofp, " = {"); for (tp = tuples; tp < tuples + maxabstain; tp++) { if(tp->exechance != 100 && tp->exechance != -100) @@ -605,9 +737,11 @@ int main(int argc, char *argv[]) automagically inclulded. */ if(needsyslib) needsyslib = 0; else coopt = 0; } - if (tp->exechance > 0) + if(!pickcompile) + { + if (tp->exechance > 0) (void) fprintf(ofp, "0, "); - else { + else { (void) fprintf(ofp, "1, "); tp->exechance = -tp->exechance; /* AIS: If the line was abstained, we need to @@ -617,16 +751,25 @@ int main(int argc, char *argv[]) tp->onceagainflag = onceagain_AGAIN; else if(tp->onceagainflag == onceagain_AGAIN) tp->onceagainflag = onceagain_ONCE; + } + if(tp->exechance >= 101) + { + /* AIS: This line has a MAYBE */ + tp->maybe = 1; + tp->exechance /= 100; + } + else tp->maybe = 0; } - if(tp->exechance >= 101) + else /* AIS: hardcoded abstain bits for PICs */ { - /* AIS: This line has a MAYBE */ - tp->maybe = 1; - tp->exechance /= 100; + if(!tp->abstainable) continue; + if(tp->exechance > 0) + (void) fprintf(ofp, "ICK_INT1 ICKABSTAINED(%d)=0;\n",tp-tuples); + else + (void) fprintf(ofp, "ICK_INT1 ICKABSTAINED(%d)=1;\n",tp-tuples); } - else tp->maybe = 0; } - (void) fprintf(ofp, "}"); + if(!pickcompile) (void) fprintf(ofp, "}"); } break; @@ -635,14 +778,15 @@ int main(int argc, char *argv[]) for (tp = tuples; tp->type; tp++) if (tp->type == ENABLE || tp->type == DISABLE || tp->type == MANYFROM) maxabstain++; - if (maxabstain) + if (maxabstain || /* AIS */ gerucomesused) { - (void) fprintf(ofp, "#define UNKNOWN\t\t0\n"); + /* AIS: Changed to use enablersm1 */ + /*(void) fprintf(ofp, "#define UNKNOWN\t\t0\n");*/ i = 0; - for (; i < (int)(sizeof(enablers)/sizeof(char *)); i++) + for (;i < (int)(sizeof(enablersm1)/sizeof(char *));i++) (void) fprintf(ofp, "#define %s\t%d\n", - enablers[i], i+1); + enablersm1[i], i); (void) fprintf(ofp, "int linetype[] = {\n"); for (tp = tuples; tp->type; tp++) @@ -657,6 +801,8 @@ int main(int argc, char *argv[]) break; case 'E': /* extern to intern map */ + if(!pickcompile) + { (void) fprintf(ofp,"int Base = %d;\n",Base); (void) fprintf(ofp,"int Small_digits = %d;\n", Small_digits); @@ -673,7 +819,14 @@ int main(int argc, char *argv[]) if(!ntails) ntails = 1; if(!nhybrids) nhybrids = 1; } - /* AIS: I de-staticed all these so they could be accessed by + else if(opoverused) + { + /* AIS: The operand-overloading code requires onespot and + twospot variables to exist. */ + if(!nonespots) nonespots = 1; + if(!ntwospots) ntwospots = 1; + } + /* AIS:I de-staticed all these so they could be accessed by yuk and cesspool, and added all the mentions of yuk and multithread. Then I changed it so the variables would be allocated dynamically, to speed up multithreading. (It's @@ -684,6 +837,18 @@ int main(int argc, char *argv[]) matter, and I won't get the entire INTERCAL community angry with me for daring to implement an extension that slows down existing programs.) */ + if (variableconstants) /* AIS */ + { + int temp=0; + (void) fprintf(ofp, "type32 meshes[%d] = {",nmeshes); + while(temptype!=MESH) /* AIS: Added this check */ (void) fprintf(ofp, " /* %s %d -> %d */\n", nameof(op->type, vartypes), op->extindex, @@ -764,13 +954,83 @@ int main(int argc, char *argv[]) { /* AIS: drop intern to extern map into the program */ (void) fprintf(ofp, "\nyukvar yukvars[]={\n"); for (op = oblist; op < obdex; op++) - (void) fprintf(ofp," {%s,%d,%d},\n", - nameof(op->type, vartypes), - op->extindex, - op->intindex); + if(op->type!=MESH) /* AIS: Added this check */ + (void) fprintf(ofp," {%s,%d,%d},\n", + nameof(op->type, vartypes), + op->extindex, + op->intindex); (void) fprintf(ofp," {YUKEND,0,0}};\n"); } - break; + } + else + { + /* Compiling for PIC */ + /* Arrays not supported on PICs */ + if(ntails || nhybrids) + lose(E256, yylineno, (char*) NULL); + /* and neither are variable constants */ + if(variableconstants) + lose(E256, yylineno, (char*) NULL); + for (op = oblist; op < obdex; op++) + { + (void) fprintf(ofp, " /* %s %d -> %d */\n", + nameof(op->type, vartypes), + op->extindex, + op->intindex); + (void) fprintf(ofp, "#define %s%d %s[%d]\n", + nameof(op->type, vartypes), + op->extindex, + nameof(op->type, varstores), + op->intindex); + if(op->ignorable) + (void) fprintf(ofp, "ICK_INT1 ignore%s%d = 0;\n", + nameof(op->type, varstores), + op->intindex); + } + (void) fprintf(ofp, "#include \"pick1.h\"\n"); + if(nonespots) + { + (void) fprintf(ofp, + "ICK_INT16 onespots[%d];\n" + "ICK_INT16 onespotsstash[%d];\n", + nonespots, + nonespots); + if(opoverused) /* AIS */ + { + int temp=nonespots; + (void) fprintf(ofp, + "overop oo_onespots[%d];\n", + nonespots); + while(temp--) + (void) fprintf(ofp, +"type32 og1spot%d(type32 t)\n{\n (void)t;\n return onespots[%d];\n}\n" +"void os1spot%d(type32 val,void(*f)())\n{\n (void)f;\n if(!ignoreonespots%d)" +" onespots[%d]=val;\n}\n",temp,temp,temp,temp,temp); + } + } + if(ntwospots) + { + (void) fprintf(ofp, + "ICK_INT32 twospots[%d];\n" + "ICK_INT32 twospotsstash[%d];\n", + ntwospots, + ntwospots); + if(opoverused) /* AIS */ + { + int temp=ntwospots; + (void) fprintf(ofp, + "overop oo_twospots[%d];\n", + ntwospots); + while(temp--) + (void) fprintf(ofp, +"type32 og2spot%d(type32 t)\n{\n (void)t;\n return twospots[%d];\n}\n" +"void os2spot%d(type32 val,void(*f)())\n{\n (void)f;\n if(!ignoretwospots%d)" +" twospots[%d]=val;\n}\n",temp,temp,temp,temp,temp); + } + } + (void) fprintf(ofp, "#include \"pick2.h\"\n"); + } + break; case 'F': /* set clockface option? */ if (clockface) @@ -800,6 +1060,9 @@ int main(int argc, char *argv[]) (void) fprintf(ofp, "CCF%d: longjmp(cjb,1);\n", compucomecount); } +#if 0 + /* AIS: This section is no longer used, because a switch + is used inline instead of using gotos into the code. */ nextcount = 0; for (tp = tuples; tp->type; tp++) if (tp->type == NEXT) @@ -815,6 +1078,7 @@ int main(int argc, char *argv[]) (int)(tp-tuples+1), (int)(tp-tuples+1)); (void) fprintf(ofp, " }"); } +#endif break; case 'J': /* # of source file lines */ @@ -858,18 +1122,27 @@ int main(int argc, char *argv[]) case 'L': /* AIS: increase Emacs compatibility */ (void) fprintf(ofp, - "/* -*- mode:c; compile-command:\"%s\" -*- */" - ,buf2); + "/* -*- mode:c; compile-command:\"%s%s%s\" -*- */", +#ifdef __DJGPP__ + compiler," ", +#else + "","", +#endif + buf2); break; - case 'M': /* AIS: place a multithreading define in program */ + case 'M': /* AIS: place new features defines in program */ /* This is needed even in a non-multithread program, to let the header files know it's non-multithread */ - (void) fprintf(ofp, "#define MULTITHREAD %d", multithread); + (void) fprintf(ofp, "#define MULTITHREAD %d\n", multithread); + /* Likewise, to let the header files know whether it + overloads operands (I don't think this is used at + the moment, though) */ + (void) fprintf(ofp, "#define OPOVERUSED %d\n",opoverused); break; case 'N': /* allocate variables */ - /* AIS: I de-staticed all these so they could be accessed by + /* AIS:I de-staticed all these so they could be accessed by yuk and cesspool, and added all the mentions of yuk and multithread. Then I changed it so the variables would be allocated dynamically, to speed up multithreading (it's @@ -882,6 +1155,8 @@ int main(int argc, char *argv[]) 'deallocated' flag. */ if (nonespots) { + if(!pickcompile) /* AIS */ + { (void) fprintf(ofp, " onespots = calloc(" "%d, sizeof *onespots);\n", @@ -890,9 +1165,20 @@ int main(int argc, char *argv[]) " oneforget = calloc(" "%d, sizeof *oneforget);\n", nonespots); + } + if(opoverused) + { + int temp=nonespots; + while(temp--) + (void) fprintf(ofp, +" oo_onespots[%d].get=og1spot%d;\n oo_onespots[%d].set=os1spot%d;\n", + temp,temp,temp,temp); + } } if (ntwospots) { + if(!pickcompile) + { (void) fprintf(ofp, " twospots = calloc(" "%d, sizeof *twospots);\n", @@ -901,8 +1187,17 @@ int main(int argc, char *argv[]) " twoforget = calloc(" "%d, sizeof *twoforget);\n", ntwospots); + } + if(opoverused) + { + int temp=ntwospots; + while(temp--) + (void) fprintf(ofp, +" oo_twospots[%d].get=og2spot%d;\n oo_twospots[%d].set=os2spot%d;\n", + temp,temp,temp,temp); + } } - if (ntails) + if (ntails&&!pickcompile) { (void) fprintf(ofp, " tails = calloc(" @@ -913,7 +1208,7 @@ int main(int argc, char *argv[]) "%d, sizeof *tailforget);\n", ntails); } - if (nhybrids) + if (nhybrids&&!pickcompile) { (void) fprintf(ofp, " hybrids = calloc(" @@ -924,11 +1219,27 @@ int main(int argc, char *argv[]) "%d, sizeof *hyforget);\n", nhybrids); } - break; + break; + case 'O': /* AIS; for GERUCOME and operand overloading */ + if(gerucomesused || nextfromsused) + fprintf(ofp,"unsigned truelineno = 0;\n"); + if(opoverused) + fprintf(ofp,"%s trueval;\n", + pickcompile?"ICK_INT32":"type32"); + break; + case 'P': /* AIS: for operand overloading */ + if(opoverused) + emitslatproto(ofp); + break; + case 'Q': /* AIS: for operand overloading */ + if(opoverused) + emitslat(ofp); + break; } - (void) fclose(ofp); + if(!outtostdout) (void) fclose(ofp); +#ifndef __DJGPP__ /* OK, now sic the C compiler on the results */ if (!compile_only&&!yukdebug&&!yukprofile) { @@ -962,7 +1273,7 @@ int main(int argc, char *argv[]) takes any input or is affected in any way by the state of the system, as the degenerated program may be wrong. At the moment, the only INTERCAL command that takes input is - WRITE IN. */ + WRITE IN. Double-oh-sevens screw this up, too. */ if(cooptsh) { sprintf(buf2,"sh %s %s", cooptsh, argv[optind]); @@ -970,11 +1281,42 @@ int main(int argc, char *argv[]) neccesary */ } } +#else /* we are using DJGPP */ + /* OK, now sic the C compiler on the results */ + if (!compile_only) + { + /* AIS: buf2 now assigned elsewhere so $L works */ + /* AIS: This changes somewhat for DJGPP, due to the + command-line cap. It creates a temporary file + with the arguments needed to give gcc. */ + FILE* rsp; + rsp=debfopen("ickgcc.rsp","w"); + fprintf(rsp,"%s\n",buf2); + fclose(rsp); + if(yukdebug || yukprofile) + { + /* Running the program from the batch file ickyuk.bat will + handle the input redirection and deletion of the files + afterwards. */ + rsp=debfopen("ickyuk.bat","w"); + fprintf(rsp,"%s.exe\ndel %s\ndel %s.exe\n", + argv[optind],buf,argv[optind]); + fclose(rsp); + } + else if(!cdebug) + { + /* delete from the batch file after compilation */ + rsp=debfopen("ickyuk.bat","w"); + fprintf(rsp,"del %s\n",buf); + fclose(rsp); + } + } +#endif } } (void) fclose(ifp); return 0; } -/* perpetrate.c ends here */ +/* perpet.c ends here */ diff --git a/src/pick1.h b/src/pick1.h new file mode 100644 index 0000000..31ded99 --- /dev/null +++ b/src/pick1.h @@ -0,0 +1,84 @@ +/* + * pick1.h - Compiler-dependent defines for PIC compilers + * + * This file allows porting of PIC-INTERCAL output files to different + * compilers. Most compilers will require this file to be modified; + * as written at the moment, it's ANSI C that invokes undefined + * behaviour (in a way that might plausibly produce correct + * results). + * +LICENSE TERMS + Copyright (C) 2006 Alex Smith + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* Place any headers, config fuse selection statements, and device + statements your compiler needs here. */ +#include + +/* Define these constants to unsigned data types of the correct + bit width. (If your compiler doesn't use 1 bit variables, you + could substitute an 8 bit variable, but that would take up + extra RAM, which may or may not drive the program over the PIC's + RAM limit.) */ +#define ICK_INT32 uint32_t +#define ICK_INT16 uint16_t +#define ICK_INT8 uint8_t +#define ICK_INT1 uint1_t + +/* Define this to an error-handling procedure. You should ignore the + arguments, as they won't make too much sense in this context. + This should block the program; the SLEEP command is one possibility, + somehow getting the PIC to disconnect its own power supply and signal + an error is another. */ +#define lose(a,b,c) for(;;) + +/* PORTA, PORTB, TRISA, and TRISB must be variables which, when read or + modified, read or modify the corresponding location in the PIC's RAM; + these are often at locations 0x05, 0x06, 0x85, and 0x86 respectively. + Place the code to do this here, if it isn't added by the header files + above. See the section below if your compiler doesn't recognize the + volatile keyword, but this code is otherwise correct. */ +#define PORTA *(volatile ICK_INT8*)0x05 +#define PORTB *(volatile ICK_INT8*)0x06 +#define TRISA *(volatile ICK_INT8*)0x85 +#define TRISB *(volatile ICK_INT8*)0x86 + +/* Volatility is important; some compilers don't notice this. */ +#define seq(a) a +/* You may need to use the commented-out code instead if your compiler + is confused about volatile. + ICK_INT8 seq(ICK_INT8 n) + { + return n; + } +*/ + +void pickinit() +{ + /* Place any initialization code that is needed here. */ +} + +/* If your implementation doesn't use function pointers, delete this and + don't write any code that uses operator-overloading. */ +typedef struct overop_t +{ + ICK_INT32 (*get)(ICK_INT32); + void (*set)(ICK_INT32); +} overop; + +#define type16 ICK_INT16 +#define type32 ICK_INT32 diff --git a/src/pick2.h b/src/pick2.h new file mode 100644 index 0000000..a8c0066 --- /dev/null +++ b/src/pick2.h @@ -0,0 +1,235 @@ +/* + * pick2.h - Runtime library for INTERCAL, for use by PIC C compilers + * + * Some of the code here was originally in fiddle.c, some was originally + * in cesspool.c. The rest is a translation into C of syslib.i. + * +LICENSE TERMS + Copyright (C) 1996 Eric S. Raymond + Copyright (C) 2006 Alex Smith + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define resume popnext + +ICK_INT32 mingle(ICK_INT16 r, ICK_INT16 s) +{ + r = ((r & 0x0000ff00) << 8) | (r & 0x000000ff); + r = ((r & 0x00f000f0) << 4) | (r & 0x000f000f); + r = ((r & 0x0c0c0c0c) << 2) | (r & 0x03030303); + r = ((r & 0x22222222) << 1) | (r & 0x11111111); + s = ((s & 0x0000ff00) << 8) | (s & 0x000000ff); + s = ((s & 0x00f000f0) << 4) | (s & 0x000f000f); + s = ((s & 0x0c0c0c0c) << 2) | (s & 0x03030303); + s = ((s & 0x22222222) << 1) | (s & 0x11111111); + return (r << 1) | s; +} + +ICK_INT32 iselect(ICK_INT32 r, ICK_INT32 s) +{ + ICK_INT32 i = 1, t = 0; + while (s) { + if (s & i) { + t |= r & i; + s ^= i; + i <<= 1; + } + else { + s >>= 1; + r >>= 1; + } + } + return t; +} + +ICK_INT16 and16(ICK_INT16 n) +{ + ICK_INT16 m; + m = (n >> 1); + if (n & 1) + m |= 0x8000; + return(m & n); +} + +ICK_INT16 or16(ICK_INT16 n) +{ + ICK_INT16 m; + m = (n >> 1); + if (n & 1) + m |= 0x8000; + return(m | n); +} + +ICK_INT32 and32(ICK_INT32 n) +{ + ICK_INT32 m; + m = (n >> 1); + if (n & 1) + m |= 0x80000000; + return(m & n); +} + +ICK_INT32 or32(ICK_INT32 n) +{ + ICK_INT32 m; + m = (n >> 1); + if (n & 1) + m |= 0x80000000; + return(m | n); +} + +ICK_INT16 xor16(ICK_INT16 n) +{ + ICK_INT16 m; + m = (n >> 1); + if (n & 1) + m |= 0x8000; + return(m ^ n); +} + +ICK_INT32 xor32(ICK_INT32 n) +{ + ICK_INT32 m; + m = (n >> 1); + if (n & 1) + m |= 0x80000000; + return(m ^ n); +} + +ICK_INT8 nextindex = 0; +ICK_INT16 next[16]; + +void pushnext(ICK_INT16 n) +{ + next[nextindex++] = n; +} + +ICK_INT16 popnext(ICK_INT8 n) +{ + if (nextindex < n) { + nextindex = 0; + return (ICK_INT16)-1; + } + else + nextindex -= n; + return(next[nextindex]); +} + +/* It's hard to do randomization on a PIC. */ +ICK_INT1 roll(ICK_INT8 n) +{ + return n>50; +} + +/* Volatility is important; some compilers don't notice this. */ +#define seq(a) a +/* You may need to use the commented-out code instead if your compiler + is confused about volatile. + ICK_INT8 seq(ICK_INT8 n) + { + return n; + } +*/ + +/* Syslib, implemented in C to save ROM space. */ +#if defined(ONESPOT1)&&defined(ONESPOT2)&&defined(TWOSPOT1) +void syslibopt1050() +{ + ONESPOT2=0; + if(ONESPOT1) ONESPOT2=TWOSPOT1/ONESPOT1; +} +void syslibopt1520() +{ + TWOSPOT1=((ICK_INT32)ONESPOT1<<16)|ONESPOT2; +} +#endif /* .1 .2 :1 */ +#if defined(TWOSPOT1)&&defined(TWOSPOT2)&&defined(TWOSPOT3) +void syslibopt1550() +{ + TWOSPOT3=0; + if(TWOSPOT2) TWOSPOT3=TWOSPOT1/TWOSPOT2; +} +void syslipopt1500() +{ + TWOSPOT3=TWOSPOT2+TWOSPOT1; +} +void syslibopt1510() +{ + TWOSPOT3=TWOSPOT1-TWOSPOT2; +} +void syslibopt1530() +{ + TWOSPOT3=TWOSPOT1*TWOSPOT2; +} +void syslibopt1540() +{ + TWOSPOT3=0; + if(TWOSPOT2) TWOSPOT3=TWOSPOT1/TWOSPOT2; +} +#ifdef TWOSPOT4 +void syslibopt1509() +{ + TWOSPOT3=TWOSPOT2+TWOSPOT1; + TWOSPOT4=1; + if(TWOSPOT30xffffffff/TWOSPOT2) TWOSPOT4=2; + TWOSPOT3=TWOSPOT1*TWOSPOT2; +} +#endif /* :4 */ +#endif /* :1 :2 :3 */ +#if defined(ONESPOT1)&&defined(ONESPOT2)&&defined(ONESPOT3) +void syslipopt1000() +{ + ONESPOT3=ONESPOT2+ONESPOT1; +} +void syslibopt1010() +{ + ONESPOT3=ONESPOT1-ONESPOT2; +} +void syslibopt1030() +{ + ONESPOT3=ONESPOT1*ONESPOT2; +} +void syslibopt1040() +{ + ONESPOT3=0; + if(ONESPOT2) ONESPOT3=ONESPOT1/ONESPOT2; +} +#ifdef ONESPOT4 +void syslibopt1009() +{ + ONESPOT3=ONESPOT2+ONESPOT1; + ONESPOT4=1; + if(ONESPOT30xffff/ONESPOT2) ONESPOT4=2; + ONESPOT3=ONESPOT1*ONESPOT2; +} +#endif /* .4 */ +#endif /* .1 .2 .3 */ +#ifdef ONESPOT1 +void syslibopt1020() +{ + ONESPOT1++; +} +#endif diff --git a/src/pickwrap.c b/src/pickwrap.c new file mode 100644 index 0000000..9351a45 --- /dev/null +++ b/src/pickwrap.c @@ -0,0 +1,46 @@ +$L +/* $A.c -- generated PIC C-code file for INTERCAL program $A.i */ + +/* This code is explicitly *not* GPLed. Use, abuse, and redistribute freely */ + +$M +$E + +$K + +#define ICKABSTAINED(d) abstain##d +#define ICKSTASH(a,b,c,d) c##stash[b]=c[b] +#define ICKRETRIEVE(a,b,c,d,e) a[b]=a##stash[b] +#define ICKIGNORE(a,b,c) ignore##c##b + +ICK_INT16 skipto=0; +$O + +$C + +$D +$P +int main(void) +{ + pickinit(); + /* degenerated code */ + ick_restart: + top: + switch(skipto) + { + case 0: + $G + } + +#ifdef YUK + if(yukloop) goto ick_restart; +#endif + lose(E633, $J, (char *)0); + + $H + + return 0; +} +$Q + +/* Generated code for $A.i ends here */ diff --git a/sizes.h b/src/sizes.h similarity index 100% rename from sizes.h rename to src/sizes.h diff --git a/unravel.c b/src/unravel.c similarity index 100% rename from unravel.c rename to src/unravel.c diff --git a/yuk.c b/src/yuk.c similarity index 98% rename from yuk.c rename to src/yuk.c index da79931..1fdc303 100644 --- a/yuk.c +++ b/src/yuk.c @@ -30,6 +30,7 @@ LICENSE TERMS #include #include #include +#include #define YUKDEBUG 1 @@ -42,6 +43,13 @@ LICENSE TERMS #include #endif +/* To help out shells that only understand backslashes in filenames. */ +#ifdef YUKCOPYLOCUS +#define STRINGIZE2(s) s +#define STRINGIZE(s) STRINGIZE2(s) +#define YUKCOPYLOC STRINGIZE(YUKCOPYLOCUS) +#endif + extern signed char onewatch[]; extern signed char twowatch[]; extern type16 oneold[]; @@ -105,7 +113,7 @@ yptimer yuktimes() void yukterm(void) { - int i,lastline,thisline,inrow; + int i,lastline,thisline,inrow=0; yptimer avgtime,avgtime2; if(yukopts==2) puts("Program ended without error."); if(!(yukopts&1)) return; @@ -748,7 +756,7 @@ void yukline(int aboff,int emitlineno) } break; case '*': - system("more < " YUKCOPYLOC); /* display the GNU GPL copying conditions */ + system("more < " YUKCOPYLOC); /* display the GNU GPL copyright */ break; default: puts("Not sure what you mean. Try typing ?."); diff --git a/yuk.h b/src/yuk.h similarity index 100% rename from yuk.h rename to src/yuk.h -- 2.43.0