Хрупкая красота
Jun. 4th, 2021 04:44 pmРешил я посмотреть, как выглядит Паскаль-компилятор в отформатированном с помощью pretty-принтера виде.
Нашлась такая и для Паскаля-автокода в системе "Пульт". Она почему-то называется "ЛЕС".
Вроде, всё прекрасно (при выдаче на АЦПУ по команде "ПА" перед "ЛЕС" все символы будут выдаваться правильно и без "ИДТИ?"), но вдруг
Никаких ошибок в исходной строке 21
letter = 'a'..'z';
нет, настоящим компилятором всё компилируется. В чём же дело? Пришлось на скорую руку декомпилировать и её, чтобы разобраться.
В конце концов мне удалось понять, в чём дело - она не любит пробелы вокруг знака равенства в объявлении типов; и облагороженная сама собой, она выглядит так:
Всё очень красиво, даже с небольшими отступами для вложенных подпрограмм, но в то же время довольно компактно: последовательности операторов присваивания подверстываются в строку, пробелы в выражениях ликвидируются, и т.п.
Никаких опций не предусмотрено, сокращённая запись _( и _) для _begin и _end разворачивается в представление в виде слов безусловно. Впрочем, это и неважно, раз
begin и end всегда оказываются на отдельной строке.
Почему-то все комментарии, бывшие в исходном тексте, пропали, хотя, судя по беглому просмотру текста, раз комментарии сохраняются
в буфер, то должны и выдаваться. Строчных комментариев, вводимых знаком %, программа не понимает.
По-видимому, если она когда и использовалась, то только для получения удобных для чтения (и подшивания к диссертациям) распечаток, поскольку редактировать файл с таким отступами было бы очень неэффективно.
Небольшое замечание: Диалоговый интерфейс у программы очень молчаливый, хотя свободного места в последней зоне ещё хватало - примерно ползоны (3 Кб). Какие-либо приветствия отсутствуют; вместо того, чтобы на непонятную строку рассказывать, какой ожидается формат указания расположения входного и выходного файлов, программа говорит НЕ БУДУ; а после 5 неудачных попыток ДЛЯ ВЫХОДА СДЕЛАЙТЕ "ЕТХ". Вот когда надо было придумать мем "капитан Очевидность".
Нашлась такая и для Паскаля-автокода в системе "Пульт". Она почему-то называется "ЛЕС".
СИСТЕМА ПУЛЬТ 04.06.81 ЛЕС ==> 500101 30 0001 (*=М-,С-*) 0002 ._РRОGRАМ СОМРIL ., 0003 ._LАВЕL 27721., 0004 ._СОNSТ 0005 SРАСЕS = ’ ’., 0006 SР = ’ ’., 0007 АSG = ’.==200’., 0008 С4096 = 4096., 0009 Т = ТRUЕ., 0010 F = FАLSЕ., 0011 О = ’0’., 0012 ВRАNСН = ’ВRАNСН’., 0013 ВАСК = ’ВАСК’., ИДТИ?
Вроде, всё прекрасно (при выдаче на АЦПУ по команде "ПА" перед "ЛЕС" все символы будут выдаваться правильно и без "ИДТИ?"), но вдруг
0097 ._ТУРЕ
0098 ВIТSЕТ = ._SЕТ ._ОF 0 .. 47.,
ОШИБКА=203 СИМ= СТР= 21
КОНТЕКСТ=
ТТЕR = ’А’..’Z’.,
INТ=INТЕGЕR.,ВООL=ВО
Никаких ошибок в исходной строке 21
letter = 'a'..'z';
нет, настоящим компилятором всё компилируется. В чём же дело? Пришлось на скорую руку декомпилировать и её, чтобы разобраться.
В конце концов мне удалось понять, в чём дело - она не любит пробелы вокруг знака равенства в объявлении типов; и облагороженная сама собой, она выглядит так:
0001 _PROGRAM PRETTY ; 0002 _LABEL 4661, 4704, 4731; 0003 _CONST 0004 F = FALSE; 0005 T = TRUE; 0006 DRUM = 270000B; 0007 NZONES = 16; 0008 SP = ’ ’; 0009 SPACES = ’ ’; 0010 LF = ’≡175’; 0011 COLON = ’:’; 0012 COMMA = ’,’; 0013 QU = ’’’’; 0014 OPAREN = ’(’; 0015 CPAREN = ’)’; 0016 STAR = ’*’; 0017 BEGIN = ’BEGIN ’; 0018 END = ’END ’; ... 0057 _TYPE 0058 INT = INTEGER; 0059 BOOL = BOOLEAN; 0060 LETTER = ’A’ .. ’Z’; 0061 DIGIT = ’0’ .. ’9’; 0062 UNALFA = _ARRAY [ 1 .. 6 ] _OF CHAR; 0063 MODE = ( M0, M1, M2, M3, M4 ); 0064 INTARR = _ARRAY [ 1 .. 1022 ] _OF INT; 0065 CHARAR = _ARRAY [ 1 .. 11024 ] _OF CHAR; 0066 STRING = 0067 _RECORD 0068 S : _ARRAY [ 1 .. 30 ] _OF CHAR; 0069 L : INT 0070 _END ; 0071 _VAR 0072 POS, INDENT, LINENUM, LEN : INT; 0073 G14Z, SAVPOS, IDX, G17Z, INDINCR : INT; 0074 OUTNUM, G20Z, G21Z : INT; 0075 TOFILE : BOOL; 0076 TOK, G24Z : ALFA; 0077 G25Z : BOOL; 0078 G26Z, G27Z, G28Z, G29Z, G30Z, G31Z, G32Z : BOOL; 0079 G33Z : BOOL; ... 0088 0089 (* +++++++++ 2 +++++++++ *) 0090 0091 _PROCEDURE ENDLN; 0092 _VAR 0093 L2V1Z, L2V2Z, L2V3Z : INTEGER; 0094 _BEGIN 0095 _IF TOFILE 0096 _THEN WRITE(LF) 0097 _ELSE 0098 _BEGIN 0099 WRITELN; L2V3Z := OUTNUM; L2V2Z := 1000; L2V1Z := 1; 0100 _WHILE L2V1Z ≤ 4 _DO 0101 _BEGIN 0102 WRITE(L2V3Z _DIV L2V2Z: 0); L2V3Z := L2V3Z _MOD L2V2Z; L2V2Z := L2V2Z _DIV 10; 0103 L2V1Z := L2V1Z+1; 0104 _END ; (* WHILE *) 0105 OUTNUM := OUTNUM+1; WRITE(SP); 0106 _END ; (* IF *) 0107 POS := 0; 0108 _END ; (* END ENDLN *) 0109 ... 0157 (* +++++++++ 2 +++++++++ *) 0158 0159 _PROCEDURE P0535; 0160 _LABEL 572, 707; 0161 _VAR 0162 L2V1Z, L2V2Z, L2V3Z, L2V4Z, L2V5Z, L2V6Z, L2V7Z : INT; 0163 L2V8Z : 0164 _RECORD 0165 C : _ARRAY [ 1 .. 9 ] _OF CHAR 0166 _END ; 0167 L2V17Z : CHAR; 0168 _BEGIN 0169 _IF ¬(IDX ≠ 0) 0170 _THEN EXIT; 0171 L2V4Z := (G17Z+1); L2V5Z := G20Z; IDX := (IDX-1); L2V8Z := [’;’, 81, 80, ’*’, ’/’, ’+’, ’-’, ’,’, 15]; 0172 _IF G31Z∨G32Z 0173 _THEN L2V8Z := [, ’,’, ’:’, ’=’, ’)’, ’(’, ’+’, ’-’]; 0174 572: WRITE(SP: G17Z); 0175 _IF (IDX < L2V5Z) 0176 _THEN 0177 _BEGIN 0178 L2V1Z := L2V4Z; 0179 _WHILE (L2V1Z ≤ IDX) _DO 0180 _BEGIN 0181 WRITE(BUF[L2V1Z]); L2V1Z := (L2V1Z+1) 0182 _END ; (* WHILE *) 0183 ENDLN; INDINCR := 0; IDX := ; G32Z := ; G31Z := ; G127Z := ; EXIT 0184 _END 0185 _ELSE 0186 _BEGIN 0187 L2V5Z := (L2V5Z-1); 0188 ( L0615 ) 0189 _BEGIN 0190 L2V1Z := 1; 0191 _WHILE (L2V1Z ≤ 9) _DO 0192 _BEGIN 0193 ( Q ); L2V17Z := L2V8Z.C[L2V1Z]; L2V2Z := L2V5Z; 0194 _WHILE (L2V2Z ≥ L2V4Z) _DO 0195 _BEGIN 0196 _IF (BUF[L2V2Z] = L2V17Z) 0197 _THEN 0198 _BEGIN 0199 _IF (G127Z ≠ 0) 0200 _THEN 0201 _BEGIN 0202 L2V6Z := 1; 0203 _WHILE (L2V6Z ≤ G127Z) _DO 0204 _BEGIN 0205 _IF (G127A[(L2V6Z*2)] > L2V2Z)∧ 0206 (G127A[((L2V6Z*2)-1)] < L2V2Z)∧(L2V1Z ≠ 9) 0207 _THEN _GOTO 707; 0208 L2V6Z := (L2V6Z+1); 0209 _END (* WHILE *) 0210 _END ; (* IF *) 0211 L2V3Z := L2V4Z; 0212 _WHILE L2V3Z ≤ L2V2Z _DO 0213 _BEGIN 0214 WRITE(BUF[L2V3Z]); L2V3Z := (L2V3Z+1) 0215 _END ; (* WHILE *) 0216 ENDLN; G17Z := G17Z+INDINCR; INDINCR := 0; L2V4Z := L2V2Z+1; 0217 L2V5Z := L2V4Z+G20Z-G17Z; 0218 _IF BUF[L2V4Z] = SP 0219 _THEN 0220 _BEGIN 0221 L2V4Z := L2V4Z+1; L2V5Z := L2V5Z+1 0222 _END ; (* IF *) 0223 _IF L2V4Z ≥ IDX 0224 _THEN 0225 _BEGIN 0226 INDINCR := 0; IDX := ; G32Z := ; G31Z := ; G127Z := ; EXIT 0227 _END ; (* IF *) 0228 _GOTO 572; 0229 _END ; (* IF *) 0230 L2V2Z := L2V2Z-1; 0231 _END ; (* WHILE *) 0232 707: L2V1Z := L2V1Z+1; 0233 _END ; (* WHILE *) 0234 _IF G127Z ≠ 0 0235 _THEN 0236 _BEGIN 0237 G127Z := 0; _GOTO L0615 0238 _END (* IF *) 0239 _END ; 0240 ERROR(999); 0241 _END (* IF *) 0242 _END ; (* END P0535 *) ... 0748 _PROCEDURE L2005; 0749 _LABEL 2007; 0750 _BEGIN 0751 2007: 0752 _SELECT 0753 (INPUT↑ = ’:’)∧G29Z : EXIT; 0754 (INPUT↑ = ’_’)∧¬G29Z : EXIT; 0755 (INPUT↑ = ’_’) : 0756 _BEGIN 0757 GETKEYWORD; L1756 0758 _END ; 0759 T : L1640 0760 _END ; (* SELECT *) 0761 _GOTO 2007 0762 _END ; (* END L2005 *) ... 1746 (* +++++++++ 2 +++++++++ *) 1747 1748 _PROCEDURE P4610; 1749 _LABEL 4624; 1750 _VAR 1751 L2V1Z, L2V2Z : INTEGER; 1752 1753 (* +++++++++ 3 +++++++++ *) 1754 1755 _FUNCTION F4515 : INT; 1756 _VAR 1757 L3V1Z : INT; 1758 _BEGIN 1759 L3V1Z := 0; 1760 _WHILE (INPUT↑ < ’9’) _DO 1761 _BEGIN 1762 L3V1Z := ((L3V1Z*8)+ORD(INPUT↑)); GET(INPUT) 1763 _END ; (* WHILE *) ... 1818 1819 (* HAЧAЛO ПPOГPAMMЫ PRETTY *) 1820 1821 _BEGIN 1822 G14Z := 0; 1823 4661: REWRITE(OUTPUT); INDENT := 0; IDX := ; POS := ; SAVPOS := ; INDINCR := ; G24Z := SPACES; G30Z := F; 1824 OUTNUM := 1; G25Z := F; G27Z := F; G29Z := ; LINENUM := 1; G127Z := 0; G12174Z := ; CBFSIZE := ; G33Z := ; 1825 G21Z := 0; G32Z := F; G31Z := F; P4610; ENDLN; 1826 4704: CHKCOMMENT; 1827 _IF INPUT↑ = OPAREN 1828 _THEN _GOTO 4704; 1829 _IF INPUT↑ ≠ ’_’ 1830 _THEN ERROR(1); 1831 GETKEYWORD; 1832 _IF TOK ≠ ’PROGRA’ 1833 _THEN ERROR(2); ... 1869 _END .
Всё очень красиво, даже с небольшими отступами для вложенных подпрограмм, но в то же время довольно компактно: последовательности операторов присваивания подверстываются в строку, пробелы в выражениях ликвидируются, и т.п.
Никаких опций не предусмотрено, сокращённая запись _( и _) для _begin и _end разворачивается в представление в виде слов безусловно. Впрочем, это и неважно, раз
begin и end всегда оказываются на отдельной строке.
Почему-то все комментарии, бывшие в исходном тексте, пропали, хотя, судя по беглому просмотру текста, раз комментарии сохраняются
в буфер, то должны и выдаваться. Строчных комментариев, вводимых знаком %, программа не понимает.
По-видимому, если она когда и использовалась, то только для получения удобных для чтения (и подшивания к диссертациям) распечаток, поскольку редактировать файл с таким отступами было бы очень неэффективно.
Небольшое замечание: Диалоговый интерфейс у программы очень молчаливый, хотя свободного места в последней зоне ещё хватало - примерно ползоны (3 Кб). Какие-либо приветствия отсутствуют; вместо того, чтобы на непонятную строку рассказывать, какой ожидается формат указания расположения входного и выходного файлов, программа говорит НЕ БУДУ; а после 5 неудачных попыток ДЛЯ ВЫХОДА СДЕЛАЙТЕ "ЕТХ". Вот когда надо было придумать мем "капитан Очевидность".