Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 63 additions & 63 deletions README.MD → README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#PL/0 Compiler
# PL/0 Compiler

This Python-based Compiler converts PL/0 source code into CL/0 virtual machine code. Both are educational languages with the aim to get faster to the real handwork of compiler-construction.

Expand Down Expand Up @@ -33,26 +33,26 @@ Additional Features
## Examples

### Hello World
~~~~
```basic
! "Hello World!".
~~~~
```

### Arithmetic expressions
~~~~
```basic
!- 3+ (-4).
~~~~
```

### I/O
~~~~
```basic
VAR input;
BEGIN
?input;
!input
END.
~~~~
```

### If
~~~~
```basic
VAR a,b;
BEGIN
?a;
Expand All @@ -68,12 +68,12 @@ BEGIN

IF ODD a THEN !7
END.
~~~~
```

### If-Else

If-Else Odd-Number tester
~~~~
```basic
VAR input;
PROCEDURE main;
BEGIN
Expand All @@ -90,10 +90,10 @@ BEGIN
END
END;
CALL main.
~~~~
```

Extended If-Else with a third case using Else-If.
~~~~
```basic
CONST pHNeutral=7;
VAR input;
PROCEDURE main;
Expand All @@ -105,10 +105,10 @@ BEGIN
ELSE !"Acid"
END;
CALL main.
~~~~
```

### While-Loop
~~~~
```basic
VAR a, fak;
BEGIN
?a;
Expand All @@ -121,10 +121,10 @@ BEGIN
! fak
END
END .
~~~~
```

### Define Procedures/ Constants/ Variables
~~~~
```basic
CONST a=5;
VAR b;
PROCEDURE main;
Expand All @@ -134,17 +134,17 @@ PROCEDURE main;
!b
END;
CALL main.
~~~~
```

### Procedures with parameters
~~~~
```basic
PROCEDURE f(x);
!x;
CALL f(7331).
~~~~
```

Exponentiation programm using a self implemented pow function
~~~~
```basic
VAR result,i,a,b;
PROCEDURE pow(base,power);
BEGIN
Expand All @@ -161,10 +161,10 @@ BEGIN
?b;
CALL pow(a,b)
END.
~~~~
```

### For-Loop
~~~~
```basic
CONST k=5;
VAR i,j;
PROCEDURE main;
Expand All @@ -175,10 +175,10 @@ BEGIN
END
END;
CALL main.
~~~~
```

### Arrays
~~~~
```basic
VAR x[4],i;
BEGIN
FOR(i:=0; i < 4; i:=i+1)
Expand All @@ -187,10 +187,10 @@ BEGIN
!x[i]
END
END.
~~~~
```

Sorting numbers
~~~~
```basic
VAR x[5],i,j,tmp;
BEGIN
/* Initialize "random" int vector*/
Expand All @@ -214,10 +214,10 @@ BEGIN
FOR(i:=0; i < 5; i:=i+1)
!x[i]
END.
~~~~
```

### Recursion
~~~~
```basic
CONST a=5;
VAR b;
PROCEDURE sub;
Expand All @@ -232,20 +232,20 @@ PROCEDURE main;
CALL sub
END;
CALL main.
~~~~
```

### Logical Expressions
~~~
```basic
BEGIN
IF { ODD 1 AND NOT ODD 1} OR NOT ODD 1 THEN
!1
ELSE
!2
END.
~~~
```

### Number guessing game
~~~~
```basic
/*
* Number-Guessing Game
*
Expand Down Expand Up @@ -307,22 +307,22 @@ BEGIN
END
END;
CALL main.
~~~~
```

## Language specification
~~~
```ebnf
<PROGRAM> ::= <BLOCK> '.'.
<BLOCK> ::= [ <CONSTANT_LIST> ]
[ <VARIABLE_LIST> ]
{ <PROCEDURE> } <STATEMENT>.
<CONSTANT_LIST> ::= 'CONST' <CONSTANT_DECLARATION> {',' <CONSTANT_DECLARATION>} ';'.
<CONSTANT> ::= ident '=' number.
<VARIABLE_LIST> ::= 'VAR' <VAR_DECLARATION> {',' <VAR_DECLARATION> } ';'.
<VARIABLE_DECLARATION> ::= ident [ '[' number ']' ].
<PROCEDURE> ::= 'PROCEDURE' ident ['(' [ <PARAMETER_LIST_DECLARATION> ] ')' ] ';' <BLOCK> ';'.
<PROCEDURE_CALL> ::= 'CALL' ident ['(' [ <PARAMETER_LIST_CALL> ] ')' ]
<PARAMETER_LIST_DECLARATION> ::= ident {',' ident }
<PARAMETER_LIST_CALL> ::= <EXPRESSION> {',' <EXPRESSION> }
{ <PROCEDURE> } <STATEMENT> .
<CONSTANT_LIST> ::= 'CONST' <CONSTANT_DECLARATION> { ',' <CONSTANT_DECLARATION> } ';' .
<CONSTANT> ::= ident '=' number .
<VARIABLE_LIST> ::= 'VAR' <VAR_DECLARATION> { ',' <VAR_DECLARATION> } ';' .
<VARIABLE_DECLARATION> ::= ident [ '[' number ']' ] .
<PROCEDURE> ::= 'PROCEDURE' ident [ '(' [ <PARAMETER_LIST_DECLARATION> ] ')' ] ';' <BLOCK> ';' .
<PROCEDURE_CALL> ::= 'CALL' ident [ '(' [ <PARAMETER_LIST_CALL> ] ')' ]
<PARAMETER_LIST_DECLARATION> ::= ident { ',' ident }
<PARAMETER_LIST_CALL> ::= <EXPRESSION> { ',' <EXPRESSION> }
<STATEMENT> ::= <ASSIGNMENT>
| <PROCEDURE_CALL>
| <INPUT_STATEMENT>
Expand All @@ -331,27 +331,27 @@ CALL main.
| <CONDITIONAL_STATEMENT>
| <LOOP_STATEMENT>
| <FOR_STATEMENT>
| 'RETURN'.
<COMPOUND_STATEMENT> ::= 'BEGIN' <STATEMENT> { ';' STATEMENT } 'END'.
<INPUT_STATEMENT> ::= '?' ident.
<OUTPUT_STATEMENT> ::= '!' (string | <EXPRESSION>).
<ASSIGNMENT> ::= ident ':=' <EXPRESSION>.
<ARRAY_INDEX> ::= '[' <EXPRESSION> ']'.
<CONDITIONAL_STATEMENT> ::= 'IF' <LOGICAL_EXPRESSION> 'THEN' <STATEMENT> ['ELSE' <STATEMENT>].
| 'RETURN' .
<COMPOUND_STATEMENT> ::= 'BEGIN' <STATEMENT> { ';' STATEMENT } 'END' .
<INPUT_STATEMENT> ::= '?' ident .
<OUTPUT_STATEMENT> ::= '!' ( string | <EXPRESSION> ) .
<ASSIGNMENT> ::= ident ':=' <EXPRESSION> .
<ARRAY_INDEX> ::= '[' <EXPRESSION> ']' .
<CONDITIONAL_STATEMENT> ::= 'IF' <LOGICAL_EXPRESSION> 'THEN' <STATEMENT> [ 'ELSE' <STATEMENT> ] .
<CONDITION> ::= 'ODD' <EXPRESSION>
| <EXPRESSION> ('=' | '#' | '<' | '<=' | '>' | '>=') <EXPRESSION>.
<LOOP_STATEMENT> ::= 'WHILE' <LOGICAL_EXPRESSION> 'DO' <STATEMENT>.
<FOR_STATEMENT> ::= 'FOR' '(' <ASSIGNMENT> ';' <LOGICAL_EXPRESSION> '; <ASSIGNMENT> ')' <STATEMENT> .
<EXPRESSION> ::= ['+' | '-'] term { ('+' | '-') <TERM> }.
<TERM> ::= <FAKTOR> { ( '*' | '/' ) <FAKTOR> }.
| <EXPRESSION> ( '=' | '#' | '<' | '<=' | '>' | '>=' ) <EXPRESSION> .
<LOOP_STATEMENT> ::= 'WHILE' <LOGICAL_EXPRESSION> 'DO' <STATEMENT> .
<FOR_STATEMENT> ::= 'FOR' '(' <ASSIGNMENT> ';' <LOGICAL_EXPRESSION> ';' <ASSIGNMENT> ')' <STATEMENT> .
<EXPRESSION> ::= [ '+' | '-' ] term { ( '+' | '-' ) <TERM> } .
<TERM> ::= <FAKTOR> { ( '*' | '/' ) <FAKTOR> } .
<FACTOR> ::= ident [ <ARRAY_INDEX> ]
| number
| '(' <EXPRESSION> ')'.
<LOGICAL_EXPRESSION> ::= LOGICAL_TERM {'OR' LOGICAL_TERM}.
<LOGICAL_TERM> ::= ['NOT'] LOGICAL_FACTOR {'AND' ['NOT'] LOGICAL_FACTOR}.
| '(' <EXPRESSION> ')' .
<LOGICAL_EXPRESSION> ::= LOGICAL_TERM { 'OR' LOGICAL_TERM } .
<LOGICAL_TERM> ::= [ 'NOT' ] LOGICAL_FACTOR { 'AND' [ 'NOT' ] LOGICAL_FACTOR } .
<LOGICAL_FACTOR> ::= CONDITION
| ( '{' LOGICAL_EXPRESSION '}').
~~~
| ( '{' LOGICAL_EXPRESSION '}' ) .
```


## Architecture
Expand All @@ -369,9 +369,9 @@ The lexical analyzer (short: lexer) transforms source code into tokens and provi
It does this transformation on-demand, when the parser asks for the next token.
One token can be a symbol, number, or a whole variable identifier.
Let's take the Hello-World programm as an example:
~~~~
```basic
!"Hello World".
~~~~
```

The lexer would identify and transform this program into the following three tokens:
- SYMBOL (!)
Expand Down Expand Up @@ -426,4 +426,4 @@ EDIT: The crossed out features managed itself to get to the actual feature list.

## License

(C) 2019 [Raphael Pour](https://raphaelpour.de), licensed under [GPL v3](http://www.gnu.de/documents/gpl-3.0.de.html)
(C) 2019 [Raphael Pour](https://raphaelpour.de), licensed under [GPL v3](http://www.gnu.de/documents/gpl-3.0.de.html)