Release 0.29 (by Alex Smith)
-Bugs found by the people on irc.freenode.org/esoteric (thanks for testing!)
+Bugs reported by Arvid Norlander
-1. Fixed the configure script to work with the default Debian shell dash.
- (reported by <ehird>)
+1. Fixed a typo in the perpet.c version of the help information.
-2. Fixed a typo in the perpet.c version of the help information.
- (reported by <AnMaster>)
+2. Fixed the CREATE statement to work on 64-bit architectures.
-3. Fixed the CREATE statement to work on 64-bit architectures.
- (reported by <AnMaster>)
-
-4. Actually fixed unlambda.i; the fix was meant to be in 0.28, and is
- described in its changelog, but for some reason never made it to
- the distributed tarball. (reported by <ehird>)
-
-5. The -F option again works. (I accidentally broke it in the preceding
- version, making it basically a no-op by mistake.) (reported by <ehird>)
-
-6. The availability of variable argument list mechanisms is now determined
+3. The availability of variable argument list mechanisms is now determined
automatically by the configure script, rather than relying on the old
method of checking which usually gets the wrong answer with modern
compilers, leading to build failures on many modern systems (previously
this was patched just for DJGPP, the patch now applies to all operating
systems and platforms). This bug is known to have affected the build on
- DOS, FreeBSD and Mac OS X, and possibly affects other platforms. (reported
- independently by both <ehird> and <AnMaster>)
+ DOS, FreeBSD and Mac OS X, and possibly affects other platforms. (also
+ reported independently by Elliott Hird)
+
+4. Fixed some nonsense in the -@ help screen that was generated by an errant
+ search-and-replace.
+
+Bugs reported by Elliott Hird
-7. The build now succeeds (with warnings) when lex or yacc are missing,
+5. Fixed the configure script to work with the default Debian shell dash.
+ (also reported independently by Debian)
+
+6. Actually fixed unlambda.i; the fix was meant to be in 0.28, and is
+ described in its changelog, but for some reason never made it to
+ the distributed tarball.
+
+7. The -F option again works. (AIS: I accidentally broke it in the preceding
+ version, making it basically a no-op by mistake.)
+
+8. The build now succeeds (with warnings) when lex or yacc are missing,
rather than failing with mysterious error messages that seem to have
nothing to do with the problems. (The success is made possible by using
the prebuilt versions; see change 11 of version 0.26, this is finishing
- what that started.) (reported by <ehird>)
+ what that started.)
Changes by Joris Huizer
-8. The [xoritself] optimiser idiom has been generalised to handle some
+9. The [xoritself] optimiser idiom has been generalised to handle some
situations where the redundant XOR operands are on different grouping
levels; this helps to optimise some heavily inlined greater-than tests.
-9. Fixed unary operators applied to constants (AIS: it seems that my patch to
+10. Fixed unary operators applied to constants (AIS: it seems that my patch to
solve this issue earlier was itself buggy).
-10. The -g option now causes optimisation of the output compiled C to be
+11. The -g option now causes optimisation of the output compiled C to be
turned off, and adds comments to the output file the same way -c does.
-11. Added more optimiser idioms: [cxorand16], [cxorand32], [cfoldintoorinand],
+12. Added more optimiser idioms: [cxorand16], [cxorand32], [cfoldintoorinand],
[or16and], [xor16and], [lshift32half], [rshiftoutofneg], [andoutofneg];
also generalised the idiom-matching code to compare 16-bit and 32-bit
constants as equal if they have the same value, and fixed some typos in
the current 16-bit complement idioms.
+13. ABSTAINING or REINSTATING are now a lot more efficient, taking an amount
+ of time proportional to the number of commands effected, rather than the
+ number of commands in the program. (AIS: I implemented this with the
+ algorithm in the patch Joris provided, but with different code, to make it
+ easier to maintain.)
+
Bugs reported by the Debian autobuilders and Joey Hess
-12. The build of the optimiser idioms is now split over many files, to reduce
+14. The build of the optimiser idioms is now split over many files, to reduce
the memory usage of gcc when it tries to compile the giant output C file.
This was a problem on ia64. (The ulimit method of preventing thrashing has
been removed, as this method works better; likewise, the optimiser
Changes by Alex Smith
-13. The build system has been completely redone, again; it now uses automake
+15. The build system has been completely redone, again; it now uses automake
as well as a much newer version of autoconf. This means that there is now
one build system that works the same way on all systems, and that all
sorts of clever tricks like out-of-tree builds, a self-rebuilding build
still there, but now there's prebuilt instead of temp, an extra directory
buildaux, and bin, lib and include have disappeared.
-14. The distribution now comes in compressed pax format. (Before anyone
+16. The distribution now comes in compressed pax format. (Before anyone
complains that they have no idea what that is, or that I'm using something
strange and nonstandard, I'd like to point out that tar is no longer part
of POSIX, but that pax is. (See man 5 tar on a recent Linux system for
so tar readers should be able to read it just fine, if you can't get your
hands on a pax reader.)
-15. convickt can now produce its output as INTERCAL initialisation of a tail
+17. convickt can now produce its output as INTERCAL initialisation of a tail
array. (This doesn't auto-offset between the different characters; it is
therefore mostly useful for producing Baudot arrays for CLC-INTERCAL-style
IO.)
-16. The function clock_gettime is now supported by the yuk profiler as an
+18. The function clock_gettime is now supported by the yuk profiler as an
alternative method of getting a high-resolution clock for profiling (it
is available on at least Linux).
-17. Added support for computed CREATE (the computation is done at create-time,
+19. Added support for computed CREATE (the computation is done at create-time,
rather than when the unknown statement is encountered); partly because
this was rather easy, but mostly because it can be used to simulate a
computed NEXT, thus making the example expansion library compunex (which I
features of NEXT, anyway, rather than the small subset COMPUNEX could
manage.)
-18. Plugged a couple of small memory leaks; however, there are still several
+20. Plugged a couple of small memory leaks; however, there are still several
much bigger memory leaks that could do with being fixed.
-19. Added support for CREATING operators, with similar syntax to the CREATION
+21. Added support for CREATING operators, with similar syntax to the CREATION
of commands. This requires the -ea options to be set to work properly.
-20. More file extensions are now supported by the external calls system. The
+22. More file extensions are now supported by the external calls system. The
.c99 extension indicates a C99 (rather than C89) file; all .c99 files are
preprocessed as C99, and if any C99 files are used the final compilation
which compiles and links everything will be done as C99 rather than C89
locations instead of the current directory.) Other .a files can be linked
in from the current directory.
-21. Fixed the handling of division by zero in the syslibc expansion library.
+23. Fixed the handling of division by zero in the syslibc expansion library.
(The Revamped Manual states 'In all cases, division by 0 returns 0'.)
-22. Made several changes to the documentation, including fixes for some rather
+24. Made several changes to the documentation, including fixes for some rather
nasty typos (two of the worst were specifying variables as IGNORED by
default, and stating that select acts like OR in TriIntercal!).
-23. Fixed a bug in the external calls system that made it impossible to write
+25. Fixed a bug in the external calls system that made it impossible to write
a COME FROM in more than one file at a time whilst still having the
resulting program work reliably.
-24. Added support for external calls to Befunge-98 programs; however, this
+26. Added support for external calls to Befunge-98 programs; however, this
distribution does not ship with a Funge-98 interpreter, so in order to use
this feature you will first have to compile a Funge-98 interpreter into a
library for use with C-INTERCAL (see README.txt or the Revamped Manual for
information on this). Also added a test program for this to the pit.
-25. Fixed some bugs in the go-away command in interfunge.i.
+27. Fixed some bugs in the go-away command in interfunge.i.
Release 0.28 (by Alex Smith) 1 Apr 2008
break;
case ENABLE:
- if(pickcompile) ick_lose(IE256, emitlineno, (char*) NULL); /* AIS */
- (void) fprintf(fp,
- "\t""int 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 == GETS) {
- (void) fprintf(fp,
- "\t"" if (linetype[i] == %s || linetype[i] == %s)\n", enablers[GETS-GETS], enablers[RESIZE-GETS]);
- } 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(ick_abstained[i]) ick_abstained[i]--;\n");
- }
- break;
-
case DISABLE:
- if(pickcompile) ick_lose(IE256, emitlineno, (char*) NULL); /* AIS */
- (void) fprintf(fp,
- "\t""int i;\n");
- for (np = tn->u.node; np; np = np->rval)
+ case MANYFROM:
+ /* AIS: This code has been rewritten to make use of the revlinetype array
+ (an optimisation that Joris Huizer came up with; however, I am not
+ using his code, but rewriting it, to make use of a single array and an
+ index to it, rather than one array for each command type, for
+ maintainability reasons. */
+ if(pickcompile) ick_lose(IE256, emitlineno, (char*) NULL);
+ (void) fprintf(fp,"\tint i;\n");
+ np=tn->u.node;
+ if(tn->type==MANYFROM)
+ {
+ np=np->rval;
+ fprintf(fp,"\tint j = ");
+ prexpr(tn->u.node->lval, fp, 1);
+ fprintf(fp,";\n");
+ }
+ for(; np; np = np->rval)
+ {
+ int npc = np->constant;
+ anothertype:
+ (void) fprintf(fp,"\n\tfor(i=revlineindex[%s];i<revlineindex[%s+1];i++)\n",
+ enablers[npc-GETS],enablers[npc-GETS]);
+ switch(tn->type)
{
- (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 == GETS) {
- (void) fprintf(fp,
- "\t"" if (linetype[i] == %s || linetype[i] == %s)\n", enablers[GETS-GETS], enablers[RESIZE-GETS]);
- } 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(!ick_abstained[i]) ick_abstained[i] = 1;\n");
+ case ENABLE: (void) fprintf(fp,"\t if (ick_abstained[revlinetype[i]])"
+ "\t\tick_abstained[revlinetype[i]]--;\n"); break;
+ case DISABLE: (void) fprintf(fp,"\t if(!ick_abstained[revlinetype[i]])"
+ "\t\tick_abstained[revlinetype[i]]=1;\n"); break;
+ case MANYFROM:(void) fprintf(fp,"\tick_abstained[revlinetype[i]]+=j;\n"); break;
+ default: ick_lose(IE778, emitlineno, (char *)NULL);
}
- break;
-
- case MANYFROM:
- if(pickcompile) ick_lose(IE256, emitlineno, (char*) NULL); /* AIS */
- (void) fprintf(fp,
- "\t""int 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)
+ switch(npc)
{
- (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 == GETS) {
- (void) fprintf(fp,
- "\t"" if (linetype[i] == %s || linetype[i] == %s)\n", enablers[GETS-GETS], enablers[RESIZE-GETS]);
- } 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""\tick_abstained[i] += j;\n");
+ case ABSTAIN: npc=DISABLE; goto anothertype;
+ case DISABLE: npc=FROM; goto anothertype;
+ case FROM: npc=MANYFROM; goto anothertype;
+ case REINSTATE: npc=ENABLE; goto anothertype;
+ case COME_FROM: npc=COMPUCOME; goto anothertype;
+ case COMPUCOME: npc=GERUCOME; goto anothertype;
+ case NEXTFROMLABEL: npc=NEXTFROMEXPR; goto anothertype;
+ case NEXTFROMEXPR: npc=NEXTFROMGERUND; goto anothertype;
+ default: break;
}
- break;
+ }
+ break;
case NEXTFROMEXPR:
case NEXTFROMGERUND:
fprintf(stderr,"\t\t separate output files; with it, the first file given\n");
fprintf(stderr,"\t\t must be the only INTERCAL file) (prevents -mypPf)\n");
fprintf(stderr,"\t-E\t:never include the system library (prevents -P)\n");
- fprintf(stderr,"\t-t\t:ick_traditional mode, accept only INTERCAL-72\n");
- fprintf(stderr,"\t-C\t:ick_clockface output (e.g. use IIII instead of IV)\n");
+ fprintf(stderr,"\t-t\t:traditional mode, accept only INTERCAL-72\n");
+ fprintf(stderr,"\t-C\t:clockface output (e.g. use IIII instead of IV)\n");
fprintf(stderr,"\t-O\t:optimize expresssions in generated code\n");
/* AIS: Changed the help message for the previous line (because the
function of -O has changed). I wrote the next group of options. */
}
break;
- case 'D': /* linetypes ick_array for abstention handling */
+ case 'D': /* linetypes array for abstention handling */
maxabstain = 0;
for (tp = tuples; tp->type; tp++)
if (tp->type == ENABLE || tp->type == DISABLE || tp->type == MANYFROM)
maxabstain++;
if (maxabstain || /* AIS */ gerucomesused)
{
+ int j=0; /* AIS */
/* AIS: Changed to use enablersm1 */
- /*(void) fprintf(ofp, "#define UNKNOWN\t\t0\n");*/
i = 0;
for (;i < (int)(sizeof(enablersm1)/sizeof(char *));i++)
(void) fprintf(ofp,
respectively) both become UNKNOWN in the
linetypes array. */
(void) fprintf(ofp, " UNKNOWN,\n");
- (void) fprintf(ofp, "};\n"); } break;
+ (void) fprintf(ofp, "};\n");
+ /* AIS: Implement the reverse of this array too (i.e.
+ from line types to lines); this significantly
+ speeds up up reinstate/abstain on gerunds. Joris
+ Huizer originally suggested the optimisation in
+ question; this implements the same algorithm in a
+ more maintainable way. (I didn't want to have to
+ keep five copies of the command list in sync; two
+ is bad enough!) */
+ (void) fprintf(ofp, "int revlinetype[] = {\n");
+ for(i=0;i < (int)(sizeof(enablersm1)/sizeof(char *));i++)
+ {
+ (void) fprintf(ofp,"/* %s */",enablersm1[i]);
+ for (tp = tuples; tp->type; tp++)
+ {
+ if((tp->ppnewtype && tp->ppnewtype-GETS == i-1) ||
+ (!tp->ppnewtype && tp->preproc &&
+ i-1 == PREPROC-GETS) ||
+ (!tp->ppnewtype && !tp->preproc &&
+ tp->type >= GETS && tp->type <= FROM &&
+ tp->type-GETS == i-1) ||
+ (!i && !tp->ppnewtype && !tp->preproc &&
+ (tp->type < GETS || tp->type > FROM)))
+ (void) fprintf(ofp, " %ld,",(long)(tp-tuples));
+ }
+ (void) fprintf(ofp,"\n");
+ }
+ (void) fprintf(ofp, "};\n");
+ (void) fprintf(ofp, "int revlineindex[] = {\n");
+ for(i=0;i < (int)(sizeof(enablersm1)/sizeof(char *));i++)
+ {
+ (void) fprintf(ofp,"/* %s */",enablersm1[i]);
+ (void) fprintf(ofp," %d,\n",j);
+ for (tp = tuples; tp->type; tp++)
+ {
+ if((tp->ppnewtype && tp->ppnewtype-GETS == i-1) ||
+ (!tp->ppnewtype && tp->preproc &&
+ i-1 == PREPROC-GETS) ||
+ (!tp->ppnewtype && !tp->preproc &&
+ tp->type >= GETS && tp->type <= FROM &&
+ tp->type-GETS == i-1) ||
+ (!i && !tp->ppnewtype && !tp->preproc &&
+ (tp->type < GETS || tp->type > FROM)))
+ j++;
+ }
+ }
+ (void) fprintf(ofp, "/* end */ %d\n};\n",j);
+ }
+ break;
case 'E': /* extern to intern map */
if(!pickcompile)