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
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
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
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
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
(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
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,
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.
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:
@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
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
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
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
@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
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
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
(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."
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.
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;
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
--- /dev/null
+/* 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+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.
+++ /dev/null
-/*
- * 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
+++ /dev/null
-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.
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?")":"");
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
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
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
(int)(cf - tuples),
cf->onceagainflag==onceagain_ONCE ? "ick_oldabstain ? ick_oldabstain : 1"
: "0");
- }
+ }
emit_guard(cf, fp);
if(multithread || compucomesused)
(void) fprintf(fp,