Releases: emkey1/pscal
v3.0 Release
Pscal v3.0.0
Date: 2025-10-20
Highlights
- New exsh front end – A Bash-compatible shell joins Pascal, CLike, Rea, and Tiny. exsh shares PSCAL’s builtin catalog, honours directory stacks, jobs, and traps, and now supports
-cinline execution, parity-focused regression tests, and detailed debug logging. - Faster VM dispatch – Builtin lookups are now hash-indexed and the VM caches procedure symbols by bytecode address, trimming dispatch costs across every language while keeping optional-module detection stable.
- Language feature growth – Pascal picks up
goto/labelsupport and compound assignment operators, while its dynamic array routines andLow/Highintrinsics are hardened. Rea’s CLI gains--no-runand refined tracing, backed by expanded scope-verification suites. - Stronger tooling –
Tests/run_all_testsauto-selects a writable temp directory and can be run from anywhere; the Rea harness survivesset -u; library runners spin up local HTTP servers with consistent summaries.
New
- Introduced the
exshshell front end with PSCAL builtin integration, Bash-style pipelines, directory-stack helpers, EXIT trap handling, and an opt-in debug log (Docs/exsh_debug_log.md). - Added Bash-compatible
-cexecution, logical-expression guards, and cached pipelines to exsh, improving benchmark parity and script ergonomics. - Pascal now accepts
goto/labelconstructs, compound assignment operators, and ships an enhanced Blackjack example with CRT scoreboard tracking. - Added
MStreamFromStringso Pascal/CLike code can convert strings to memory streams without manual temp files—a prerequisite for socket helpers and new network demos. - Rea CLI adds
--no-runfor compile-only workflows alongside refined bytecode dumps and trace-head limits; new class/closure/module scope suites validate OOP semantics.
Improvements
- Replaced the builtin registry with hash tables and cached procedure lookup metadata, preventing contention and shaving lookups for hot VM paths.
- Thread helpers grow
ThreadSpawnBuiltin,ThreadPoolSubmit,ThreadGetResult,ThreadGetStatus,ThreadSetName,ThreadLookup,ThreadStats,ThreadPause,ThreadResume, andThreadCancel, letting exsh queue allow-listed VM builtins on worker threads whileWaitForThreadand the new worker-lookup helpers report their cached status codes. Documentation now includes sample transcripts and the explicit allowlist for threaded builtins. - Inlined shell loop guards, added owned-string helpers, and deferred exit handling in logical contexts to eliminate performance regressions observed in shellbench.
- Updated SDL demos with corrected controls, shared font fallbacks, fast landscape rendering validation, and WASD zoom controls for the 3D bouncing balls showcase.
- Expanded documentation: compiler flags, exsh debugging, and Rea programmer guidance all reflect the new workflows.
Tests/run_all_testsnow establishes a writableTMPDIR, keeps network suites opt-in viaRUN_NET_TESTS=1, and shells into theTests/directory so directory-stack parity stays stable.- Rea’s regression harness gracefully handles empty skip lists and argument manifests under
set -u, preventing spurious macOS failures.
Fixed
- Resolved numerous exsh correctness issues: errexit is preserved across traps, redirection backups no longer collide, IO-number parsing matches Bash, and directory stacks now mirror Bash output under differing
$PWDroots. - Pascal dynamic array
SetLengthretains prior contents,Low/Highoperates on dynamic arrays, and multidimensional resizing no longer scrubs data. - Rea parser accepts type keywords as identifiers, constructor ordering is enforced, and cached bytecode invalidation respects binary timestamps.
- Eliminated double frees and stale metadata introduced during the builtin registry refactor and guarded thread helper detection.
- Corrected example glitches including Blackjack prompts, CRT colour artefacts, and SDL font paths.
Upgrade Notes
- Rebuild with
cmake -S . -B build -DRELEASE_BUILD=ONandcmake --build buildto ensure all front ends pick up the hash-based registry and procedure caches. Clean builds are recommended for downstream packagers. Tests/run_all_testsnow defaults toRUN_NET_TESTS=0. ExportRUN_NET_TESTS=1(and optionallyRUN_SDL=1) before invoking the script to exercise socket and HTTP fixtures as part of release verification.- Library regression suites (
Tests/libs/run_all_tests.py) start local HTTP servers; when running inside restricted environments you may need elevated permissions (passable via--pythonor sandbox approvals). - exsh scripts share PSCAL’s builtin catalog; rebuild or redeploy extended modules (SQLite, yyjson, OpenAI, etc.) alongside the VM so optional capabilities remain discoverable via
--dump-ext-builtins. - Threaded scripts should review the new Docs/threading.md guide. The worker pool still honours legacy handle-based APIs (
WaitForThread,ThreadGetStatus, etc.), and Pascal’sThreadingunit remains compatible—existing code keeps working while newer helpers add naming, metrics, and pool-size overrides.
Verification Checklist
cmake -S . -B build && cmake --build buildTests/run_all_tests(optionally exportRUN_NET_TESTS=1 RUN_SDL=1)TMPDIR=$PWD/Tests/tmp python3 Tests/libs/run_all_tests.py(requires local socket permissions)TMPDIR=$PWD/Tests/tmp python3 Tests/scope_verify/rea/rea_scope_test_harness.py- Spot-check flagship examples:
build/bin/exsh Examples/exsh/pipelinebuild/bin/exsh Examples/exsh/parallel-check github.com example.combuild/bin/pascal Examples/pascal/base/ThreadsProcPtrDemobuild/bin/clike Examples/clike/base/thread_demobuild/bin/rea Examples/rea/base/threads
What's Changed
- Fix SDL quit flag deadlock by @emkey1 in #934
- Sync Devel branch to main by @emkey1 in #985
- Allow Pascal @ to take general lvalues by @emkey1 in #1035
- Improve Mandelbrot thread scheduling by @emkey1 in #1036
- Add realtime clock extended builtin by @emkey1 in #1037
- Add CLI dumps for extended builtin inventory by @emkey1 in #1039
- Adopt MIT license for PSCAL by @emkey1 in #1040
- Add yyjson extended builtins by @emkey1 in #1038
- Gate Rea terminal init behind PSCAL_INIT_TERM by @emkey1 in #1041
- Add shared conditional preprocessor for extended builtin checks by @emkey1 in #1042
- Devel Merge to main by @emkey1 in #1043
- Exercise CLI options on all front ends by @emkey1 in #1044
- Add clike demo for sqlite and yyjson extended builtins by @emkey1 in #1045
- Skip run_with_timeout wrapper on Alpine by @emkey1 in #1046
- Enhance Pascal weather JSON demo by @emkey1 in #1047
- Add custom Xcode project generator by @emkey1 in #1049
- Free weather_json HTTP response stream by @emkey1 in #1050
- Fix Xcode project root path by @emkey1 in #1051
- Fix Xcode header search path for generated project by @emkey1 in #1052
- Fix Xcode generator version macros by @emkey1 in #1053
- Fix quoting in Xcode project macros by @emkey1 in #1054
- Make C-like AST type annotations optional by @emkey1 in #1055
- Handle unquoted build metadata in Xcode by @emkey1 in #1056
- Add Xcode runner target for configurable launch by @emkey1 in #1057
- Revert "Add Xcode runner target for configurable launch" by @emkey1 in #1059
- Add Xcode runner target for selectable PSCAL binaries by @emkey1 in #1058
- Fix debug global linkage for Xcode targets by @emkey1 in #1060
- Fix integer precision warnings by @emkey1 in #1061
- Load Xcode runner config from default locations by @emkey1 in #1062
- Clarify pascal args for Xcode runner by @emkey1 in #1063
- Add SDL include paths to the Xcode project by @emkey1 in #1066
- Revert "Add SDL include paths to the Xcode project" by @emkey1 in #1067
- Seed SDL include paths for Xcode builds by @emkey1 in #1065
- Include runner target in generated Xcode project by @emkey1 in #1068
- Fix CASE codegen to handle multiple labels by @emkey1 in #1069
- Add Rea OpenWeather forecast example by @emkey1 in #1070
- Hoist OpenWeather mstreams out of branch scopes by @emkey1 in #1071
- Fix Rea parser dropping function statements by @emkey1 in #1072
- Add C-like scope verification harness by @emkey1 in #1073
- Add scoped pattern matching and exception support to Rea by @emkey1 in #1075
- Align clike scope tests with C semantics by @emkey1 in https://github....
release/v2.3.1
Pscal v2.3.1
Date: 2025-10-05
Highlights
- OpenAI extended built-ins now ship a first-party chat completion bridge for Pascal, C-like, and Rea with helper libraries and demos.
- Rea adds a
--no-runmode, parser/class fixes, and a brand-new programmer's guide to speed up onboarding. - The OpenAI chat demo graduates into a generic OpenAI-compatible client with LM Studio presets, resilient JSON/UTF-8 handling, and transparent diagnostics.
- Runtime resilience improves via deeper Pascal unit fallbacks, portable builtin registry allocation, and restored
ReadKeybehaviour.
New
- Extended built-ins
- Added the optional
openaicategory withOpenAIChatCompletions(model, messagesJson, [optionsJson, apiKey, baseUrl]), delivering direct/chat/completionsaccess; toggle it with-DENABLE_EXT_BUILTIN_OPENAI=ON/OFF. - Shipped helper libraries under
lib/{pascal,clike,rea}/openaiso every front end can compose requests and extract assistant replies without hand-written JSON plumbing. - Documented the new category in
Docs/extended_builtins.md, including env-var fallbacks toOPENAI_API_KEYwhen no key is supplied at call time.
- Added the optional
- Examples & demos
- Added
Examples/pascal/base/OpenAINewApiDemo, demonstrating prompt assembly, option overrides, and environment-driven authentication for the new builtin. - Rebuilt the Rea chat sample into a reusable CLI that targets public OpenAI endpoints, local proxies, or LM Studio via system prompts, base/endpoint overrides, raw options JSON, and a
--lmstudioshortcut.
- Added
- Documentation
- Published
Docs/rea_programmers_guide.mdwith tooling walkthroughs, compiler flags, and bytecode workflows for the Rea front end. - Expanded the Rea CLI documentation to cover new flags, disassembly guidance, and extended builtin discovery helpers.
- Published
Improvements
- Rea front end & tooling
- Added
--no-runsoreacan compile programs without launching the VM, and taughtTests/run_rea_tests.shto exercise the flag alongside version, strict, and disassembly checks. - The regression harness now canonicalises repository paths, validates
--dump-ext-builtinsoutput, and shifts fixture mtimes safely for caching scenarios. - Scope verification suites picked up class-constructor coverage to guard object-oriented regressions.
- Added
- OpenAI chat tooling
- Request builders precompute buffer sizes, use dynamic strings for defaults, and emit full payload/authorization diagnostics to speed up API troubleshooting.
- LM Studio presets infer base URLs/endpoints, sanitise model identifiers, trim whitespace, and copy CLI arguments safely; a fallback selects the first advertised model when none is provided.
- Secrets logged from demos are masked entirely, and HTTP 400 responses now replay payloads, URLs, and contextual hints without exposing credentials.
- Runtime & libraries
- Pascal unit discovery probes additional relative directories so redistributed builds still locate
lib/pascalwithout manual--unit-pathtweaks. - The extended builtin registry replaced non-portable
strndupusage with an explicit allocator, improving compatibility with stricter libcs. - Sample Fibonacci programs now exit with status
1when rejecting oversized inputs to better signal failure to the shell.
- Pascal unit discovery probes additional relative directories so redistributed builds still locate
Fixed
- Rea language & CLI
- Class constructors execute exactly once with the correct scope resolution, restoring behaviour relied upon by the new regression tests.
- The parser now allows type keywords as identifiers in legal positions, eliminating spurious "unexpected keyword" errors.
ReadKeyhandling was restored after a bad merge so SDL keyboard input matches the 2.3.0 baseline.
- OpenAI integration
- Chat payload builders allocate correctly for empty message lists, declare helpers before use, and honour UTF-8 multibyte sequences so streamed replies render intact.
- LM Studio flows trim preset whitespace, sanitise model slugs, and honour presets without explicit models while copying CLI arguments reliably to the request payload.
- Secrets shorter than four characters are now fully masked, and diagnostics summarise payloads and endpoints when servers reject a request.
Build & Install
- Configure with
cmake -S . -B build [-DENABLE_EXT_BUILTIN_OPENAI=ON/OFF]alongside the existing SDL and extended builtin toggles, thencmake --build build.
Testing
Tests/run_rea_tests.shnow enforces canonical casing, verifies extended builtin dumps, and exercises the new--no-runpath; class scope regression fixtures backstop the constructor repairs.
Compatibility
OpenAIChatCompletionsdefaults tohttps://api.openai.com/v1and falls back toOPENAI_API_KEYwhen the API key parameter is empty; the Rea demo also honoursLLM_API_KEYfor local proxies.- The LM Studio preset expects a server on
http://127.0.0.1:1234; adjust the base URL or disable the preset when targeting other hosts. - Disable the
openaicategory at configure time when distributing to offline targets or toolchains without libcurl.
Known Notes
- The OpenAI builtin returns raw JSON. Use the supplied helper libraries or the demos as references when integrating with custom front ends.
- Network access and valid credentials remain mandatory for the
openaicategory; demo scripts surface 400-level hints but cannot recover from upstream configuration errors automatically.
What's Changed
- Fix SDL quit flag deadlock by @emkey1 in #934
- Sync Devel branch to main by @emkey1 in #985
- Allow Pascal @ to take general lvalues by @emkey1 in #1035
- Improve Mandelbrot thread scheduling by @emkey1 in #1036
- Add realtime clock extended builtin by @emkey1 in #1037
- Add CLI dumps for extended builtin inventory by @emkey1 in #1039
- Adopt MIT license for PSCAL by @emkey1 in #1040
- Add yyjson extended builtins by @emkey1 in #1038
- Gate Rea terminal init behind PSCAL_INIT_TERM by @emkey1 in #1041
- Add shared conditional preprocessor for extended builtin checks by @emkey1 in #1042
- Devel Merge to main by @emkey1 in #1043
- Exercise CLI options on all front ends by @emkey1 in #1044
- Add clike demo for sqlite and yyjson extended builtins by @emkey1 in #1045
- Skip run_with_timeout wrapper on Alpine by @emkey1 in #1046
- Enhance Pascal weather JSON demo by @emkey1 in #1047
- Add custom Xcode project generator by @emkey1 in #1049
- Free weather_json HTTP response stream by @emkey1 in #1050
- Fix Xcode project root path by @emkey1 in #1051
- Fix Xcode header search path for generated project by @emkey1 in #1052
- Fix Xcode generator version macros by @emkey1 in #1053
- Fix quoting in Xcode project macros by @emkey1 in #1054
- Make C-like AST type annotations optional by @emkey1 in #1055
- Handle unquoted build metadata in Xcode by @emkey1 in #1056
- Add Xcode runner target for configurable launch by @emkey1 in #1057
- Revert "Add Xcode runner target for configurable launch" by @emkey1 in #1059
- Add Xcode runner target for selectable PSCAL binaries by @emkey1 in #1058
- Fix debug global linkage for Xcode targets by @emkey1 in #1060
- Fix integer precision warnings by @emkey1 in #1061
- Load Xcode runner config from default locations by @emkey1 in #1062
- Clarify pascal args for Xcode runner by @emkey1 in #1063
- Add SDL include paths to the Xcode project by @emkey1 in #1066
- Revert "Add SDL include paths to the Xcode project" by @emkey1 in #1067
- Seed SDL include paths for Xcode builds by @emkey1 in #1065
- Include runner target in generated Xcode project by @emkey1 in #1068
- Fix CASE codegen to handle multiple labels by @emkey1 in #1069
- Add Rea OpenWeather forecast example by @emkey1 in #1070
- Hoist OpenWeather mstreams out of branch scopes by @emkey1 in #1071
- Fix Rea parser dropping function statements by @emkey1 in #1072
- Add C-like scope verification harness by @emkey1 in #1073
- Add scoped pattern matching and exception support to Rea by @emkey1 in #1075
- Align clike scope tests with C semantics by @emkey1 in #1074
- Fix struct initialization and printf translation by @emkey1 in #1076
- Fix Rea vtable emission and class constant lookup by @emkey1 in #1078
- Fix Rea scoping for grouped declarations by @emkey1 in #1079
- Flatten Rea declaration groups before semantic analysis by @emkey1 in https://github.com/emkey1/pscal/p...
V2.3.0 Release
Pscal v2.3.0
Date: 2025-10-01
Highlights
- Extended built-ins now bundle sqlite and yyjson support with CLI and runtime introspection so programs can detect optional capabilities.
- Landscape and Mandelbrot demos ship fast render paths by default, complete with validation fallbacks, refreshed visuals, and new graphics built-ins.
- Developer tooling reorganized around
Tests/libs, dedicated front-end runners, and a hand-maintained Xcode project that mirrors CMake targets. - Pscal now distributes under the MIT license, aligning with new third-party components and simplifying downstream redistribution.
New
- Extended built-ins
- Added the sqlite category with connection, statement, metadata, and binding helpers that work uniformly across Pascal, CLike, and Rea.
- Added the yyjson category, bundling the upstream parser and exposing document/query helpers plus smoke coverage for every front end.
- Introduced
--dump-ext-builtinson all binaries and new introspection routines (ExtBuiltinCategoryCount,HasExtBuiltin, etc.) so programs and tests can enumerate active categories, groups, and functions. - Added a
RealTimeClockhelper to the system category and ensured builtin identifiers remain stable even when optional modules are disabled.
- Graphics & demos
- Implemented a fast SDL landscape rendering pipeline with sky refreshes, improved sun/cloud shading, and water level configuration; the renderer now validates incoming terrain descriptors and falls back to the safe path when fast draw support is missing.
- Enabled the fast draw path by default for Rea landscape demos and surfaced runtime fallbacks when extended built-ins are omitted.
- Registered a
glCullFacebuiltin for the CLike front end and documented its usage in the graphics reference. - Optimized the SDL Mandelbrot example with multithreaded scheduling and tuned constants for smoother rendering on constrained devices.
- Languages & runtime
- Rea's lexer/parser now accepts
matchidentifiers, refines comment heuristics, and restores context-aware//handling so inline comments survive integer-division fixes. - Pascal's address-of operator works on array elements, and byte arguments now coerce safely when invoking integer-only builtins.
- CRT helpers track text attributes for the CLike runtime, enabling color-preserving libraries and test fixtures.
- Front ends share a conditional preprocessor so
#ifdefchecks can test for extended builtin categories at compile time.
- Rea's lexer/parser now accepts
- Tooling & IDE
- Examples reorganized into
Examples/{pascal,rea}/{base,sdl}families with updated assets and bake steps for vertex data. - Added a hand-maintained Xcode project and generator (
xcode/) with configurable run schemes for Pascal, CLike, and Rea binaries. - Documented the scope and library harnesses, updated AGENTS for the new layouts, and added explicit scripts for exercising each library suite.
- Examples reorganized into
Improvements
- HTTP helpers tolerate transport failures, cancellation, and throttled downloads; Pascal runtime warnings now log without aborting executions.
- GraphLoop accepts real-valued delays, validates inputs, and exposes the same behavior across SDL back ends and Rea demos.
- Module caches handle growing import lists without invalidating or leaking state, and extended builtin inputs are verified before reaching the renderer.
- Library test harnesses standardize gray output across Pascal and CLike suites, skip timeout wrappers on Alpine, and gained dedicated driver scripts.
- SDL demos refine plasma color ramps, bake landscape vertices before rendering, and correct control bindings and font packaging for bundled games.
Fixed
- Resolved compiler crashes triggered by byte-to-integer parameter coercions and kept builtin ID assignments consistent across optional builds.
- Landscape demos clamp terrain min/max parameters, recompute MVP matrices correctly, and repair movement controls introduced during refactors.
- Rea scope and comment handling now keeps identifiers in
matchexpressions, respects inline comments, and improves module cache growth handling. - Block game and landscape samples restore
OutTextXYusage, active piece rendering, and water level initialization. - Weather JSON demos free HTTP resources, normalize UNIX timestamp formatting, and round temperatures before display.
Build & Install
- Configure with
cmake -S . -B build [-DSDL=ON] [-DBUILD_DASCAL=ON] [-DENABLE_EXT_BUILTIN_SQLITE=ON/OFF] [-DENABLE_EXT_BUILTIN_YYJSON=ON/OFF]. - Build via
cmake --build build -jand install withcmake --install build(installs front ends, VM, decompiler, JSON compiler, and optional completions). - The Xcode project in
xcode/mirrors these targets and exposes configurable runners for rapid iteration without CMake regeneration.
Testing
- Use
Tests/run_pascal_tests.sh,Tests/run_clike_tests.sh, andTests/run_rea_tests.shfor targeted library suites;Tests/run_all_suites.pyaggregates them when needed. - SDL tests default to dummy drivers; set
RUN_SDL=1for real hardware. Network suites remain behindRUN_NET_TESTS=1to preserve offline runs. - Extended builtin enumeration and sqlite/yyjson smoke tests honor
REA_TEST_EXT_BUILTINSandREA_TEST_HAS_YYJSONin environments without optional modules.
Compatibility
- VM bytecode cache version remains
PSCAL_VM_VERSION = 7; bytecode from v2.21 continues to load without recompilation. - sqlite support expects an available system SQLite3 library; disable the category when packaging for targets without it.
- The bundled yyjson library carries an MIT license, matching the project's updated licensing.
--dump-ext-builtinsemits a line-oriented inventory consumed by the new harnesses; keep scripts in sync if you alter its format.
Known Notes
- Fast landscape rendering depends on the graphics extended built-ins; when disabled, the demo automatically falls back to the previous renderer.
- SDL graphics still require real video/audio drivers when dummy backends are not configured.
What's Changed
- Fix SDL quit flag deadlock by @emkey1 in #934
- Sync Devel branch to main by @emkey1 in #985
- Allow Pascal @ to take general lvalues by @emkey1 in #1035
- Improve Mandelbrot thread scheduling by @emkey1 in #1036
- Add realtime clock extended builtin by @emkey1 in #1037
- Add CLI dumps for extended builtin inventory by @emkey1 in #1039
- Adopt MIT license for PSCAL by @emkey1 in #1040
- Add yyjson extended builtins by @emkey1 in #1038
- Gate Rea terminal init behind PSCAL_INIT_TERM by @emkey1 in #1041
- Add shared conditional preprocessor for extended builtin checks by @emkey1 in #1042
- Devel Merge to main by @emkey1 in #1043
- Exercise CLI options on all front ends by @emkey1 in #1044
- Add clike demo for sqlite and yyjson extended builtins by @emkey1 in #1045
- Skip run_with_timeout wrapper on Alpine by @emkey1 in #1046
- Enhance Pascal weather JSON demo by @emkey1 in #1047
- Add custom Xcode project generator by @emkey1 in #1049
- Free weather_json HTTP response stream by @emkey1 in #1050
- Fix Xcode project root path by @emkey1 in #1051
- Fix Xcode header search path for generated project by @emkey1 in #1052
- Fix Xcode generator version macros by @emkey1 in #1053
- Fix quoting in Xcode project macros by @emkey1 in #1054
- Make C-like AST type annotations optional by @emkey1 in #1055
- Handle unquoted build metadata in Xcode by @emkey1 in #1056
- Add Xcode runner target for configurable launch by @emkey1 in #1057
- Revert "Add Xcode runner target for configurable launch" by @emkey1 in #1059
- Add Xcode runner target for selectable PSCAL binaries by @emkey1 in #1058
- Fix debug global linkage for Xcode targets by @emkey1 in #1060
- Fix integer precision warnings by @emkey1 in #1061
- Load Xcode runner config from default locations by @emkey1 in #1062
- Clarify pascal args for Xcode runner by @emkey1 in #1063
- Add SDL include paths to the Xcode project by @emkey1 in #1066
- Revert "Add SDL include paths to the Xcode project" by @emkey1 in #1067
- Seed SDL include paths for Xcode builds by @emkey1 in #1065
- Include runner target in generated Xcode project by @emkey1 in #1068
- Fix CASE codegen to handle multiple labels by @emkey1 in #1069
- Add Rea OpenWeather forecast example by @emkey1 in #1070
- Hoist OpenWeather mstreams out of branch scopes by @emkey1 in #1071
- Fix Rea parser dropping function statements by @emkey1 in #1072
- Add C-like scope verification harness by @emkey1 in https://github.com/emkey...
Release v2.2.1
Highlights
- Bytecode & VM: Dedicated
TO_BOOL, direct field/array load instructions, and explicit builtin/user procedure call opcodes make truthiness and dispatch consistent across front ends, plus other internal optimizations to improve performance of the VM. - Language front ends: Pascal, CLike, and Rea gain XOR expressions, Rea adds a
nilliteral, and Pascal introduces anoverride builtindirective for intentional overrides. - Tooling & Tests: All compilers understand
--no-cache, regression scripts run cache-free, and a new Pascal PerformanceBenchmark program exercises the VM. - Reliability: Deferred global initializer handling keeps constructors, vtables, and mutex registries ordered correctly even under nested
newcalls and spawned threads.
New
- Bytecode & VM
- Added
TO_BOOLto normalize truthiness without extraNOTsequences. - Introduced
LOAD_FIELD_VALUE,LOAD_FIELD_VALUE16,LOAD_ELEMENT_VALUE, andLOAD_ELEMENT_VALUE_CONSTso the VM can fetch record and array values directly. - Added
CALL_BUILTIN_PROCandCALL_USER_PROC, storing builtin IDs alongside names and allowing user procedures (including nested Pascal routines and constructors) to be invoked by name.
- Added
- Front-end languages
- Pascal and CLike now parse and fold
xorexpressions, emitting the VM's native XOR opcode; Rea lexes the keyword as well. - Rea recognizes a
nilliteral and usesTO_BOOLfor short-circuiting so boolean expressions match Pascal/CLike semantics. - Pascal's lexer accepts ASCII identifiers on all libc implementations and comment directives such as
// override builtin fibonaccito silence intentional builtin replacements.
- Pascal and CLike now parse and fold
- CLI & Docs
- Pascal, CLike, and Rea CLIs gained
--no-cacheto force recompilation, and documentation for standalone front ends now covers the new builtin procedure call flow. - Added
Examples/Pascal/PerformanceBenchmark, a comprehensive workload that overrides builtin math routines, along with updated language reference notes.
- Pascal, CLike, and Rea CLIs gained
What's Changed
- Add SDL OpenGL initgraph support by @emkey1 in #938
- Move SDL GL swap builtins to 3D module and document front-end usage by @emkey1 in #939
- Register SDL GL builtins in front ends by @emkey1 in #940
- Add 3D SDL demos for each front end by @emkey1 in #941
- Add seeded Rea terrain demo and SDL helpers by @emkey1 in #942
- Support scientific notation in Rea numbers by @emkey1 in #943
- Register cast builtins globally by @emkey1 in #944
- Fix extended builtin registration for mandelbrotrow by @emkey1 in #945
- Add StopAllSounds builtin and use it to halt pwav playback by @emkey1 in #980
- Use CALL_BUILTIN_PROC in CLike and update Rea expectations by @emkey1 in #986
- Update CLike CALL emission for CALL_USER_PROC by @emkey1 in #987
- Add XOR opcode support by @emkey1 in #988
- Add comprehensive Pascal benchmark program by @emkey1 in #989
- Add Rea short-circuit regression and document boolean semantics by @emkey1 in #990
- Fix ProcessPeople benchmark for PSCAL parser by @emkey1 in #991
- Add direct field/element load opcodes and update tests by @emkey1 in #992
- Add directive to silence builtin override warnings by @emkey1 in #993
- Clamp string growth in ManipulateStrings benchmark by @emkey1 in #994
- Optimize local increment bytecode by @emkey1 in #995
- Fix INC_LOCAL to support enumerated loop variables by @emkey1 in #996
- Extend performance benchmark workload by @emkey1 in #997
- Optimize peephole patterns and restore Mandelbrot example by @emkey1 in #998
- Prevent default console colors from forcing black background by @emkey1 in #999
- Simplify Sierpinski threads parameter handling by @emkey1 in #1000
- Add constant array access bytecode optimization by @emkey1 in #1001
- Restore legacy write builtin id by @emkey1 in #1002
- Update disassembly expectations for write builtin id by @emkey1 in #1003
- Fix format warnings in logging utilities by @emkey1 in #1004
- Ensure extended builtins register compiler metadata by @emkey1 in #1005
- Fix Pascal cached message scan warnings by @emkey1 in #1006
- Fix cached stderr scan without memmem by @emkey1 in #1007
- Make dascal ASan optional when unavailable by @emkey1 in #1008
- Ensure Pascal cache invalidates when units change and support no-cache test runs by @emkey1 in #1009
- Fix Pascal lexer identifier detection on musl by @emkey1 in #1010
- Speed up regression test scripts by @emkey1 in #1011
- Stabilize builtin IDs across optional SDL builds by @emkey1 in #1012
- Fix Rea vtable addresses after peephole optimization by @emkey1 in #1013
- Allow SDL input without renderer by @emkey1 in #1014
- Fix SDL landscape movement and switch to mouse look by @emkey1 in #1015
- Optimize SDL landscape rendering by @emkey1 in #1016
- Fix Rea method calls exhausting frame locals by @emkey1 in #1017
- Fix jump alignment in LandscapeDemo by tracking slot usage by @emkey1 in #1020
- Fix camera-relative movement in SDL landscape demo by @emkey1 in #1021
- Parallelize terrain build with worker slices by @emkey1 in #1023
- Allow INC_LOCAL/DEC_LOCAL to update real slots by @emkey1 in #1024
- Refactor SDL landscape demo to OOP architecture by @emkey1 in #1025
- Fix dynamic locals misclassifying globals as locals by @emkey1 in #1026
- Fix Rea method call type retention by @emkey1 in #1027
- Add nil literal support to Rea front-end by @emkey1 in #1028
- Fix constructor invocation for parameterless new expressions by @emkey1 in #1029
- Add hangman5 regression test for vtable emission by @emkey1 in #1030
- Add release notes for v2.21 by @emkey1 in #1031
- Handle missing killpg in run_with_timeout helper by @emkey1 in #1033
- Add release notes for v2.21 by @emkey1 in #1032
- Fix terminal raw mode handling for ReadKey by @emkey1 in #1034
Full Changelog: v2.2...v2.2.1
v2.2 Release
Lots of new stuff and bug fixes. Probably some new bugs as well. See below and release notes for additional information.
What's Changed
- Use Pascal erase builtin with clike remove alias by @emkey1 in #490
- Fix Dos GetTime example and update builtins documentation by @emkey1 in #491
- docs: restore builtin examples and reorganize math builtins by @emkey1 in #492
- Handle precision in clike printf formatting by @emkey1 in #494
- Fix Chudnovsky term initialization and recurrence by @emkey1 in #495
- Add explicit INT32/DOUBLE type support by @emkey1 in #497
- Fix duplicated type enums after merge by @emkey1 in #498
- Fix type coercion and float read handling by @emkey1 in #499
- Use extended real types in Chudnovsky demos and builtin by @emkey1 in #500
- Add long double support to clike and runtime by @emkey1 in #501
- Handle all numeric types in readln builtin by @emkey1 in #502
- feat: add compound assignment support by @emkey1 in #503
- Use 64-bit ints for numeric literals by @emkey1 in #504
- Allow factorial and fibonacci to accept all integer types by @emkey1 in #505
- Handle non-ordinal types in vmBuiltinSucc by @emkey1 in #506
- Fix byte/word Inc/Dec handling by @emkey1 in #507
- Fix GetDate var handling in DOS unit by @emkey1 in #508
- Fix float comparison in clike pointer torture test by @emkey1 in #509
- Fix dynamic array in mandelbrot_row example by @emkey1 in #510
- Orient Mandelbrot row example traditionally by @emkey1 in #511
- Orient Mandelbrot row example traditionally by @emkey1 in #512
- Add sizeof operator to CLike front end. by @emkey1 in #513
- Support char array string initialization in CLike by @emkey1 in #514
- Handle small terminals in MandelbrotRow example by @emkey1 in #515
- Fix byte array handling for SDL demos by @emkey1 in #516
- Center SDL Mandelbrot output by @emkey1 in #517
- Fix upcase builtin char type handling by @emkey1 in #518
- docs: clean up documentation and missing sections by @emkey1 in #519
- Expose VM version query and optional compatibility checks by @emkey1 in #520
- Add registry and query API for extended builtins by @emkey1 in #522
- Handle char as integer-like value by @emkey1 in #521
- Fix char comparison in switch by @emkey1 in #523
- Handle paramcount as wide integer by @emkey1 in #524
- Fix CLike numeric literal constant lookup by @emkey1 in #525
- Fix SDLInteractiveMandelbrot fractal rendering by @emkey1 in #526
- Fix integer ++/-- promoting to float by @emkey1 in #527
- Disallow implicit int-to-real conversions by @emkey1 in #528
- Overload min/max to preserve integer results by @emkey1 in #529
- Add Unicode char support by @emkey1 in #530
- Fix CaseStatementSuite test output to remove stray escape sequence by @emkey1 in #531
- Fix char range and numeric mixing in Pascal VM by @emkey1 in #532
- Fix CLike array tests by allowing numeric promotion by @emkey1 in #533
- Allow mixed numeric comparisons in VM by @emkey1 in #534
- Allow implicit int-to-real conversions by @emkey1 in #535
- Merge current (tested) Devel Branch back to Main by @emkey1 in #536
- Add basic VM threading support with scheduler by @emkey1 in #537
- Add thread spawn and join support to Pascal front end by @emkey1 in #538
- Add basic threading primitives to C-like frontend by @emkey1 in #539
- Fix thread join scheduling to avoid hanging child threads by @emkey1 in #540
- Escape newlines in disassembler output by @emkey1 in #541
- Add thread-safe Mandelbrot builtin and threaded SDL example by @emkey1 in #542
- Fix threaded SDL Mandelbrot example by @emkey1 in #543
- Properly emit global array dimensions in CLike by @emkey1 in #544
- Add thread opcode disassembly support by @emkey1 in #545
- Fix spawn lookup for camelCase functions by @emkey1 in #546
- Fix forward function calls in CLike compiler by @emkey1 in #547
- Update threaded SDL Mandelbrot example to render incrementally by @emkey1 in #548
- Update threaded SDL Mandelbrot example to render incrementally by @emkey1 in #550
- Allow join on array expressions in CLike by @emkey1 in #551
- Document multithreading support across VM and frontends by @emkey1 in #552
- Use thread-local terminal state by @emkey1 in #553
- Guard builtin registry with mutex by @emkey1 in #554
- Make core builtins thread safe by @emkey1 in #555
- Enable multithreaded VM scheduler by @emkey1 in #556
- Guard extended builtin registry for multithreaded access by @emkey1 in #557
- Add extended thread spawn/join debug test by @emkey1 in #558
- Ensure threaded Mandelbrot quits on Q by @emkey1 in #559
- Ensure threaded Mandelbrot quits on Q by @emkey1 in #560
- Add mutex constructs with standard and recursive support by @emkey1 in #561
- Add mutex coordination to threaded Mandelbrot example by @emkey1 in #562
- Skip global mutex for constant globals by @emkey1 in #563
- Make dascal build optional by @emkey1 in #564
- Handle lowercase quit key in SDL examples by @emkey1 in #565
- Expose topper() in C-like front end by @emkey1 in #566
- Rename clike front-end functions to CamelCase by @emkey1 in #567
- Use lowerCamelCase for helper and builtin functions by @emkey1 in #568
- Improve runtimeError messages for upcase builtin by @emkey1 in #569
- Fix locals for spawned CLike functions by @emkey1 in #570
- Relocate remaining Pascal frontend files under Pascal directory by @emkey1 in #571
- Handle varying working directories in ApiSendReceiveTest by @emkey1 in #572
- Avoid locking during delay builtin by @emkey1 in #573
- docs: add threading notes for extended built-ins by @emkey1 in #574
- refactor: conditionally lock builtins by @emkey1 in #577
- Use threads and mutex in interactive Mandelbrot example by @emkey1 in #576
- Handle mixed boolean and integer operands in logical ops by @emkey1 in #578
- Fix SDL event polling for interactive Mandelbrot example by @emkey1 in #579
- Treat boolean as integer-like for CLike by @emkey1 in #580
- Fix interactive Mandelbrot example exit handling by @emkey1 in #581
- Align interactive Mandelbrot demo with threaded main by @emkey1 in #584
- Restore zoom controls to interactive Mandelbrot demo by @emkey1 in #585
- Restore zoom controls to interactive Mandelbrot demo by @emkey1 in #586
- Restore zoom controls to interactive Mandelbrot demo by @emkey1 in #587
- Fix mouse input handling in SDL Mandelbrot interactive example by @emkey1 in #588
- Avoid real indexing in interactive Mandelbrot demo by @emkey1 in #589
- Add regression test for integer promotion by @emkey1 in #590
- Ensure G...
PSCAL v2.1
Pscal v2.1
Date: 2025-09-05
This release delivers substantial improvements to the CLike front-end, adds compile-only (disassembly) modes to both front-ends, expands regression test coverage, and strengthens CI.
Highlights
- New flags for compile-only workflows:
--dump-bytecode: compile and disassemble, then execute.--dump-bytecode-only: compile and disassemble, then exit (no execution).
- VM concurrency:
- Lightweight threads with spawn/join exposed via both front-ends.
- Mutexes (standard and recursive) with create/lock/unlock/destroy APIs for safe synchronization.
- CLike semantics:
- Short-circuit logical
&&and||. - Shift operators
<<and>>with standard precedence and left-associativity. - Improved
~behavior on integers (bitwise-like via(-x - 1)); non-integers fall back to logical NOT.
- Short-circuit logical
- Examples: all compile (dump-only mode) under headless SDL defaults.
- CI: builds, runs tests, and compiles all Examples in dump-only mode.
Getting Started
cmake -S . -B build [-DSDL=ON]
cmake --build build
# Pascal
build/bin/pascal --dump-bytecode-only Examples/Pascal/hello
# CLike
build/bin/clike --dump-bytecode-only Examples/clike/helloSDL
- When built with
-DSDL=ON, the CLike preprocessor definesSDL_ENABLEDso you can guard code:
#ifdef SDL_ENABLED
// SDL graphics/audio
#endif- Headless defaults: test scripts set
SDL_VIDEODRIVER=dummyandSDL_AUDIODRIVER=dummy(skip SDL tests). - To run SDL content, set
RUN_SDL=1and a real video driver.
Environment Variables
CLIKE_LIB_DIR: search directory for CLike imports.PASCAL_LIB_DIR: root library directory for Pascal units (.pl).SDL_VIDEODRIVER,SDL_AUDIODRIVER,RUN_SDL: control SDL behavior for tests/examples.
Compatibility
- VM bytecode cache version:
PSCAL_VM_VERSION = 5.
Changes Since v2.0
- Front-ends: new compile-only flags in Pascal and CLike.
- VM: added/lightened support for concurrency with threads and mutexes (including recursive mutexes). Tests demonstrate spawn/join and mutex id reuse.
- CLike: parser/codegen upgraded for shifts and short-circuit; improved
~for integers. - Tests: added CLike and Pascal cases; VM-oriented checks.
- Examples: fixed
chudnovsky_nativeconstant literal typing. - Docs: updated README and tutorial for options, semantics, SDL, and env vars.
- CI: compiles all Examples in dump-only mode, in addition to test suites.
Known Notes
~uses an arithmetic expansion for integer types; there is no dedicated VM bitwise-not opcode.- Shifts are supported for integer-like types; shifting real values is not meaningful and should be avoided.
Enjoy!
Bug Fix Release, Document Update/Fix
Mostly a bug fix/documentation update.
What's Changed
- Add interactive zoom to SDL MandelbrotRow demo by @emkey1 in #459
- Fix boolean check in SDL Mandelbrot example by @emkey1 in #460
- Add const qualifier to CLike by @emkey1 in #462
- Handle allocation and I/O errors by @emkey1 in #464
- Run CacheStalenessTest using temporary sources by @emkey1 in #465
- Implement Str() builtin for Pascal, itoa() for CLike by @emkey1 in #467
- Fix fillrect usage in clike Space Game demo by @emkey1 in #468
- docs: tidy and expand documentation by @emkey1 in #469
- Merge pull request #462 from emkey1/codex/add-missing-clike-functiona… by @emkey1 in #470
- Merge most recent Devel branch additions/changes by @emkey1 in #471
- Add documentation index to Docs directory by @emkey1 in #472
- Support enum arithmetic in Pascal for loops by @emkey1 in #473
- Fix enum output for writeln by @emkey1 in #474
- Organize extended builtins into categories by @emkey1 in #475
- Add configurable extended builtin categories by @emkey1 in #476
- Normalize StringUtil unit filename by @emkey1 in #478
- Make builtins case-insensitive by @emkey1 in #479
- Register SetLength builtin for Pascal by @emkey1 in #480
- Fix SetLength var parameter handling and add regression test by @emkey1 in #481
- Check initializer types in variable declarations by @emkey1 in #482
- Fix sort_string example to sort through pointer by @emkey1 in #483
- Fix linked list example for CLike front end by @emkey1 in #484
- Fix linked list example for CLike front end by @emkey1 in #485
- Fix linked list example for CLike front end by @emkey1 in #486
- Fix REPL output for clike interpreter by @emkey1 in #487
- Fix REPL output for clike interpreter by @emkey1 in #488
- Merge most recent Development Changes by @emkey1 in #489
Full Changelog: v2.0...v2.0.1
Release 2.0
PSCAL Project Overview
At the time of this writing PSCAL is possibly the world's largest and most complex vibe coding project. It was created primarily
with Gemini 2.5 Pro's Coding partner and more recently, Open AI's Codex utilizing GPT-5. Other AI tools were utilized in early
development, which dates back to March of 2025. This release comes just nine days after the initial release. See the "What's
Changed" section below for details on how much has changed in that time. One of many additions was the creation and
incorporation of a new front end reminiscent of C.
PSCAL is an extensible virtual machine and compiler suite implemented in C. The project ships with multiple frontends that all
target the shared, stack-based virtual machine:
- Pascal compiler: A frontend for a Pascal-like language with a hand-written lexer and parser.
- Clike compiler: A compact, C-style language frontend that includes its own preprocessor and a REPL for interactive sessions.
- Tiny compiler: An educational frontend written in Python.
All frontends generate a compact bytecode stream that is executed by the VM. This virtual machine provides a rich set of built-in routines and offers optional integrations with SDL2 for graphics and audio, and libcurl for networking. The system is
designed to be easily extensible, allowing for the addition of new built-in functions.
Core Architecture
The project follows a classic compiler and virtual machine design:
- Frontends: Each frontend is responsible for parsing its respective language (Pascal-like or C-like) and constructing an Abstract Syntax Tree (AST).
- Compiler: A compiler processes the AST, performs semantic analysis (for the C-like language), and generates bytecode. The C-like frontend also includes an optimization pass to improve the generated code.
- Virtual Machine (VM): A stack-based VM executes the bytecode, providing a portable runtime environment.
- Symbol Table: A hash table-based symbol table manages variables, functions, and types during compilation.
Key Features and Capabilities
- Dual Language Support: The ability to compile both Pascal-like and C-like code to the same bytecode is a major feature.
- Graphics and Audio: Through SDL bindings, the language supports creating graphical applications with audio capabilities, including window creation, shape and text rendering, and sound playback.
- Networking: A networking API using
libcurlallows for making HTTP requests and handling responses. - Rich Built-in Library: A comprehensive set of built-in functions is provided for:
- File I/O (
readln,writeln,fileexists). - Math (
sin,cos,sqrt,factorial,fibonacci,chudnovsky). - String manipulation (
copy,pos,length). - System interaction (
getpid,dos_exec).
- File I/O (
- Bytecode Caching: To speed up subsequent runs, the compiler can cache bytecode for source files that have not been modified.
How It Works
- Parsing: Source code is processed by the appropriate lexer and parser to build an Abstract Syntax Tree (AST).
- Semantic Analysis: For the C-like language, a semantic analysis pass checks the AST for correctness, such as type errors.
- Compilation: The compiler traverses the AST to generate a portable, low-level bytecode representation of the program.
- Execution: The virtual machine executes the bytecode. As a stack-based machine, it uses a stack for data manipulation and calculations while processing the bytecode instructions.
Requirements
- C compiler with C11 support
- CMake 3.24 or newer
- libcurl
- Optional: SDL2, SDL2_image, SDL2_mixer and SDL2_ttf when building with
-DSDL=ON
Building
mkdir build && cd build
cmake .. # add -DSDL=ON to enable SDL support
makeTo explicitly disable SDL support:
cmake -DSDL=OFF ..Testing
After compiling, run the regression suite:
cd Tests; ./run_all_testsDirectory Layout
- src/: Core compiler(s) and virtual machine sources
- backend_ast: Contains the backend of the compiler, focusing on the Abstract Syntax Tree (AST). It includes the code for built-in functions and interface.s
- clike: The complete frontend for the C-like language.
- compiler: Contains core components of the compiler that are shared across the different language frontends such as bytecode definition and the portion that translates the AST into bytecode.
- core: Houses fundamental utilities and data structures used throughout the project. This includes implementations for lists, bytecode caching, and common type definitions.
- ext_builtins: The source code for additional, "external" built-in functions. This modular design allows for new features to be added to the language easily.
- pascal: The Pascal-like language frontend, containing its lexer, parser, and AST implementation.
- symbol: The implementation of the symbol table, which is a critical component for the compiler to manage identifiers such as variables and functions.
- vm: The source code for the stack-based virtual machine that executes the bytecode produced by the front ends.
- lib/pascal/: Standard library units written in Pscal
- lib/clike/: Standard modules written in clike
- lib/sounds/: Audio assets shared by front ends
- Examples/: Sample programs for each front end
- Docs/: Project and language documentation
- tools/: Additional front ends and utilities (e.g. tools/tiny)
- Tests/: Regression suite
License
Pscal is released under The Unlicense.
What's Changed
- Support Chr/Ord in compile-time expressions by @emkey1 in #202
- Add stubs for SDL graphics builtins by @emkey1 in #203
- Ensure SDL window opens for Multi Bouncing Balls by @emkey1 in #205
- Removed AST Interpreter by @emkey1 in #206
- chore: apply camelCase naming for vm helpers by @emkey1 in #207
- Add standalone VM executable by @emkey1 in #208
- Allow integer to word coercion for delay built-in by @emkey1 in #209
- Fix EOF file parameter handling by @emkey1 in #210
- Avoid double free of VM global symbol table by @emkey1 in #211
- Fix double free in VM cleanup by @emkey1 in #212
- Fix VM loading for bytecode-only runs by @emkey1 in #213
- Serialize type definitions for VM runtime by @emkey1 in #214
- Mark enum members as constants for caching by @emkey1 in #215
- Allow integer constants for BYTE parameters by @emkey1 in #216
- Serialize procedure return types in bytecode cache by @emkey1 in #217
- Devel by @emkey1 in #218
- Add Tiny language compiler by @emkey1 in #220
- fix: ignore curly-brace comments in tinyc lexer by @emkey1 in #221
- Detect integer overflow in VM arithmetic by @emkey1 in #222
- Document integer overflow limits in language reference by @emkey1 in #223
- Add tiny language examples for tinyc compiler by @emkey1 in #224
- Allow 'write' without expression in tiny compiler by @emkey1 in #225
- docs: guide for custom VM frontends by @emkey1 in #226
- Add Tiny C front end for stand-alone VM by @emkey1 in #227
- Add tinycc examples by @emkey1 in #228
- Add tinycc wrapper with verbose diagnostics by @emkey1 in #229
- Add tinycc wrapper with verbose diagnostics by @emkey1 in #230
- Link tinyc target with SDL libraries by @emkey1 in #232
- Link tinyc target with SDL include and link paths by @emkey1 in #233
- Add SDL backend sources for tinyc build by @emkey1 in #234
- Fix TinyC lexer and parser to fully implement grammar by @emkey1 in #235
- feat: add function support to tinyc frontend by @emkey1 in #236
- Use OP_WRITE_LN for printf in tinyc by @emkey1 in #237
- Add scanf support to tinyc using readln by @emkey1 in #238
- Use scanf for input in Tiny C factorial example by @emkey1 in #239
- Fix tinyc main setup and local variable initialization by @emkey1 in #240
- Add tests for tinyc frontend by @emkey1 in #241
- docs: document tiny and tinyc frontends by @emkey1 in #242
- Merge latest dev stuff by @emkey1 in #243
- Preserve symbol tables in AST copies by @emkey1 in #244
- Fix upvalue resolution in nested routines by @emkey1 in #245
- Implement inline directive support in compiler by @emkey1 in #246
- Handle inline functions by @emkey1 in https://github.com/...
Release 1.0
Initial Release. I've tested everything I can think of, but there are probably still some bugs.
I've spent almost no time looking at the Interpreter portion of the code and will likely remove it before the next release. There is a reasonably functional version of the Interpreter only code in a separate branch.
Compiles and runs on MacOS 15.6 and Debian 12.6, likely to compile on most Linux distress. You'll need SDL2 libraries if you want graphics and sound support.
More information below...
Pascal Interpreter and Bytecode VM
This C program is a comprehensive implementation of a Pascal compiler and interpreter. It's designed to take Pascal source code and execute it in one of two ways: either by directly interpreting a structured representation of the code or by compiling it into a compact bytecode format and running it on a virtual machine.
Core Components
The program is logically divided into several key parts:
-
Frontend: This is responsible for reading and understanding the Pascal source code.
- The Lexer (
frontend/lexer.c) scans the source text and converts it into a stream of tokens (like keywords, identifiers, and operators). - The Parser (
frontend/parser.c) takes these tokens and builds an Abstract Syntax Tree (AST), which is a tree-like structure that represents the code's logic.
- The Lexer (
-
Backend: This is where the program is actually executed. There are two backend options:
- AST Interpreter (
backend_ast/interpreter.c): This backend "walks" through the AST and executes the code's logic directly. - Bytecode Compiler & VM: This is a two-step process:
- The Compiler (
compiler/compiler.c) traverses the AST and translates it into a lower-level, more efficient format called bytecode. - The Virtual Machine (VM) (
vm/vm.c) then executes this bytecode. This is generally faster than interpreting the AST directly.
- The Compiler (
- AST Interpreter (
-
Core Utilities: These are the foundational pieces that support the rest of the program.
- A Symbol Table (
symbol/symbol.c) keeps track of all the variables, procedures, and functions in the code. - A rich set of Built-in Functions (
backend_ast/builtin.c) provides standard Pascal functionalities likewriteln,readln, mathematical functions, and more.
- A Symbol Table (
Execution Flow
When you run the program, it typically follows these steps:
- Parsing: The
main.cfile orchestrates the process, starting with the lexer and parser to build the AST from a given Pascal source file. - Execution Choice: Based on command-line flags, the program decides which backend to use.
- If the AST interpreter is chosen, it directly executes the AST.
- Otherwise, it proceeds to the compilation step.
- Compilation (Optional): The compiler generates bytecode from the AST. This bytecode can be cached (
core/cache.c) to avoid recompiling the same file on subsequent runs. - VM Execution (Optional): The VM takes the bytecode and runs the program.
Key Features
This isn't just a simple interpreter; it has a number of advanced features:
- Cross-Platform Graphics: It includes bindings to the SDL library (
backend_ast/sdl.c), allowing Pascal code to create windows, draw shapes, render text, and handle mouse and keyboard input. - Audio Support: It can load and play sound files (
backend_ast/audio.c). - Networking: There's a built-in API for making network requests (
backend_ast/builtin_network_api.c), enabling the Pascal code to interact with web services. - Modular Design: The code is well-organized into different directories and files, each with a clear responsibility. This makes it easier to understand and maintain.
- Dual Execution Modes: The ability to switch between an AST interpreter and a bytecode VM is a sophisticated feature that allows for flexibility (e.g., easier debugging with the interpreter, better performance with the VM).
In short, this is a feature-rich and well-structured implementation of the Pascal programming language, complete with modern capabilities like graphics, sound, and networking.
What's Changed
- Avoid undefined behavior in string lowering helper by @emkey1 in #1
- Make SDL optional by @emkey1 in #2
- Initialize strings before Readln by @emkey1 in #3
- Initialize local array variables by @emkey1 in #4
- Handle fixed-length global strings in VM by @emkey1 in #5
- Support type tokens in low/high and test char bounds by @emkey1 in #6
- Handle global enum variable initialization by @emkey1 in #7
- Discover tests via script location by @emkey1 in #8
- Add PSCAL env override and binary check to tall script by @emkey1 in #9
- Simplify CASE branch jump logic by @emkey1 in #10
- Support file variable initialization in bytecode by @emkey1 in #11
- Implement Low/High for char and enums by @emkey1 in #12
- Handle enum type propagation and comparisons by @emkey1 in #13
- Handle string file IO and add regression tests by @emkey1 in #14
- Handle char type for low/high builtins by @emkey1 in #15
- Handle enum types correctly across parser, symbols, and VM by @emkey1 in #16
- Adjust word node type declaration in hangman example by @emkey1 in #17
- Add optional SDL build targets and central executable list by @emkey1 in #18
- Use pointer alias for Hangman word list nodes by @emkey1 in #19
- Guard disassembler from invalid field constants by @emkey1 in #20
- Support 16-bit field name indices for record access by @emkey1 in #21
- Support 16-bit global name indices in VM and compiler by @emkey1 in #22
- Add 16-bit global definition opcode by @emkey1 in #23
- Support 16-bit global type name operands by @emkey1 in #24
- Add opcode for initializing local pointer variables by @emkey1 in #25
- Handle const definitions with 16-bit global indices by @emkey1 in #26
- Support more arithmetic in compile-time evaluation by @emkey1 in #27
- Add RenderCopy procedures and test by @emkey1 in #28
- Rename SDLInteractiveMandelbrot constants to avoid globals by @emkey1 in #29
- Evaluate nested const arithmetic by @emkey1 in #30
- Remove bytecode emission for const declarations by @emkey1 in #31
- Use 16-bit constant indices for array bounds by @emkey1 in #32
- Handle enum arguments in succ by @emkey1 in #33
- Handle low(char) as character type and test ordinal zero by @emkey1 in #34
- Improve readln type detection by @emkey1 in #35
- Use unsigned char for character builtins by @emkey1 in #36
- Handle ordinal return types for succ, low, high by @emkey1 in #37
- Handle enums in succ builtin by @emkey1 in #38
- docs: clarify optional SDL2 dependency by @emkey1 in #39
- docs: describe building without SDL by @emkey1 in #40
- Conditionally run SDL tests and examples by @emkey1 in #41
- Handle succ for enum values by @emkey1 in #42
- Handle enum metadata in succ builtin by @emkey1 in #43
- Handle fixed-length strings in value copying by @emkey1 in #44
- refactor: centralize value helpers by @emkey1 in #46
- refactor: centralize record and array helpers in utils by @emkey1 in #45
- Add reusable set helpers and VM set operations by @emkey1 in #47
- Ensure Low(char) test uses chr(0) by @emkey1 in #48
- Preserve string type when assigning chars by @emkey1 in #49
- Ensure Tests Makefile only runs existing test files by @emkey1 in #50
- Add SDL initialization checks to RenderCopyRect builtins by @emkey1 in #51
- Support nested procedure scopes by @emkey1 in #52
- Add upvalue support for nested routines by @emkey1 in #53
- Fix string element access base pointer by @emkey1 in #54
- Add logging for nested env and test nested variable access by @emkey1 in #55
- Add CharAt nested function to nested routine test by @emkey1 in #56
- Add exit builtin and routine exit flag by @emkey1 in #57
- Reset exit flag after rout...