A Pascal compiler frontend written in TypeScript, organized as an npm-workspaces monorepo. Each stage is published as its own npm package, but they evolve together here.
source.pas
│
▼
┌──────────────────┐ tokens ┌───────────────┐ AST ┌────────────────────┐ JS
│ pascal-tokenizer │ ───────▶ │ pascal-parser │ ──────▶ │ pascal-js-compiler │ ────▶ output.js
└──────────────────┘ └───────────────┘ └────────────────────┘
│ tokens
▼
┌────────────────────────┐
│ pascal-code-formatter │ ──▶ pretty Pascal
└────────────────────────┘
| Package | npm | Description |
|---|---|---|
pascal-tokenizer |
Lexer: turns Pascal source into a token stream. | |
pascal-parser |
Builds an AST from the token stream. | |
pascal-js-compiler |
Code generation: emits JavaScript from the AST. | |
pascal-code-formatter |
Pretty-prints / formats Pascal source. |
The pipeline is now complete end to end: pascal-js-compiler closes it by turning
the parser's AST into runnable JavaScript.
playground/ is an interactive web app: type Pascal and watch the
tokens, AST, formatted source and compiled JavaScript update live — then hit Run to
execute the compiled output in the browser. Its editor is syntax-highlighted by the
toolchain's own tokenizer.
Run it locally:
cd playground && npm install && npm run devnpm install # install all workspace deps (links packages together)
npm run build # build every package
npm test # run every package's testsThe toolchain currently parses and compiles a usable procedural subset:
program,const,var, andprocedure/function(with by-value parameters, local declarations, and recursion).var(by-reference) parameters are parsed but not compiled: the code generator rejects them rather than emit code that silently fails to propagate mutations to the caller.- statements: assignment (
:=),if/then/else,while,for..to/downto,repeat..until,case..of,begin..end, and procedure calls - expressions with full precedence, parentheses, and the operators
+ - * /,div,mod,and,or,not(boolean operands only — the bitwise integer overload ofand/or/notis not supported), and the relational set - one-dimensional arrays (
array[lo..hi] of T) with 1-based indexing writeln/writemapped toconsole.log/process.stdout.write
See ROADMAP.md for what's next (records, multi-dim arrays, …).
Versioning and publishing are handled with Changesets; each package keeps its own version and is published under its own unique name.
npm run changeset # describe the change + bump
npm run version-packages # apply version bumps
npm run release # build + publish changed packagesMIT © Damian Sire