post

Pascal-S

Pascal-S is a subset of Pascal selected for introductory programming courses. The implementation is especially designed to provide comprehensive and transparant error diagnostics and economical service for small jobs.
The system consists of a compiler and an interpreter and is defined as a single, self-contained Pascal program.
Pascal-S is written in Pascal, and forms an excellent introduction to the art of designing small compilers.

Ben-Ari built on Pascal-S in the first version of his “Principles of concurrent programming” and introduced concurrency, see the Pascal-S Copascal page.

It is a interesting to see how many CDC-Pascal specialities are built into this compiler/interpreter.

  • Keywords are recognized by a binary search through a list of alfa’s (a standard datatype in CDC-Pascal) which are a 60-bit machine word packed with 10 6-bit characters. Since both DO and DOWNTO are keywords it is apparent from the ordering of the list that space comes after letters in the CDC character set <.li>
  • Some of the handling of large integers will only succeed on a CDC pascal implementation programs data gave the desired results
  • In Simpleexpression a 36 is emitted to negate both reals and integers, but the interpreter does this for both reals and integers s(.t.).i := – s(.t.).i;
    On the CDC this actually works for reals too

Corrections to the original (Jan van de Snepscheut):

  • line 295 (counting from 1 starting at program Pascal-S) is
    gen1(mulc, ttab[t].size); gen0(add)
    whereas the version printed in the book accidentally reads
    gen1(mulc, ttab[t].size)
    the corrected versions also implements boolean negation
  • the procedure funcdeclaration in the version printed in the book is
    erroneous. The first line on page 376 in the book should read
    if lev>1 then dx:=-1
    the last line of the procedure should read
    gen1(exit,itab[f].resultadr-dx); lev:=lev-1; dx:=odx

Wirth’s original paper is reprinted in Barrons book. Another version of Pascal-S appears in Snepscheut’s book and this uses symbolic names and contains a small peephole optimizer.
Publications where Pascal-S appeared in source format are:

  • PASCAL-S: A Subset and its Implementation, by Niklaus Wirth, Zurich : Eidgenossische Technische Hochschule, 1975. 61 s., Berichte des Instituts fur Informatik;
  • Pascal – The Language and its Implementation, by D. W. Barron, Chichester :
    John Wiley and Sons, 1980. 201 s. , ill., Wiley Series in Computing
  • Principles of Concurrent Programming, by M. Ben-Ari, Englewood Cliffs, N.J. :
    Prentice-Hall, Inc., 1982, 172 s. , ill.
  • What Computing is All About, by Jan L. A. van de Snepscheut



Downloads:


Some information on this page has been published by Scott Moore on the Standard Pascal pages and by Birger Nielsen (pages now lost).

Articles by Wirth et al

Collection of mostly historical articles on Pascal, by Niklaus Wirth and others. From the Pascal compilers to recollections.

On certain Basic Concepts of Programming Languages, Wirth, May 1967
What can we do about the Unnecessary Diversity of Notation for Syntactic Definitions?, Wirth, 1977

An Axiomatic Definition of the Programming Language Pascal, Wirth, Hoare, November 1972
A Collection of Pascal Programs Wirth, Wirth, July 1979
Data Structures and Algorithms Informatics, Wirth August 1984
Error Recovery in Descent Parsers, Urs Ammann. Mai 1978
Implementations of Pascal on Systems With No Control Characters, Wirth, June 1973
The Programming Language Pascal (Revised Report), November 1972
On Code Generation in a PASCAL Compiler, Urs Amnann
On Code Generation in a PASCAL Compiler, Urs Amnann, eth-3056-01
Pascal-P Compiler Implementation Notes, K.V. Nori, Urs Ammann, Christian Jacobi, 1974
Planned Changes To The Programming Language PASCAL, Wirth, June 1972
P-Machine Description, ETH, Januari 73
Program development by step-wise refinement, Wirth, January 1971
The Zurich Implementation, Urs Amman
The Pascal(P) Compiler:_Implementation_Notes, K.V. Nori, U. Ammann, K.Jensen, H.H. Naegeli, Dec 1974
The Programming Language_Pascal, Wirth, 1970
The Programming Language Pascal (Revised Report), Wirth, November 1972
The Programming Language_Pascal (Revised Report), Wirth, July 1973
A Pascal processor Validation Suite, Wichman, Sale, March 1980
Pascal Newsletter May 1974
Page 1 History of Pascal documented. Page 6 Wirth describes Pascal 6000-3.4. Page 18 Wirth describes Pascal-P (the P-machine, probably P1)
Program development by step-wise refinement, Wirth, January 1971
On the Composition of Well-structured Structured Programs, Wirth, 1974
Effective Technology transfer, Wirth 1995
Essay on programming, Wirth, March 1999
Programming Languages_What To_Demand And How To Assess Them, Wirth, April 1976
Recollection On the Development of Pascal, Wirth, 1993
Recollection On the Development of Pascal, Wirth 1993
Recollection On the Development of Pascal, Wirth 1983

A Plea for Lean Software, Wirth, February 1995
Good Ideas, Through the Looking Glass, Wirth, 2006
Good Ideas, Through the Looking Glass, Wirth, 2005
On the Design of Programming Languages, Wirth, 1974
Turing Award, Wirth, 1984
Type Extensions, Wirth 1988
What can we do about the Unnecessary Diversity of Notations for Syntactic Definitions, Wirth ,1977
A plea for Lean Software, Wirth, February 1995
Zwanzig Jahre Institut Informatik. F. Bauer, Edsger Dijkstra, 1988
Finite State Machines, Programmable Logic Devices, and the Crux of Growing Complexity, 2008
The Year of Informatics, 2008
Computers and Computing A Personal Perspective, December 2015
A Triptychon of Digital Circuits, August 2005
Was ist ein Denkplatz, und warum erstreben wir ihn?
Als Computer noch erklärbar waren, 2008
A Brief History of Software Engineering, 2008
A Note on Division, 2008
An Essay on Programming, 1999

Carlo Pescio A Few Words with Niklaus Wirth Software Development, Vol. 5 No. 6, June 1997

Lilith section updated

I have added the repository by Jos Dreesen on Lilith and the Emulith emulator with a local copy.
Jos maintains a ftp with just the files, I made it available as web pages here with higher availability and easier viewing of images and videos.

Emulith

Px compilers

The Pascal-P compiler was created in 1973, then went through several versions, which so far have not been available. Ch. Jacobi gives an overview of the Pascal-P versions in PUG newsletter #4:

Name Origination Year Source Description
Pascal P1 Zurich 1973 No Either of the early Pascal-P systems (released in March and July 1973 respectively)
Pascal-P2 Zurich 1974 Yes The Pascal-P system released in May 74
Pascal-P3 Zurich 1976 No The new Pascal-P system with the same hypothetical machine as the one underlying the Pascal P2 system
Pascal-P4 Zurich 1976 Yes The new Pascal-P system with a slightly modified hypothetical machine (allowing a more efficient implementation)

The versions of P1 that existed have (so far) not been available. The revised version, P2, is available, and was used as the basis for the UCSD system. P3 was a “step” implementation used to bridge between P2 and P4, and is also not obtainable.

The last major version of Pascal-P was P4.

PL/0

PL/0 is a small educational language designed and implemented by Wirth to be used as an example of compiler development.

The language was presented by Niklaus Wirth in his book “Algorithms + Data Structures = Programs” (1975). Later versions of this book did not contain PL/0, but the small compilers did appear in the Compiler Construction series.

His later book “Compilerbau” or “Compiler Construction”, 1976) provided also the full source code of PL/0 compiler written in Pascal. Later editions (3rd, 1984)  the PL/0 compiler was rewritten in Modula and enhanced a bit with e.g. print statements.

After Oberon was conceived the example language was succeeded by Oberon-0. Sources of these PL/0 and Oberon-0 compilers”

See the Books by Wirth page for the relevant Compiler Construction books.
Note that PL/0 only appeared in the 1975 English version of Algorithms + Data Structures = Programs, it is not present in the German version Algorithmen und Data Structuren book of 1975.

PL/0 1975 Pascal version from Compilerbau (1977) and Algorithms + Data Structures = Programs (1976)

Chapter 5 of Algorithms and Data Structures

The capabilities of the language were intentionally, for study, limited:

–the only data type are integer numbers. Still all constants and variables used have to be declared explicitly, not deduced at compile-time.
–the only operators provided are arithmetical and comparison ones.
–there is one built-in function odd which checks whether the integer argument is odd.
– there are no input/output routines; instead the compiler prints the new value of each variable whenever it gets changed.
– the flow control structures are represented by if-then and while-do constructs, as well as user-defined procedures (which can’t accept any parameters).

The syntax of PL/0 (1975 version) described in extended Backus-Naur form

program = block .

block = [ const ident = number {, ident = number} ;]
        [ var ident {, ident} ;]
        { procedure ident ; block ; } statement .

statement = [ ident := expression | call ident 
              | ? ident | ! expression 
              | begin statement {; statement } end 
              | if condition then statement 
              | while condition do statement ].

condition = odd expression |
            expression (=|#|&amp;lt;|&amp;lt;=|&amp;gt;|&amp;gt;=) expression .

expression = [ +|-] term { (+|-) term}.

term = factor {(*|/) factor}.

factor = ident | number | ( expression )

Elements of syntax

Case-sensitivity yes
Variable assignment :=
Variable declaration var
Block begin … end
Physical (shallow) equality =
Physical (shallow) inequality #
Comparison < >
Function definition procedure <name>; <body>;
Function call call <name>
Sequence ;
If – then if <condition> then <trueBlock>
Loop forever while 1 = 1 do <loopBody>
While condition do while do <loopBody>

To compile with Delphi, Freepascal, or any compiler where object is a reserved name: rename identifier ‘object’. For FPC add {$mode ISO} to allow the goto.

program pl0(input,output);
{pl/0 compiler with code generation}
label 99;
const norw = 11;     {no. of reserved words}
   txmax = 100;      {length of identifier table}
   nmax = 14;        {max. no. of digits in numbers}
   al = 10;          {length of identifiers}
   amax = 2047;      {maximum address}
   levmax = 3;       {maximum depth of block nesting}
   cxmax = 200;      {size of code array}
type symbol =
   (nul,ident,number,plus,minus,times,slash,oddsym,
    eql,neq,lss,leq,gtr,geq,lparen,rparen,comma,semicolon,
    period,becomes,beginsym,endsym,ifsym,thensym,
    whilesym,dosym,callsym,constsym,varsym,procsym);
    alfa = packed array [1..al] of char;
    object = (constant,varible,proc);
    symset = set of symbol;
    fct = (lit,opr,lod,sto,cal,int,jmp,jpc);   {functions}
    instruction = packed record
                     f: fct;           {function code}
                     l: 0..levmax;     {level}
                     a: 0..amax        {displacement address}
                  end;
{   lit 0,a  :  load constant a
    opr 0,a  :  execute operation a
    lod l,a  :  load varible l,a
    sto l,a  :  store varible l,a
    cal l,a  :  call procedure a at level l
    int 0,a  :  increment t-register by a
    jmp 0,a  :  jump to a
    jpc 0,a  :  jump conditional to a   }
var ch: char;         {last character read}
    sym: symbol;      {last symbol read}
    id: alfa;         {last identifier read}
    num: integer;     {last number read}
    cc: integer;      {character count}
    ll: integer;      {line length}
    kk, err: integer;
    cx: integer;      {code allocation index}
    line: array [1..81] of char;
    a: alfa;
    code: array [0..cxmax] of instruction;
    word: array [1..norw] of alfa;
    wsym: array [1..norw] of symbol;
    ssym: array [char] of symbol;
    mnemonic: array [fct] of
                 packed array [1..5] of char;
    declbegsys, statbegsys, facbegsys: symset;
    table: array [0..txmax] of
           record name: alfa;
              case kind: object of
              constant: (val: integer);
              varible, proc: (level, adr: integer)
           end;
procedure error(n: integer);
begin writeln(' ****',' ': cc-1, '^',n: 2); err := err+1
end {error};
 
procedure getsym;
   var i,j,k: integer;
 
   procedure getch;
   begin if cc = ll then
      begin if eof(input) then
                 begin write(' program incomplete'); goto 99
                 end;
         ll := 0; cc := 0; write(cx: 5,' ');
         while not eoln(input) do
            begin ll := ll+1; read(ch); write(ch); line[ll]:=ch
            end;
         writeln; readln; ll := ll + 1; line[ll] := ' ';
      end;
      cc := cc+1; ch := line[cc]
   end {getch};
 
begin {getsym}
   while ch  = ' ' do getch;
   if ch in ['a'..'z'] then
   begin {identifier or reserved word} k := 0;
      repeat if k &amp;lt; al then
         begin k := k+1; a[k] := ch
         end;
         getch;
      until not(ch in ['a'..'z','0'..'9']);
      if k &amp;gt;= kk then kk := k else
         repeat a[kk] := ' '; kk := kk-1
         until kk = k;
      id := a; i := 1; j := norw;
      repeat k := (i+j) div 2;
         if id &amp;lt;= word[k] then j := k-1;
         if id &amp;gt;= word[k] then i := k+1
      until i &amp;gt; j;
      if i-1 &amp;gt; j then sym := wsym[k] else sym := ident
   end else
   if ch in ['0'..'9'] then
   begin {number} k := 0; num := 0; sym := number;
      repeat num := 10*num + (ord(ch)-ord('0'));
         k := k+1; getch
      until not(ch in ['0'..'9']);
      if k &amp;gt; nmax then error(30)
   end else
   if ch = ':' then
   begin getch;
      if ch = '=' then
      begin sym := becomes; getch
      end else sym := nul;
   end else
   begin sym := ssym[ch]; getch
   end
end {getsym};
 
procedure gen(x: fct; y,z: integer);
begin if cx &amp;gt; cxmax then
           begin write(' program too long'); goto 99
           end;
   with code[cx] do
      begin f := x; l := y; a := z
      end;
   cx := cx + 1
end {gen};
 
procedure test(s1,s2: symset; n: integer);
begin if not(sym in s1) then
        begin error(n); s1 := s1 + s2;
           while not(sym in s1) do getsym
        end
end {test};
 
procedure block(lev,tx: integer; fsys: symset);
   var dx: integer;     {data allocation index}
      tx0: integer;     {initial table index}
      cx0: integer;     {initial code index}
   procedure enter(k: object);
   begin {enter object into table}
      tx := tx + 1;
      with table[tx] do
      begin name := id; kind := k;
         case k of
         constant: begin if num &amp;gt; amax then
                              begin error(30); num :=0 end;
                      val := num
                   end;
         varible: begin level := lev; adr := dx; dx := dx + 1;
                  end;
         proc: level := lev
         end
      end
   end {enter};
 
   function position(id: alfa): integer;
      var i: integer;
   begin {find indentifier id in table}
      table[0].name := id; i := tx;
      while table[i].name &amp;lt;&amp;gt; id do i := i-1;
      position := i
   end {position};
 
   procedure constdeclaration;
   begin if sym = ident then
      begin getsym;
         if sym in [eql, becomes] then
         begin if sym = becomes then error(1);
            getsym;
            if sym = number then
               begin enter(constant); getsym
               end
            else error(2)
         end else error(3)
      end else error(4)
   end {constdeclaration};
 
   procedure vardeclaration;
   begin if sym = ident then
           begin enter(varible); getsym
           end else error(4)
   end {vardeclaration};
 
   procedure listcode;
      var i: integer;
   begin {list code generated for this block}
      for i := cx0 to cx-1 do
         with code[i] do
            writeln(i:5, mnemonic[f]:5, 1:3, a:5)
   end {listcode};
 
   procedure statement(fsys: symset);
      var i, cx1, cx2: integer;
      procedure expression(fsys: symset);
         var addop: symbol;
         procedure term(fsys: symset);
            var mulop: symbol;
            procedure factor(fsys: symset);
               var i: integer;
            begin test(facbegsys, fsys, 24);
               while sym in facbegsys do
               begin
                  if sym = ident then
                  begin i:= position(id);
                     if i = 0 then error(11) else
                     with table[i] do
                     case kind of
                        constant: gen(lit, 0, val);
                        varible: gen(lod, lev-level, adr);
                        proc: error(21)
                     end;
                     getsym
                  end else
                  if sym = number then
                  begin if num &amp;gt;  amax then
                           begin error(30); num := 0
                           end;
                     gen(lit, 0, num); getsym
                  end else
                  if sym = lparen then
                  begin getsym; expression([rparen]+fsys);
                     if sym = rparen then getsym else error(22)
                  end;
                  test(fsys, [lparen], 23)
               end
            end {factor};
 
         begin {term} factor(fsys+[times, slash]);
            while sym in [times, slash] do
             begin mulop:=sym;getsym;factor(fsys+[times,slash]);
              if mulop=times then gen(opr,0,4) else gen(opr,0,5)
             end
         end {term};
      begin {expression}
         if sym in [plus, minus] then
            begin addop := sym; getsym; term(fsys+[plus,minus]);
               if addop = minus then gen(opr, 0,1)
            end else term(fsys+[plus, minus]);
         while sym in [plus, minus] do
            begin addop := sym; getsym; term(fsys+[plus,minus]);
               if addop=plus then gen(opr,0,2) else gen(opr,0,3)
            end
      end {expression};
 
      procedure condition(fsys: symset);
         var relop: symbol;
      begin
         if sym  = oddsym then
         begin getsym; expression(fsys); gen(opr, 0, 6)
         end else
         begin expression([eql, neq, lss, gtr, leq, geq]+fsys);
            if not(sym in [eql, neq, lss, leq, gtr, geq]) then
               error(20) else
            begin relop := sym; getsym; expression(fsys);
               case relop of
                  eql: gen(opr, 0, 8);
                  neq: gen(opr, 0, 9);
                  lss: gen(opr, 0, 10);
                  geq: gen(opr, 0, 11);
                  gtr: gen(opr, 0, 12);
                  leq: gen(opr, 0, 13);
               end
            end
         end
      end {condition};
 
   begin {statement}
      if sym = ident then
      begin i := position(id);
         if i = 0 then error(11) else
         if table[i].kind &amp;lt;&amp;gt; varible then
            begin {assignment to non-varible} error(12); i := 0
            end;
         getsym; if sym = becomes then getsym else error(13);
         expression(fsys);
         if i &amp;lt;&amp;gt; 0 then
            with table[i] do gen(sto, lev-level, adr)
      end else
      if sym = callsym then
      begin getsym;
         if sym &amp;lt;&amp;gt; ident then error(14) else
            begin i := position(id);
               if i = 0 then error(11) else
               with table[i] do
                  if kind=proc then gen(cal, lev-level, adr)
                  else error(15);
               getsym
            end
      end else
      if sym = ifsym then
      begin getsym; condition([thensym, dosym]+fsys);
         if sym = thensym then getsym else error(16);
         cx1 := cx; gen(jpc, 0, 0);
         statement(fsys); code[cx1].a := cx
      end else
      if sym = beginsym then
      begin getsym; statement([semicolon, endsym]+fsys);
         while sym in [semicolon]+statbegsys do
         begin
            if sym = semicolon then getsym else error(10);
            statement([semicolon, endsym]+fsys)
         end;
         if sym = endsym then getsym else error(17)
      end else
      if sym = whilesym then
      begin cx1 := cx; getsym; condition([dosym]+fsys);
         cx2 := cx; gen(jpc, 0, 0);
         if sym = dosym then getsym else error(18);
         statement(fsys); gen(jmp, 0, cx1); code[cx2].a := cx
      end;
      test(fsys, [], 19)
   end {statement};
 
begin {block} dx:=3; tx0:=tx; table[tx].adr:=cx; gen(jmp,0,0);
   if lev &amp;gt; levmax then error(32);
   repeat
      if sym = constsym then
      begin getsym;
         repeat constdeclaration;
            while sym = comma do
               begin getsym; constdeclaration
               end;
            if sym = semicolon then getsym else error(5)
         until sym &amp;lt;&amp;gt; ident
      end;
      if sym = varsym then
      begin getsym;
         repeat vardeclaration;
            while sym = comma do
               begin getsym; vardeclaration
               end;
            if sym = semicolon then getsym else error(5)
         until sym &amp;lt;&amp;gt; ident;
      end;
      while sym = procsym do
      begin getsym;
         if sym = ident then
            begin enter(proc); getsym
            end
         else error(4);
         if sym = semicolon then getsym else error(5);
         block(lev+1, tx, [semicolon]+fsys);
         if sym = semicolon then
            begin getsym;test(statbegsys+[ident,procsym],fsys,6)
            end
         else error(5)
      end;
      test(statbegsys+[ident], declbegsys, 7)
   until not(sym in declbegsys);
   code[table[tx0].adr].a := cx;
   with table[tx0] do
      begin adr := cx; {start adr of code}
      end;
   cx0 := 0{cx}; gen(int, 0, dx);
   statement([semicolon, endsym]+fsys);
   gen(opr, 0, 0); {return}
   test(fsys, [], 8);
   listcode;
end {block};
 
procedure interpret;
   const stacksize = 500;
   var p,b,t: integer; {program-, base-, topstack-registers}
      i: instruction; {instruction register}
      s: array [1..stacksize] of integer; {datastore}
   function base(l: integer): integer;
      var b1: integer;
   begin b1 := b; {find base l levels down}
      while l &amp;gt; 0 do
         begin b1 := s[b1]; l := l - 1
         end;
      base := b1
   end {base};
 
begin writeln(' start pl/0');
   t := 0; b := 1; p := 0;
   s[1] := 0; s[2] := 0; s[3] := 0;
   repeat i := code[p]; p := p + 1;
      with i do
      case f of
      lit: begin t := t + 1; s[t] := a
           end;
      opr: case a of {operator}
           0: begin {return}
                 t := b - 1; p := s[t + 3]; b := s[t + 2];
              end;
           1: s[t] := -s[t];
           2: begin t := t - 1; s[t] := s[t] + s[t + 1]
              end;
           3: begin t := t - 1; s[t] := s[t] - s[t + 1]
              end;
           4: begin t := t - 1; s[t] := s[t] * s[t + 1]
              end;
           5: begin t := t - 1; s[t] := s[t] div s[t + 1]
              end;
           6: s[t] := ord(odd(s[t]));
           8: begin t := t - 1; s[t] := ord(s[t] = s[t + 1])
              end;
           9: begin t := t - 1; s[t] := ord(s[t] &amp;lt;&amp;gt; s[t + 1])
              end;
          10: begin t := t - 1; s[t] := ord(s[t] &amp;lt; s[t + 1])
              end;
          11: begin t := t - 1; s[t] := ord(s[t] &amp;gt;= s[t + 1])
              end;
          12: begin t := t - 1; s[t] := ord(s[t] &amp;gt; s[t + 1])
              end;
          13: begin t := t - 1; s[t] := ord(s[t] &amp;lt;= s[t + 1])
              end;
          end;
      lod: begin t := t + 1; s[t] := s[base(l) + a]
           end;
      sto: begin s[base(l)+a] := s[t]; writeln(s[t]); t := t - 1
           end;
      cal: begin {generate new block mark}
              s[t + 1] := base(l); s[t + 2] := b; s[t + 3] := p;
              b := t + 1; p := a
           end;
      int: t := t + a;
      jmp: p := a;
      jpc: begin if s[t] = 0 then p := a; t := t - 1
           end
      end {with, case}
   until p = 0;
   write(' end pl/0');
end {interpret};

begin {main program}
   for ch := chr(0) to chr(255) do ssym[ch] := nul;
   word[ 1] := 'begin     ';      word[ 2] := 'call      ';
   word[ 3] := 'const     ';      word[ 4] := 'do        ';
   word[ 5] := 'end       ';      word[ 6] := 'if        ';
   word[ 7] := 'odd       ';      word[ 8] := 'procedure ';
   word[ 9] := 'then      ';      word[10] := 'var       ';
   word[11] := 'while     ';
   wsym[ 1] := beginsym;     wsym[ 2] := callsym;
   wsym[ 3] := constsym;     wsym[ 4] := dosym;
   wsym[ 5] := endsym;       wsym[ 6] := ifsym;
   wsym[ 7] := oddsym;       wsym[ 8] := procsym;
   wsym[ 9] := thensym;      wsym[10] := varsym;
   wsym[11] := whilesym;
   ssym[ '+'] := plus;       ssym[ '-'] := minus;
   ssym[ '*'] := times;      ssym[ '/'] := slash;
   ssym[ '('] := lparen;     ssym[ ')'] := rparen;
   ssym[ '='] := eql;        ssym[ ','] := comma;
   ssym[ '.'] := period;     ssym[ '#'] := neq;
   ssym[ '&amp;lt;'] := lss;        ssym[ '&amp;gt;'] := gtr;
   ssym[ '['] := leq;        ssym[ ']'] := geq;
   ssym[ ';'] := semicolon;
   mnemonic[lit] := '  lit';   mnemonic[opr] := '  opr';
   mnemonic[lod] := '  lod';   mnemonic[sto] := '  sto';
   mnemonic[cal] := '  cal';   mnemonic[int] := '  int';
   mnemonic[jmp] := '  jmp';   mnemonic[jpc] := '  jpc';
   declbegsys := [constsym, varsym, procsym];
   statbegsys := [beginsym, callsym, ifsym, whilesym];
   facbegsys  := [ident, number, lparen];
   page(output); err := 0;
   cc := 0; cx := 0; ll := 0; ch := ' '; kk := al; getsym;
   block(0, 0, [period]+declbegsys+statbegsys);
   if sym &amp;lt;&amp;gt; period then error(9);
  if err=0 then interpret else write(' errors in pl/0 program');
99: writeln
end.
post

Project Oberon

Hardware FPGA implementation document by Niklaus Wirth

Project Oberon emulators

Emulator for the Oberon RISC machine by Peter de Wachter

Oberon RISC Emulator for Pascal Markus Greim

Project Oberon emulator in JavaScript and Java  Michael Schierl

Pipistrella hardware FPGA

Here is a summary of acronyms and version names jwr robrts net gleaned from
various messages and sources. Please provide feedback and corrections
as appropriate.

ALO ARM Linux Oberon (Oberon in LNO family, for ARM CPU eg Raspberry Pi)
ETHO ETH Oberon (ETH is Eidgen?ssische Technische Hochschule Z?rich)
LEO Linux ETH Oberon [ETHO 2.4.3 for Linux x86]
LNO Linux Native Oberon
NO Native Oberon
OCP Oberon Community Platform
OLR Oberon Linux Revival

Is ETH-Linux-Oberon the same as LEO or LNO? (Probably it is LEO.) Is
Linux-ETH-Oberon the same as LEO? Same as ETH-Linux-Oberon?
See https://lists.inf.ethz.ch/pipermail/oberon/2015/007996.html
and https://lists.inf.ethz.ch/pipermail/oberon/2008/005410.html

BB BlackBox Component Builder, Component Pascal IDE
from Oberon Microsystems, http://www.oberon.ch/blackbox.html
CP Component Pascal
[A dialect in the Oberon family most similar to Oberon-2]

AOS Active Object System (2003)
UnixAOS Unix-based AOS
WinAOS Windows-based AOS
Bluebottle New system based on AOS kernel (2005)
A2 New system after Bluebottle (2008)
See http://www.oberon.ethz.ch/ for AOS/Bluebottle/A2 history
Crazy-Fresh Bluebottle [see http://www.ethoberon.ethz.ch/] Crazy-Fresh
A2 [see http://sourceforge.net/projects/a2oberon/files/]

The following appear to be versions of the language definition itself.
In another message another day I plan to identify documentation for each.

Original Oberon (1987/88/90)
Revised Oberon (1992) [later called Oberon-07]
Oberon-2 is a compatible superset of Revised Oberon (1992)
Oberon-07 is a new language based on Oberon and Oberon-SA
See http://oberon07.com/ and http://oberon07.com/FAQ.xhtml
See https://www.inf.ethz.ch/personal/wirth/Oberon/Oberon07.pdf
See https://www.inf.ethz.ch/personal/wirth/Oberon/Oberon07.Report.pdf
Project Oberon (1992) Ceres-based NS32032 implementation of Revised Oberon
see http://www.ethoberon.ethz.ch/WirthPubl/ProjectOberon.pdf
Project Oberon (2013) FPGA-based RISC5 implementation of Oberon-07
see http://www.projectoberon.com/ and
https://www.inf.ethz.ch/personal/wirth/
Oakwood Guidelines for Oberon-2 Compiler Developers

Other names found for various Oberon implementations and versions include:

Oberon S3 = Oberon System 3 (Became ETH Oberon)
Oberon V4 (Associated with both ETH and University of Linz)
See http://sourceforge.net/projects/oberon/ and
http://www.ssw.uni-linz.ac.at/Research/Projects/Oberon.html
See http://users.cms.caltech.edu/~cs140/140a/Oberon/system_faq.html for
Oberon = V1 ( V2 V4 | System3 )
Oberon V1 [Original Oberon??]
Oberon V2 [??]
Oberon V4 [Started at ETH, more development at University of Linz]
Oberon System3 [Became ETH Oberon]

Native Oberon [Based on ETH Oberon]
(see http://www.oberon.ethz.ch/downloads/index for current versions)
(see http://www.oberon.ethz.ch/archives/systemsarchive/native_new)
PC Native Oberon [for Intel-compatible PCs]
PC Native Oberon for Dummies [for Windows installation]
Linux-based Native Oberon [LNO]
SharkOberon [for DEC Shark Network Computers, ARM-based]
Native Oberon Alpha [http://www.oberon.ethz.ch/faq/faqnativealfabeta]
Native Oberon Beta [see same link as Alpha]

Versions at http://www.oberon.ethz.ch/archives/languagearchive/genealogy
Oberon
Oberon-V
Oberon X
Active Oberon
Oberon-SA
Active Oberon for .NET
Object Oberon
Oberon-2
Concurrent Oberon
Action Oberon
Oberon-D
Component Pascal

Versions at http://www.ethoberon.ethz.ch/genealsys.html not already above
SPARC-Oberon
MacOberon
DEC-Oberon
RISC Oberon
MS-DOS Oberon
Chameleon Oberon
HP-Oberon
Oberon for Windows
Spirit of Oberon
Hybrid Oberon
Oberon for Linux
Oberon Linux PPC
more versions named according to supporting OS?

Another acronym observed is OP2, which is a Portable Oberon compiler
by R Crelier

School of Niklaus Wirth: The Art of Simplicity

School of Wirth

Got myself an excellent book on the Art of Simplicity. Niklaus Wirth designed programming langauages like Pascal and sequels like Modula-2 and Oberon.  His style and dedication to simplicity in a clear writing and presentation style made a great impression on me.

This book gives unique insights in what has happened and is still happening in the school of Niklaus Wirth. Excellent book!

From the Back Cover

Niklaus Wirth is one of the great pioneers of computer technology and winner of the ACM’s A.M. Turing Award, the most prestigious award in computer science. He has made substantial contributions to the development of programming languages, compiler construction, programming methodology, and hardware design. While working at ERH Zurich, he developed the languages Pascal and Modula-2. He also designed an early high performance workstation, the Personal Computer Lilith, and most recently the language and operating system Oberon.
While Wirth has often been praised for his excellent work as a language designer and engineer, he is also an outstanding educator – something for which he is not as well known. This book brings together prominent computer scientists to describe Wirth’s contributions to education. With the exception of some of his colleagues such as Professors Dijkstra, Hoare, and Rechenberg, all of the contributors to this book are students of Wirth. The essays provide a wide range of contemporary views on modern programming practice and also illuminate the one persistent and pervasive quality found in all his work: his unequivocal demand for simple solutions. The authors and editors hope to pass on their enthusiasm for simple engineering solutions along with their feeling for a man to whom they are all so indebted.

Contents

Editors: László Böszörményi, Jürg Gutknecht, Gustav Pomberger

Photos and videos Lilith

In may 2006 Jos Dreesen send me the following photos of a surviving, but then not functional Lilith. In january 2008 Jos succeeded in having this machine running again, one of the few functional remaining Lilith computers (there may be a functioning one at ETH, about ten are known to exist)!

Lilith

Lilith

Lilith

Lilith

Photos made by Jos Dreesen, 2006

Lilith

Lilith

Lilith

Lilith

Lilith

Lilith

Lilith

Lilith

Lilith

Lilith

Lilith

Lilith

Lilith

Lilith

 

Lilith
Lilith
ALU
Lilith
Backplane
Lilith
Lilith
CDP
Lilith
Lilith
DSK
Lilith
Lilith
DSP
Lilith
Lilith
IFU
Lilith
Lilith
Lilith
Lilith
M128
Lilith
Lilith
Lilith
Lilith
M64
Lilith
Lilith
Magnet
Lilith
Lilith
MCU
Lilith
POWER
Lilith
Lilith
SD120

Photos made by Jos Dreesen, 2008-2012

Niklaus Wirth

niklaus_wirthProfessor Niklaus Wirth is an honered and well respected computer scientist. Very influencal with his work on programming, programming languages and operating systems design. Designer of

Pascal, Modula, Oberon, the Lilith computer and more. As a professor at the ETH in Zurich Switzerland he advanced our knowledge and capabilities with computers and their programming.

On these pages information on:
– work before Pascal: Euler, PL360, Algol W
sources of the early Pascal compilers from ETH Zurich: From 1972 CDC6000 to the Pascal-Px, Pascal-S and the toy/learning compilers Pl/O and Oberon-0
Lilith and Modula
– Oberon to Project Oberon
articles by Niklaus Wirth and others on Pascal, Modula-2 to Oberon
full books by Niklaus Wirth

Wirth not only designed languages, he also supervised and designed hardware and operating systems and applications, combining the strengths of his programming languages with a well suited platform. The first computer is called Lilith, of which about 100 were built around 1980. In 1981 he wrote an article about Lilith: “The Personal Computer Lilith”, on this page you find also photo’s recently made of a surviving and working Lilith computer. Project Oberon followed and, though long retired, he is still working on it!

More videos with Niklaus Wirth on youtube

 

Summary of projects by N. Wirth, 1962 – 1999

Euler, 1962-1965
Efforts to identify and combine the essential and fundamental concepts of programming languages, in particular of ALGOL 60, led to Wirth’s dissertation under the guidance of Prof. H. D. Huskey at the University of California at Berkeley, and to the definition of the language Euler. The language was implemented on the IBM 704 computer. After publication the project was continued at Stanford University and resulted in an improved implementation on the Burroughs B5000 computer. This work led the foundation for the method of the microprogrammed, stack-oriented interpreter, first tested on an IBM 360/30 computer. This method became widespread much later and was to play a key role in the implementation of high-level languages on microcomputers. Another important aspect of this research was the development of efficient, general parsing methods, and the systematic coupling of semantic interpretation with syntactic analysis. The so-called precedence grammars originated in the context of this project.

ALGOL W, 1964-1967
The work on Euler attracted the interest of the IFIP Working Group 2.1. This group had the task of promulgating and further enhancing ALGOL 60. Three proposals for a successor language were submitted in 1965. In the decisive meeting at Warsaw in the fall of 1966, the proposal of A. van Wijngaarden was elected to be further pursued. In 1970, it eventually became ratified by IFIP as ALGOL 68. Whereas it represented a radically new language, Wirth’s proposal had been less ambitious and based on the idea to extend ALGOL 60. A compiler was implemented for his (subsequently modified) proposal, and it later became used (under the name Algol W) at many universities operating IBM 360 computers. It contributed significantly to uphold the ideas of ALGOL 60.
Since Algol-W was implemented on one of the first IBM 360 computers, and because only an assembler and a Fortran compiler were available, which both were deemed as unsuitable, Wirth conveived a so-called system implementation language. It was supposed to facilitate and speed up the Algol effort, and at the same time it was to be simple enough to avoid a large effort for its own implementation. These goals were fully achieved, and the resulting language PL360 unexpectedly became used at many other installations too. It was the prototype for other, similar developments for other computer architectures.

<strongPascal, 1968-1972
Freed from the constraining influence of a working group’s consensus, Wirth developed the language Pascal in Zurich. The basis was Algol-W and the desire to have a language that would satisfy the requirements of system design (compilers, operating systems, etc.). Also, there was to be a basis of clear concepts and structures, definable axiomatically and independently of any particular computer, as the language was to be suitable also for teaching in an academic environment. Pascal has satisfied these requirements; it is today one of the most widely used languages in computer science education. The first Pascal compiler was designed in Zurich for the CDC 6000 computer family, and it became operational in 1970. Already in 1972 Pascal was used in introductory programming courses.

Venus, 1970-71
In 1970, the Federal Institute of Technology (ETH) acquired a large-scale computer system. In its selection, priority was given to the efficient processing of numerical problems (number crunching). Whereas the concept of time-sharing spread everywhere else, the chosen CDC Cyber system’s software was ill-suited for this mode of operation. Under the direction of Wirth and with the cooperation of the ETH Computation Center, the time sharing system Venus emerged in 1970. It met the stringent requirement of not infringing on the effectiveness of the batch processed number crunching tasks. Wirth programmed the Venus text editor; the system, although by now obsolescent, is still in daily use at ETH. It made it possible to introduce the concept of time-sharing to ETH, without which a modern computation center would be unthinkable.

Pascal-P, 1972-74
It had always been a major goal in the development of Pascal to demonstrate that structured languages need not be inferior to the predominant Fortran, if sufficient attention and care was paid to their implementation. But it soon became clear that industry had no interest in undertaking this demonstrations, although such engineering projects typically should fall into industry’s domain. A second Pascal compiler effort was therefore launched at ETH. The new compiler produced code that was as good as that generated by commercially developed Fortran compilers. Furthermore, this project served as a test for the method of stepwise program refinement propagated by Wirth. A fringe benefit was the welcome capability to satisfy requests to help implement Pascal on other computers, as these requests from other universities became more frequent. The solution lay in replacing the new compiler’s code generator by one producing code for a hypothetical architecture that was easily implemented on other machines in the form of a hand-coded interpreter. This architecture, stack-based, became known as the P-machine, its instruction set as P-code. (P for portable). It became the basis of the large majority of Pascal implementations which first appeared on large-scale computers (IBM, Univac, DEC, Siemens). But the genuine break-through occurred after microprocessors became widely available and it became clear that Pascal-P implementation was feasible for them (UCSD- Pascal).

Modula, 1973-76
Programming languages are mathematical theorems. They represent a methodology of programming, of abstract machine construction. In 1973, Wirth started a project to investigate the basic concepts of designing systems with concurrent processes, i.e. of multi- programming. The emerging design rules (guidelines) inevitably led to the formulation of language constructs expressing the generation and synchronization of concurrent activities. Their embedding in an environment of a minimal support language led to Modula. Implementation was conducted on a PDP-11 computer. A first successful application was the system Hexapus that allowed to connect minicomputers in laboratories with the Computation Center and is still in popular use today.

Lilith, 1977-1981
During a sabbatical year spent at the Xerox Palo Alto Research Center, Wirth was confronted with an entirely new concept in computer usage: the personal work station. Without the least doubt, the personal work station was superior to the conventional computation center almost wherever computers were used: for the computer scientist, the system designer, in the office, the laboratory, and in particular also in the class room. Unquestionably, the advances in microelectronics would make it possible to manufacture personal work stations economically within the next five years. Whoever had a work station at his disposal would be ahead in the development of software suitable to this new mode of operation. In 1977, Wirth initiated a research project to develop a powerful work station: Lilith. A primary objective was to combine the design of hardware and software. Thereby the project expanded into an integrated design effort for hardware, microcode, operating system, compiler, and elementary application programs. The new mode of highly interactive usage required new concepts concerning the operating system and editors.
Inspite of the enormous task, the goal was successfully reached within three years thanks to the intensive and dedicated work of up to seven assistants. Today, 60 Lilith computers are in daily use at the Institute at ETH, and about 250 more in universities and in industry (e.g. Burroughs, Floating-Point Systems, TRW, Tektronix, Signetics) in the USA. Lilith demonstrated that a workstation can be a powerful, convenient, and even economical tool not only in the office, but in applications which so far had been the exclusive domain of large scale computers, such as computer-aided design.

Apart from the operating system and the compiler, interactive editors belong to the basic software of a system intended for program development. Editors were to be designed in entirely new ways; after all, the challenge lay in making optimal use of the new facilities offered by the hardware, the high-resolution, bit-mapped screen, and the mouse as a position input device. Both the prototype text editor Dina and the editor Sil for line drawings were programmed by Wirth himself. Dina was the ancestor of the later document preparation systems Andra and Lara which allow arbitrary text layout and the use of many fonts, and Sil is heavily used to draw all kinds of diagrams, in particular circuit diagrams.

Perhaps the most significant contribution of the Lilith project was that it made it possible to conceive solutions that would not have been thinkable with commercially available products. The first 10 Liliths were installed in 1980, five years before similar systems were marketed.

Modula-2, 1977-1980
Among other things, it was the conscious restriction to use a single programming language only that made the completion of the Lilith project possible in such a short time. Wirth decided to design a revision of Pascal, sacrificing upward compatibility in return for the advantage of avoiding Pascal’s deficiencies: Modula-2. The principal new concepts were:
– The module as a unit of program which can be compiled separately.
– The coroutine as the basic buiding block for systems involving concurrent processes.
– An encapsulated set of types and procedures which allow access to machine-specific objects.

The first Modula-2 compiler was completed at ETH in 1979. It was implemented on a PDP-11 computer and then ported onto Lilith. The interest in Modula-2 soon grew, because it offered considerable advantages over Pascal, particularly in the construction of large systems developed by teams. The compiler was distributed to several hundred universities and places in industry, and soon there were companies offering their own developments (Logitech, Volition Systems, Tartan Laboratories). The advantages of Modula-2 were above all paying off in the development of the Lilith software itself. The compiler, the entire operating system, the editors, and all utilities were programmed exclusively in Modula-2. This demonstrated that the confinement to a single language is not only possible but even advantageous.

Computer-Network, 1980-82
The personal workstation gains enormously in value, if it is connected with other stations via a network. Impersonal stations, so-called servers, are of great importance, such as printers and central file stores. Under the direction of Wirth, a network interface was developed for Lilith, based on the principle of Ethernet. This 3 Mbit/s computer network was the first of its kind in Switzerland.

Laser Printer, 1982
Although Wirth had experienced the impressive versatility and the undisputable advantages of laser printers at Xerox in 1976, he had to wait until 1982 to obtain such a device at an affordable price. He acquired the first laser printer of this kind in Europe (Canon LBP-10), designed the hardware and software interface for Lilith, and thereby showed that Lilith was an ideal real-time computer to drive a laser printer’s video signal, powerful enough to generate the 6 million raster dots of a printed page while the page is moving past the printer’s drum. Under pressure to publish a book on Modula-2, he also programmed the document formatter system Skylla/Zeus, with which it was possible to produce the camera-ready original of the book.

Modula-2 Compiler, 1983-85
Over the years it became evident that the available Modula-2 compilers, including the one from ETH, were less than optimal, and through mediocre performance sometimes deterred users to take full advantage of Modula-2. Wirth decided to develop a new compiler from scratch by himself. It is based on the simple principle of one-pass compilation, whose application had become possible because of the large memories of modern computers, and which eliminates most of the slow accesses to secondary storage devices. The new compiler is remarkable because of its clear structure, its compactness and its efficiency. The program is about 5000 lines long, compared to 10’000 of its predecessor and 100’000 of comparable Ada compilers, and it compiles itself in less than 2 minutes, compared with half an hour required by its predecessor. These advantages are not only visible in the compiler’s use, but they demonstrate that powerful modern languages do not necessarily require giant, complex translators, as is so often claimed.

Ceres 1 – 3, 1984-1990
Five years after Lilith, a second project was started to develop a new workstation. Not the design of a new processor architecture stood in the foreground, but rather the acquisition of know-how in the structure and use of modern hardware technology, also in conjunction with software development. Hence, the computer was to be based on a commercially available microprocessor. The choice fell to the NS32000 family of National Semiconductor (then still called the 16000). After the completion of a prototype with the 32016 processor, both Wirth and co-designer H. Eberle felt that a new design should be based on a 32-bit scheme. The second prototype was therefore built around the NS32032 part, the first genuine 32-bit processor on the market. The memory consisted of 64 256K-DRAM and 32 novel, dual-port 64K-VRAM chips, the latter implementing the frame buffer for the 1024×800 bit-mapped display with minimal bus interference.
In early 1986 33 Ceres-1 computers were built by Hardmeier & Co. in Winterthur, and subsequently tested in our Institute, proving that our goals for robustness and cost effectiveness were well reached. They were immediately put into daily use for research and teaching. A second series was built in the following year.

Progress in semiconductor technology had accelerated to a degree that after only a few years much more powerful machines could be built, even with reduced cost. In 1987-88, Ceres-2 was developed, mostly by B. Heeb under Wirth’s supervision. It was based on the NS32532 processor, delivering a sevenfold increase in power over Ceres-1. The use of 1M-bit DRAMs facilitated the enlargement of memory to 4 or 8 Mbytes. 20 Ceres-2 machines were built by the same company in 1988.

The third model, Ceres-3, was designed in 1989 with the purpose of providing a low-cost workstation for student laboratories. The ratio of power vs. cost was of foremost concern. The station, built around the NS32GX32 processor, also had to operate without any moving parts in order to minimize maintenance cost and noise. No fan was to be used for cooling. The goals were met, and in 1990 100 Ceres-3 were built, all of them by a single engineer in four months. Since then, the machines are in use in offices and mostly student laboratories, connected by a network and served by a Ceres-1 server machine.

Oberon Language and System, 1986-1990
A sabbatical year at the Xerox Palo Alto Research Center (1984-85) brought Wirth into closer touch with the Cedar Operating System, developed in the preceding years at PARC. This was perhaps the first system truly tuned to the needs of personal workstations, and freed from the framework inherited from central computers with a batch processing mode. In daily use, however, Cedar showed all too clearly the symptoms of large software developed by large groups of people: it was bulky and unreliable. It had already become so complex, and its structure had become so intertwined that it was most difficult, if not impossible, to understand it. Wirth decided to undertake the development of a new system, based on concepts suggested by Cedar, but with the firm goal to keep its size such that it could be well understood as a whole, and could be explained in detail in the literature and in courses. Together with J. Gutknecht he worked on the conception and the detailed programming for the following 3-4 years, after which the basic, but easily extensible system was operational.
Although it was planned to use Modula-2 to implement the Oberon System, it soon became evident that a fundamental facility needed for extensibility was lacking: type extension. It was decided to also discard various facilities of lesser importance of Modula-2, and to construct a new, derived language and its compiler. Being an integral part of the project, the language also obtained the name Oberon.

Language and System soon became the standard tools in the Institute for software development, and in particular the development of system extensions. Wirth himself developed and programmed a graphics editor and software for the network connecting the Ceres workstations. A particular challenge was the design of a server station for printing, file distribution, and electronic mail, all together under the constraint of Oberon’s single process property. Using a simple, clear concept proved to be a large benefit; the server operates without failure continuously for years.

Hardware Design with Field Programmable Gate Arrays (FPGAs), 1990-1999
Similarity and difference between hardware and software design always had intrigued Wirth as a topic. With the emergence of programmable logic devices, the gap between the two fields narrowed. A project to familiarize a team with the new possibilities was established, and research in design methods using the new devices was started. It led to a set of design tools, including a specification language (Debora, B. Heeb), its compiler with several “back ends” for printed circuits boards, PLDs, and FPGAs. The usefulness of these tools was demonstrated by applying them in the construction of a workstation (Chamaeleon, also Ceres-3). The construction process starting from a textual specification and ending with a board layout and PLD programs was automated, and it required almost no manual intervention.
Wirth realized early, that FPGAs would be particularly useful as a field for experimentation in learning digital circuit design, replacing expensive, pluggable circuit modules by programmable cells. He equipped 25 Ceres-3 workstations in a student laboratory with an FPGA and uses them intensively in a digital design class. Along with a new project in tool design went the formulation of his language Lola, specifically tailored to the need of teaching in a systematic manner, dispensing with the myriads of side-issues inherent in commercial HDLs. The tool set consists of a compiler converting the program (circuit) text into an abstract data structure suitable for further processing, an editor for constructing circuits implemented by the FPGA, i.e. for generating a layout, and a checker comparing the specification in Lola with the layout.

Automatic Control of Model Helicopter
In 1995 Wirth joined a project undertaken at the Institute of Automatic Control and Measurement. The goal was the development of a system to allow a model helicopter to fly autonomously a preprogrammed path. Wirth designed an on-board computer system with a Strong-ARM processor at its core. Aside from the hardware, he also programmed various software tools, including an Oberon subset compiler with additional features for real-time programming. The computer board was built by I. Noack.
The resulting computer system, called Olga, made use of experience with programmable gate arrays, and used the novel Xilinx-Algotronix 6200 fine-grained FPGA for the generation and sensing of pulse-width modulated signals to control the servos. Furthermore, the computer was connected to a compass, a global positioning system (GPS), and a data link via several standard RS-232 interfaces. This system resulted in a drastic reduction of weight and power consumption, and an increase in computing performance compared to the one used before, in spite of the fact that floating-point arithmetic was to be programmed based on integer arithmetic.

The helicopter carrying Olga weighs about 15 kg and is powered by a 35ccm engine. Wirth pushed for a second project based on a downsized helicopter model with a weight of less than 5 kg and a conventional 10ccm engine. This was realized with a considerably smaller computer board, but the same Strong-ARM core and software base. The large FPGA was replaced by several small PLDs. This project, Horla, was confined to the more modest goal of using the computer only to stabilize the inherently unstable craft, while position, speed and direction would remain under remote control by the pilot.

Both projects collected in a remarkable way the various techniques and tools on which Wirth had worked during the past decade: Compiler, operating system, programmable devices (FPGA, PLD) and their design tools including the language Lola, and circuit design in general. Both projects were successful, although only after several years of effort – and patience.

Teaching
Wirth became professor at ETH in 1968. In 1970, he and his colleague C.A. Zehnder presented a proposal for the introduction of a curriculum in computer science. A second attempt to establish the subject as an academic discipline failed again in 1974. A new Department was finally established in 1981, and Wirth became its head from 1982 to 1984, and again 1988-1990.
Meanwhile, the computer science courses continued to be directed primarily towards the students of mathematics and electrical engineering. Wirth had a strong influence on the contents of the introductory courses and gave form to many of the advanced courses. Several times his lecture material condensed into books which became translated into many languages: Systematic Programming (1972), Algorithms and Data Structures (1975), Compiler Construction (1976). Also his books Pascal – User Manual and Report (1974), Programming in Modula-2 (1982), Programming in Oberon (1992), and Project Oberon (1993) are widely read.