-
Notifications
You must be signed in to change notification settings - Fork 7
/
lispf4.orig
10487 lines (9664 loc) · 316 KB
/
lispf4.orig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
******HELP
Note.
in the code there are some nonstandard statements.
In the function ratom we use double precision variables to pick upp
the value of a number beeing read. This is beceause we dont want to loose
precision when reading big integer numbers.
But then we make integer numbers
and single precision real numbers by assignment. Here you can solve
this problem by either removing the double precision declaration
or use some conversion function on your computer (double to integer,
double to real, integer do double).
Installing Lispf4
=================
Lispf4 is delivered as ONE file, EXPORT, containing source code in
Fortran, Lisp, and assembler language (only for Dec10/20 and IBM).
Each subfile in EXPORT starts with a line containing
******<filename>
where <filename> is the name of the source code file.
The subfiles are
HELP this text
DOC installation (and user) guide
* FLOSOR auxiliary routines for the interpreter
* HEART the heart of the interpreter
* F4COM COMMON block with areas used by the interpreter
MOD modifications for full prompting (see below)
OPENF modifications for symbolic file names (see below)
DEC20 assembler routines for DEC20
DEC10 assembler routines for DEC10
VAXFTN machine dependent routines in Fortran for VAX11
VAXLSP machine dependent Lisp functions for VAX11
IBM assembler routines for IBM
* FLOSYS data file for initialization of Lispf4 bootstrap
* LIBRRY library functions in Lisp for Lispf4 bootstrap
DEBUGLOG log of run with debuglines in floexp enabled
The only files that are needed to get a "primitive" system
are the 5 files marked with "*". The other files can of course
be of help if you want to fix symbolic I/O and other things.
Below follows an overview of the installation process. You should
also read the installation guide (subfile DOC).
Do the following to install Lispf4:
1. Split EXPORT into the various subfiles with, e.g., an editor.
The second subfile contains the documentation of the system with
installation guide.
2. Find the subroutine INIT1 in the subfile FLOSOR, where some machine
dependent constants are defined. Change them according to the
documentation. Note that you probably need to change declarations
of the COMMON block in the subfile F4COM. Some areas in F4COM should
be declared INTEGER*2 in order to save space considerably
(e.g. CAR, CDR, and stacks). In the file delivered there are INTEGER*2
declarations on those places where such declarations should be done.
However, you may not get enough Lisp cells with INTEGER*2; in such
cases you should change all INTEGER*2 declarations into INTEGER, after-which
you may increase the CAR/CDR areas (don't forget NFREET in INIT1) from
the current 28000 ('optimal' for INTEGER*2 CAR/CDR) into, e.g., 38000.
All areas are declared in the COMMON block F4COM.
The Fortran program contains statements
INCLUDE 'F4COM.FOR'
on those places where F4COM should be inserted.
Caution! Don't forget to redimension IMESS, and to change FORMATs in
RDA4 and WRA4.
Note also that the subroutines SETCHT and GETCHT in FLOSOR make use of
the fact that A1 format characters are stored left justified.
On, e.g., VAX11 SETCHT and GETCHT must be redefined using the
Fortran function MOD. (The constant CHDIV is then unused).
3. When all constants are defined you may compile and link Lispf4.
LISPF4 uses the Fortran source code in the files FLOSOR, HEART,
and DUMMY.
You may also need to program two machine dependent routines in
assembler or Fortran (GETCH and PUTCH, see documentation).
Be absolutely sure that GETCHT, SETCHT, GETCH, and PUTCH work
before testing Lispf4!
4. Now you can start LISPF4. It will read some messages from logical unit
LUNSYS (default 23). Connect LUNSYS to the subfile FLOSYS.
5. If the system starts properly you get an underline (_) as prompter.
If the system does not start properly it's time to try to find out what was
wrong. Most problems with lispf4 are with text and I/O. If you get problems
you can enable the debug lines in floexp (marked CDEBUG) and run
lispf4. The debug lines print various parts of the buffers and pname
on lunuts (the terminal). A log of what this output should look like is
supplied in the file DEBUGLOG. You have to modify the A5 format in the
debug lines to whatever A format is a integer on your machine.
The DEBUGLOG also shows how to load the librray file.
Note ! on DEC20 fortran runtime will ask for a filename if you try
to read or write on a unit that is not opened. In other systems you
would have to open the LIBBRY.LSP file on unit 55 to get the same result
as in the logfile. (same thing with flosys.lsp and unit 23)
6. At this point you should be able to talk to Lisp. Call the function
(IOTAB 1 x)
where x is logical unit number for the subfile LIBRRY.
(this file contains all library functions and will load them all,
if you dont want all packages you have do edit the file yourself)
7. When the file is loaded do
(ROLLOUT 'LF3)
The system will ask for logical unit number. Answer with logical unit
number connected to a Fortran file for binary (unformatted) writing/reading.
8. If everything worked, try to do
(ROLLIN 'LF3)
and to answer with the same logical unit number as by the ROLLOUT.
9. Now LISPF4 should work!
10. Most operating systems allow references to physical file names from
Fortran. If your OS disallows this then GOTO 12.
Modify the function OPENF in FLOSOR, which, given a pointer to a Lisp
string containing a file name, opens the file and returns a new
logical unit number. The current code is made for DEC10/20.
You must also modify the Lisp function SOPENF in the subfile LIBRRY
which takes a Lisp file name and constructs a physical file name
for your OS. E.G. for DEC20 it transforms the Lisp file name FOO
into DSK:FOO.LSP before calling OPENF (Lisp function OPEN0).
11. Load OPENF before FLOSOR.
12. Compile the subfile INIT2 and put it first in the load list.
INIT2 intercepts some initiation code in LISPF4 by directly reading
the LISPF4 rollout from a logical unit number defined in INIT2.
13. Now we have the load order
INIT2,(OPENF,)FLOSOR,HEART
Load, link, and save the load module.
14. Run the load module. the system should read the LISPF4 rollout from
unit 7 (or whatever you define in INIT2).
15. If you have defined your own OPENF then set
(SETQ SYMBIO T)
and roll it out on the physical file LF4 with
(ROLLOUT 'LF4)
16. Lispf4 prints a prompt text when reading from the terminal.
(The SUBR PROMPTTEXT may change this prompt text)
In the delivered version the prompt text is printed on a separate
line, but you probably prefer to print it without line feed.
Since it is machine dependent to print Fortran strings without
ending line feeds, you then need to redefine two I/O routines.
The subfile MOD contains the modified code for DEC20; it is
probably rather similar on your computer.
MOD should be loaded before FLOSOR.
17. Most operating systems allow you to make a subroutine which is called
when the user types a special interrupt character on the terminal
(CTRL-H on DEC20, CTRL-C on VAX11, BREAK on IBM etc)
In Lispf4 you may use this for interrupting the interpretation.
You must then make an assebler routine, BRSET, which sets up an
interrupt so that the subroutine BRSERV (without arguments) is called
whenever the user types the interrupt character.
The assembly code for DEC20 and IBM contains code for interrupt
handling. Note that there are some minor changes in the main
Fortran program for IBM. (As indicated by comments in the source
code). The interrupt handler for IBM is written for the time sharing
system GUTS, which should simulate correctly (hopefully) TSO.
18. On some operating systems there may be a problem that the hash
function of Lispf4 makes use of the fact that A1 format characters
are left justified in the word. On such systems (e.g. VAX11) you
should redefine the function IHADR in the subfile FLOSOR.
19. On some computers (e.g. DEC20) CAR and CDR is represented more
efficiently by using half word pointers, but the Fortran compiler
cannot handle small integers. In such cases one may implement CAR and
CDR as (assembly) functions.
For RPLACA and RPLACD two more subroutines SETCAR(X,Y) and SETCDR(X,Y)
need to be defined and all CAR(X)=xxx and CDR(X)=xxx must be replaced
with calls to SETCAR and SETCDR. To simplify this all such places in
the interpreter have the fortran line
C*SETC*R statement
where 'statement' is the call to SETCAR/SETCDR replacing the previous
Fortran line. The assembly code for DEC20 contains code for handling
of half word integers.
CAR,CDR,SETCAR, and SETCDR as subprograms may also be used for other
purposes, e.g. software paging.
In the text above we say that something should be loaded "before"
something else. This is only a way of getting a specified module
loaded if there are more than one module with that name. I.e in the code
there is a dummy defined OPENF function if you have written your own
openf you can on DEC20
load my-openf,main-code
and your openf will be loaded and not the dummy one in the main code.
If this is not possible you have to remove the OPENF dummy function in
the main code.
******DOC (LISPF4 DOCUMENTATION)
INTRODUCTION
LISP F4 is a LISP interpreter written in FORTRAN IV. The interpreter
is (almost) a subset of INTERLISP. LISP F4 originates from LISP 1.5
through LISP F1 to LISP F3. LISP F4 is about 3 - 10 times more
efficient then LISP F1 and have features like floating point numbers
and arrays. LISP F4 is easy to implement.
This document contains two parts, a users guide and a implementation
guide. The users guide presupposes basic knowledge of the LISP commands
and functions (See Haraldsson LISP-details, referred to as Ha 75).
********* USER'S GUIDE ************
PRIMARY DATATYPES
Small integers Range -n,n where n is implementation
dependent.
If x is the maximum positive integer
in a full word, n is x-size of CAR,CDR
Floating point Range depending on the size of a full word
numbers Characterized by BYTES, IRESOL, IPOWER, FUZZ.
Lists Given as (A B (C D)) etc.
Strings Given as "THIS IS A STRING"
Alfanum atom. Max. no of characters = size of I/O-buff/2
(default = 80).
Arrays Containing pointers,
integers and
floating point numbers.
INTERNAL REPRESENTATIONS
A more complete description of the internal representations is
needed for a complete knowledge and usage of LISP F4 from the user's
point of view.
a) THE ADDRESS SPACE.
The address space is shown by the following figure:
1 MAX
I---------------------I----------I---------------I-----------------I
NIL alphanum atoms lists pointers to pointers to
and strings real numbers small integers
MAX = the largest positive integer in a halfword (or full word) in
your computer.
b) ALPHANUMERICAL ATOMS AND STRINGS.
CAR CDR
I----------------I----------------I
I I --------> property list
I-------I--------I----------------I
V
global value
The global value of an atom is stored in CAR(atom). (EVAL checks for
a bound value BEFORE a global value - as in INTERLISP but in
contradiction to LISP 1.5). A global value may be set either by
SET/SETQ at the top level, or directly by RPLACA. If a global value
has not been assigned, car(atom) points to the atom NOBIND.
STRINGS are represented exactly as atoms except for
- car(string) points to the atom STRING
- Two different strings may have the same printname.
- Strings always have themselves as the value.
SUBSTRINGS are like strings, but instead of having a print name
- car(substring) = SUBSTR
- cdr(substring) = (sourcestring start .length)
PRINTNAMES are accessed through the pointer representing the atom
and hidden from the user in a special area.
FUNCTION DEFINITIONS.
In INTERLISP each atom-record also has a "function field" called
function cell (Ha 75 page 4). In LISP F4 user defined functions
are stored as LAMBDA or NLAMBDA expressions under the property
FNCELL. SUBR's and FSUBR's are recognized by their pointer-value
but in order to simulate the facility of making use of "free
function indicators", GETD is defined to return (SUBR . FOO) if
FOO is a FORTRAN coded SUBR, and (FSUBR . FOO) if it is a FSUBR.
The forms (SUBR . FOO) and (FSUBR . FOO) are simulated function
indicators and legal function arguments to apply.
Ex.:
(DE KAR(X) ((SUBR . CAR) X>
This definition of KAR causes KAR to behave exactly as CAR
independently of whether CAR has been redefined to something else.
c) FLOATING POINT NUMBERS AND ARRAYS
FLOATING POINT NUMBERS are stored in consecutive floating point words in
upper PNAME.
Atoms obeying the following syntax are treated as numbers. If
floating point numbers:
number::= sm ! smEsn
s ::= + ! - ! empty
n ::= d ! dn
d ::= 0 ! 1 ! 2 ! 3 ! 4 ! 5 ! 6 ! 7 ! 8 ! 9
m ::= n ! n. ! n.n ! .n
The "E" has the same meaning as in Fortran.
Floating point numbers are printed as compactly as possible,
either with or without the "E".
ARRAYS contain pointers, integers or floating point numbers.
CAR(pointer value) = LISPF4-ARRAY
CDR(pointer value) = NIL
By this means it is possible to call a Fortran subroutine with an
actual parameter consisting of an address to an array part if the
corresponding formal parameter is a properly typed array.
Arrays cannot be read-in. They are printed as
#xxx # = left square bracket
where xxx is the array pointer value.
d) THE SYMBOL TABLE CAN BE LOOKED UPON
The function
(OBLIST x)
creates a new list of atoms, with the last atom created as the first
member of the list, and the atomic argument x as the last one. As
as T is the last one defined by a "clean" system, (OBLIST T) gives you
all but SUBR's and FSUBR's.
e) VARIABLE BINDINGS IN PARAMETER STACK
Variable bindings are stored in a parameter stack (as in Interlisp)
and is implicitly given to EVAL, APPLY and EVLIS.
Functions that use the stack.
If you want to evaluate something and skip part of the stack
you use the function EVSTK
(EVSTK form stkpos)
This function works like eval but begins searching the stack at
stkpos.
If you are used to a function EVALA (lisp 1.5) this is what you
should use (EVALA works but will put the alist on the stack and
that takes time)
To get a stkpos you use the function BINDENV
(BINDENV var)
returns stackaddress to the block before the block
where var is bound.
The address is returned as a smallnum
pointing to the topmarker of the block.
If you try to supply anything that don't point
to a topmarker to EVSTK or APPLYSTK you will
get an error. This means you can only
get lisp to start searching at a block boundary.
_(DE TEST (BAR)(PROG () (PRINT BAR)(PRINT (EVSTK 'BAR (BINDENV BAR>
TEST
_(SETQ BAR 88)
88
_(TEST 77)
77
88
NIL
The function TEST is defined to print its argument
and print the value of it's argument outside it's
own block.
The function applystk will do the same as applya in the same way.
(APPLYSTK func list stkpos)
To safe definitions of RPTQ and SETQQ
(RPTQ
(NLAMBDA (N X)
(APPLYSTK 'RPT (LIST (EVSTK N (BINDENV N)) X) (BINDENV N))))
(SETQQ
<NLAMBDA L (APPLYSTK 'SET L (BINDENV L>)
To look at the stack there is the function BTV*
_(PP BAR)
(BAR
(LAMBDA (U) (FOO (ADD1 U))))
(BAR)
_(PP FOO)
(FOO
(LAMBDA (X) (FUM (LIST X 77))))
(FOO)
_(PP FUM)
(FUM
(LAMBDA (L) (BTV*) (PRINT (REVERSE L))))
(FUM)
_(BAR 567)
Environment Tops
11 13
#13 <0 11>
#12 *FORM (BTV*)
#11 <-8 8>
#10 L (568 77)
#9 *FORM (FUM (LIST X 77))
#8 <-5 5>
#7 X 568
#6 *FORM (FOO (ADD1 U))
#5 <0 2>
#4 U 567
#3 *FORM (BAR 567)
#2 <0 0>
#1 *FORM (LISPX)
*** Bottom ***
(77 568)
(77 568)
The function ALIST will build a list of dotted pairs
with the variable and it's value from the stack.
ALIST with no argument will not include the *FORM variables
but (ALIST T) will.
_(DE A(X Y)(B 6 Y))
A
_(PP A)
(A
(LAMBDA (X Y) (B 6 Y)))
(A)
_(DE B(Z W)(SETQ R1 (ALIST))(SETQ R2(ALIST T>
B
_(PP B)
(B
(LAMBDA (Z W) (SETQ R1 (ALIST)) (SETQ R2 (ALIST T))))
(B)
_(A 567 88)
((W . 88)
(Z . 6)
(*FORM B 6 Y)
(Y . 88)
(X . 567)
(*FORM A 567 88))
_R1
((W . 88)
(Z . 6)
(Y . 88)
(X . 567))
_R2
((W . 88)
(Z . 6)
(*FORM B 6 Y)
(Y . 88)
(X . 567)
(*FORM A 567 88))
Two small functions are defined. The last of them will
set R1 to (ALIST) and R2 to (ALIST T)
f) LISTS are represented as two pointer records with
CAR and CDR fields.
g) NUMBERS ARE IMPLEMENTED AS HIGH VALUED POINTERS.
The value of a small integer is the value of the pointer subtracted
by a proper offset. The value of a real number is stored in a full
word hidden from the user (but found through its pointer value).
ATOMS OF PREDESIGNED MEANING
Here is a list of those atoms which may be of interest for the LISP F4
user.
NIL,T These atoms can not be destroyed by any functions
such as RPLACA etc.
NOBIND is stored in car of undefined atoms.
LISPF4-STRING is stored in car of strings.
LISPF4-SUBSTR is stored in car of substrings.
LISPF4-ARRAY is stored in car of arrays.
ADVISEDFNS List of advised functions.
BROKENFNS List of broken functions.
CURFNS List of those functions which have been defined
before the first time (CURFILE file) was preformed.
CURFILE Name of the current file (used by the MAKEFILE
package).
FILELST List of files loaded so far. Updated by the function
CURFILE.
*PRINTLEVEL The printlevel used by TRACE.
I/O HANDLING
Though LISP F4 was designed to be as true a subset of INTERLISP as
possible, there do exist some minor differences. Most of then have
to do with I/O.
a) INPUT CHARACTERS OF SPECIAL MEANING.
. for dotted pairs. Must be separated by blanks!
A '.' which can not be interpreted as 'a dotted pair'
is read as an atom.
% escape character
' QUOTE character
" " string character
<> super brackets
All those characters works the same as in INTERLISP.
~ 'rescue character'. When this character is seen by
the read routine, LISP F4 will enter BREAK. (Useful
for infinite read loops for example).
b) CHANGING THE MEANING OF SPECIAL CHARACTERS.
The "meaning" of all characters are stored in a table which is
accessible by the function
(CHTAB x) Read the type of x
(CHTAB x n) Change the type of x.
Returns old type.
CHTAB uses the first character of the atom x.
The following character table is standard.
Type Means
1 space
2 (
3 )
4 <
5 >
6 "
7 '
8 user break
9 .
10 alphanumerical
11 +
12 -
13-22 0-9
23 %
24 rescue character
25 E exponent
26 # = square bracket
Ex.: If you want to have $ as a super bracket, and > as an ordinary
letter do:
(SETQ TYPE (CHTAB '%> (CHTAB 'A>
(CHTAB '$ TYPE)
and if you want to have * as a break character do
(CHTAB '* 8)
after which A*B will be read as the three atoms A * B separately.
c) CHANGING LOGICAL UNITS ETC.
All I/O functions refer to a table with the following meaning:
No Means
1 FORTRAN logical input no
2 current read position
3 left margin - input
4 right margin - input
5 FORTRAN logical output no
6 current print position
7 left margin - output
8 right margin - output
9 the print length
10 the print depth
The table us accessible by the function
(IOTAB i) read position i in the table
(IOTAB i val) put val in position i. Returns
old value.
If val is T and i is 1 or 5, the default value (= standard Input/Output)
is put in position i.
A number of basic functions coded in LISP such as READPOS, INUNIT etc.
are defined by using IOTAB, so in practice you rarely use IOTAB
yourself.
d) CHANGING STANDARD BEHAVIOR OF LISP F4.
The function
(SYSFLAG i) Read flag i.
(SYSFLAG i x) Change flag i to x (=T or NIL).
Returns old value.
is used to read/write flags with the following meaning:
Flag no T (which is default) means:
1 GBC message
2 output is pretty printed
3 (QUOTE s) printed as 's
4 convert atoms to capital letters (machine dep.)
5 Add % and " when so needed for a
correct read back.
6 unused
7 Print sublists on separate lines, unless
it is the first (or sometimes second) sub-
expression.
NIL means: during pretty print, do not begin
a new line if the current expression will
fit on line.
e) BASIC I/O FUNCTIONS.
The following functions work as in INTERLISP except that they do not
have a file argument.
(READ) (RATOM) (READC)
(PRINT x) (PRIN1 x) (PRIN2 x) (TERPRI)
(EJECT) (SPACES n)
In addition the following functions are defined using IOTAB. If
n is NIL they return the current value, otherwise a new value n is set
and the old value is returned.
(INUNIT n) logical input no
(OUTUNIT n) logical output no
(PRINTLEVEL n) the max depth of printing. (Lists below
this level will be printed as ...)
(PRINTLENGTH n) the max length of printing. (Elements
beyond this length will be indicated as ---)
As a matter of fact, PRINT, PRIN1 and PRIN2 are also defined in
LISP using the one and only printing function PRIN0 which is defined
as:
(PRIN0 x a b)
x value to be printed (No TERPRI before or after!)
a =NIL Do not print % or "
=T Print % or " when so necessary to read
atoms back
=T pretty print with flag no 7 = NIL
=n (a number) - " - = T
During pretty-print, lists headed by an atom carrying the function
definition (FSUBR . QUOTE) will be treated as comments: They will
be printed starting from 20 pos. to the left of the right margin.
Ex.: By doing (PUTD '* (GETD 'QUOTE)) * behaves as QUOTE and
expressions like (* comment comment ...) will be printed as comments.
In addition two functions are defined:
(PRINTL s1 s2 ..)
preforms PRIN1 on s1 s2 etc.
(PRINTL-SP s1 s2 ..)
works as PRINTL but separates s1 s2 etc. by spaces.
The function
(PROMPTTEXT string)
allows you to specify a prompt text to be printed when reading from the
terminal.
A new function REWIND is defined:
(REWIND n) Rewinds the logical unit n.
Rewind should be logically the same as closing the file.
f) SAVE/RESTORE OF THE CORE IMAGE.
The functions
(ROLLOUT lu)
(ROLLIN lu)
saves/restores a compact core image of the status of LISP F4. This
read them back at a later stage. (an other way of saving is to use
MAKEFILE)
It is possible to perform ROLLIN also if the size of LISP F4 has been
changed since the last ROLLOUT. If though the new version is too
small to hold the saved core image ROLLIN returns NIL (= failure to
rollin)
g) THE MAKEFILE PACKAGE.
This package is coded in LISP and follows the conventions for
INTERLISP makefile. The only commands in FILEVARS which are
implemented are:
* (P ...) (PROP ...) (E ...) (IFPROP ...)
The MAKEFILE package is designed to work in a similar way both if your
Fortran dialect allows for symbolic file names and for only logical unit
numbers.
If you use symbolic file names, MAKEFILE and LOAD will behave as in Interlisp.
If you need to use logical unit numbers, MAKEFILE and LOAD will prompt you
for the logical unit number of the file corresponding to the symbolic name
given to MAKEFILE/LOAD. You may also provide this association with the function
(OPEN file io no)
file your symbolic name
io I or INPUT for input files
O or OUTPUT for output files
other for input/output files
no FORTRAN logical unit
and if you have no further use of the file you may remove its logical
unit number by
(CLOSE file)
For systems allowing references to physical file names MAKEFILE, LOAD,
ROLLIN, and ROLLOUT use the SUBR
(OPEN0 file input mode)
which opens a sequential file named 'file'. If the flag 'input' is T the
file is opened for input, otherwise for output. 'mode' is T if the file
is a ROLLIN/ROLLOUT file, and NIL otherwise. OPEN0 opens the
file and returns a logical unit number which can be used by INUNIT, and
OUTUNIT, ROLLIN, or ROLLOUT.
The function
(CURFILE file)
declares that new function definitions shall
belong to this file and will be added to the list fileFNS.
The global variable CURFILE contains the name of the current file.
Ex.: Define some functions and save them as your file MYFILE on the
logical unit 25.
(OPEN 'MYFILE 'O 25) (this line not needed when your system
uses symbolic file names, or if you let
MAKEFILE prompt you for logical unit
number of MYFILE)
(CURFILE MYFILE)
(DE ....>
(DE ....>
etc.
(MAKEFILE 'MYFILE T)
A pretty printed version of all functions is now written on unit 25
(argument no 2 is used as PRIN0's argument no 3 when it performs the
printout).
ERROR HANDLING AND BREAK.
Mostly all errors detected by LISP F4 call the function SYSERROR
which is a SUBR and which calls RESET after printing a message.
SYSERROR is then redefined in one of the standard LISP packages as
a LAMBDA function which calls BREAK1 after the message.
BREAK1 is the ordinary "break-function" and may therefore also have been
called by a user setup break, and inside BREAK1 the following
commands exist:
! return to previous break if any. Otherwise reset.
GO print "broken form" and continue.
OK continue
RETURN x return the value of x.
EVAL eval broken form and break afterwards.
The value of the form is stored in the atom !VALUE
!EVAL as EVAL etc, but the function
!GO is first unbroken
!OK then rebroken
UB unbreaks the function.
BR breaks the function.
BT backtrace of function calls
BTV backtrace of function calls and variable bindings
(BTV*) (a function call!). Total backtrace of everything on
the parameter stack.
?= prints the arguments of the broken function
any other input is evaluated and value is printed.
In addition to BREAK1, the functions BREAK0 BREAK UNBREAK REBREAK and
TRACE are defined and work as in INTERLISP.
There also exists a function BREAK11, which is a LAMBDA version of
BREAK1 (which in turn is a NLAMBDA) and a function UNTRACE.
Each error is associated with a number. The function
(ERRORN)
returns the number for the last error occurred, and
(ERRORMESS n)
prints out a corresponding message.
Note that you may modify SYSERROR in order to introduce your own handling
of certain types of errors. For example, it is trivial to introduce run
time expanded macros by using SYSERROR. You then only have to modify SYSERROR
so that the macro is expanded and evaluated if you get 'undefined function'
((ERRORN)=2) and if the undefined function has a macro definition.
On most computers it is possible to associate an interrupt with some
special character so that an interrupt occurs whenever the user types that
character. In the implementation guide it is described how to implement
keyboard interrupts within Lispf4. If your implementation has keyboard
interrupt you will enter a BREAK whenever you type the interrupt character.
The interrupt feature is very useful for breaking indefinite looping.
It may also be used for interrupting printings of large S-expressions.
The interrupt characters are normally
DEC20: CTRL-H
VAX11: CTRL-C
IBM/370: BREAK
Check with your Lispf4 implementor for the interrupt character on your
Lispf4 implementation!
EDIT
Two edit functions are implemented:
(EDITF fn . edcom) edit a function. Value = NIL.
(EDITS s edcom) edit any s-expr. Value = s
edcom = list of edit commands
(or NIL).
The following commands are implemented.
P Print to level 2
PP PrettyPrint to level 2
? Print to level 100
?? PrettyPrint to level 100
Note: In INTERLISP the print commands are not exactly as ours.
OK Leaves the editor
UP Sets the c(urrent)expr, so that car of
new cexpr is equal to the old cexpr.
F expr searches the first occurrence of expr
in the cexpr regardless of level
NX next expression
! sets cexpr to top level expression
S x set x to cepr. Useful in combination
with US.
n An integer, if positive set cexpr to the
n:th element of cexpr, if negative to the
n:th element from the end, and if n=0
cexpr := superexpression which contains cexpr.
(n) n >= 1 deletes the n:th expression of cexpr
(n e1 ...) n >= 1 replaces the n:th expression by e1 ...
(-n e1 ...) n >= 1 inserts e1 ... before the n:th element.
(N e1 ...) adds e1 ... to the end of cexpr
(R x y) All occurrences off x are replaced by y.
(BI n m) Both In. Aleft parenthesis is inserted before
the n:th element and a right parenthesis is
inserted after the m:th element.
(BO n) Both Out. Removes both parenthesis from the
n:th element.
(LI n) Left In. Inserts a left parenthesis before the
n:th element and a corresponding right at the
end
(LO n) Left Out. Removes the left parenthesis from
the n:th element. All elements after the
n:th element are deleted.
(RI n m) Right In. Inserts a right parenthesis after
rest of the n:th element is brought up to the
level of the current expression.
(RO n) Right Out. Removes the right parenthesis from
the n:th element, moving it to the end of the
current expression. All elements following
the n:th element are moved inside the n:th
element.
(: e1 ...) Replaces current expression by e1 ...
(MBD e1 ...) Ex.: We have (PRINT X) and we want
(COND ((NULL L) (PRINT X) NIL)
(T (PRINT X) (GO LOP)))
we do
(MBD (COND ((NULL L) * NIL)
(T * (GO LOP))))
(XTR e1 ...) Ex.: We have (COND ((NULL L) NIL)
(T (PRINT L))
and we want (PRINT L)
we do
(XTR 3 2), (XTR (PRINT L)) or
(XTR PRINT)
(MARK x) Save the current chain in x.
S and US can be used in different edit sessions.
Ex.: Move the PROG expression of FOO to be the PROG expression of
another function FII.
(EDITF FOO)
F PROG S DEF OK
(EDITF FII)
(US DEF (3 DEF)) OK
The 3:rd element (the prog expression of FII) is replaced by the one
stored in DEF.
MISCELLANEOUS
A new function GO* is defined as a FSUBR.
(GO* LAB)
searches through all current PROG's for a label LAB. If it is found
a jump is performed. If it is not, NIL is returned and no other action
takes place.
GO* is a way of implementing ERRORSET, ERRORBANG, TRYTOEVALUATE, FAIL,
etc.
Ex.:
ERRORSET is defined as:
(DE ERRORSET (ERRORFORM ERRFLG)
(PROG NIL
(RETURN (LIST (EVAL ERRORFORM)))
ERRORSET>
and SYSERROR is defined as:
(DE SYSERROR (ERRORTYPE FN ARG FORM)
- print message if ERRORFLG = T -
(GO* ERRORSET)
(BREAK11 FORM T NIL>
When SYSERROR is called it tries to jump to the laber ERRORSET. If it
succeeds (error occurred under errorset) a "big jump" to ERRORSET is
performed and the function ERRORSET returns NIL. Otherwise BREAK11 is
called.
String functions:
In addition to those explained in Ha 75 (page 108) three new string
functions are defined:
(STRALLOC n c)
The first character of the literal atom (or /sub/string) c is fetched,
and a new string of length n is allocated, and filled with the character
from c.
Other functions not reported in Ha 75 are:
(ABS n)
(ADDLIST a l) if memb(a,l) then l else cons(a,l)
(SORT l) Destructive sorting function
(EVLIS l) mapcar(l,'EVAL)
(GCGAG flg) Print message when GBC (if flg = T)
(NTH l n) Performs CDR n-1 times on l
(RPT n s) evaluate s n times
(RPTQ n s) as RPT but s is not evaluated at calling
time.
(SIGN n) 0 or 1 or -1 depending on the sign of n
(CLOCK) time in milliseconds.
(TIME) time of the day