comparison 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
comparison
equal deleted inserted replaced
995:6883f5911eb7 996:859f9b4339e6
1 #!/usr/bin/perl -w
2
3 # Compiler/user interface/whatnot for CLC-INTERCAL
4
5 # This file is part of CLC-INTERCAL
6
7 # Copyright (c) 2006-2008 Claudio Calvelli, all rights reserved.
8
9 # CLC-INTERCAL is copyrighted software. However, permission to use, modify,
10 # and distribute it is granted provided that the conditions set out in the
11 # licence agreement are met. See files README and COPYING in the distribution.
12
13 require 5.005;
14
15 my $initial_times;
16 BEGIN { $initial_times = [time, times] }
17
18 use strict;
19 use Getopt::Long;
20
21 use vars qw($VERSION $PERVERSION);
22 ($VERSION) = ($PERVERSION = "CLC-INTERCAL/Base bin/sick 1.-94.-2") =~ /\s(\S+)$/;
23
24 use Language::INTERCAL::Sick '1.-94.-2';
25 use Language::INTERCAL::GenericIO '1.-94.-2', qw($stdsplat);
26 use Language::INTERCAL::Rcfile '1.-94.-2';
27 use Language::INTERCAL::Interface '1.-94.-2';
28
29 $| = 1;
30
31 my $user_interface = '';
32 my $rclist = 0;
33 my $timehandle = 0;
34 my $rcfile = new Language::INTERCAL::Rcfile;
35 my $compiler = new Language::INTERCAL::Sick($rcfile);
36
37 if (defined &Getopt::Long::Configure) {
38 Getopt::Long::Configure qw(no_ignore_case auto_abbrev permute bundling);
39 } else {
40 $Getopt::Long::ignorecase = 0;
41 $Getopt::Long::autoabbrev = 1;
42 $Getopt::Long::order = $Getopt::Long::PERMUTE;
43 $Getopt::Long::bundling = 1;
44 }
45
46 my $setoption = sub { $compiler->setoption(@_) };
47
48 GetOptions(
49 # User Interface Options
50 'graphic|X' => sub { $user_interface = 'X' },
51 'curses|c' => sub { $user_interface = 'Curses' },
52 'line' => sub { $user_interface = 'Line' },
53 'batch' => sub { $user_interface = 'None' },
54 'interface|i=s' => \$user_interface,
55 # source character set options
56 'ascii|a' => sub { $compiler->setoption('charset', 'ASCII') },
57 'baudot|b' => sub { $compiler->setoption('charset', 'Baudot') },
58 'ebcdic|e' => sub { $compiler->setoption('charset', 'EBCDIC') },
59 'hollerith|h' => sub { $compiler->setoption('charset', 'Hollerith') },
60 'guess|g' => sub { $compiler->setoption('charset', '') },
61 'charset=s' => $setoption,
62 # code generation options
63 'optimise|O' => $setoption,
64 'nooptimise' => sub { $compiler->setoption('optimise', 0) },
65 'backend|l=s' => $setoption,
66 'bug=i' => $setoption,
67 'ubug=i' => $setoption,
68 'output|o=s' => $setoption,
69 'name|n=s' => $setoption,
70 'include|I=s' => sub { $rcfile->setoption(@_) },
71 'preload|p=s' => $setoption,
72 'nopreload' => sub { $compiler->clearoption('preload') },
73 'suffix=s' => $setoption,
74 # misc options
75 'nouserrc' => sub { $rcfile->setoption('nouserrc', 1) },
76 'rcfile|r=s' => sub { $rcfile->setoption(@_) },
77 'stdverb=s' => sub {
78 my ($opt, $file) = @_;
79 my $mode = $file =~ s/^([ra]),// ? lc($1) : 'r';
80 my $vh =
81 new Language::INTERCAL::GenericIO
82 ('FILE', $mode, $file);
83 $compiler->setoption('verbose', $vh);
84 },
85 'verbose|v' => sub { $compiler->setoption('verbose', $stdsplat) },
86 'quiet|q' => sub { $compiler->setoption('verbose', 0) },
87 'rclist' => \$rclist,
88 'times' => sub { $timehandle = $stdsplat },
89 'notimes' => sub { $timehandle = 0 },
90 'stdtrace=s' => sub {
91 my ($opt, $file) = @_;
92 my $mode = $file =~ s/^([ra]),//i ? lc($1) : 'r';
93 my $th =
94 new Language::INTERCAL::GenericIO('FILE',
95 $mode,
96 $file);
97 $compiler->setoption('trace_fh', $th);
98 $compiler->setoption('trace', 1);
99 },
100 'trace' => sub { $compiler->setoption('trace', 1) },
101 'notrace' => sub { $compiler->setoption('trace', 0) },
102 # compile program
103 '<>' => sub { $compiler->source($_[0]); },
104 ) or usage();
105
106 set_options();
107 my $server = Language::INTERCAL::Server->new();
108 $compiler->server($server);
109 my $now = printtimes($initial_times, "Time to start up");
110 $compiler->load_objects();
111 $now = printtimes($now, "Time to load objects");
112
113 if ($rclist) {
114 $compiler->save_objects(0);
115 printtimes($now, "Time to save objects");
116 printtimes($initial_times, "Total execution time");
117 print map { "$_\n" } @{$rcfile->getoption('rcfiles')};
118 exit 0;
119 }
120
121 # XXX sick has not yet been updated to work with interactive interfaces
122 #my $ui_obj = Language::INTERCAL::Interface->new($server,
123 # $user_interface,
124 # $rcfile->getitem('SPEAK'));
125 my $ui_obj = Language::INTERCAL::Interface->new(undef, 'None');
126 if (! $ui_obj->has_window) {
127 $compiler->save_objects(0);
128 printtimes($now, "Time to save objects");
129 printtimes($initial_times, "Total execution time");
130 exit 0;
131 }
132
133 $rcfile->run($ui_obj);
134 printtimes($now, "Time to set up rcfiles");
135
136 $ui_obj->run($compiler);
137 printtimes($initial_times, "Total execution time");
138
139 sub set_options {
140 $rcfile->load;
141 my $db = $rcfile->getitem('PRODUCE');
142 $compiler->setoption('default_backend', $db) if $db ne '';
143 $compiler->setoption('default_charset', $_)
144 for $rcfile->getitem('WRITE');
145 $compiler->setoption('default_suffix', $_)
146 for $rcfile->getitem('UNDERSTAND');
147 $compiler->setoption('default_extra', $_)
148 for $rcfile->getitem('UNDERSTAND ANYWHERE');
149 }
150
151 sub usage {
152 (my $p = $0) =~ s#^.*/##;
153 die "Usage: $p [-alphabet] files...\n";
154 }
155
156 sub printtimes {
157 return 0 unless $timehandle;
158 my ($prev, $title) = @_;
159 my @now = (time, times);
160 my $wall = $now[0] - $prev->[0];
161 my $user = $now[1] - $prev->[1];
162 my $system = $now[2] - $prev->[2];
163 for ($wall, $user, $system) {
164 if ($_ > 60) {
165 $_ = sprintf "%d:%05.2f", int($_ / 60), $_ - 60 * int($_ / 60)
166 } else {
167 $_ = sprintf "%.2f", $_;
168 }
169 }
170 $wall =~ s/\.00$//;
171 $timehandle->read_text("$title\: $wall (${user}u ${system}s)\n");
172 \@now;
173 }
174 __END__
175
176 =pod
177
178 =head1 NAME
179
180 sick - Compiler for CLC-INTERCAL
181
182 =head1 SYNOPSIS
183
184 B<sick> [options] B<files>...
185
186 =head1 DESCRIPTION
187
188 B<sick> is the main development environment for CLC-INTERCAL. If
189 files are specified, these will be compiled using the options in
190 effect at the point where they appear on the command line, and
191 they are compiled to objects (if they are not already object).
192 After all the options have been processed, the program enters
193 interactive mode, unless otherwise specified.
194
195 The program will be compiled using a compiler selected using command
196 line options; if nothing is selected, the compiler depends on the file
197 suffix:
198
199 =over 4
200
201 =item CLC-INTERCAL program source
202
203 These files must have suffix B<.i> or B<.clci>. These will be prefixed,
204 by default, with the compiler object I<sick.io>.
205
206 =item CLC-INTERCAL compiler source
207
208 These files must have suffix B<.iacc>. These will be prefixed, by default,
209 with the compiler object I<iacc.io> and produce a compiler object (which
210 can be executed as a program, but will do nothing - it's only useful as a
211 preload before compiling from source).
212
213 =item C-INTERCAL program source
214
215 These have suffix B<.ci> and will be prefixed with the compiler object
216 I<ick.io>.
217
218 =item CLC-INTERCAL assembler source
219
220 These have suffix B<.iasm> and will be prefixed with the compiler object
221 I<asm.io>.
222
223 =item Traditional INTERCAL program source
224
225 These will have suffix B<.1972> and will be prefixed with the compiler
226 object I<1972.io>
227
228 =item Compiler extensions
229
230 Suffixes B<.i>, B<.ci>, B<.clci> and B<.iasm> can contain a list of letters
231 and numbers between the spot (B<.>) and the rest of the suffix; these
232 select compiler extensions to be added.
233
234 =over 8
235
236 =item Base
237
238 Numbers between B<2> and B<7> change the default base by loading compiler
239 objects B<2.io> to B<7.io>.
240
241 =item Bitwise Divide
242
243 Letter B<d> in the suffix adds the compiler object I<bitwise-divide.io>,
244 which changes the normal unary divide operation to use bitwise, rather
245 than arithmetic, shifts. It can be used with I<sick> or I<iasm> but
246 not with I<ick>.
247
248 =item COME FROM gerund
249
250 Letter B<g> in the suffix adds the compiler object I<come-from-gerund.io>,
251 which enables the COME FROM gerund statements; since I<ick> does not parse
252 such statements, this letter can only be used with I<sick> or I<iasm>.
253
254 =item Computed labels
255
256 Letter B<l> in the suffix adds the compiler object I<computed-labels.io>,
257 which adds grammar rules to parse computed statement labels; this can
258 be used only with I<sick>.
259
260 =item NEXT
261
262 Letter B<n> in the suffix adds the compiler object I<next.io>,
263 which enables the NEXT statement in I<sick>; since I<ick> enables this
264 by default, this letter can only be used with I<sick>.
265
266 =item INTERcal NETworking
267
268 Letter B<r> in the suffix adds the compiler object I<internet.io>,
269 which adds syntax for the I<STEAL>, I<SMUGGLE> and I<CASE> statements;
270 it can be used with I<ick> or I<sick>.
271
272 =item System call
273
274 Letter B<s> in the suffix adds the compiler object I<syscall.io>, which hides
275 a "PLEASE NEXT FROM (666)" in a dark corner of your operating system.
276
277 =item Threaded program
278
279 Letter B<t> in the suffix selects threaded mode by loading compiler object
280 I<thick.io>. This also changes the default compiler to I<ick> if the suffix
281 is B<.i>: to use I<sick> one would use I<.tclci>.
282
283 =item Wimp mode
284
285 Letter B<w> in the suffix adds the compiler object I<wimp.io>, which causes
286 the program to start in wimp mode when it is executed. An equivalent result
287 can be obtained by passing the B<--wimp> option to the executable program.
288
289 =back
290
291 =back
292
293 The actual list of suffixes recognised can be changed by editing the file
294 F<system,sickrc> or F<.sickrc>. See the option B<--rcfile> for a discussion
295 on how and where B<sick> finds these files, and L<sickrc> for a description
296 of the file format.
297
298 If a preload file is specified on the command line, the defaults derived
299 from the suffix are not used. It is also possible to use default preloads
300 from a different file suffix by explicitely saying B<-suffix>=I<S> - in
301 this case, the compiler acts as if the file had name I<name.S>
302
303 In addition, compiler objects are always recognised, with whatever suffix.
304 These bypass the first compiler pass and jump directly to the runtime
305 (just-too-late) compiler. However, if the optimiser has been selected
306 when these objects were compiled, and there are no postprocessor statements,
307 the just-too-late compiler will be automatically replaced by a more
308 traditional "compile-time" compiler. If this is confusing, wait until
309 you see the rest.
310
311 If a file is specified without suffix, and there is a compiler object in the
312 include path with the same name and suffix B<.io>, the suffix is automatically
313 added, whether you wanted it or now.
314
315 As soon as each program is written into B<sick>, a pre-compiler will
316 produce an internal compiler object. If B<sick> enters interactive mode,
317 these objects will be available in memory for single-stepping, running,
318 or just ignoring completely and getting on with the real work.
319
320 If B<sick> loads all the required programs and objects successfully, but
321 does not enter interactive mode, any program source is read back out to
322 disk in object format, using the same file name with the suffix replaced
323 by B<.io> if no output file is specified. If a backend is specified in
324 the command line before a program is loaded, B<sick> will produce an
325 executable via that backend instead of an object.
326
327 The compiler accepts several options, some of which are documented here.
328 Options and files can be mixed in any order, each file is loaded and
329 compiled using whatever options precedes it on the command line. For
330 example:
331
332 sick --verbose --optimise prog1.i --quiet prog2.i --batch
333
334 will tell you everything about compiling I<prog1.i> but not about I<prog2.i>.
335 Both programs will be optimised. On the other hand:
336
337 sick --optimise prog1.i --nooptimise prog2.i --batch
338
339 will optimise I<prog1.i> but not I<prog2.i>.
340
341 All options can be "undone" (sometimes it's even clear how) except
342 B<--include> which applies to all objects loaded after it, and
343 B<--rcfile> which applies to all objects, even the ones loaded before
344 it (just to be different).
345
346 =head2 User Interface Options
347
348 =over 4
349
350 =item B<-X> / B<--graphic>
351
352 Enters X-based graphical user interface. Requires Perl-GTK. This is the
353 default if Perl-GTK is installed, the environment variable I<$DISPLAY> is
354 set and the opening of the X display succeeds.
355
356 =item B<-c> / B<--curses>
357
358 Enters full screen, curses-based interface. This is the default if the
359 X based interface cannot be started, the environment variable I<$TERM>
360 is set and the terminal name is known.
361
362 =item B<--line>
363
364 Enters the line-mode user interface. This is the default if the X based
365 and the curses based interfaces do not work.
366
367 =item B<--batch>
368
369 Avoids entering interactive mode. This is the default if the standard
370 input and output are not connected to a terminal and the X based interface
371 cannot be started.
372
373 =item B<-i>I<type> / B<--interface>=I<type>
374
375 Selects the user interface I<type>. Currently, only I<X>, I<Curses>,
376 I<Line> and I<None> are defined, but more can be installed as compiler
377 plug-ins. If the interface selected is I<None>, B<sick> will work in
378 batch mode. In addition, an empty string will reinstate the default
379 behaviour.
380
381 =back
382
383 =head2 Source Character Set Options
384
385 =over 4
386
387 =item B<-a> / B<--ascii>
388
389 Assumes that program source is in ASCII.
390
391 =item B<-b> / B<--baudot>
392
393 Assumes that program source is in Baudot.
394
395 =item B<-e> / B<--ebcdic>
396
397 Assumes that program source is in EBCDIC.
398
399 =item B<-h> / B<--hollerith>
400
401 Assumes that program source is in Hollerith.
402
403 =item B<-g> / B<--guess>
404
405 Does not make assumptions about the source character set. If the character
406 set cannot be guessed, will produce an error. This is the default.
407
408 =item B<--charset>=I<name>
409
410 Assumes that program source is in the given character sets. Valid values are
411 currently I<ASCII>, I<Baudot>, I<EBCDIC>, I<Hollerith>; an empty I<name> is
412 equivalent to specifying option B<--guess>).
413
414 =back
415
416 =head2 Code Generation Options
417
418 =over 4
419
420 =item B<-O> / B<--optimise>
421
422 Invokes the optimiser. This is a letter o, not a zero. This will cause the
423 extra object I<optimise.io> to be prefixed after the last compiler and
424 before the real program. The program is then executed: when the optimiser
425 takes control, it will force compilation of the rest of the program (thereby
426 executing the compiler at compile-time, instead of runtime as it normally
427 does), and the resulting object is checkpointed, so the next time it will
428 automatically skip the initialisation and compilation stages. In addition,
429 the "optimise" register is set, instructing the compiler to invoke the
430 optimiser when it runs.
431
432 If you specify B<-O> and B<-poptimise> (see below), you are asking for
433 trouble, so don't do that.
434
435 =item B<--nooptimise>
436
437 Disables automatic preloading and execution of I<optimise.io>.
438
439 =item B<-o>I<name> / B<--output>=I<name>
440
441 Selects a name for the output file. Some character sequences are recognised
442 inside I<name>: I<%p> will be replaced by the source program's basename;
443 I<%s> will be replaced by the appropriate suffix for the selected backend,
444 I<%o> will provide the original file name specified on the command line,
445 without suffix (this can differ from I<%s> because I<%s> can be prefixed
446 with a directory from the search path) and I<%%> will produce a single I<%>.
447
448 The default is I<%p.%s>, which produces the object name described at the
449 beginning of this document. A suffix is not automatically added if the
450 output name does not contain I<%s>; this might be useful in ocnjunction
451 with the I<Perl> backend to produce a file without a suffix, for example:
452
453 sick --output=%p --backend=Perl sourcefile.i
454
455 will compile I<sourcefile.i> and produce perl script I<sourcefile>.
456
457 If the output file is specified as an empty string, the code generation step
458 will never be done.
459
460 =item B<-n>I<name> / B<--name>=I<name>
461
462 Sets the program's I<name>, if the code generator requires it (currently,
463 no backends use a name, but some of the planned ones will). The default is
464 I<%o>. The same %-escapes as defined for the output file name are defined.
465
466 =item B<-l>I<name> / B<--backend>=I<name>
467
468 Selects a different compiler back end. The default is I<Object>, which
469 produces a compiler object (suffix I<.io>). The distribution also includes
470 a I<Perl> backend, which produces an executable Perl program (suffix I<.pl>).
471 In addition, the pseudo backend I<Run> will run the program instead of
472 writing any object. In this case, the output file name is ignored. Note
473 that the program will only run if the compiler is in batch mode.
474 Other back ends can be provided as compiler plug ins. The distribution
475 also contains a I<ListObject> backend, which does not produce executables
476 but object listings. A future version might allow to "compile" the output
477 of the I<ListObject> back end, but this is currently impossible because not
478 all the internal state of the object is provided, only the part which is
479 likely to be useful to a human reader.
480
481 =item B<--bug>=I<number>
482
483 Selects a different probability for the compiler bug. The compiler bug is
484 implemented by initialising the compiler's state with the required probability:
485 when a statement is compiled (usually at runtime), a "BUG" instruction is
486 emitted with the required probability. The default is 1%.
487
488 =item B<--ubug>=I<number>
489
490 Selects a probability for the unexplainable compiler bug. This is the compiler
491 bug which occurs when the probability of a (explainable) compiler bug is zero.
492 Only wimps would use this option. The default is 0.01%.
493
494 =item B<-p>I<name> / B<--preload>=I<name>
495
496 Selects a compiler object to prefix to the program. If this option is
497 specified, the compiler won't automatically prefix objects as suggested by
498 the suffix. The program B<'oo, ick'> included in previous version of
499 CLC-INTERCAL used option B<-p> to select a parser. Since the main use of
500 preloads is to select an alternative (runtime) compiler, it is felt that
501 it is appropriate to keep the same letter for this option.
502
503 The file name specified does not include the suffix F<.io>, which is
504 always added. The file must be a compiler object, not source code.
505
506 The special object I<optimise> should always loaded via B<-O>. Using
507 B<-poptimise> will not necessarily put the object in the correct place,
508 and will not instruct the precompiler to do whatever magic it needs to
509 do to bootstrap the optimiser.
510
511 To completely disable preloading (this is only done when compiling the
512 optimiser, which is used to compile itself) use an empty string.
513
514 =item B<--nopreload>
515
516 Resets the default behaviour of selecting preloads based on suffixes.
517
518 =item B<--suffix>=I<suffix>
519
520 Specifies a suffix to use when selecting preloads. If this option is
521 not specified, the suffix is taken from the file name to be compiled.
522
523 =item B<-I>I<path> / B<--include>=I<path>
524
525 Adds a directory before the standard search path for compiler objects
526 and source code. If a file is accessible from the current directory,
527 it is never searched in any include path.
528
529 If this option is repeated, the given paths will be searched in the
530 order given, followed by the standard paths.
531
532 =back
533
534 =head2 Misc Options
535
536 =over 4
537
538 =item B<-r>I<name> / B<--rcfile>=I<name>
539
540 Executes commands from file I<name> before entering interactive mode.
541 This option can be repeated, to execute more than one file. If it is
542 not specified, the standard library, the current directory, and the
543 current user's home directory are searched for files with name
544 F<system.sickrc> or F<.sickrc>, which are then executed. The order
545 for this search is: specified library (B<--include>), system library,
546 home directory, current directory. This is different from the search
547 order used when looking for objects or source code. If a directory
548 contains both F<.sickrc> and F<system.sickrc>, the F<system.sickrc>
549 is executed first, followed by F<.sickrc>. Also note that if the
550 current directory or the home directory appear in the search path
551 and contain one of these files, they will be executed twice.
552
553 If filenames are explicitely specified, they must be fully qualified:
554 the search path is not used to find them.
555
556 =item B<--nouserrc>
557
558 Prevents loading a user rcfile (.sickrc); also limits loading of
559 system.sickrc to the first one found. This option is normally only
560 used during installation, to prevent interference from previous
561 versions of CLC-INTERCAL.
562
563 =item B<-v> / B<--verbose>
564
565 Tells everything it's doing (on Standard Error).
566
567 =item B<--stdverb>=I<file>
568
569 Sends verbose output to I<file>.
570
571 =item B<--trace>
572
573 Enables tracing; if compiling from source, the compiler is also
574 traced; to trace a program, compile it to an object and then run
575 it with B<--trace>.
576
577 =item B<--stdtrace>=I<file>
578
579 Enables tracing and selects an output file for the trace information.
580
581 =item B<--notrace>
582
583 Disables tracing; preloading I<trace.io> has priority over this option.
584
585 =item B<-q> / B<--quiet>
586
587 Stop talking to Standard Error.
588
589 =item B<--times>
590
591 Prints a summary of the time take for each major action. This setting is
592 independent of B<--verbose>.
593
594 =item B<--notimes>
595
596 Does not print execution times: this is the default.
597
598 =item B<--rclist>
599
600 Prints the names of all rcfiles found. It prevents starting interactive mode.
601 For example, the following command (which should work with I<any> Unix shell)
602 opens all the system and user sickrc files in your favourite editor:
603
604 sh -c '"${EDITOR:-vi}" "`sick --rclist`"'
605
606 This can be useful to update the defaults.
607
608 =back
609
610 =head1 BUGS
611
612 There are more options than ls(1). This is construed to be a feature.
613
614 =head1 SEE ALSO
615
616 The INTERCAL on-line documentation, by entering B<sick>'s interactive mode
617 and finding the "help" menu (X), key (Curses) or command (Line).
618