Awesome
PPLEngine
An engine for PPL/PPE PCBoard handling - just for fun.
Features:
- A new decompiler/disassembler engine (ppld)
- A compiler (pplc) that compiles UTF-8/CP437 files to output CP437 PPEs
- A runtime (pplx) that runs .PPE files on console
- A language server that provides developer functionality in any editor that supports lsp
Why are you doing this?
Just for fun. Started this project initially to learn rust.
What works
- Decompiler is pretty complete (report bugs!). I would say it's better than everything we had back in the 90'.
- Compiler should be able to parse a PPS and generate running PPE files
- Runner should basically work.
- Started to implement a LSP to provide syntax highlighting and tooltips.
Decompiler
Decompiler is completely rewritten and can disassemble now on top of recompilation.
-
PPE 3.40 Support
-
Reconstruction of control structures currently is broken due of a rewrite of the decompiler if you want then/elseif/else, while…endwhile, for…next, break & continue, select case support go back to b67e861a734c57c1a7b2fb891725260ae6d7f343 The new decompiler infrastructure is much better and the decompilation result should be 100% correct. (The old one may contain bugs) And it supports 15.4 but the AST is a bit different so the reconstruction needs to be rewritten.
The old source could be used as starting point - but the new one has way better tools for AST analyzation that should be used instead of the old hacky approach.
-
It tries to do some name guessing based on variable usage.
PCBoard Programming Language Decompiler
Usage: ppld [OPTIONS] <FILE>
Arguments:
<FILE> file[.ppe] to decompile
Options:
--raw raw ppe without reconstruction control structures
-d, --disassemble output the disassembly instead of ppl
--output output to console instead of writing to file
--style <STYLE> keyword casing style, valid values are u=upper (default), l=lower, c=camel
-h, --help Print help
-V, --version Print version
The dissamble output can be used to see what the compilers are generating and for debugging purposes.
Compiler
Supports up to 15.4 PPL (1.0 -> 3.40 PPE format)
Should be compatible to the old PCB compiler with some slight differences (see PPL differences)
The compiler automatically generates user variables, if needed but behavior can be changed with command line options. It does some optimizations so it should produce smaller & faster exectuables than the original one.
pplc has following options:
PCBoard Programming Language Compiler
Usage: pplc [OPTIONS] <FILE>
Arguments:
<FILE> file[.pps] to compile (extension defaults to .pps if not specified)
Options:
-d, --disassemble output the disassembly instead of compiling
--nouvar force no user variables
--forceuvar force user variables
--nowarnings don't report any warnings
--ppl-version <PPL_VERSION> version number for the compiler, valid: 100, 200, 300, 310, 330 (default), 340
--dos input file is CP437
-h, --help Print help
-V, --version Print version
As default the compiler takes UTF8 input - DOS special chars are translated to CP437 in the output.
Note: All old DOS files are usually CP437 - so it's recommended to use --dos for compiling these.
PPL differences
The aim is to be as compatible as possible.
- Added keywords that are invalid as identifiers (but are ok for labels):
LET
,IF
,ELSE
,ELSEIF
,ENDIF
,WHILE
,ENDWHILE
,FOR
,NEXT
,BREAK
,CONTINUE
,RETURN
,GOSUB
,GOTO
,SELECT
,CASE
,DEFAULT
,ENDSELECT
I think it improves the language and it's open for discussion. Note that some aliases like "quit" for the break keyword is not a keyword but is recognized as 'break' statement. I can change the status of a keyword so it's not a hard limit - as said "open for discussion".
- Added
€
as valid identifier character. (for UTF8 files) - Return type differences in function declaration/implementation is an error, original compiler didn't care.
Runner
- pplx is able to run several PPEs on command line still has many limits but it's usable
- Feel free to request support for missing PPEs there are still bugs
PCBoard Programming Language Execution Environment
Usage: pplx [OPTIONS] <FILE>
Arguments:
<FILE> file[.ppe] to run
Options:
-s, --sysop if set, the executable will run in sysop mode
-h, --help Print help
-V, --version Print version
Runner differences
Fixed an recursion bug:
DECLARE PROCEDURE FOO(VAR BYTE X)
BYTE C
FOO(C)
PRINTLN "End value:", C
PROCEDURE FOO(VAR BYTE X)
BYTE LOC
LOC = X + 1
if (X > 2) RETURN
X = X * 2
PRINTLN LOC ,":", X
FOO(LOC)
PRINTLN LOC ,":", X
X = LOC
ENDPROC
The value of LOC changes between prints but does not in PCBoard. pcboard prints:
1:0
2:2
3:4
3:4
2:2
1:0
End value:1
Correct is:
1:0
2:2
3:4
3:4
3:2
3:0
End value:3
Would be easy to simulate the bug (just swap local write back & variable write back in endproc handling). But I don't assume that this bug affects any existing PPEs.
TODO
- Execution engine needs to be completed.
- Real Compiler/Decompiler support for 15.4 (debugging the old dos pplc/pcobard is the way to go here)
- Possible rewrite the expression decompilation part - it's hard to follow atm.
- LSP needs to be extended - find references, rename, code completion etc.
Building & Running
- Get rust on your system https://www.rust-lang.org/tools/install
cd PPLEngine
cargo build -r
running in release mode:
cd target/release
./ppld [PPEFILE]
./pplx [PPEFILE]
./pplc [PPLFILE]
Result is printed to stdout
Testing the lsp using vs code:
cd ppl-lsp
pnpm i
cargo build
then start vs code with
code .
And run from inside vs code the project with F5. A new vs code opens with PPL support. (Still need to figure out how to plug in the lsp for other editors)