LINUX.ORG.RU

О божественном C и введение в него через ed

 , ,


4

2

Бытие (частично) определяет.

*Какая регулярка преобразует for с телом в while с телом ?

*Какой #define макрит for в while?

ps. походу операция ,(запятая) обусловлена(в том числе) автоматизацией преобразований - (опят же регулярки) вызова функции с набором аргументов в инлайн какой нить.

*Какой #define макрит for в while?

#include <stdio.h>
#include <stdlib.h>

#define FOR(a, b, c, ...) {a;while(b){__VA_ARGS__ c;}}

int main(void)
{
  for(int i = 0; i < 10; i++)
  {
    printf("test %d\n", i);
  }
  
  printf("\n");
  
  FOR(int i = 0, i < 10, i++,
  {
    printf("test %d\n", i);
  }   
  )
    
  return EXIT_SUCCESS;
}
SZT ★★★★★ ()
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от deep-purple

дык гипотетическое прозрение в том, что "прелести С а до этого B синтаксиса " от чуваков которые в разные LR и прочие грамматики - а средством ввода был телетайп - поэтому синтаксис Сишки очень g/re/p-френдли - для блочного полу и полностью автоматического транслированния. - т.е регулярка(с расшириностями подобна якству) могла и на асме ваяться. тем отцам не привыкать

qulinxao3 ()
Ответ на: комментарий от vodz

дефайн эт так «эстетство»

любо увидеть регулярку -(в худшем случае кусок С транслятора - делающее преобразование for->while цикл - в этом[худшем] - наиболее древний сырец из возможных)

qulinxao3 ()
Ответ на: комментарий от deep-purple

нет, но иначе оно работать и не могло - регулярками такую многословность синтаксиса не распарсить.

AST это всего-лишь опциональное промежуточное представление. Написать транслятор, особенно первых версий С, можно и без него.

Serral ()

*Какая регулярка преобразует for с телом в while с телом ?

есть в районе Plan9 публикация про структурные регекспы. они могут. алсо, редактор sam был под это заточен.

anonymous ()
Ответ на: комментарий от deep-purple

распарсишь. смотря какие регулярки. вот правильные регулярки от Роба Пайка (без Кернигана).

внизу ссылка про sam и его командый язык. как vim, только команды структурные. есть дефолтный регион (.) с которым работают все команды.

anonymous ()

*Какой #define макрит for в while?

#define многоэтажный, вестимо. с \ для продолжения строк. типа RAII в Си и/или, макро with-open-file из лиспа.

вот тут и заметна вся кривизна сишечки в структуральнейше-лингвистическом смысле. блин, да ещё древний PL/I, из которого си спёр комментарии вида /* ... */ уже это умел!

препроцессор в PL/I уже умел

  1. запускать выполнение обычных функций, в том числе из стандартной библиотеки во время компиляции макроса

  2. результат компиляции макроса подставлять в компилятор.

уже этого было достаточно. например, вот здесь есть кроме обучалок по PL/I (и примеров GUI + XML под OS/2 на PL/I и на немецком) – пример реализации parse конструкции из REXX (реализованной как макрос на PL/I препроцессоре)

вот сравнение PL/I и Cи с точки зрения проектных решений. так вот, с этой точки зрения сишечка сосает присвистывая.

и всё это было ещё в оптимистичных 60х! а потом словно какая-то разруха, деградация и mass total упрощение началось: Multics в unics, PL/I в сишечку (ублюдочный потомок BCPL), нормальные идеи и реализацию исходников Multics: Emacs, Lisp и т.п. – в костыли и огрызки.

файловые сегменты из Multics всё ещё нигде толком не реализованы прилично. эта идея так и не дошла до авторов юникс, хотя виртуальную память с подкачкой страниц вполне стащили, ибо плохо лежала.

опять же, надо смотреть не только лишь ядро и тулчейн – а и софт на этом понаписанный. доступны эмуляторы мейнфрейма мультикс, софт оттуда – тоже в исходниках. и знаете что? емакс на PL/I выглядит понятнее жму емакса на сишке написанном. ибо эти высокоуровневые конструкции задействованы по уму.

и это ещё без DSL вроде макроса parse из REXX на пару экранов кода! просто как язык PL/I более высокоуровневый «няшной сишечки» (хотя тоже не так высок по сравнению с адой, например).

а дальше случается как в Масяне: «повсюду разруха, деградация, декаданс и зомби-апокалипсис… а мы тут пьём =)» – юникс это деградация по сравнению с мультикс, а си(да и С++ тоже) – по сравнению с PL/I из 60-х.

хотя есть осовремененная реализация PL/I-KT и вообще, pl1.su. поддерживает DirectX, DLL-ки и прочее. написано руками на ассемблере. так что можно вступать и компилировать (например, исторические сорцы Мультикс допортировать до не только лишь мейнфрейма и эмулятора – даёшь Multics x86-64 современный порт на голом железе !!!)

…это всё при том что там всё ещё заметно препроцессорное «строки подставляют текст в текст». но уже появляется «выражение в выражение».

в лиспе и структурных S-выражениях это ещё более заметно.

anonymous ()
Ответ на: комментарий от qulinxao3

конструкция parse из REXX на препроцессоре PL/I

 %noprint;

 /*      REXX parse Statement as PL/I macro         */
 /*                                                 */
 /* Commas separate items, * is the placeholder.    */
 /* Example:                                        */
 /* parse upper value (S) with (Name, '.', Ext, *); */

       /*--------------------------------------------------------*/
      /* Eberhard Sturm                   Tel: +49-251-83-31679 */
     /* Universitaetsrechenzentrum       Fax: +49-251-83-31555 */
    /* Einsteinstr. 60        Internet: sturm@uni-muenster.de */
   /* D-48149 Muenster                           "Team PL/I" */
  /* www.uni-muenster.de/URZ/Mitarbeiter/EberhardSturm.html */
 /*--------------------------------------------------------*/


примеры по книжке отсюда :

использующий пример:

*process pp (macro) insource;
 B69: /* Test of parse statement */
 procedure options (main);

 %declare parse entry;
 %include parse;
 dcl V char (20) var;
 dcl X char (8) var;
 dcl Y char (3) var;

 V = 'CONFIG.SYS';
 parse value (V) with (X '.' Y);
 put (X, Y);

 end B69;

реализация parse.cpy (на препроцессоре PL/I):

 %Parse: /* to example B69 */
  procedure (Value, With) statement;

  dcl (Value, With) char;
  dcl (A, B, C, Name) char;
  dcl K fixed;

  if ^parmset(Value) | ^parmset(With) then do;
     note ('Option missing in parse statement.', 12);
     return ('/*?*/');
     end;

  K = index(With, "'");
  A = substr(With, 1, K-1);
  B = substr(With, K, 3);
  C = substr(With, K+3);
  Name = '$' || counter();
  ans ('do;') skip noscan;
  ans (comment('parse value (' || Value || ') with ('
       || With || ');')) skip noscan;
  ans ('dcl ' || Name || ' fixed bin;') skip noscan;
  ans (Name || ' = index(' || Value || ', ' || B || ');')
      skip noscan;
  ans (A || ' = substr(' || Value || ', 1, ' || Name || '-1);')
      skip noscan;
  ans (C || ' = substr(' || Value || ', ' || Name || '+1);')
      skip noscan;
  ans ('end;') skip noscan;

 %end Parse;
anonymous ()
Ответ на: конструкция parse из REXX на препроцессоре PL/I от anonymous

конструкция parse из REXX на препроцессоре PL/I, весь исходник -- part 1

 %noprint;

 /*      REXX parse Statement as PL/I macro         */
 /*                                                 */
 /* Commas separate items, * is the placeholder.    */
 /* Example:                                        */
 /* parse upper value (S) with (Name, '.', Ext, *); */

       /*--------------------------------------------------------*/
      /* Eberhard Sturm                   Tel: +49-251-83-31679 */
     /* Universitaetsrechenzentrum       Fax: +49-251-83-31555 */
    /* Einsteinstr. 60        Internet: sturm@uni-muenster.de */
   /* D-48149 Muenster                           "Team PL/I" */
  /* www.uni-muenster.de/URZ/Mitarbeiter/EberhardSturm.html */
 /*--------------------------------------------------------*/

 declare
    $APOS1 bin fixed, /* position of start point for assignment */
    $APOS2 bin fixed, /* position behind end point for assignment */
    $MPOS  bin fixed, /* position of start point for next matching */
    $WPOS1 bin fixed, /* position of first char of word */
    $WPOS2 bin fixed, /* position behind the word */
    $XPOS  bin fixed; /* temporary storage */

 %declare Parse entry;

 %Comlen: /********************************* return length of comment */
  procedure (S, I) returns (fixed);

  declare
     I fixed,
     S char;
  declare
     K fixed;
  declare
     substr builtin;

  do K = I + 2 by 1;
     if substr (S, K, 2) = '*/' then return (K - I + 2);
     end;

 %end Comlen;

 %Strlen: /********************************** return length of string */
  procedure (S, I) returns (fixed);

  declare
     I fixed,
     S char;
  declare
     K fixed;
  declare
     (length, substr) builtin;

  do K = I + 1 to length (S) - 1;
     if substr (S, K, 1) = '''' then
        if substr (S, K + 1, 1) = ''''
           then
              K = K + 1;
           else
              goto Leave_loop;
     end;
  Leave_loop:;

  return (K - I + 1);

 %end Strlen;

 %Parlen: /**************** return length of parenthesized expression */
  procedure (S, I) returns (fixed);

  declare
     I fixed,
     S char;
  declare
     C char,
     K fixed,
     J fixed;
  declare
     substr builtin;

  K = 1;
  do J = I + 1 by 1;
     C = substr (S, J, 1);
     if C = '(' then K = K + 1;
     else if C = '''' then
        J = J + Strlen (S, J) - 1;
     else if C = ')' then
        if K = 1 then return (J - I + 1);
                 else K = K - 1;
     end;

 %end Parlen;

 %Itmlen: /******************* return length of blank-surrounded item */
  procedure (S, I) returns (fixed);

  declare
     I fixed,
     S char;
  declare
     C char,
     J fixed;
  declare
     (length, substr) builtin;

  do J = I to length (S);
     C = substr (S, J, 1);
     if C = ',' then goto Leave_loop;
     if C = '(' then
        J = J + Parlen (S, J) - 1;
     else if C = '''' then
        J = J + Strlen (S, J) - 1;
     end;
  Leave_loop:;

  return (J - I);

 %end Itmlen;

 %Line: /****************** for improved readability (simple version) */
  procedure (S) returns (char);

  declare
     S char;
  declare
     K fixed;
  declare
     (length, substr) builtin;

  do K = length (S) + 5 to 1 by -71; end;

  return ('/**/ ' || S || substr (                                     '

 ', 1, -K));

 %end Line;

anonymous ()

Re: конструкция parse из REXX на препроцессоре PL/I, весь исходник -- part 2


 %Find_stmts: /****************** generate statements to find pattern */
  procedure (Upper, Value, Pat) returns (char);

  declare
     Pat   char,
     Upper char,
     Value char;
  declare
     C     char,
     Stmts char;
  declare
     (index, length, substr) builtin;

  C = substr (Pat, 1, 1);
  if Pat = '''''' then
     Stmts = Line ('$APOS2, $MPOS = LENGTH (' || Value || ') + 1;');
  else if C = '''' | C = '(' then do;
     if C = '(' then Pat = substr (Pat, 2, length (Pat) - 2);
     if Upper = 'TRUE'
        then
           Stmts = Line ('$APOS2 = INDEX (SUBSTR ('
              || 'TRANSLATE (' || Value || ','
              || '''ABCDEFGHIJKLMNOPQRSTUVWXYZ'','
              || '''abcdefghijklmnopqrstuvwxyz''), $MPOS), '
              || Pat || ') + $MPOS - 1;');
        else
           Stmts = Line ('$APOS2 = INDEX (SUBSTR ('
              || Value || ', $MPOS), ' || Pat || ') + $MPOS - 1;');
     Stmts = Stmts || Line ('IF $APOS2 = $MPOS - 1 THEN '
        || '$APOS2, $MPOS = LENGTH (' || Value || ') + 1;')
        || Line ('ELSE $MPOS = $APOS2 + LENGTH (' || Pat || ');');
     end;
  else if Pat = '+0' | Pat = '-0' then
     Stmts = Line ('$MPOS = $APOS2;')
        || Line ('$APOS2 = LENGTH (' || Value || ') + 1;');
  else if index ('+-0123456789', C) ^= 0 then do;
     if C = '+' | C = '-'
        then
           Stmts = Line ('$XPOS = $APOS2 ' || Pat || ';');
        else
           Stmts = Line ('$XPOS = ' || Pat || ';');
     Stmts = Stmts
        || Line ('IF $XPOS <= $MPOS THEN DO;')
        || Line ('$APOS2 = LENGTH (' || Value || ') + 1;')
        || Line ('$MPOS = $XPOS;')
        || Line ('IF $MPOS < 1 THEN $MPOS = 1;')
        || Line ('END;')
        || Line ('ELSE DO;')
        || Line ('$APOS2, $MPOS = $XPOS;')
        || Line ('IF $MPOS > LENGTH (' || Value || ') + 1 THEN '
                  || '$APOS2, $MPOS = LENGTH (' || Value || ') + 1;')
        || Line ('END;');
     end;

  return (Stmts);

 %end Find_stmts;

 %Assign_stmts: /*************** generate statements to assign values */
  procedure (Upper, Value, Var) returns (char);

  declare
     Upper char,
     Value char,
     Var   char;
  declare
     Looping fixed,
     K       fixed,
     Stmts   char,
     V       char;
  declare
     (index, length, substr) builtin;

  Stmts = Line ('$WPOS2 = $APOS1;');
  do Looping = 0 by 0;
     K = index (Var, ' ');
     V = substr (Var, 1, K - 1);
     Var = substr (Var, K + 1);
     if Var = '' then goto Leave_loop;
     Stmts = Stmts
        || Line ('$WPOS1 = VERIFY (SUBSTR (' || Value
        || ', $WPOS2, $APOS2 - $WPOS2), '' '') + $WPOS2 - 1;')
        || Line ('IF $WPOS1 = $WPOS2 - 1 THEN $WPOS1 = $APOS2;')
        || Line ('$WPOS2 = INDEX (SUBSTR (' || Value
        || ', $WPOS1, $APOS2 - $WPOS1), '' '') + $WPOS1 - 1;')
        || Line ('IF $WPOS2 = $WPOS1 - 1 THEN $WPOS2 = $APOS2;');
     if V ^= '*' then
        if Upper = 'TRUE'
           then
              Stmts = Stmts || Line (V || ' = SUBSTR (TRANSLATE ('
              || Value || ', ''ABCDEFGHIJKLMNOPQRSTUVWXYZ'', '
              || '''abcdefghijklmnopqrstuvwxyz''), '
              || '$WPOS1, $WPOS2 - $WPOS1);');
           else
              Stmts = Stmts || Line (V || ' = SUBSTR ('
              || Value || ', $WPOS1, $WPOS2 - $WPOS1);');
     Stmts = Stmts || Line
        ('IF $WPOS2 < $APOS2 THEN $WPOS2 = $WPOS2 + 1;');
     end;
  Leave_loop:;
  if V ^= '*' then
     if Upper = 'TRUE'
        then
           Stmts = Stmts || Line (V || ' = '
           || 'SUBSTR (TRANSLATE (' || Value
           || ', ''ABCDEFGHIJKLMNOPQRSTUVWXYZ'', '
           || '''abcdefghijklmnopqrstuvwxyz''), '
           || '$WPOS2, $APOS2 - $WPOS2);');
        else
           Stmts = Stmts || Line (V || ' = SUBSTR ('
           || Value || ', $WPOS2, $APOS2 - $WPOS2);');

  return (Stmts);

 %end Assign_stmts;
anonymous ()

Re: конструкция parse из REXX на препроцессоре PL/I, весь исходник -- part 3, end


 %Parse: /************************************ REXX-statement in PL/I */
  procedure (Upper, Value, With) statement returns (char);

  declare
     Upper char,
     Value char,
     With  char;
  declare
     Looping fixed,
     I       fixed,
     L       fixed,
     Stmts   char,
     Var     char;
  declare
     (index, length, parmset, substr) builtin;

 /* check parameters: */
  if ^parmset (Value) | ^parmset (With) then
     note ('VALUE and WITH options are required.', 12);
  if parmset (Upper)
     then do;
        if Upper ^= '' then
           note ('UPPER has to be used without a value.', 8);
        Upper = 'TRUE';
        end;
     else
        Upper = 'FALSE';

 /* replace comments in WITH by blank: */
  I = 1;
  do Looping = 0 by 0;
     if I >= length (With) then goto Leave_replace;
     if substr (With, I, 1) = '''' then
        I = I + Strlen (With, I);
     else if substr (With, I, 2) = '/*' then do;
        L = Comlen (With, I);
        With = substr (With, 1, I - 1) || ' ' || substr (With, I + L);
        I = I + 1;
        end;
     else
        I = I + 1;
     end;
  Leave_replace:;
  if Value = '' | With  = '' then
     note ('VALUE and WITH options must not be empty.', 12);

 /* create statements: */
  Stmts = Line ('DO;') || Line ('$APOS1, $APOS2, $MPOS = 1;');

  Var = '';
  do I = 1 to length (With);
     if substr (With, I, 1) ^= ' ' &
        substr (With, I, 1) ^= ',' then do;
        L = Itmlen (With, I);
        if index ('0123456789+-''(', substr (With, I, 1)) = 0
           then                                /* variable or * found */
              Var = Var || substr (With, I, L) || ' ';
           else do;                                  /* pattern found */
              Stmts = Stmts ||
                 Find_stmts (Upper, Value, substr (With, I, L));
              if Var ^= '' then
                 Stmts = Stmts
                    || Assign_stmts (Upper, Value, Var);
              Var = '';
              Stmts = Stmts || Line ('$APOS1 = $MPOS;');
              end;
        I = I + L - 1;
        end;
     end;
  if Var ^= '' then                             /* trailing variables */
     Stmts = Stmts
        || Find_stmts (Upper, Value, '''''')
        || Assign_stmts (Upper, Value, Var);

  return (Stmts || Line ('END;'));

 %end Parse;
anonymous ()
Ответ на: комментарий от qulinxao3

в общем, у PL/I были «системные диалекты»: начиная от PL/S на котором Фредерик Брукс мифический человекомесяц ооооо (проект OS и System/360) через PL/M от Гари Килдалла из Digital Research, CP/M.

на которых было реализовано всё тоже самое что и на сишечке. только на более высокоуровневом языке: PL/M по сути ассемблер с просто типизированными переменными, но уже есть эти типы, макроподстановки declare, какие-то формулы и оптимизации выражений. то есть, это не просто такой ассемблер, уже появляются выражения.

до полноценного PL/I с препроцессором.

тут бы и сделать следующий шаг: реализовывать PL/I как башню макроязыков типа SICP, «Гёдель, Эшер, Бах» и прочее. на цепочке: препроцессор\низкоуровневый PL/M\конкретный ассемблер.

при этом пользуясь всей стандартной библиотекой и её функциями в препроцессоре, в макросах. ибо PL/I.

PL/I-KT был написан как переписывание на ассемблере исходного компилятора упрощённого PL/I, кажется, именно на PL/M и написанного.

вот эту линию и надо было развивать. потом получилось бы пара языков, в этой башне: скриптовый REXX с синтаксисом «как в PL/I», высокоуровневый PL/I с препроцессором с полноценным CTFE (только результат всё ещё строчно ориентированный, а не на AST выражения произвольных типов). и нечто вроде PL/M где-то между, на низком уровне.

история пошла по-другому, и PL/I так и остался широко распространён в узких кругах «программистов на IBM, но не PC»

в тех же слайдах про PL/I и OS/2:

существует примерно 300 000 программистов на PL/I во всём мире

(c) circa примерно 1995

anonymous ()
Ответ на: комментарий от qulinxao3

исходник одним файлом

parse.cpy на препроцессоре PL/I

встраивание REXX parse DSL в PL/I через макрос, по сути – функции времени компиляции.

видно:

  1. как формируется строка конкатенацией, которая потом скармливается из препроцессора компилятору

  2. что её обрабатывают точно те же функции стандартной библиотеки PL/I, что и все остальные. никаких таких особых builtins.

  3. «достаточно умный компилятор» может всё это соптимизировать лучше, чем код, написанный руками. тем более из макросов. тем более из обкоцанных макросов, которые нифига не могут.

anonymous ()
Ответ на: комментарий от qulinxao3

-Я кажусь вам академиком с большим задом,
Один, мол, я жрец поэзий непролазных.
А мне в действительности единственное надо –
Чтоб больше поэтов хороших и разных.
В. Маньяковский «Послание пролетарским поэтам»

разных и так уже много. давайте лучше хороших.

anonymous ()
Ответ на: комментарий от qulinxao3

алсо, любопытно поковырять TMG, TransMoGrifier. в каком-то виде. по синтаксису вроде бы META II напоминает.

из мануалов: EPL

The current implementation of EPL generates very inefficient code in certain cases. This section describes a restricted subset of EPL. This restricted EPL, REPL, excludes all of those constructions which generate inefficient code.

из словаря: EPL:

EPL

Early PL/I. This compiler was done at BTL in the mid-60s by Doug McIlroy, Bob Morris, and others when it became clear that Digitek wouldn’t produce a compiler. EPL was written in TMG and was incredibly slow. See the article on PL/I.

теперь, в свою очередь словарь про TMG:

TMG

TransMoGrifier. Compiler-compiler language created by Bob McClure at Texas Instruments about 1964. Used by Doug McIlroy and Bob Morris to write EPL. Some TMG source is online.

TMG:

Doug McIlroy has described how he and Bob Morris used TMG from Bob McClure at Texas Instruments to write the EPL compiler.

TMG was the compiler definition tool used by Ken Thompson to write the compiler for the B language on his PDP-7 in 1970. B was the immediate ancestor of C. (Dennis Ritchie, The Evolution of the Unix Time-sharing System)

по виду, исходник ниже напоминает метакомпилятор META II. очень похожая на него грамматика, по форме. по сути и семантике – тут вчитываться надо.

любопытно, что на этом был раскручен мини-компилятор PL/I (как и B). BCPL же исходники доступны, он написан сам на себе *(и Ocode это термин оттудова, для самораскрутки переносимого кроссплатформенного компилятора. отсюда .o – файлы, так же как Pcode в UCSD Pascal).

anonymous ()
Ответ на: комментарий от anonymous

вообще вот это вот из инструкций знаешь что напомнило? LambdaMOO и MUDы. только здесь это полноценная ОС со средствами разработки. с довольно странным на современный взгляд какого-нибудь недохипстера выбором средств разработки.

logout
Repair.SysAdmin logged out 07/12/17 1001.0 pst Wed
CPU usage 1 sec, memory usage 0.2 units, cost $0.06.
hangup
Multics has disconnected you
Connection closed by foreign host.

вот чего ни разу не жалко. представляешь, сколько машиночасов за многия $$$ были сэкономлены юниксофикацией вместо мультиксов на твоём локалхосте, $username?

anonymous ()
Ответ на: комментарий от deep-purple

Эта терминология кривая, компилятор это сборщик, если понимать это прямо. Речь тут обычно о трансляторе. Не думаю что для парсера транслятора строить AST обязательно, ведь что такое AST? Это перевод некоторого синтаксиса в объекты языка, «внутреннее представление». Это необходимо для интерпретатора, но транслятор это просто переводчик с языка на язык. Когда переводчик переводит с английского на русский он строит AST? (могу ошибаться)

grammaticq ()
Ответ на: комментарий от grammaticq

+1. это ещё более наглядно по реализации какого-нибудь бейсика на M4, был такой. всё это можно сделать и переписыванием термов, если язык реализации компилятора достаточно гибкий, как M4. и/или, исходный язык построчный и достаточно тупой – как бейсик.

AST нужен не столько ради синтаксического, сколько семантического анализа. ну и есть языки которые без семантики не распарсишь, она контекстна.

anonymous ()
Ответ на: комментарий от qulinxao3

AST в 1972+- у Томпсона?

Не у Томпсона, а у Ритчи. Денниса Ритчи. Покойного Денниса Ритчи, дурилка ты картонная.

AST в 1972+- ?
сырец тех лет укажешь?

Я всегда подозревал, что ты - норкоман.

https://github.com/qrush/unix/tree/master/src/c

/*

	    	C compiler, part 2

	Copyright 1972 Bell Telephone Laboratories, Inc.

*/

Там пока еще нет enum'ов и sturct'ур, да и в машине только целочисленные операции.

LamerOk ★★★★★ ()
Ответ на: комментарий от grammaticq

си является макроассемблером, и все что делает транслятор – это переписывание инструкций си на инструкции асма

В неоптимизирующих компиляторах K&R C - возможно. Но 70-е немного прошли.

anonymous ()
Ответ на: комментарий от qulinxao3

дык гипотетическое прозрение в том, что "прелести С а до этого B синтаксиса " от чуваков которые в разные LR и прочие грамматики - а средством ввода был телетайп - поэтому синтаксис Сишки очень g/re/p-френдли - для блочного полу и полностью автоматического транслированния

ну сравни языки того времени: фокал и MUMPS, PL/I, REXX. все они line oriented, построчно ориентированные а не на законченные структурные выражения. PL/I несколько выбивается, но препроцессор тут тоже строчно-ориентированный а не AST ориентированный. а какой-нибудь алгол с call-by-name – блочно ориентированный. или MacLisp = прямой потомок Lisp 1.5.

эволюция примерно как от формата PostScript (где поток мотать можно только вперёд, и нужно /showpage чтобы показать страницу) до PDF (который по сути COS формат словарей с индексами для быстрого поиска и произвольной (обычно постраничной, но ничего не ограничивает полёт мысли) адресации бинарных потоков, которые могут быть сжатые, юникодные, обработаны фильтром, быть формой для ввода, яваскриптом для валидации или 3D для демонстрации в фидобраузере PDF просмотрщике).

потом в си какие-то builtins и intrinsic добавляют для оптимизации. то есть уже не только лишь в текст.

anonymous ()
Ответ на: комментарий от qulinxao3

ted: ted, qedx и teco/emacs, а также дивная история от Russ Cox про правильные и быстрые регулярки. со структурными выражениями (тут уже надо читать статью Пайка про sam).

anonymous ()
Ответ на: комментарий от LamerOk

откровение Кена Томсона в майском интервью 2019 году Кернигану - ознакомься

из прямой речи Кена Томсона следует что после того как КТ закончил упихивание «компилятора В» т.е «Compiler B» т.е «BC Prog Lang» в 4K 18битных слов - и юникс был им же переписан большей частью(т.е осталось достаточно много .s ошмётков) на «NewB»

из той же реплики - Ритчи с момента реализации его же предложения о структурах стал главным мантейнером сего язычка который B+структуры+разноразмерные типы-терминалы.

в той части которая обсуждается что B что С неразличимы.

qulinxao3 ()
Ответ на: комментарий от anonymous

в том и забава что когда ознакамливаешься с эпохой пред этим известной по герою обнаруживаешь что герой уникален для не своей эпохи - а в своё время был конечно героичен (тем и отличился что героизировался) НО в чертах для другой эпохи уникальный не так уникален для своей эпохи.

ща плотнее ознакамливаюсь с историей Pascal -0 -4 -P0 -P4 и как оно плесенораспространялось и есть некоторое зерно в утверждение Вирта что килерапликуха Unix для языка Си

как килерапликуха VisiCalc для ваще рынка перс.компов в офисах.

до сих пор в офисах электронные таблицы ( и их эквиваленты - т.е. по сути современные счёты - калькуляторы при помощи которых можно моделировать количественные системы с доступным для пользователя интерфейсом) основная прога ( оставляя в стороне чистую подготовку документов в ворд-процессорах)

у PL/I как и у Algol68 - слишком сильная ориентация на «замок из слоновой кости»

когда как и у Pascal сначала а очень быстро затем перехват Сишкой - через образовательные (а в дальнейшем игрушки - графические менюшки ) -

информативно как индустрия в целом на витках Pascal… Си … Java …. Python … и многие другие языки - расширяет число пользователей( т.е проблему последней мили)

qulinxao3 ()