Mercurial > repo
diff interps/clc-intercal/CLC-INTERCAL-Base-1.-94.-2/bin/sick @ 996:859f9b4339e6
<Gregor> tar xf egobot.tar.xz
author | HackBot |
---|---|
date | Sun, 09 Dec 2012 19:30:08 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/interps/clc-intercal/CLC-INTERCAL-Base-1.-94.-2/bin/sick Sun Dec 09 19:30:08 2012 +0000 @@ -0,0 +1,618 @@ +#!/usr/bin/perl -w + +# Compiler/user interface/whatnot for CLC-INTERCAL + +# This file is part of CLC-INTERCAL + +# Copyright (c) 2006-2008 Claudio Calvelli, all rights reserved. + +# CLC-INTERCAL is copyrighted software. However, permission to use, modify, +# and distribute it is granted provided that the conditions set out in the +# licence agreement are met. See files README and COPYING in the distribution. + +require 5.005; + +my $initial_times; +BEGIN { $initial_times = [time, times] } + +use strict; +use Getopt::Long; + +use vars qw($VERSION $PERVERSION); +($VERSION) = ($PERVERSION = "CLC-INTERCAL/Base bin/sick 1.-94.-2") =~ /\s(\S+)$/; + +use Language::INTERCAL::Sick '1.-94.-2'; +use Language::INTERCAL::GenericIO '1.-94.-2', qw($stdsplat); +use Language::INTERCAL::Rcfile '1.-94.-2'; +use Language::INTERCAL::Interface '1.-94.-2'; + +$| = 1; + +my $user_interface = ''; +my $rclist = 0; +my $timehandle = 0; +my $rcfile = new Language::INTERCAL::Rcfile; +my $compiler = new Language::INTERCAL::Sick($rcfile); + +if (defined &Getopt::Long::Configure) { + Getopt::Long::Configure qw(no_ignore_case auto_abbrev permute bundling); +} else { + $Getopt::Long::ignorecase = 0; + $Getopt::Long::autoabbrev = 1; + $Getopt::Long::order = $Getopt::Long::PERMUTE; + $Getopt::Long::bundling = 1; +} + +my $setoption = sub { $compiler->setoption(@_) }; + +GetOptions( + # User Interface Options + 'graphic|X' => sub { $user_interface = 'X' }, + 'curses|c' => sub { $user_interface = 'Curses' }, + 'line' => sub { $user_interface = 'Line' }, + 'batch' => sub { $user_interface = 'None' }, + 'interface|i=s' => \$user_interface, + # source character set options + 'ascii|a' => sub { $compiler->setoption('charset', 'ASCII') }, + 'baudot|b' => sub { $compiler->setoption('charset', 'Baudot') }, + 'ebcdic|e' => sub { $compiler->setoption('charset', 'EBCDIC') }, + 'hollerith|h' => sub { $compiler->setoption('charset', 'Hollerith') }, + 'guess|g' => sub { $compiler->setoption('charset', '') }, + 'charset=s' => $setoption, + # code generation options + 'optimise|O' => $setoption, + 'nooptimise' => sub { $compiler->setoption('optimise', 0) }, + 'backend|l=s' => $setoption, + 'bug=i' => $setoption, + 'ubug=i' => $setoption, + 'output|o=s' => $setoption, + 'name|n=s' => $setoption, + 'include|I=s' => sub { $rcfile->setoption(@_) }, + 'preload|p=s' => $setoption, + 'nopreload' => sub { $compiler->clearoption('preload') }, + 'suffix=s' => $setoption, + # misc options + 'nouserrc' => sub { $rcfile->setoption('nouserrc', 1) }, + 'rcfile|r=s' => sub { $rcfile->setoption(@_) }, + 'stdverb=s' => sub { + my ($opt, $file) = @_; + my $mode = $file =~ s/^([ra]),// ? lc($1) : 'r'; + my $vh = + new Language::INTERCAL::GenericIO + ('FILE', $mode, $file); + $compiler->setoption('verbose', $vh); + }, + 'verbose|v' => sub { $compiler->setoption('verbose', $stdsplat) }, + 'quiet|q' => sub { $compiler->setoption('verbose', 0) }, + 'rclist' => \$rclist, + 'times' => sub { $timehandle = $stdsplat }, + 'notimes' => sub { $timehandle = 0 }, + 'stdtrace=s' => sub { + my ($opt, $file) = @_; + my $mode = $file =~ s/^([ra]),//i ? lc($1) : 'r'; + my $th = + new Language::INTERCAL::GenericIO('FILE', + $mode, + $file); + $compiler->setoption('trace_fh', $th); + $compiler->setoption('trace', 1); + }, + 'trace' => sub { $compiler->setoption('trace', 1) }, + 'notrace' => sub { $compiler->setoption('trace', 0) }, + # compile program + '<>' => sub { $compiler->source($_[0]); }, +) or usage(); + +set_options(); +my $server = Language::INTERCAL::Server->new(); +$compiler->server($server); +my $now = printtimes($initial_times, "Time to start up"); +$compiler->load_objects(); +$now = printtimes($now, "Time to load objects"); + +if ($rclist) { + $compiler->save_objects(0); + printtimes($now, "Time to save objects"); + printtimes($initial_times, "Total execution time"); + print map { "$_\n" } @{$rcfile->getoption('rcfiles')}; + exit 0; +} + +# XXX sick has not yet been updated to work with interactive interfaces +#my $ui_obj = Language::INTERCAL::Interface->new($server, +# $user_interface, +# $rcfile->getitem('SPEAK')); +my $ui_obj = Language::INTERCAL::Interface->new(undef, 'None'); +if (! $ui_obj->has_window) { + $compiler->save_objects(0); + printtimes($now, "Time to save objects"); + printtimes($initial_times, "Total execution time"); + exit 0; +} + +$rcfile->run($ui_obj); +printtimes($now, "Time to set up rcfiles"); + +$ui_obj->run($compiler); +printtimes($initial_times, "Total execution time"); + +sub set_options { + $rcfile->load; + my $db = $rcfile->getitem('PRODUCE'); + $compiler->setoption('default_backend', $db) if $db ne ''; + $compiler->setoption('default_charset', $_) + for $rcfile->getitem('WRITE'); + $compiler->setoption('default_suffix', $_) + for $rcfile->getitem('UNDERSTAND'); + $compiler->setoption('default_extra', $_) + for $rcfile->getitem('UNDERSTAND ANYWHERE'); +} + +sub usage { + (my $p = $0) =~ s#^.*/##; + die "Usage: $p [-alphabet] files...\n"; +} + +sub printtimes { + return 0 unless $timehandle; + my ($prev, $title) = @_; + my @now = (time, times); + my $wall = $now[0] - $prev->[0]; + my $user = $now[1] - $prev->[1]; + my $system = $now[2] - $prev->[2]; + for ($wall, $user, $system) { + if ($_ > 60) { + $_ = sprintf "%d:%05.2f", int($_ / 60), $_ - 60 * int($_ / 60) + } else { + $_ = sprintf "%.2f", $_; + } + } + $wall =~ s/\.00$//; + $timehandle->read_text("$title\: $wall (${user}u ${system}s)\n"); + \@now; +} +__END__ + +=pod + +=head1 NAME + +sick - Compiler for CLC-INTERCAL + +=head1 SYNOPSIS + +B<sick> [options] B<files>... + +=head1 DESCRIPTION + +B<sick> is the main development environment for CLC-INTERCAL. If +files are specified, these will be compiled using the options in +effect at the point where they appear on the command line, and +they are compiled to objects (if they are not already object). +After all the options have been processed, the program enters +interactive mode, unless otherwise specified. + +The program will be compiled using a compiler selected using command +line options; if nothing is selected, the compiler depends on the file +suffix: + +=over 4 + +=item CLC-INTERCAL program source + +These files must have suffix B<.i> or B<.clci>. These will be prefixed, +by default, with the compiler object I<sick.io>. + +=item CLC-INTERCAL compiler source + +These files must have suffix B<.iacc>. These will be prefixed, by default, +with the compiler object I<iacc.io> and produce a compiler object (which +can be executed as a program, but will do nothing - it's only useful as a +preload before compiling from source). + +=item C-INTERCAL program source + +These have suffix B<.ci> and will be prefixed with the compiler object +I<ick.io>. + +=item CLC-INTERCAL assembler source + +These have suffix B<.iasm> and will be prefixed with the compiler object +I<asm.io>. + +=item Traditional INTERCAL program source + +These will have suffix B<.1972> and will be prefixed with the compiler +object I<1972.io> + +=item Compiler extensions + +Suffixes B<.i>, B<.ci>, B<.clci> and B<.iasm> can contain a list of letters +and numbers between the spot (B<.>) and the rest of the suffix; these +select compiler extensions to be added. + +=over 8 + +=item Base + +Numbers between B<2> and B<7> change the default base by loading compiler +objects B<2.io> to B<7.io>. + +=item Bitwise Divide + +Letter B<d> in the suffix adds the compiler object I<bitwise-divide.io>, +which changes the normal unary divide operation to use bitwise, rather +than arithmetic, shifts. It can be used with I<sick> or I<iasm> but +not with I<ick>. + +=item COME FROM gerund + +Letter B<g> in the suffix adds the compiler object I<come-from-gerund.io>, +which enables the COME FROM gerund statements; since I<ick> does not parse +such statements, this letter can only be used with I<sick> or I<iasm>. + +=item Computed labels + +Letter B<l> in the suffix adds the compiler object I<computed-labels.io>, +which adds grammar rules to parse computed statement labels; this can +be used only with I<sick>. + +=item NEXT + +Letter B<n> in the suffix adds the compiler object I<next.io>, +which enables the NEXT statement in I<sick>; since I<ick> enables this +by default, this letter can only be used with I<sick>. + +=item INTERcal NETworking + +Letter B<r> in the suffix adds the compiler object I<internet.io>, +which adds syntax for the I<STEAL>, I<SMUGGLE> and I<CASE> statements; +it can be used with I<ick> or I<sick>. + +=item System call + +Letter B<s> in the suffix adds the compiler object I<syscall.io>, which hides +a "PLEASE NEXT FROM (666)" in a dark corner of your operating system. + +=item Threaded program + +Letter B<t> in the suffix selects threaded mode by loading compiler object +I<thick.io>. This also changes the default compiler to I<ick> if the suffix +is B<.i>: to use I<sick> one would use I<.tclci>. + +=item Wimp mode + +Letter B<w> in the suffix adds the compiler object I<wimp.io>, which causes +the program to start in wimp mode when it is executed. An equivalent result +can be obtained by passing the B<--wimp> option to the executable program. + +=back + +=back + +The actual list of suffixes recognised can be changed by editing the file +F<system,sickrc> or F<.sickrc>. See the option B<--rcfile> for a discussion +on how and where B<sick> finds these files, and L<sickrc> for a description +of the file format. + +If a preload file is specified on the command line, the defaults derived +from the suffix are not used. It is also possible to use default preloads +from a different file suffix by explicitely saying B<-suffix>=I<S> - in +this case, the compiler acts as if the file had name I<name.S> + +In addition, compiler objects are always recognised, with whatever suffix. +These bypass the first compiler pass and jump directly to the runtime +(just-too-late) compiler. However, if the optimiser has been selected +when these objects were compiled, and there are no postprocessor statements, +the just-too-late compiler will be automatically replaced by a more +traditional "compile-time" compiler. If this is confusing, wait until +you see the rest. + +If a file is specified without suffix, and there is a compiler object in the +include path with the same name and suffix B<.io>, the suffix is automatically +added, whether you wanted it or now. + +As soon as each program is written into B<sick>, a pre-compiler will +produce an internal compiler object. If B<sick> enters interactive mode, +these objects will be available in memory for single-stepping, running, +or just ignoring completely and getting on with the real work. + +If B<sick> loads all the required programs and objects successfully, but +does not enter interactive mode, any program source is read back out to +disk in object format, using the same file name with the suffix replaced +by B<.io> if no output file is specified. If a backend is specified in +the command line before a program is loaded, B<sick> will produce an +executable via that backend instead of an object. + +The compiler accepts several options, some of which are documented here. +Options and files can be mixed in any order, each file is loaded and +compiled using whatever options precedes it on the command line. For +example: + + sick --verbose --optimise prog1.i --quiet prog2.i --batch + +will tell you everything about compiling I<prog1.i> but not about I<prog2.i>. +Both programs will be optimised. On the other hand: + + sick --optimise prog1.i --nooptimise prog2.i --batch + +will optimise I<prog1.i> but not I<prog2.i>. + +All options can be "undone" (sometimes it's even clear how) except +B<--include> which applies to all objects loaded after it, and +B<--rcfile> which applies to all objects, even the ones loaded before +it (just to be different). + +=head2 User Interface Options + +=over 4 + +=item B<-X> / B<--graphic> + +Enters X-based graphical user interface. Requires Perl-GTK. This is the +default if Perl-GTK is installed, the environment variable I<$DISPLAY> is +set and the opening of the X display succeeds. + +=item B<-c> / B<--curses> + +Enters full screen, curses-based interface. This is the default if the +X based interface cannot be started, the environment variable I<$TERM> +is set and the terminal name is known. + +=item B<--line> + +Enters the line-mode user interface. This is the default if the X based +and the curses based interfaces do not work. + +=item B<--batch> + +Avoids entering interactive mode. This is the default if the standard +input and output are not connected to a terminal and the X based interface +cannot be started. + +=item B<-i>I<type> / B<--interface>=I<type> + +Selects the user interface I<type>. Currently, only I<X>, I<Curses>, +I<Line> and I<None> are defined, but more can be installed as compiler +plug-ins. If the interface selected is I<None>, B<sick> will work in +batch mode. In addition, an empty string will reinstate the default +behaviour. + +=back + +=head2 Source Character Set Options + +=over 4 + +=item B<-a> / B<--ascii> + +Assumes that program source is in ASCII. + +=item B<-b> / B<--baudot> + +Assumes that program source is in Baudot. + +=item B<-e> / B<--ebcdic> + +Assumes that program source is in EBCDIC. + +=item B<-h> / B<--hollerith> + +Assumes that program source is in Hollerith. + +=item B<-g> / B<--guess> + +Does not make assumptions about the source character set. If the character +set cannot be guessed, will produce an error. This is the default. + +=item B<--charset>=I<name> + +Assumes that program source is in the given character sets. Valid values are +currently I<ASCII>, I<Baudot>, I<EBCDIC>, I<Hollerith>; an empty I<name> is +equivalent to specifying option B<--guess>). + +=back + +=head2 Code Generation Options + +=over 4 + +=item B<-O> / B<--optimise> + +Invokes the optimiser. This is a letter o, not a zero. This will cause the +extra object I<optimise.io> to be prefixed after the last compiler and +before the real program. The program is then executed: when the optimiser +takes control, it will force compilation of the rest of the program (thereby +executing the compiler at compile-time, instead of runtime as it normally +does), and the resulting object is checkpointed, so the next time it will +automatically skip the initialisation and compilation stages. In addition, +the "optimise" register is set, instructing the compiler to invoke the +optimiser when it runs. + +If you specify B<-O> and B<-poptimise> (see below), you are asking for +trouble, so don't do that. + +=item B<--nooptimise> + +Disables automatic preloading and execution of I<optimise.io>. + +=item B<-o>I<name> / B<--output>=I<name> + +Selects a name for the output file. Some character sequences are recognised +inside I<name>: I<%p> will be replaced by the source program's basename; +I<%s> will be replaced by the appropriate suffix for the selected backend, +I<%o> will provide the original file name specified on the command line, +without suffix (this can differ from I<%s> because I<%s> can be prefixed +with a directory from the search path) and I<%%> will produce a single I<%>. + +The default is I<%p.%s>, which produces the object name described at the +beginning of this document. A suffix is not automatically added if the +output name does not contain I<%s>; this might be useful in ocnjunction +with the I<Perl> backend to produce a file without a suffix, for example: + + sick --output=%p --backend=Perl sourcefile.i + +will compile I<sourcefile.i> and produce perl script I<sourcefile>. + +If the output file is specified as an empty string, the code generation step +will never be done. + +=item B<-n>I<name> / B<--name>=I<name> + +Sets the program's I<name>, if the code generator requires it (currently, +no backends use a name, but some of the planned ones will). The default is +I<%o>. The same %-escapes as defined for the output file name are defined. + +=item B<-l>I<name> / B<--backend>=I<name> + +Selects a different compiler back end. The default is I<Object>, which +produces a compiler object (suffix I<.io>). The distribution also includes +a I<Perl> backend, which produces an executable Perl program (suffix I<.pl>). +In addition, the pseudo backend I<Run> will run the program instead of +writing any object. In this case, the output file name is ignored. Note +that the program will only run if the compiler is in batch mode. +Other back ends can be provided as compiler plug ins. The distribution +also contains a I<ListObject> backend, which does not produce executables +but object listings. A future version might allow to "compile" the output +of the I<ListObject> back end, but this is currently impossible because not +all the internal state of the object is provided, only the part which is +likely to be useful to a human reader. + +=item B<--bug>=I<number> + +Selects a different probability for the compiler bug. The compiler bug is +implemented by initialising the compiler's state with the required probability: +when a statement is compiled (usually at runtime), a "BUG" instruction is +emitted with the required probability. The default is 1%. + +=item B<--ubug>=I<number> + +Selects a probability for the unexplainable compiler bug. This is the compiler +bug which occurs when the probability of a (explainable) compiler bug is zero. +Only wimps would use this option. The default is 0.01%. + +=item B<-p>I<name> / B<--preload>=I<name> + +Selects a compiler object to prefix to the program. If this option is +specified, the compiler won't automatically prefix objects as suggested by +the suffix. The program B<'oo, ick'> included in previous version of +CLC-INTERCAL used option B<-p> to select a parser. Since the main use of +preloads is to select an alternative (runtime) compiler, it is felt that +it is appropriate to keep the same letter for this option. + +The file name specified does not include the suffix F<.io>, which is +always added. The file must be a compiler object, not source code. + +The special object I<optimise> should always loaded via B<-O>. Using +B<-poptimise> will not necessarily put the object in the correct place, +and will not instruct the precompiler to do whatever magic it needs to +do to bootstrap the optimiser. + +To completely disable preloading (this is only done when compiling the +optimiser, which is used to compile itself) use an empty string. + +=item B<--nopreload> + +Resets the default behaviour of selecting preloads based on suffixes. + +=item B<--suffix>=I<suffix> + +Specifies a suffix to use when selecting preloads. If this option is +not specified, the suffix is taken from the file name to be compiled. + +=item B<-I>I<path> / B<--include>=I<path> + +Adds a directory before the standard search path for compiler objects +and source code. If a file is accessible from the current directory, +it is never searched in any include path. + +If this option is repeated, the given paths will be searched in the +order given, followed by the standard paths. + +=back + +=head2 Misc Options + +=over 4 + +=item B<-r>I<name> / B<--rcfile>=I<name> + +Executes commands from file I<name> before entering interactive mode. +This option can be repeated, to execute more than one file. If it is +not specified, the standard library, the current directory, and the +current user's home directory are searched for files with name +F<system.sickrc> or F<.sickrc>, which are then executed. The order +for this search is: specified library (B<--include>), system library, +home directory, current directory. This is different from the search +order used when looking for objects or source code. If a directory +contains both F<.sickrc> and F<system.sickrc>, the F<system.sickrc> +is executed first, followed by F<.sickrc>. Also note that if the +current directory or the home directory appear in the search path +and contain one of these files, they will be executed twice. + +If filenames are explicitely specified, they must be fully qualified: +the search path is not used to find them. + +=item B<--nouserrc> + +Prevents loading a user rcfile (.sickrc); also limits loading of +system.sickrc to the first one found. This option is normally only +used during installation, to prevent interference from previous +versions of CLC-INTERCAL. + +=item B<-v> / B<--verbose> + +Tells everything it's doing (on Standard Error). + +=item B<--stdverb>=I<file> + +Sends verbose output to I<file>. + +=item B<--trace> + +Enables tracing; if compiling from source, the compiler is also +traced; to trace a program, compile it to an object and then run +it with B<--trace>. + +=item B<--stdtrace>=I<file> + +Enables tracing and selects an output file for the trace information. + +=item B<--notrace> + +Disables tracing; preloading I<trace.io> has priority over this option. + +=item B<-q> / B<--quiet> + +Stop talking to Standard Error. + +=item B<--times> + +Prints a summary of the time take for each major action. This setting is +independent of B<--verbose>. + +=item B<--notimes> + +Does not print execution times: this is the default. + +=item B<--rclist> + +Prints the names of all rcfiles found. It prevents starting interactive mode. +For example, the following command (which should work with I<any> Unix shell) +opens all the system and user sickrc files in your favourite editor: + + sh -c '"${EDITOR:-vi}" "`sick --rclist`"' + +This can be useful to update the defaults. + +=back + +=head1 BUGS + +There are more options than ls(1). This is construed to be a feature. + +=head1 SEE ALSO + +The INTERCAL on-line documentation, by entering B<sick>'s interactive mode +and finding the "help" menu (X), key (Curses) or command (Line). +