Re: HELP: PL/0 Compiler

Ed Davis <ed_davis@my-deja.com>
1 Oct 2000 00:23:08 -0400

          From comp.compilers

Related articles
HELP: PL/0 Compiler planinc@cs.curtin.edu.au (2000-09-15)
Re: HELP: PL/0 Compiler ed_davis@my-deja.com (Ed Davis) (2000-10-01)
| List of all articles for this month |

From: Ed Davis <ed_davis@my-deja.com>
Newsgroups: comp.compilers
Date: 1 Oct 2000 00:23:08 -0400
Organization: Deja.com - Before you buy.
References: 00-09-106
Keywords: Pascal

    planinc@cs.curtin.edu.au (Adrian Planinc) wrote:
>
> I have been fiddling around with Niklaus Wirth's PL/0
> compiler.
>
> Namely, I've got a copy of the original Pascal source of the
> compiler and have explored the possibilities of adding
> further control structures to it as an exercise.
>
> I am especially interested if anyone has any ideas or even
> Pascal source lying around which implements a FOR construct.
> This is something I am having trouble with especially!


I too like fiddling around with that compiler. It seems to be a very
well written piece of code, and easy to modify.


Two other small compilers I like working with are Oberon-0 and
obfuscated C. The non-obfuscated version is very well written and is
about as easy to modify as pl/0.


I have a version of pl/0 I found on the net - not sure if it is
identical with the original, but it is pretty close. Anyway, I've
attempted to add the for statement, as in:


for ident := expr1 to|downto expr2 do statement;


Here is what I have come up with so far. In procedure statement, add
the following:


        end else if sym = forsym then begin
        { for var := expr to expr do statement; }
                getsym; { skip for }
                if sym <> ident then
                        error(0); { ident expected }
                i := position(id, tx);{ find in symtab }
                { make sure it is a variable }


                if i = 0 then
                        error(11) {ident not found in symtab}
                else if table[i].kind <> variable then begin
                        error(12); {assignment to non variable}
                        i := 0
                end;


                getsym; { skip ident }


                if sym = becomes then
                        getsym
                else
                        error(13); { expecting assignment operator }


                expression(lev, tx);
                gen(sto, lev - table[i].level, table[i].adr);
                if sym = downtosym then
                        d := -1
                else if sym = tosym then
                        d := 1
                else
                        error(0); { to|downto expected }
                getsym; { skip to|downto }
                expression(lev, tx);{ evaulate expr }
                gen(opr, 0, 15); { duplicate to expr value }
                { load index value }
                gen(lod, lev - table[i].level, table[i].adr);
                if d = 1 then { do comparison }
                        gen(opr, 0, 11) { >= }
                else
                        gen(opr, 0, 13);{ <= }
                j := cx;
                gen(jpc, 0, 0); { jump if needed }
                if sym = dosym then
                        getsym { skip do }
                else
                        error(18); {'do' required }


                statement(lev, tx);
                gen(opr, 0, 15); { duplicate to expr value }
                { load index value }
                gen(lod, lev - table[i].level, table[i].adr);
                gen(opr, 0, 9); { <> - compare with expr value }
                x := cx;
                gen(jpc, 0, 0);


                { load index value }
                gen(lod, lev - table[i].level, table[i].adr);
                {add 'd' to it }
                gen(lit, 0, d);
                gen(opr, 0, 2);
                gen(sto, lev - table[i].level, table[i].adr);


                gen(jmp, 0, j + 1); { jump back to top }
                code[j].a := cx; { fixup }
                code[x].a := cx; { fixup }
                gen(int, 0, -1); { pop left over 'to value' }
        end


Some additional notes:


I extended lit and int to also accept negative values. Originally,
they were declared as taking small positive numbers.


I added a 'dup top of stack' instruction.


Error recovery is non-existent.


Of course you will need to add the new keywords and symbols to the
appropriate tables.


I am thinking about converting this version to C and continuing on from
there. If anyone knows of an already existing C version, please let me
know!


If you add anything, or fix any of the bugs in the for statement code,
I would be glad hear from you.


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.