Mercurial > repo
view interps/clc-intercal/CLC-INTERCAL-Base-1.-94.-2/Changes @ 6858:ff90693af5e8
<Elronnd> touch hw/python
author | HackBot |
---|---|
date | Mon, 15 Feb 2016 01:54:13 +0000 |
parents | 859f9b4339e6 |
children |
line wrap: on
line source
Changes from CLC-INTERCAL 1.-94.-3 to 1.-94.-2 * Moved all documentation, user interfaces and the calculator stuff to separate packages, so their installation is now optional. The documentation is always available from the website, so people may not need to install that at all. There is a plan to move the INTERNET stuff to its own separate package as well, but this hasn't been done yet. * Changed Makefile.PL to be a thin wrapper around a new module, Language::INTERCAL::InstallModule - this is going to do all the work for CLC-INTERCAL but also for all the optional modules. One day, it'll also be possible to have a Build.PL without extra effort. * Added $VERSION (derived from $PERVERSION) to all modules; this is required so that the compiler can be uploaded to CPAN and made available to a wider unsuspecting audience. Added a check in the test programs to make sure the $VERSION can be found by ExtUtils::MakeMaker, and hence by the CPAN software. * Made generic filehandle code (GenericIO.pm) more generic and modular; this will allow extensions to define new file types. * Make some changes in Interpreter.pm because the above changes to GenericIO broke it. * FIxed some invalid HTML in the documentation. As I was there, I changed the Makefile so that it can generate the file error.html from the list of splats, and parsers.html from the list of bytecodes. The generated HTML will be produced in blib/htmldoc * A new version of Language::INTERCAL::HostIP has been produced for better integration with the rest of CLC-INTERCAL. This version is no longer derived (just inspired) from Sys::HostIP, after I tried to submit patches to it and could not contact the author. * Fixed a bug in the Hollerith encoding (thanks to ais523 for the bug report); see the end of doc/html/charset.html * Fixed a problem that caused the calculator to splat when dealing with registers overloaded by a previous line. * Fixed a problem with class WRITE IN. Also added test programs for class I/O. * Fixed a problem with the theft server when invoked with --linger=0 Changes from CLC-INTERCAL 1.-94.-4 to 1.-94.-3 * Fixed some incompatibility between the implementation of REINSTATE and the documentation. Thanks ais523 for pointing that out. * Updated documentation (see doc/html) to reflect the current state of the compiler. * Fixed error building CLC-INTERCAL when a previous version was present. I always clean up after myself :-) so I never noticed this. Thanks to Mark Brown (maintainer of the debian package of clc-intercal as well as more useful packages) for the report. A similar problem also occurred while testing (t/??intercalc-*), which has also been fixed * Added the two crawling horrors as accessible registers; however, there isn't much one can do with them apart from enslaving and overloading them. Still, they are there, ready for the time they can be used properly. * Fixed a problem where constant labels did not have the correct value if the, ehm, constant had been changed. This can happen if you use overloading. This isn't the same as computed labels. Something similar could also happen with ABSTAIN FROM (label) where the label was a modified constant. Fixed that too. * Made some changes to the grammars (see 1972.iacc, iacc.iacc, ick.iacc and sick.iacc) to speed up the compilation process (there was an urgent need for it!). My favourite example of pathological parser behaviour, examples/hello.i now takes about 2 minutes to compile, compared with the over 30 minutes of 1.-94.-4). Moreover, there is now a faster way to enable/disable the buttons in the calculator which makes it usable in "sick" mode. For this reason, the calculator now defaults to "sick" mode, the previous default was "ick" because "sick" was too slow. * Added some more tests to the test suite; this allowed me to find and fix a bug in "ick" compatibility mode which generated wrong bytecode for REINSTATE, and to notice that ABSTAIN and REINSTATE weren't supported in the calculator (they are now). * Written a reference implementation for the INTERNET (INTERcal NETworking). See files under directory doc/INTERNET in this distribution for the draft specification, which is a modification of the article originally posted on alt.lang.intercal. If you have any comments, do let me know. * Made some changes to .sickrc and system.sickrc so that they can contain defaults for programs other than sick; these are specified as mappings for weird program suffixes, to allow older versions of CLC-INTERCAL to read new sickrc files without producing an error - however in the unlikely case a program has suffix ..<program>.<option> the older versions will get confused by it (but you wouldn't be able to compile these programs under any version of CLC-INTERCAL anyway). Intercalc now uses two options from the sickrc: ..INTERCALC.LANGUAGE defines the default language and default language options, to be used when the command line does not contain a -l / --language; and ..INTERCALC.MODE defines the operating mode (one, expr, full) to be used when the command line does not contain -m / --mode. The new INTERNET library also uses options from the sickrc: ..INTERNET.PORT contains the port number to be used for communication (default 64928 until we can obtain an official port assignment) and ..INTERNET.DEVICE.<device_name> contains the broadcast address for an interface (default: try to determine them - or disable part of the functionality of the CASE statement if that fails). See the appropriate section of the README file for another discussion of this. * Fixed a bug in intercalc which made it impossible to perform an assignment in "full" mode! Well, it worked in batch mode... * Added menus in intercalc (as well as special syntax to access the menu functions in batch mode) to change language, base and (un)select options. Note that some changes (change base, change mode) will just load the changes in memory, while other (change language, unselect option) require a reload of the compiler; doing this in the middle of entering a statement or expression is permitted but may cause unexpected results. Even when the compiler needs to be reloaded, the contents of registers remains unchanged (except for the special registers, if the options loaded change them). It is also possible to read out the current state (to a file) and write it back in (from a file) so you can quit the calculator and start it again in the same state (with the limitations, to be removed in a future version, that the operating mode must be the same). In a future version, the calculator will also be able to change the options stored in your .sickrc to correspond to the current ones selected from the menu. For now, you can "Read as" to save the current state to a file, then when you write that back in you get all your options (mode, language, base, options) restored with it. * Finished the initialisation code included in compiled objects so that one can select wimp mode and other stuff from the command line; any unrecognised option is saved in special register ^AV and any environment is saved in special register ^EV. Although these registers are not accessible to user programs, one can always add the syntax for them or write an extension which will be able to use them. * Added new system calls to syscall.iasm to allow file operations and TCP sockets. Note that this is not related to the INTERNET extension. * Found a very rare bug in the assignment to arithmetic unary divide, which was so rare it only manifested by running "make test" about 100 times in a row. At the same time fuxed a related bug which had never manifested. Changed the test script to run more tests when the result involves random numbers to help picking these things out in future. Changes from CLC-INTERCAL 1.-94.-5 to 1.-94.-4 * Simplified Makefile.PL * Changed the system call interface which is now written in assembler (that would be INTERCAL assembler, not your computer's native assembler). It even works in the calculator, if you use -osyscall... * Improved "sick.iacc" to allow more sensible templates (e.g. "READ OUT REGISTER LIST" or "READ OUT EXPRESSION", whereas before you could only use "READ OUT REGISTER"). * All internal data types (Spot, Twospot, Hybrid, Tail, Whirlpool) are now subclasses of the same thing, DataItem. This allows uniform implementation of calculating and using a register, a simple place where registers and elements can be overloaded, and an easy way to produce splats, for example when arrays are used where classes would be expected etc. * Added "WRITE IN EXPRESSION" which is roughly equivalent to writing in a numeric value and then assigning the value to the expression. Alphanumeric and binary WRITE INs are currently only possible if EXPRESSION is a single register of suitable type (tail, hybrid or shark fin). For maximum obfuscation do something like PLEASE WRITE IN #1 and see what happens. * Made substantial changes to the bytecode - this is necessary to implement CONVERT and SWAP. The objects will now be incompatible with 1.-94.-5's objects but hopefully I won't need to make any more incompatible changes later. While doing this, going through the various grammar and checking all generated code - needless to say, found and fixed some bugs. Language::INTERCAL::Bytecode is now generated automatically from a list of bytecode opcodes and internal registers: this means that a C version (for a C runtime) can be generated from the same list and guaranteed to be consistent; it also means that now the module is much faster to load, as its initialisation can now be done while generating it. The new module also allows to classify opcodes by type and to automate some tasks (such as interpreting bytecode and generating code dependent on a bytecode sequence): this allows a simplification of both interpreters and backends. There is also the advantage that the POD documentation is also generated from the same list, so the two don't get inconsistent with each other as they used to. * Added splat *123, program attempted more than 80 levels of NEXTing, which was never produced by CLC-INTERCAL before. Ditto for *621, RESUME #0, and *632, RESUME instead of GIVE UP. * Changed Language::INTERCAL::Splats to be generated like the bytecode. In fact, any other module can now be generated from a data file and a template by just including @@DATA anywhere in it: see comments at the start of Generate/Generate. * Added unary divide because I just couldn't resist. You don't have to use it if you don't approve of it. In fact, you are not very likely to use it as it is almost, but not quite, completely useless. * Changed the way the compilers (and compiler compilers etc) work, simplifying just about everything. Removed the CoreDump backend, which was only used to produce compilers (etc) and is now unnecessary. * Extensively changed Language::INTERCAL::Object to bring it up to date with all the other changes. As I was there, implemented CONVERT and SWAP. Note that the functionality is now split between Language::INTERCAL::Object and Language::INTERCAL::Interpreter * Added the possibility to assign to any expression, providing a shortcut to assigning to an overloaded register: for example: DO .&1 <- #2 * Added ABSTAIN FROM / REINSTATE COMPILER BUG, equivalent to requesting that the compiler does not generate a bug. When the compiler bug is ABSTAINed FROM, it may still execute as an unexplainable compiler bug. As a side effect, one can now also COME FROM COMPILER BUG and so on, although this is not likely to be very useful as the COME FROM executes after the bug, or in other words does not execute at all. Note that the above does not stop the unexplainable compiler bug. In fact, by ABSTAINing FROM the explainable bug, one may trigger the unexplainable one. Also added the ABSTAIN FROM / REINSTATE QUANTUM COMPUTING, together with all the normal friends such as COME FROM QUANTUM COMPUTING etc. These statements refer to any quantum statement in the program. Note that there are no template (just gerunds) for COMPILER BUG and QUANTUM COMPUTING. Also note that an ABSTAIN FROM QUANTUM COMPUTING WHILE REINSTATING IT will cause the program to have a split personality, one quantum, one classical. Or something like that. * Also made substantial changes to the parser. The idea is that in many cases the program never needs to be recompiled at runtime, even if the compiler does change during execution. We do this by guessing how many alternative versions of the code we are likely to need, and generating them all. The way it's implemented now it reduces the recompile but could do a lot more, which is planned for 1.-93 or (if I find the time) 1.-94.-3 As I was there, I've put some code towards writing the optimiser. * Changed the way the compiler handles top-level symbols (i.e. ?PROGRAM) to avoid the code generated becoming exponentially large, just to be then compressed back to normal by _setcode() (in Parser.pm). This problem is a consequence of the previous change. Note that the compiler is stil slower than it needs to be, but further improvements will need to wait for a new release. * Added a lot of functionality to the calculator (intercalc), which now works in "oic" and "expr" mode (see the docs), and will probably work in "full" mode but it is untested. Anyway, you can astonish all your friends with a calculator where you can type something like: #1 <- #2 and thereafter whenever you use the number 1 you get 2 instead, for example: .1 <- #5 .2 will give you 5 (or rather "V") because you've assigned to .2... OK, it is a bit slow just now but this is because the compiler is slow, and improvements will follow in 1.-94.-3. Honest. * Minor changes/fixes/etc in: Language::INTERCAL::ArrayIO Language::INTERCAL::Charset Language::INTERCAL::Charset::Baudot Language::INTERCAL::Exporter Language::INTERCAL::GenericIO Language::INTERCAL::Interface::None Language::INTERCAL::Numbers Language::INTERCAL::ReadNumbers Language::INTERCAL::Reggrim Language::INTERCAL::WriteNumbers Changes from CLC-INTERCAL 1.-94.-6 to 1.-94.-5 * Done some changes to the parser as a preparation for further development (planned between 1.-94.-4 and 1.-94-release). * Removed licence.* and the corresponding paragraph in the README etc. It was a joke but it is getting difficult to maintain. * Added a separate gerund for loops and events (before they had a common gerund); added a possibility to ABSTAIN FROM LOOPING, which also abstains from events, and the corresponding templates. Ditto for CONVERT/SWAP to distinguish betweem loops/events and generic statements. * Fixed a bug in the bytecode generated for loops, which could not possibily work in bases other than 2. Ditto for the corresponding CONVERT and SWAP. * Fixed a typo on the grammar which caused any expression to be recognised as end of comment; computed labels appear as (expression), so this is now the syntax checked. And a related grammar bug caused invalid code when processing labels! * Fixed the "COME FROM gerund" code, which caused problems with examples/quantum/come-from-gerund.gi * Made some changes in Language::INTERCAL::GenericIO to fix some problems with the example programs provided. * Fixed some problems with the bytecode generated for REMEMBER Changes from CLC-INTERCAL 1.-94.-7 to 1.-94.-6 * Added an INTERCAL desk calculator (intercalc) - just a stub for now but it'll grow into something one day. * Bug fixes in the sick.iacc grammar: some quantum statements were incorrectly specified; also READ OUT * did not parse correctly. * Some rewriting of the parser allows more flexibility when writing grammars; also, there is now a mechanism to extract the whitespace discarded by the compiler: this may be, one day, used to embed Whitespace (see http://compsoc.dur.ac.uk/whitespace/) into INTERCAL. Also, the code looking for the end of a comment, which used to look for the first DO, PLEASE or (number) after a parse error, now uses symbols defined in the grammar instead. This means that, for example, sick now recovers correctly from a parse error just before a computed label; formerly, it would consider the computed label as part of the comment because it did not match the simple pattern. Yes, the compiler is getting slower, but I have ideas on how to improve that, which I plan to work on in 1.-93; meanwhile, this release will test all the grammars and iacc files. * Removed the "deep recursion" messages when compiling the licence agreement (this would also happen in any other suitably complicated grammar). * Removed references to the old licence from all source files, and updated copyright statement and perversion number. * Fixed some weirdness in the generation of manpages from pod, caused by the weirdness of the source directory structure. * Added an option to link any two objects together; this is similar to the preload used to compile things, but can be applied to any object, even one already compiled. Moreover, using --preload prevents guessing a list of preloads, so you need to specify them all in the command line; --link is an independent mechanism and does not stop the default preloads: see the example in the next bullet. Note however that not all objects designed to use with --preload will work with --link; for example, attempting to --link 3.io will not switch the base at runtime: instead it will cause your program to fail to run. The reason is that 3.io has been designed to be included at compile time, not at runtime. * Added a "trace mode" which allows one to watch bytecode while it is executed. To use it, compile to object as normal and then link with trace.io: sick -lObject PROGRAM.i (or whatever) sick -lRun PROGRAM.io --link trace.io of course, you can combine the two: sick -lRun PROGRAM.i --link trace.io The advantage of --link over --preload in this case is that --link does not clear the preload list; the equivalent command using --preload, and assuming you haven't changed the system.sickrc is: sick -lRun -psick -ptrace -ppostpre PROGRAM.i Note that trace.io has been designed to be included at runtime. While it works in this example, it may cause other preloads to stop working if they appear after trace.io in the command line. * Changed the encoding of Hollerith into bytes to interleave the bits instead of splitting them. Changes from CLC-INTERCAL 1.-94.-8 to 1.-94.-7 * New licence. * Minor problems in the documentation fixed (could cause some fussy browsers to display the examples incorrectly). Changes since CLC-INTERCAL 0.05 * NOTE: CONVERT and SWAP are currently unimplemented in the prerelease 1.-94 compiler. Use the new CREATE and DESTROY instead (see below). * ALSO NOTE: This file is sorted by decreasing order of sanity. You may stop reading at any point, but, if you continue, things are guaranteed to get worse. * New version scheme including negative revision numbers has been introduced. * "Version" renamed "perversion" for honesty. * Implemented the just-too-late compiler people have heard me talking about: see file doc/just-too-late.pod * Modified the operators to support Tri-INTERCAL (and all bases up to 7) and of course add the extra operators (Unary BUT, etc); the notation will be different from their C-INTERCAL's counterpart (because the whirlpool has already been used for classes); unary BUT is written ?; unary Add Without Carry is written | (in C-INTERCAL compatibility mode, BUT is @ and Add is ^). * Updated the WRITE IN code to allow input in Latin, like C-INTERCAL 0.20; also added an alternative spelling for Gaelic Neoni (0). * Added new stashes. INTERCAL 1972 and C-INTERCAL have two stashes: one for the program counter (used by NEXT) and one for all the other registers. CLC-INTERCAL 0.05 had three (two independent ones for the program counter: did anybody notice that you can do NEXT from within a lecture, do a FINISH LECTURE, and you can still RESUME? In other words, you could do subroutine returns in the wrong order and it wold work (for INTERCAL values of work); after all, you can already stash registers and then retrieve them in the wrong order, as long as the registers are distinct). CLC-INTERCAL 1.-94 has sixteen independent stashes, but we aren't (yet) admitting what they are used for. It helps to remove that unfortunate resemblance between stashes and stacks. You can now stash a register several times and then retrieve it in any order, not just the reverse of the stashing. If this is confusing, don't worry, we can't figure out why one would want to do that either. * Updated READ code to allow array slices (e.g. if ;1 is a 2-dimensional array, READ OUT ;1 SUB #2 will read out all elements of ;1 which have first subscript #2). For reasons which shall remain unexplained, WRITE IN can only use whole array or single elements, no slices (this, of course, might change in a future release). * Implemented the CREATE statement, as well as its companion DESTROY: the syntax is different from what had been announced (but never implemented) before, and use of these statements require knowledge of the INTERCAL virtual machine, which will be documented in future (possibly). The parser is now provided in its source form (a list of CREATE statements), and this can be used as example by anybody who is interested to extend the compiler. A mini-compiler is provided in src/iacc.iacc (source) and src/iacc.io (object) to compile the full compiler. * Implemented a new statement, the "NEXT FROM". This is similar to "COME FROM", except that the current position is stashed. For example, the two programs: (1) DO .1 <- #1 | DO (2) NEXT PLEASE READ OUT .1 | PLEASE READ OUT .1 DO GIVE UP | DO GIVE UP DO NEXT FROM .1 | (2) DO .1 <- #2 DO .1 <- #2 | PLEASE RESUME #1 PLEASE RESUME #1 produce the same result ("II"). It is an error to have more than one "NEXT FROM" looking at the same label, or a "NEXT FROM" and a "COME FROM". This limitation might be removed in future releases. Also note that we think this new statement is cool, so you won't have to ask the compiler to include it (as you need to do with "NEXT"/"RESUME"/"FORGET"), it's always available. * Also allowed "Gerund" forms of "COME FROM" and "NEXT FROM", so they now look like ABSTAINs and REINSTATEs in the grammar. There is an example in examples/quantum/come-from-gerund.gi; Since programs using this construct incur some performance penalty (every statement is now a potential target for a "COME FROM"/"NEXT FROM", not just ones with labels), it needs to be explicitly enabled by preloading "come-from-gerund" or using the suffix ".gi" instead of ".i" * Also updated the definition of "GERUND" to include "COMMENTING" (which can be abbreviated "COMMENTS") - with all INTERCAL compilers, unrecognised statements are treated as comments; if they are executed, they print themselves as error messages and abort. Now it is possible to ignore errors by saying: PLEASE ABSTAIN FROM COMMENTING You can, of course, REINSTATE COMMENTS, although this might transform genuine comments ("PLEASE NOTE: THIS IS A COMMENT") into error messages. But then, you had a similar problem when comments had labels. * Modified the initialisation code to make the command-line and the environment available to the program. These will be found in the special array registers ^1 and ^2, respectively. The arrays are bidimensional, with ^1 SUB #1 containing the first argument, ^1 SUB #2 the second, and so on. Needless to say, these arguments are provided as if they had been written in, so they are likely to be in Baudot or something as bad as that. A class library to implement associative arrays is going to be provided one day - this would be just what you need to use ^2 (the environment). Please note that these registers are used by the initialisation code, and are not normally accessible to the program (but see the next point) * Made some of the program's internal state accessible to the program via a set of special registers (%n). For example, "DO %1 <- #1" will cause the program to do something unexpected (because %1 is the first part of the instruction pointer, the rest being %2 and %3). Note that a statement starting with "DO %1" can now be an assignment or something else, for example "DO %10 <- #1" is an assignment, and "DO %10 READ OUT .1" is a statement which reads out a register one time in ten. This is OK because IACC (the parser generator) happily accepts nondeterministic grammars, and sometimes even produces the expected results. The use of these registers should be limited to the compiler itself. In fact, they are currently only available to the compiler, but nobody stops the programmer from making them available with the appropriate CREATEs. If you really must, the list of these register is around line 82 of Language/INTERCAL/Object.pm -- look for %special_registers. Note that you cannot use any % or ^ register unless it's listed there, and you cannot always resize ^ registers. Some of the registers behave weirdly. * Rewritten the write/read code to allow more flexibility from within the program - this is used by the compiler itself as well as by other things which are currently kept secret. The word "Outercal" has been uttered again. * Added some more quantum constructs: DO register <- expression WHILE NOT ASSIGNING TO IT DO COME FROM (label) WHILE NOT COMING FROM THERE DO CREATE ... WHILE NOT CREATING IT DO DESTROY(... WHILE NOT DESTROYING IT DO ENROL register TO LEARN subjects WHILE NOT ENROLLING DO ENSLAVE register TO register WHILE LEAVING IT FREE DO FINISH LECTURE WHILE CONTINUING IT DO FORGET expression WHILE NOT FORGETTING DO FREE register TO register WHILE LEAVING IT IN SLAVERY DO NEXT FROM (label) WHILE NOT NEXTING FROM THERE DO GIVE UP WHILE CONTINUING TO RUN DO register GRADUATES WHILE REMAINING A STUDENT DO register LEARNS subject WHILE NOT LEARNING IT DO (label) NEXT WHILE NOT NEXTING DO RESUME expression WHILE NOT RESUMING DO RETRIEVE registers WHILE NOT RETRIEVING THEM DO STASH registers WHILE NOT STASHING THEM DO STUDY subject AT (label) IN CLASS @(number) WHILE NOT STUDYING IT DO WRITE IN registers WHILE NOT WRITING THEM Note that quantum assignment will also generate quantum bits on side effects: if the expression contains some overloading, the overloading will take effect while not taking effect; if the assignment modifies constants (see next point), they will retain their previous value while assuming a new one. This applies to most of the new constructs except (just to be different) quantum COME FROM, which always applies side effects but causes the program to jump while remaining stationary (similarly quantum NEXT FROM and behaves like quantum COME FROM) Examples for all forms of quantum constructs are found in directory examples/quantum: all these files can be compiled with the default CLC-INTERCAL compiler; in addition, examples/threads.i is a program which demonstrates the use of (non-quantum) threads, and must be compiled using the Threaded INTERCAL compatibility mode ("thick"). * Allowed to modify constants by assigning to an overloaded register, for example: PLEASE DO .1 <- .1/#1 will (shock! horror!) leave the value of .1 unchanged, but at the same time modifies the value of #1 to whatever value was in .1 before the assignment. Note that this changes more than you might expect: for example, the "1" in ".1" will now change too... so when you try to assign to .1 (for example to restore #1 to its former value), you might get a different register. The way around it is: PLEASE DO .2 <- #1 PLEASE ENSLAVE .2 TO .1 DO .1 <- #1234 DO .1 <- .1/#1 DO SOMETHING WITH #1 CHANGED TO #1234 DO $.2 <- .2 DO FREE .2 FROM .1 You need to use $.2, because .1 is not accessible in any other way. Of course, you are responsible for keeping the value of #2 constant during the above code. You probably guessed a simpler solution already: PLEASE DO .1234 <- #1 PLEASE ENSLAVE .1234 TO .1 DO .1 <- #1234 DO .1 <- .1/#1 DO SOMETHING WITH #1 CHANGED TO #1234 DO $.1 <- .1 DO FREE .1234 FROM .1 This works because the references to .1 are really references to .1234, which of course contains .1; and $.1 is really $.1234 which is the real .1 People who want to keep their sanity should avoid assigning to constants. (come to think of it, people who want to keep their sanity should avoid INTERCAL...) People who are not so worried about their sanity can read all about overloading in the documentation. * A new operating system interface is available via the use of the special register %OS and the compiler module "syscall.iacc" (which can be added to sick by using the option "-psick -psyscall" or, better, "--suffix=si"). After you added "syscall.iacc" to your program, it will behave as if the operating system had, lurking in its darkest corner, the statement: DO NEXT FROM (666) (In fact, it is a computed NEXT FROM and the label is specified by the internal register %OS; however, since the register is not accessible to the program, it is just as good as a noncomputed one, unless you use CREATE to make the register accessible). The operation code is contained in register +.1-$%OS which is just a shortand for "the spot register with the same number as the last register assigned to before the system call". For example, the following: (666) DO .666 <- #2 would execute system operation #2, whatever it is. However, the following: (666) DO :123 <- #2 would execute the system operation with code in .123 (the assignment was to :123, which of course does not alter .123, but sets the register number to be used to 123, so the expression "+.1-$%OS" becomes equivalent to "+.1-:123" which is of course ".123". Also note that if a thread has never assigned to a register, it is an error to use the syscall interface. A program starting with: (666) DO NOT GIVE UP would therefore produce an error. One more note, "writing" a register means assigning to it. For example, the following program would obtain a system operation number from the operator: (666) PLEASE WRITE IN .1 An then there is: (666) DO RETRIEVE :1 + ,2 + ;3 which can decide to use .1, .2 or .3 depending on the actual order of evaluation (the RETRIEVE is considered to modify all the registers listed). In all versions of CLC-INTERCAL, registers are retrieved in order, so, until we change something, this uses .3 for the opcode. Enslaving, freeing, enrolling and graduating are not considered modifications in this context. Overloading is also not considered a modification (including assignment to overloads) although it probably ought to be. If you want consistency, don't use INTERCAL. For example: PLEASE .1 <- .2/#3 (666) DO .2 <- #4 would execute the system call with ".1", not ".2", because the last assignment is to an overloaded register (in fact, it is altering #3 to be the same as #4, so it is not assigning to a register at all!) The list of system operations does not necessarily correspond with the O.S. kernel's list of syscalls, or with anything else. It is currently documented only by the self-explanatory source code in syscall.i - which also doubles as example for "COME FROM GERUND" and "CREATE". Parameters to the call are contained in registers with the same number as the opcode: +:1-$%OS for numbers, +,1-$%OS for strings and +;1-$%OS for lists of numbers. Of course, some opcodes have nonstandard calling conventions. It is possible to disable system calls using "DO ABSTAIN FROM NEXTING FROM", and re-enable them with "DO REINSTATE NEXTING FROM". * Since you are still here, you can read the comment before subroutine _forall_statement() in Language::INTERCAL::Object and reproduced below: # The following subroutine handles the rather dubious case in which the # compiled program has changed, and the program counter needs adjusting # in all threads to find where the current code has gone. The reason it # is called _forall_statements is because this can only happen when we # sweep through the program, for example to find come froms, labels, and # what have you. In all other cases, the program counter automagically # adapts to the code. Really. Look at _run_code() if you don't believe me