]> thyrsus.com Git - intercal.git/commitdiff
Pre-0.28 'd' snapshot.
authorAlex Smith <ais523@bham.ac.uk>
Mon, 31 Mar 2008 08:28:04 +0000 (04:28 -0400)
committerEric S. Raymond <esr@thyrsus.com>
Thu, 26 Aug 2010 00:34:49 +0000 (20:34 -0400)
(This is a retrospective comment.)

13 files changed:
Makefile
Makefile.in
NEWS.txt
doc/ick.txi
etc/intercal.el
include/abcess.h
pit/CATALOG
pit/explib/compunex.c [new file with mode: 0644]
pit/explib/syslibc.c [new file with mode: 0644]
pit/explib/syslibc.doc [new file with mode: 0644]
pit/lib/syslibc.c [deleted file]
pit/lib/syslibc.doc [deleted file]
src/feh2.c

index 50da8ca0e5fff0813648222fd625513df6afa9a2..7a4ec620d4881fb5bf63e85c194b51fe801ffc97 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -56,7 +56,7 @@ SOURCES = $(CSOURCES) $(ISOURCES) $(YSOURCES) $(HEADERS) $(BUILD) $(MISC) $(DOCS
 
 all: bin/ick bin/convickt lib/libick.a lib/libickmt.a lib/libyuk.a lib/libickec.a ial
 
-ial: include/ick_ec.h include/fiddle.h include/abcess.h include/ick_lose.h include/yuk.h include/syslib.i include/syslib.3i include/syslib.4i include/syslib.5i include/syslib.6i include/syslib.7i lib/ick-wrap.c lib/pickwrap.c lib/coopt.sh lib/COPYING.txt lib/syslibc.c include/atari.bin include/baudot.bin include/ebcdic.bin include/latin1.bin
+ial: include/ick_ec.h include/fiddle.h include/abcess.h include/ick_lose.h include/yuk.h include/syslib.i include/syslib.3i include/syslib.4i include/syslib.5i include/syslib.6i include/syslib.7i lib/ick-wrap.c lib/pickwrap.c lib/coopt.sh lib/COPYING.txt lib/syslibc.c lib/compunex.c include/atari.bin include/baudot.bin include/ebcdic.bin include/latin1.bin
 
 include/ick_ec.h: src/ick_ec.h
        -cp src/ick_ec.h include/ick_ec.h
@@ -94,8 +94,10 @@ lib/coopt.sh:temp/coopt.sh
 lib/COPYING.txt:COPYING.txt
        -cp COPYING.txt lib/COPYING.txt
 
-lib/syslibc.c:pit/lib/syslibc.c
-       -cp pit/lib/syslibc.c lib/syslibc.c
+lib/syslibc.c:pit/explib/syslibc.c
+       -cp pit/explib/syslibc.c lib/syslibc.c
+lib/compunex.c:pit/explib/compunex.c
+       -cp pit/explib/compunex.c lib/compunex.c
 
 include/atari.bin:src/atari.bin
        -cp src/atari.bin include/atari.bin
index 07300294740d5983702976f4c8d47382be0f69eb..8856d90afc44b76b8270a32bc82d817dcda3249f 100644 (file)
@@ -55,7 +55,7 @@ SOURCES = $(CSOURCES) $(ISOURCES) $(YSOURCES) $(HEADERS) $(BUILD) $(MISC) $(DOCS
 
 all: bin/ick@EXEEXT@ bin/convickt@EXEEXT@ lib/libick.a lib/libickmt.a lib/libyuk.a lib/libickec.a ial
 
-ial: include/ick_ec.h include/fiddle.h include/abcess.h include/ick_lose.h include/yuk.h include/syslib.i include/syslib.3i include/syslib.4i include/syslib.5i include/syslib.6i include/syslib.7i lib/ick-wrap.c lib/pickwrap.c lib/coopt.sh lib/COPYING.txt lib/syslibc.c include/atari.bin include/baudot.bin include/ebcdic.bin include/latin1.bin
+ial: include/ick_ec.h include/fiddle.h include/abcess.h include/ick_lose.h include/yuk.h include/syslib.i include/syslib.3i include/syslib.4i include/syslib.5i include/syslib.6i include/syslib.7i lib/ick-wrap.c lib/pickwrap.c lib/coopt.sh lib/COPYING.txt lib/syslibc.c lib/compunex.c include/atari.bin include/baudot.bin include/ebcdic.bin include/latin1.bin
 
 include/ick_ec.h: src/ick_ec.h
        -cp src/ick_ec.h include/ick_ec.h
@@ -93,8 +93,10 @@ lib/coopt.sh:temp/coopt.sh
 lib/COPYING.txt:COPYING.txt
        -cp COPYING.txt lib/COPYING.txt
 
-lib/syslibc.c:pit/lib/syslibc.c
-       -cp pit/lib/syslibc.c lib/syslibc.c
+lib/syslibc.c:pit/explib/syslibc.c
+       -cp pit/explib/syslibc.c lib/syslibc.c
+lib/compunex.c:pit/explib/compunex.c
+       -cp pit/explib/compunex.c lib/compunex.c
 
 include/atari.bin:src/atari.bin
        -cp src/atari.bin include/atari.bin
index 6b7cac06b557fd33e88be6136ea5b1df412ab99a..06a4908033ffe3690b75692be20d9e2383d36564 100644 (file)
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -140,9 +140,12 @@ Changes by Alex Smith
     also edited unlambda.i in the pit, which was taking advantage of this
     error (and erroring out if optimisation was turned off).
 
+23. Fixed a bug with the ON THE WAY TO line number displayed when COME FROMs
+    are involved that I accidentally introduced in 0.25.
+
 Changes from elsewhere
 
-23. Added yet another nontrivial INTERCAL program to the pit; interfunge.i
+24. Added yet another nontrivial INTERCAL program to the pit; interfunge.i
     (written by Jeffrey Lee) is a Befunge-93 interpreter written in INTERCAL.
     (It appears to conform to the standard (I actually ran it against a
     testsuite, and it passed); its only pecularities, apart from the language
index 0ec1082cbdaa72748c47a1aa07e2249f7f08e0b1..ed07fc18e2e4139504bd6fd233764c222cbcfa79 100644 (file)
@@ -1636,6 +1636,13 @@ legal if you specifically specified that it was legal by using the
 (including a situation in which operand overloading causes a reverse
 assignment to happen), this error happens at runtime.
 
+This error can also come up when a scalar variable is overloaded to an
+array (which doesn't make sense, but could happen if someone exploited
+bugs in the CREATE statement (@pxref{CREATE})), and an attempt is made
+to read or assign to that variable.  (Subscripting a scalar variable
+is a syntax error, so there is no use for doing such an overload
+anyway.)
+
 @ieanchor E281
 @cindex spark, nesting limit
 @cindex ears, nesting limit
@@ -2822,7 +2829,7 @@ time, so has to guess a 32-bit result for a select with a 32-bit type as
 its right operand even when the result might actually turn out to be of
 a 16-bit type, and so this behaviour prevents an error when a select
 operation returns a value with a 16-bit data type and is used as an
-argument to amingle.)  The result is a 32-bit value (that is, it is of a
+argument to a mingle.)  The result is a 32-bit value (that is, it is of a
 32-bit data type, even if its value fits into the onespot range), which
 consists of bits alternated from the two arguments; to be precise, its
 most significant bit is the most significant bit of its first argument,
@@ -4171,7 +4178,7 @@ created by @code{COME FROM}; ordinary threads share only
 share variables and stashes.  (They still have separate instruction
 pointers, separate instruction pointer stacks, such as the NEXT stack,
 and separate choicepoint lists.  Overloading information is shared,
-though.  Being woven is a relationship between two or more threads,
+though.)  Being woven is a relationship between two or more threads,
 rather than an attribute of a thread, although a thread can be
 referred to as being unwoven if it is not woven to any other thread.
 
@@ -4222,7 +4229,7 @@ case you're wondering: dormant threads are always unwoven.)
 To create a choicepoint, the statement identifier @code{MAYBE} is
 used, rather than the more usual @code{DO} or @code{PLEASE}.
 (Combination statement identifiers are still allowed, but must be in
-the order @code{MAYBE DO PLEASE NOT} with optionally some parts
+the order @code{MAYBE PLEASE DO NOT} with optionally some parts
 omitted, or different versions of @code{NOT} used, or both.) Here's an
 example:
 
@@ -4471,7 +4478,7 @@ DO PIN :2
 @end example
 
 The twospot variable is conceptually divided into 4 blocks of 8 bits.
-The highet two blocks control the directions of the pins in
+The highest two blocks control the directions of the pins in
 @code{PORTB} (most significant block) and @code{PORTA} (second most
 significant block); a 1 on any bit means that the corresponding I/O
 pin should be set to send data, and a 0 means that it should be set to
@@ -4557,7 +4564,9 @@ the stashes for the 1600-range variables yourself.)
 So what syntax is available in created statements@?  All the capital
 letters except @samp{V} (which is an operator in @ical{}) are
 available and can be used freely and as many times as desired; they
-match themselves literally.  Whitespace is allowed, but is ignored
+match themselves literally.  However, they are not allowed to spell an
+@ical{} keyword at any point (so watch out for @code{DO} and
+@code{FROM}, for instance).  Whitespace is allowed, but is ignored
 (both in the @code{CREATE} template statement, and in the code being
 created; so @code{DO SW ITCH :8 WITH :50} will also have been
 created).  Then, there are three groups of matchable data: scalar
@@ -4914,7 +4923,7 @@ wrapper function for it).  It can be used within any function regardless
 of how it was declared, and never returns; instead, it pops the specified
 number of @code{NEXT} stack entries and resumes execution at the last one
 popped, just as the @ical{} statement does.  This causes the same errors
-as the @ical{} statement if the amount of entries popped is zero or
+as the @ical{} statement if the number of entries popped is zero or
 larger than the @code{NEXT} stack.
 
 @findex ick_return_or_resume
@@ -5004,10 +5013,16 @@ The signature defines the syntax that you are defining; whenever that
 syntax is encountered within the @ical{} program, it will @code{NEXT}
 to the line number you specify, which can do various clever things and
 then @code{RESUME} back to the @ical{} program (or if you're defining
-a flow-control operation, you might want to @code{FORGET} or even
-leave the @code{NEXT} stack entry there and do other things).  This
-allows the external calls system to define whole new @ical{} commands,
-with the same power as any other programming language.
+a flow-control operation, you might want to leave the @code{NEXT}
+stack entry there and do other things).  However, note that the
+overloading of @code{:1601}, etc.@:, will still take place as in the
+@ical{} version of @code{CREATE} if the @option{-a} option is used
+(@pxref{-a}), so care is needed when writing flow control statements
+that they work both with and without the option and don't cause
+@code{STASH} leaks (which means no @code{FORGET}ting the relevant
+@code{NEXT} stack entry, and no looking at 1600-range variables).
+This allows the external calls system to define whole new @ical{}
+commands, with the same power as any other programming language.
 
 There are various restrictions on what syntax you can @code{CREATE}
 with this method, which are best explained by an explanation of the
@@ -5274,6 +5289,8 @@ completely different way.
 
 @subheading syslibc
 @findex syslibc
+@cindex system library, in C
+@cindex C, system library
 
 @option{syslibc} is an implementation of the base-2 @ical{} system
 library in C (@pxref{System Library}); using it in programs running in
@@ -5290,6 +5307,25 @@ note that the speed gains in arithmetic will be accompanied by the
 performance penalty of using the external calls infrastructure, unless
 you were already using it.
 
+@subheading compunex
+@findex compunex
+@cindex computed NEXT
+@cindex NEXT, computed
+
+As an example of using @code{ick_create}, a very simple expansion
+library is provided to enable a computed NEXT capability, by defining
+a new command @code{COMPUNEX}.  It is used as @code{DO .1 COMPUNEX}
+(allowing any expression in place of the .1), and is similar to an
+ordinary @code{NEXT}, but has two limitations: it takes up two
+@code{NEXT} stack entries, and the top one should not be
+@code{RESUMEd} past or forgotten (thus it isn't a particularly useful
+command, except maybe to produce the equivalent of something like
+function pointers).  By the way, note that @cic{} avoids computed
+@code{NEXT} mainstream for much the same way that @clcic{} avoids
+@code{NEXT} altogether; it makes things too easy.  This example is
+provided mostly just to demonstrate the syntax, and the care that
+needs to be taken with implementing flow control operators.
+
 @node Differences to Other Compilers
 @chapter Differences to Other Compilers
 @cindex INTERCAL compilers
@@ -6372,7 +6408,9 @@ copyright conditions as the original @ical{} source.  (Note that the
 libraries @file{libick.a} and @file{libickmt.a} are GPL, though, so
 you cannot redistribute an executable produced by @command{ick} or by
 linking a C file to either of those libraries unless the original
-@ical{} source was GPL.)  Also, this manual, and the files that are
+@ical{} source was GPL.)  For similar reasons, the expansion library
+@file{syslibc.c} (currently the only one in the distribution) is
+explicitly public domain.  Also, this manual, and the files that are
 the source code for creating it, are licensed under the GNU Free
 Documentation License rather than the GPL, and the licenses themselves
 (@file{fdl-1-2.txi} and @file{COPYING.txt}) are licensed under a
index 82ecf272385ef1bf4e66c14baba2554f3a331af0..4f14969e5c8253c59799653cd288339ee6c81622 100644 (file)
@@ -94,6 +94,7 @@
   (define-abbrev intercal-mode-abbrev-table "wh"  "" 'intercal-wh-abbrev) ;AIS
   (define-abbrev intercal-mode-abbrev-table "goa" "" 'intercal-goa-abbrev) ;AIS
   (define-abbrev intercal-mode-abbrev-table "gob" "" 'intercal-gob-abbrev) ;AIS
+  (define-abbrev intercal-mode-abbrev-table "cr"  "" 'intercal-cr-abbrev) ;AIS
   (define-abbrev intercal-mode-abbrev-table "ma"  "MAYBE" nil) ;AIS
   (define-abbrev intercal-mode-abbrev-table "tr"  "" 'intercal-tr-abbrev) ;AIS
   (define-abbrev intercal-mode-abbrev-table "cal" "" 'intercal-cal-abbrev) ;AIS
 (make-intercal-abbrev intercal-wh-abbrev "WHILING" "WHILE") ;AIS
 (make-intercal-abbrev intercal-goa-abbrev "GOING AHEAD" "GO AHEAD") ;AIS
 (make-intercal-abbrev intercal-gob-abbrev "GOING BACK" "GO BACK") ;AIS
+(make-intercal-abbrev intercal-cr-abbrev "CREATION" "CREATE") ;AIS
 
 (defun intercal-do-abbrev ()
   "Emit a DO (usually).  Occasionally, emit PLEASE DO."
@@ -192,7 +194,7 @@ res  RESUME ret  RETRIEVE   st   STASH
 wr   WRITE IN  pl   PLEASE     tr   TRY AGAIN
 on   ONCE       ag   AGAIN      ma   MAYBE
 goa  GO AHEAD   gob  GO BACK    do   DO, or sometimes PLEASE DO
-cal  CALCULATING (gerund only)  wh   WHILE
+cal  CALCULATE  cr   CREATE     wh   WHILE
 
 Carriage return takes you to the first tab stop (code indent level).
 Certain other single keys are bound to things which may or may not be useful.
index e027d124d382cf24fb5d9033e3448104b855ba7c..ba240912e48b122a51bef25eb19d89863e807581 100644 (file)
@@ -117,6 +117,10 @@ extern void ick_retrieve(void *to, unsigned int type, unsigned int index,
                         ick_bool forget, ick_overop* oo);
 extern unsigned int ick_roll(unsigned int n);
 
+/* AIS: Lose with IE277 */
+extern ick_type32 ick_ieg277(ick_type32);
+extern void ick_ies277(ick_type32, void(*)());
+
 /* defined in arrgghh.c */
 extern void ick_parseargs(int argc, char **argv);
 extern int ick_printflow;
index cdb4a29e6319b77b88500765d47b054baa63e31c..79bbb73fd8726b1be2c2d3569281543b6b50d195 100644 (file)
@@ -130,7 +130,8 @@ by Alex Smith
   tests/ignorret.doc  What ignorret does on several compilers\r
   tests/normaldist.i  Checking the standard deviation of (1910)\r
   tests/testcreate.i  A test for the CREATE statement\r
-  lib/syslibc.c              The INTERCAL base 2 syslib, optimised version in C\r
+  explib/syslibc.c    The INTERCAL base 2 syslib, optimised version in C\r
+  explib/compunex.c   An example flow-control routine (computed NEXT)\r
   sort.i              An insertion-sort program testing computed ABSTAIN\r
 \r
 by Malcom Ryan\r
diff --git a/pit/explib/compunex.c b/pit/explib/compunex.c
new file mode 100644 (file)
index 0000000..a9d0683
--- /dev/null
@@ -0,0 +1,29 @@
+/* Public domain, by Alex Smith.
+   An example of CREATing statements from C, in this case an example COMPUNEX
+   statement that does a computed NEXT. (Note that newly CREATEd statements
+   can't contain consecutive characters that spell an INTERCAL keyword; also,
+   I wanted a name that was 8 chars or shorter to serve as a DOS filename.)
+
+   Note that as a CREATEd command, COMPUNEX uses one NEXT stack entry itself,
+   meaning the COMPUNEX will take up two NEXT stack entries total. Programs
+   that do large RESUMEs will need to take this into account. (Tail call
+   optimisation would require some sort of GOTO, but ick_goto isn't documented
+   and therefore shouldn't be used, right? */
+#include <ick_ec.h>
+
+/* This name starts ick_, but isn't used; in general, the prefix ick_my_ is
+   reserved for expansion libraries (as are the line numbers 1600-1699) because
+   it doesn't conflict either with the compiler or with any linked-in C
+   programs. */
+ICK_EC_FUNC_START(ick_my_compunex)
+{
+  ick_startup( {
+      ick_create(".COMPUNEX",1600);
+      ick_create(";COMPUNEX",1600);
+      ick_create("~COMPUNEX",1600);
+    });
+  ick_linelabel(1600);
+  ick_next(ick_c_value(0));
+  ick_resume(1);
+}
+ICK_EC_FUNC_END
diff --git a/pit/explib/syslibc.c b/pit/explib/syslibc.c
new file mode 100644 (file)
index 0000000..4155fe1
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * The INTERCAL system library, optimised version in C.
+ *
+ * This is provided as an example of how to write a C program
+ * that links to INTERCAL programs, to demonstrate the external
+ * call code.
+ *
+ * Written originally by Alex Smith, and released to the public
+ * domain. This library comes with NO WARRANTY.
+ */
+
+#include <ick_ec.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+/* This identifier name breaches the namespace rule that ick_ must be
+   avoided, but this library has to work with both other people's
+   INTERCAL programs and other people's C programs. So I've chosen an
+   identifier name which breaches the rules (so that it doesn't clash
+   with other people's C programs) but isn't used anywhere in the
+   compiler, and so doesn't clash with it either.
+*/
+
+static void errout(int routine, char* msg)
+{
+  fprintf(stderr,"C-INTERCAL system library: (%d): %s\n", routine, msg);
+  exit(EXIT_FAILURE);
+}
+
+ICK_EC_FUNC_START(ick_my_custom_syslib)
+{
+  register uint16_t os1, os2;
+  register uint32_t ts1, ts2;
+  static int seededyet = 0;
+
+  ick_linelabel(1000);
+  os1=ick_getonespot(1);
+  os2=ick_getonespot(2);
+  if(0xffff-os1<os2) errout(1000, "onespot overflow");
+  ick_setonespot(3,os1+os2);
+  ick_resume(1);
+  return; /* so the compiler knows the next line can't be reached from here */
+
+  ick_linelabel(1009);
+  os1=ick_getonespot(1);
+  os2=ick_getonespot(2);
+  ick_setonespot(4,1);
+  if(0xffff-os1<os2) ick_setonespot(4,2);
+  ick_setonespot(3,os1+os2);
+  ick_resume(1);
+  return;
+
+  ick_linelabel(1010);
+  ick_setonespot(3,ick_getonespot(1)-ick_getonespot(2));
+  ick_resume(1);
+  return;
+
+  ick_linelabel(1020);
+  ick_setonespot(1,ick_getonespot(1)+1U);
+  ick_resume(1);
+  return;
+
+  ick_linelabel(1030);
+  os1=ick_getonespot(1);
+  os2=ick_getonespot(2);
+  if(os1&&0xffff/os1<os2) errout(1030, "onespot overflow");
+  ick_setonespot(3,os1*os2);
+  ick_resume(1);
+  return;
+
+  ick_linelabel(1039);
+  os1=ick_getonespot(1);
+  os2=ick_getonespot(2);
+  ick_setonespot(4,1);
+  if(os1&&0xffff/os1<os2) ick_setonespot(4,2);
+  ick_setonespot(3,os1*os2);
+  ick_resume(1);
+  return;
+
+  ick_linelabel(1040);
+  os2=ick_getonespot(2);
+  if(!os2) errout(1040, "division by zero");
+  ick_setonespot(3,ick_getonespot(1)/os2);
+  ick_resume(1);
+  return;
+
+  ick_linelabel(1050);
+  os1=ick_getonespot(1);
+  ts1=ick_gettwospot(1);
+  if(!os1) errout(1050, "division by zero");
+  ts1/=os1;
+  if(ts1>0xffffLU) errout(1050, "onespot overflow");
+  ick_setonespot(2,(uint16_t)ts1);
+  ick_resume(1);
+  return;
+
+  ick_linelabel(1500);
+  ts1=ick_gettwospot(1);
+  ts2=ick_gettwospot(2);
+  if(0xffffffffLU-ts1<ts2) errout(1500, "twospot overflow");
+  ick_settwospot(3,ts1+ts2);
+  ick_resume(1);
+  return;
+
+  ick_linelabel(1509);
+  ts1=ick_gettwospot(1);
+  ts2=ick_gettwospot(2);
+  ick_setonespot(4,1);
+  if(0xffffffffLU-ts1<ts2) ick_setonespot(4,2);
+  ick_settwospot(3,ts1+ts2);
+  ick_resume(1);
+  return;
+
+  ick_linelabel(1510);
+  ick_settwospot(3,ick_gettwospot(1)-ick_gettwospot(2));
+  ick_resume(1);
+  return;
+
+  ick_linelabel(1520);
+  ick_settwospot(1,(((uint32_t)ick_getonespot(1))<<16)+ick_getonespot(2));
+  ick_resume(1);
+  return;
+
+  ick_linelabel(1530);
+  ick_settwospot(1,ick_getonespot(1)*ick_getonespot(2));
+  ick_resume(1);
+  return;
+
+  ick_linelabel(1540);
+  ts1=ick_gettwospot(1);
+  ts2=ick_gettwospot(2);
+  if(ts1&&0xfffffffflu/ts1<ts2) errout(1540, "twospot overflow");
+  ick_settwospot(3,ts1*ts2);
+  ick_resume(1);
+  return;
+
+  ick_linelabel(1549);
+  ts1=ick_gettwospot(1);
+  ts2=ick_gettwospot(2);
+  ick_setonespot(4,1);
+  if(ts1&&0xfffffffflu/ts1<ts2) ick_setonespot(4,2);
+  ick_settwospot(3,ts1*ts2);
+  ick_resume(1);
+  return;
+
+  ick_linelabel(1550);
+  ts2=ick_gettwospot(2);
+  if(!ts2) errout(1550, "division by zero");
+  ick_settwospot(3,ick_gettwospot(1)/ts2);
+  ick_resume(1);
+  return;
+
+  ick_linelabel(1900);
+  if(!seededyet) srand(time(0));
+  seededyet=1;
+  ick_setonespot(1,rand()/(1+RAND_MAX/65536));
+  ick_resume(1);
+  return;
+
+  ick_linelabel(1910);
+  /* Here, we use the same algorithm as the original INTERCAL,
+     so as to produce similarly-distributed results.
+
+     If we add together 12 uniform random variables in the range #0 to
+     (.1 / 12), then the resulting random variable has a mean of (.1 /
+     2), and a variance of 12 times the original variance, which is
+     (((.1 * .1) / 144) / 12), giving a final variance of ((.1 * .1) /
+     144) and a final standard deviation of .1 / 12. */
+  if(!seededyet) srand(time(0));
+  seededyet=1;
+  os1=ick_getonespot(1);
+  os2 =rand()/(RAND_MAX/((os1   )/12));
+  os2+=rand()/(RAND_MAX/((os1+ 1)/12));
+  os2+=rand()/(RAND_MAX/((os1+ 2)/12));
+  os2+=rand()/(RAND_MAX/((os1+ 3)/12));
+  os2+=rand()/(RAND_MAX/((os1+ 4)/12));
+  os2+=rand()/(RAND_MAX/((os1+ 5)/12));
+  os2+=rand()/(RAND_MAX/((os1+ 6)/12));
+  os2+=rand()/(RAND_MAX/((os1+ 7)/12));
+  os2+=rand()/(RAND_MAX/((os1+ 8)/12));
+  os2+=rand()/(RAND_MAX/((os1+ 9)/12));
+  os2+=rand()/(RAND_MAX/((os1+10)/12));
+  os2+=rand()/(RAND_MAX/((os1+11)/12));
+  ick_setonespot(2,os2);
+  ick_resume(1);
+  return;
+
+  /* Several existing INTERCAL programs rely on the routine (1001),
+     which is undocumented and therefore shouldn't be used. So as not
+     to break those programs, here it is: */
+  ick_linelabel(1001);
+  ick_resume(ick_getonespot(5));
+  return;
+
+}
+ICK_EC_FUNC_END
diff --git a/pit/explib/syslibc.doc b/pit/explib/syslibc.doc
new file mode 100644 (file)
index 0000000..2b5c69b
--- /dev/null
@@ -0,0 +1,29 @@
+Alex Smith, 26 March 2008
+
+syslibc.c is an example of a C program designed to be used with the
+INTERCAL external call code. It only attempts to emulate the base 2
+algorithms, but in a base 2 program it should be a valid drop-in
+replacement for the real system library.  (Don't forget to use the -eE
+options when linking this to an INTERCAL program; -e to allow C
+programs to be linked in, and -E to suppress the 'real' syslib.)
+
+The library is designed foremost to ensure that all errors are checked
+(as they would be in the INTERCAL, although you get the error messages
+produced by C code), and secondarily for speed (it is substantially
+faster than the INTERCAL version of the system library, but that isn't
+particularly surprising).
+
+Note that some INTERCAL programs rely on undocumented features of the
+system library; I have implemented the commonly-used (1001), but some
+of the example programs (for instance primes.i) NEXT to other
+undocumented internal lines of syslib.i, and such programs will error
+out on the C version of the syslib.
+
+There are some situations in which the C program will cause errors,
+but the INTERCAL version wouldn't; remember that any attempt to alter
+or view an INTERCAL variable from C code causes an error if that
+variable doesn't exist in the INTERCAL program. Therefore, in order to
+use a particular routine, you should mention all the variables that
+are its inputs and outputs somewhere in your INTERCAL program; in
+particular, if you're using overflow-checked routines, make sure you
+mention .4 at least once in your program.
diff --git a/pit/lib/syslibc.c b/pit/lib/syslibc.c
deleted file mode 100644 (file)
index 4155fe1..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * The INTERCAL system library, optimised version in C.
- *
- * This is provided as an example of how to write a C program
- * that links to INTERCAL programs, to demonstrate the external
- * call code.
- *
- * Written originally by Alex Smith, and released to the public
- * domain. This library comes with NO WARRANTY.
- */
-
-#include <ick_ec.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-
-/* This identifier name breaches the namespace rule that ick_ must be
-   avoided, but this library has to work with both other people's
-   INTERCAL programs and other people's C programs. So I've chosen an
-   identifier name which breaches the rules (so that it doesn't clash
-   with other people's C programs) but isn't used anywhere in the
-   compiler, and so doesn't clash with it either.
-*/
-
-static void errout(int routine, char* msg)
-{
-  fprintf(stderr,"C-INTERCAL system library: (%d): %s\n", routine, msg);
-  exit(EXIT_FAILURE);
-}
-
-ICK_EC_FUNC_START(ick_my_custom_syslib)
-{
-  register uint16_t os1, os2;
-  register uint32_t ts1, ts2;
-  static int seededyet = 0;
-
-  ick_linelabel(1000);
-  os1=ick_getonespot(1);
-  os2=ick_getonespot(2);
-  if(0xffff-os1<os2) errout(1000, "onespot overflow");
-  ick_setonespot(3,os1+os2);
-  ick_resume(1);
-  return; /* so the compiler knows the next line can't be reached from here */
-
-  ick_linelabel(1009);
-  os1=ick_getonespot(1);
-  os2=ick_getonespot(2);
-  ick_setonespot(4,1);
-  if(0xffff-os1<os2) ick_setonespot(4,2);
-  ick_setonespot(3,os1+os2);
-  ick_resume(1);
-  return;
-
-  ick_linelabel(1010);
-  ick_setonespot(3,ick_getonespot(1)-ick_getonespot(2));
-  ick_resume(1);
-  return;
-
-  ick_linelabel(1020);
-  ick_setonespot(1,ick_getonespot(1)+1U);
-  ick_resume(1);
-  return;
-
-  ick_linelabel(1030);
-  os1=ick_getonespot(1);
-  os2=ick_getonespot(2);
-  if(os1&&0xffff/os1<os2) errout(1030, "onespot overflow");
-  ick_setonespot(3,os1*os2);
-  ick_resume(1);
-  return;
-
-  ick_linelabel(1039);
-  os1=ick_getonespot(1);
-  os2=ick_getonespot(2);
-  ick_setonespot(4,1);
-  if(os1&&0xffff/os1<os2) ick_setonespot(4,2);
-  ick_setonespot(3,os1*os2);
-  ick_resume(1);
-  return;
-
-  ick_linelabel(1040);
-  os2=ick_getonespot(2);
-  if(!os2) errout(1040, "division by zero");
-  ick_setonespot(3,ick_getonespot(1)/os2);
-  ick_resume(1);
-  return;
-
-  ick_linelabel(1050);
-  os1=ick_getonespot(1);
-  ts1=ick_gettwospot(1);
-  if(!os1) errout(1050, "division by zero");
-  ts1/=os1;
-  if(ts1>0xffffLU) errout(1050, "onespot overflow");
-  ick_setonespot(2,(uint16_t)ts1);
-  ick_resume(1);
-  return;
-
-  ick_linelabel(1500);
-  ts1=ick_gettwospot(1);
-  ts2=ick_gettwospot(2);
-  if(0xffffffffLU-ts1<ts2) errout(1500, "twospot overflow");
-  ick_settwospot(3,ts1+ts2);
-  ick_resume(1);
-  return;
-
-  ick_linelabel(1509);
-  ts1=ick_gettwospot(1);
-  ts2=ick_gettwospot(2);
-  ick_setonespot(4,1);
-  if(0xffffffffLU-ts1<ts2) ick_setonespot(4,2);
-  ick_settwospot(3,ts1+ts2);
-  ick_resume(1);
-  return;
-
-  ick_linelabel(1510);
-  ick_settwospot(3,ick_gettwospot(1)-ick_gettwospot(2));
-  ick_resume(1);
-  return;
-
-  ick_linelabel(1520);
-  ick_settwospot(1,(((uint32_t)ick_getonespot(1))<<16)+ick_getonespot(2));
-  ick_resume(1);
-  return;
-
-  ick_linelabel(1530);
-  ick_settwospot(1,ick_getonespot(1)*ick_getonespot(2));
-  ick_resume(1);
-  return;
-
-  ick_linelabel(1540);
-  ts1=ick_gettwospot(1);
-  ts2=ick_gettwospot(2);
-  if(ts1&&0xfffffffflu/ts1<ts2) errout(1540, "twospot overflow");
-  ick_settwospot(3,ts1*ts2);
-  ick_resume(1);
-  return;
-
-  ick_linelabel(1549);
-  ts1=ick_gettwospot(1);
-  ts2=ick_gettwospot(2);
-  ick_setonespot(4,1);
-  if(ts1&&0xfffffffflu/ts1<ts2) ick_setonespot(4,2);
-  ick_settwospot(3,ts1*ts2);
-  ick_resume(1);
-  return;
-
-  ick_linelabel(1550);
-  ts2=ick_gettwospot(2);
-  if(!ts2) errout(1550, "division by zero");
-  ick_settwospot(3,ick_gettwospot(1)/ts2);
-  ick_resume(1);
-  return;
-
-  ick_linelabel(1900);
-  if(!seededyet) srand(time(0));
-  seededyet=1;
-  ick_setonespot(1,rand()/(1+RAND_MAX/65536));
-  ick_resume(1);
-  return;
-
-  ick_linelabel(1910);
-  /* Here, we use the same algorithm as the original INTERCAL,
-     so as to produce similarly-distributed results.
-
-     If we add together 12 uniform random variables in the range #0 to
-     (.1 / 12), then the resulting random variable has a mean of (.1 /
-     2), and a variance of 12 times the original variance, which is
-     (((.1 * .1) / 144) / 12), giving a final variance of ((.1 * .1) /
-     144) and a final standard deviation of .1 / 12. */
-  if(!seededyet) srand(time(0));
-  seededyet=1;
-  os1=ick_getonespot(1);
-  os2 =rand()/(RAND_MAX/((os1   )/12));
-  os2+=rand()/(RAND_MAX/((os1+ 1)/12));
-  os2+=rand()/(RAND_MAX/((os1+ 2)/12));
-  os2+=rand()/(RAND_MAX/((os1+ 3)/12));
-  os2+=rand()/(RAND_MAX/((os1+ 4)/12));
-  os2+=rand()/(RAND_MAX/((os1+ 5)/12));
-  os2+=rand()/(RAND_MAX/((os1+ 6)/12));
-  os2+=rand()/(RAND_MAX/((os1+ 7)/12));
-  os2+=rand()/(RAND_MAX/((os1+ 8)/12));
-  os2+=rand()/(RAND_MAX/((os1+ 9)/12));
-  os2+=rand()/(RAND_MAX/((os1+10)/12));
-  os2+=rand()/(RAND_MAX/((os1+11)/12));
-  ick_setonespot(2,os2);
-  ick_resume(1);
-  return;
-
-  /* Several existing INTERCAL programs rely on the routine (1001),
-     which is undocumented and therefore shouldn't be used. So as not
-     to break those programs, here it is: */
-  ick_linelabel(1001);
-  ick_resume(ick_getonespot(5));
-  return;
-
-}
-ICK_EC_FUNC_END
diff --git a/pit/lib/syslibc.doc b/pit/lib/syslibc.doc
deleted file mode 100644 (file)
index 764d699..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-Alex Smith, 26 March 2008
-
-syslibc.c is an example of a C program designed to be used with the
-INTERCAL external call code. It only attempts to emulate the base 2
-algorithms, but in a base 2 program it should be a valid drop-in
-replacement for the real system library.  (Don't forget to use the -eE
-options when linking this to an INTERCAL program; -e to allow C
-programs to be linked in, and -E to supress the 'real' syslib.)
-
-The library is designed foremost to ensure that all errors are checked
-(as they would be in the INTERCAL, although you get the error messages
-produced by C code), and secondarily for speed (it is substantially
-faster than the INTERCAL version of the system library, but that isn't
-particularly surprising).
-
-Note that some INTERCAL programs rely on undocumented features of the
-system library; I have implemented the commonly-used (1001), but some
-of the example programs (for instance primes.i) NEXT to other
-undocumented internal lines of syslib.i, and such programs will error
-out on the C version of the syslib.
-
-There are some situations in which the C program will cause errors,
-but the INTERCAL version wouldn't; remember that any attempt to alter
-or view an INTERCAL variable from C code causes an error if that
-variable doesn't exist in the INTERCAL program. Therefore, in order to
-use a particular routine, you should mention all the variables that
-are its inputs and outputs somewhere in your INTERCAL program; in
-particular, if you're using overflow-checked routines, make sure you
-mention .4 at least once in your program.
index 0442fdde4bb76a8bf9ce075b6791f43c124189c6..158359bd49e8096e08120db8b83ae8e85248c365 100644 (file)
@@ -1681,7 +1681,7 @@ static void emit_guard(tuple *tn, FILE *fp)
     if (tn->exechance < 100)
        (void) fprintf(fp, "ick_roll(%d) && ", tn->exechance);
     if ((tn->type != NEXT && tn->type != GO_BACK && tn->type != COME_FROM
-        && /* AIS */ tn->type != NEXTFROMLABEL)
+        && /* AIS */ tn->type != NEXTFROMLABEL && tn->type != UNKNOWN)
        || tn->onceagainflag == onceagain_NORMAL)
       (void) fprintf(fp, "!ICKABSTAINED(%d))%s {\n", (int)(tn - tuples),
                     /* AIS */ tn->maybe?")":"");
@@ -1762,9 +1762,14 @@ void emit(tuple *tn, FILE *fp)
                emitlineno = up->ick_lineno;
                break;
            }
-    } else if (tn->ncomefrom)
-      emitlineno = comefromsearch(tn,1); /* AIS: For multithreading.
-                                           Return the 1st if we're forking. */
+    }
+    else if (tn->ncomefrom)
+    {
+       /* AIS: For multithreading. Return the 1st if we're forking. */
+      emitlineno = comefromsearch(tn,1);
+      if(emitlineno != -1)
+       emitlineno = tuples[emitlineno-1].ick_lineno;
+    }
     else if (tn < tuples + ick_lineno - 1)
        emitlineno = tn[1].ick_lineno;
     else
@@ -1809,8 +1814,9 @@ void emit(tuple *tn, FILE *fp)
        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) &&
+       continue in the normal fashion). UNKNOWN is also handled this way,
+       because CREATEd statements can be NEXT-like but not COME FROM-like. */
+    if ((tn->type == NEXT || tn->type == GO_BACK || tn->type == UNKNOWN) &&
        tn->onceagainflag != onceagain_NORMAL)
     {
       /* ONCE/AGAIN has already been swapped by perpet.c in the case
@@ -2551,8 +2557,8 @@ void emit(tuple *tn, FILE *fp)
        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 || useickec) && tn->type != NEXTFROMLABEL))
+       tn->type != NEXT && tn->type != GO_BACK && tn->type != UNKNOWN &&
+       ((tn->type != COME_FROM && tn->type != NEXTFROMLABEL) || useickec))
     {
       /* See my comments against the NEXT code for more information.
         This code is placed here so COME FROM ... ONCE constructs work
@@ -2606,7 +2612,7 @@ void emit(tuple *tn, FILE *fp)
                (int)(cf - tuples),
                cf->onceagainflag==onceagain_ONCE ? "ick_oldabstain ? ick_oldabstain : 1"
                : "0");
-      }      
+      }
       emit_guard(cf, fp);
       if(multithread || compucomesused)
        (void) fprintf(fp,