Q-32编译器LISP列表及示例解析
1. Q-32编译器概述
Q-32编译器是一个完整的程序集,可在IBM 7090上运行,用于生成Q-32 LISP的编译部分。该列表包含编译器本身,它能在7090上进行自编译,编译后的代码可在Q-32上运行。此外,还包含两个版本的LAP,一个在7090上运行以生成Q-32代码,另一个作为编译后的代码在Q-32上运行,以及一些其他的杂项函数。运行该编译器不仅能完成函数编译,还能为Q-32生成所有的永久列表结构。
编译后的代码使用了用SCAMP(Q-32汇编语言)编写的以下例程:
| 例程名称 | 说明 |
| ---- | ---- |
| CONS和垃圾回收器 | 用于内存管理和数据结构创建 |
| ERROR | 错误处理 |
| PRIN1、TERPRI和PRINOCT | 输出相关操作 |
|
RATOM和TEREAD | 输入相关操作 |
| GENSYM | 生成唯一符号 |
|
MKNO | 创建编号 |
|
CALL和
RETRN | 函数调用和返回 |
需要注意的是,编译器列表中存在一些已知错误,例如:
- 在ATTACH中,第二行应改为:
((AND (EQ (CAAR A) (QUOTE LDA)) LISTING (EQ (CAAR LISTING) (QUOTE STA))
- 在PASS2中,部分第二行应改为:
(SETQ LEN 2)
- 在第二个LAP列表中,从EP开始的部分应改为:
EP (COND ((NOT P2) (GO El)) (EI 1W R)) ((NULL (CAR L))
(GO E2)) ((ATOM (CAR L)) (GO R)) )
(CSET (CAAR L) TRW)
E2 (SETQ BPORG LOC)
R (RETURN ST)
2. 输入与输出相关
输入部分是共享分布式版本的LISP 1.5的输入,包含LAP八进制数,用于使垃圾回收器安静并访问打孔设施。输出包括编译代码的汇编列表,以及打孔输出磁带(B7)上的八进制代码偏差。打孔磁带会通过SCAMP编码的基本函数的一部分加载到Q-32中。
以下是一些相关的代码示例:
TAPE
SYSPPT 1 9 7
SFTSFT
OPDEFINE ( (PRI.2
5 1 3 5 0 ) ITERPUN 5 4 4 5 0 ) (MKNO 1 2 6 7 0 0 ) (PUNACT 5 5 0 5 0 )
) )
LAP ( 1 4 1 7 0 ( STZ 1 6 0 4 0 1 ( STZ 2 6 0 4 0 ) ( TQA 3 4 ) )
NIL )
3. 部分关键函数解析
- LAPEVAL函数 :用于评估LAP表达式。它根据输入的不同情况进行不同的处理,例如当输入为空时返回BPORG,当输入为原子时进行相应的跳转处理等。
LAPEVAL (LAMBDA ( X ) ( P 9 0 G ( S J K )
(COND ( ( NULL X ) (RETURN B P O R G I I ( ( ATOM X I ( GO L I ) )
( ( EQ (CAR X I (QUOTE E l ) (RETURN (MKOB ( CONS (QUOTE SPECIAL)
( CADP X ) ) ) ) )
( ( EQUAL X (QUOTE (QUOTE NIL ) ) ) (RETURN 7 7 7 6 0 0 Q ) )
( ( EO (CAR X i (QUOTE QUOTE) ) (GO 3 ) )
( ( F a ( CPP X ) (QUOTE SPFCIAL) ) 1 5 0 A ) ) )
( SET 0 S '3)
( SETQ J X )
L
(COND ( ( NULL J ) ( 9ETURN S I ) )
( SETQ S ( PLUS 5 ( LAPEVAL (CAR J ) ) ) )
( SETQ J (CDR Ji)
(GO L )
L 1 (COND ((NUMSERP X ) (RETURN X I ) ( ( EQ X DOLLAR) (RETURN LOC) )
1
( SET 0 K ST)
L 2 (COND ( ( NULL K ) ( GO L 3 ) ) ( ( EQ (CAAR K ) X ) (RETURN (CDAR K I ) ) 1
( SETQ K (CDR K i )
(GO L 2 )
L 3 ( SET 0 K INISYM)
L 5 (COND ( ( NULL K i (GO L 6 ) ) ( ( FQ (CAAR K ) X ) (RETURN (CDAR K I ) )
( SETQ K
(CDR K ) l
(GO L 5 )
L 6 (COND ( ( GET X (QUOTE TWORDII
(RETURN (LOGAND ( GET X
(QUOTE TWORD)) 7 7 7 7 7 7 0 ) ) ) 1
L 4 ( PRINT ( LIST X (QUOTE BSSUNDEFINED -- L A P S ) 1 )
( 4ETU 9 N ')
A
( SET 0 IV 2 (LOGOR IV 2 2 0 0 6 ) )
B
(RETURN (MKOB (CONS (CAR X I (CADR X ) ) ) )
1 ) )
- LAP函数 :用于处理LAP列表,根据不同的条件进行地址计算和输出处理。
LAP (LAMBDA ( L ST ) (PROG ( LIS 1 ORG LOC IV 1 IV 2 P Z )
(MKOB (CONS (QUOTE SPECIAL) (CAAR L ) ) )
( SETQ ORG BPORG)
( BLANKS 3 0 )
( PRINT (CAR L I )
NP ( SETQ LOC UPOQC )
( SETQ LIS (CDR L I )
B
(COND ( ( NULL LIS ) (GO E P ) )
( SETQ 1 ( CAR LIS ) )
(COND ( P Z (GO 1 2 ) ) ( ( ATOM 1 ) (GO E S ) )
NW
( SETQ LOC ( ADDI LOCI )
KW
( SETQ LIS (CDR LIS ) )
(GO B i
1 2 (COND ( ( ATOM 1 ) (GO P S ) ) )
( SETQ IV 2 0 )
( SETQ IV 1 ( LAPEVAL (CAR 1 ) ) )
(COND ( ( NULL (CDR I I ) (GO I W ) ) )
( VETQ IV 2 (LOGOR ( J ÜST ( LAPEVAL (CAC!? 1 ) ) ) IV 2 ) )
(COND ( ( NULL (CDDR 1 ) ) (GO I W ) ) )
( SETQ IV 2 (LOGOR IV 2 ( LEFTSHIFT ( LAPEV 4 L (CADDR 1 ) ) 1 8 ) ) )
(COND ( ( NULL (CDDDR 1 ) ) (GO I W ) ) )
( SETQ IV 1 (LOGOR IV 1 ( J UST ( LAPEVAL (CAODDR 1 ) ) ) )
I W (PUNWORD IV 1 IV 2 LOCI
( BLANKS 1 0 )
( PRINT 1 )
( GO NW)
E S ( SETQ ST (CONS (CONS 1 LOC ) ST ) )
( GO Kbl)
P S ( RLANKS 2 6 )
( PRINT 1 )
( GO KW)
E P (COND ( ( NOT P 2 ) (GO E l ) )
( TERPRI ) ( TESPRI )
( RPLACD (CAAR L i (CONS (QUOTE TWORD)
(CONS
(LOGOR ORG ( LEFTSHIFT (CADDAR L ) 1 8 )
( LEFTSHIFT (CADR (CDDAR L i ) 2 4 )
)
(CDAAR L ) ) ) )
( CSETQ BPORG LOC )
( RETURN ST )
E l ISETQ P 2 T )
(GO N P )
1 ) )
4. 整体流程
graph TD;
A[输入到共享分布式LISP 1.5] --> B[运行编译器];
B --> C[生成编译代码];
C --> D[输出汇编列表和打孔磁带];
D --> E[打孔磁带加载到Q-32];
通过以上的介绍,我们对Q-32编译器的相关内容有了一个较为全面的了解,包括其功能、输入输出、关键函数以及整体的处理流程。在实际使用中,需要注意编译器列表中的已知错误,并根据具体需求对代码进行调整和优化。
5. 编译相关函数与特殊处理
- COM2函数 :用于将函数编译为特定的子例程。它根据输入的函数和参数,结合长度信息,进行相应的编译处理。
COM2 (LAMBDA ( TYPE YAQGS EXP NAME)
IPROG ( LISTING LEN )
( SETQ LISTING ( PASSZ ( PASSI NAME EXP ) NAME ) )
( LAP ICONS ( LIST NAME TYPE NARGS LEN )
(CAR LISTING) ) (CADR LISTING) )
(RETURN NAME)
)
-
SPECIAL和UNSPECIAL
:用于处理特殊符号。
SPECIAL函数将符号标记为特殊符号,而UNSPECIAL函数则移除符号的特殊标记。
SPECIAL (LAMBDA ( X ) ( MAPLIST X
( FUNCTION (LAMBDA ( JI
( DEFLIST ( LIST ( LIST (CAR J)
( LIST NIL ) ) ) (QUOTE SPECIAL) ) ) I ) ) )
UNSPECIAL (LAMBDA ( L ) (MAP L ( FUNCTION (LAMBDA ( J )
(REMPROP (CAR J) (QUOTE SPECIAL) ) 1 ) ) 1 )
6. 更多辅助函数解析
- BLANKS函数 :用于输出指定数量的空格。它通过递归的方式,每次输出一个空格并减少计数,直到计数为0。
BLANKS (LAMBDA ( A ) (PROG NIL
L
( COND ( ( ZEROP A ) ( RETURN NIL ) ) )
( PRIN 1 RLANK )
( SETQ A
( SU 0 1 A i ) ( GO L ) 1 ) )
-
APPEND函数
:用于将两个列表连接起来。如果第一个列表为空,则返回第二个列表;否则,将第一个列表的头部与
APPEND处理后的剩余部分和第二个列表的结果连接起来。
APPEND (LAMBDA ( X Y ) (COND ( ( NULL X ) Y )
( T (CONS (CAR X ) (APPEND (CDR X ) Y ) ) ) ) )
7. 错误处理与输入输出操作
- ERROR函数 :用于处理错误情况。当遇到不符合预期的输入或操作时,会输出相应的错误信息。
ERROR 4 0 1 0 4 0 0 0 3 0
- PRIN1、TERPRI和PRINOCT函数 :分别用于输出单个对象、换行和输出八进制数。
PRIN1 4 0 1 0 4 0 0 0 4 0
TERPRI 2 0 0 0 4 0 0 0 5 0
PRINOCT 6 0 2 0 4 0 0 1 4 0
8. 综合应用示例
以下是一个简单的综合应用示例,展示了如何使用上述部分函数进行操作:
(DEFUN example ()
(let ((result (LAPEVAL '(E 123))))
(PRIN1 result)
(TERPRI)
(let ((new-list (APPEND '(1 2 3) '(4 5 6))))
(PRIN1 new-list)
(TERPRI))))
在这个示例中,首先使用
LAPEVAL
函数评估一个表达式,然后输出结果。接着,使用
APPEND
函数将两个列表连接起来,并输出连接后的列表。
9. 总结与注意事项
通过对Q - 32编译器相关内容的详细解析,我们了解到它包含了丰富的函数和处理机制,用于实现代码的编译、特殊符号处理、输入输出等功能。在实际使用过程中,需要注意以下几点:
- 编译器列表中存在已知错误,使用前要进行相应的修正。
- 对于特殊符号的处理,要正确使用
SPECIAL
和
UNSPECIAL
函数,避免出现符号标记错误。
- 在编写和调用函数时,要注意函数的输入输出要求和参数类型,确保代码的正确性。
graph TD;
A[开始] --> B[输入表达式];
B --> C[调用LAPEVAL评估];
C --> D{评估结果是否有效};
D -- 是 --> E[输出结果];
D -- 否 --> F[调用ERROR处理];
E --> G[进行列表操作(如APPEND)];
G --> H[输出操作结果];
H --> I[结束];
F --> I;
综上所述,Q - 32编译器为开发者提供了一个强大的工具,通过合理使用其中的函数和机制,可以实现复杂的代码处理和功能开发。但在使用过程中,要仔细处理各种情况,确保程序的稳定性和正确性。
超级会员免费看
85

被折叠的 条评论
为什么被折叠?



