This project is rather large and the work is not that linear. To make the logs readable I will from time to time rewrite them.
Project logs:
- Convert SC.PAS to SimpleC.c(done).
- Adjust the code for the CPU word width and memory model (done).
- Build tool train(done):
- Subleq code generator (using the Simple Compiler OpCodes as input),
- Subleq Assembler, and
- Subleq Interpreter.
- Modify the Simple Compiler to export OpCodes to suit OpCode2Subleq.
- Link up and debug the tool chain (done):
- SimpleC -> OpCode2Subleq -> Subleq_Asm -> Subleq_Int
Mission Completed
I now have a working Subleq Compiler. Yes it is very primitive and very very slow but that can be made better.
Here is the test code ("1.SC"):
begin A=4 B=1 if A<B then write A*10<b else begin write 1<B*10 write B*10, (a+b)*(-5) end C=-1 write C endHere is the tool chain in action:
C:\AlanX\SimpleC\OpCode2Subleq>SimpleC -o 1.opc 0<1.sc Tokenised Code: Line 1: BEGIN Line 2: A = 4 Line 3: B = 1 Line 4: IF A < B THEN Line 5: WRITE A * 10 < B Line 6: ELSE BEGIN Line 7: WRITE 1 < B * 10 Line 8: WRITE B * 10 , ( A + B ) * ( - 5 ) Line 9: END Line 10: C = - 1 Line 11: WRITE C Line 12: END Done. C:\AlanX\SimpleC\OpCode2Subleq>OpCode2Subleq -i 1.opc -o 1.sasm C:\AlanX\SimpleC\OpCode2Subleq>Subleq_Asm -i 1.sasm -o 1.code -l 1.list C:\AlanX\SimpleC\OpCode2Subleq>Subleq_Int -i 1.code -l 1.list -t 1.trace SUBLEQ Interpreter 1 10 -25 -1 Interpreter finished C:\AlanX\SimpleC\OpCode2Subleq>pause Press any key to continue . . .
Speed
The interpreter takes a full 4 seconds to execute! Hard to believe anything could be this slow.
Code Size
- 1.sc - 12 lines
- 1.opc - 74 lines including the header (95 words)
- 1.sasm - 3126 lines including comments (5530 words)
Improvements
Rather than fix/improve Simple Compiler it may be better to port a more complete compiler to work with OpCode2Subleq.
The tool train would suit a Transport Triggered Architecture (TTA) like my "Weird CPU" if the word size is increased from 8 bits to 12 bits or 16 bits.
Conclusion
Subleq is horribly inefficient.
PL/0
It is pretty clear that the root source of most of these simple compilers is Wirth's PL/0 as the language syntax (i.e. the expression part) is identical with the same names, omissions and unary minus fault. Unfortunately they did not carry through the rest of PL/0.
I have sourced Wirth's original PLZero Pascal source code which I will follow for upgrades to Simple Compiler.
Tokeniser
I have split the tokeniser out of Simple Compiler as it can be done and it reduces the code size of Simple Compiler.
String Tokens
I prefer working with string tokens (e.g. "IF" than working with integer tokens (e.g. _if) as I don't need a list of token definitions. So I will rework the code to suit.
PL/0 in C
Ported Wirth's PL/0 Pascal source code into C. Now I am a native Pascal programmer and Wirth was the Inventor of Pascal. So it is a bit sad that I ported his code to C.
PL/0 Extensions
The basic PL/0 is a bit primitive (no strings!). So I have added arrays and (Pascal) strings. It also recognise the majority of dialects I have seen. But no built in functions, or user functions or procedure parameter lists. I am not trying to clone a full version of Pascal, just a very basic compiler for home brew CPUs.
The compiler syntax error reporting needs a bit of work to be more helpful, and finally there are no run-time checks!
But overall I am very happy with this little compiler.
P-Code to Subleq
The PL/0 compiler exports "P-Code". This needs to be translated into Subleq. There are 26 Instructions to recognise. Few of the instructions are simple.
AlanX
add llvm r code generate