uLisp relies on the processor stack to handle return addresses and local variables.
On the ARM and AVR processors supported by uLisp the stack grows down from the top of RAM, so you can increase the size of available stack by reducing the amount of dynamic memory allocated to the uLisp workspace.
However, on the ESP32 uLisp runs inside the Arduino loop() task, which is implemented as a FreeRTOS task with a fixed 8 KB stack. This stack size is independent of the amount of RAM allocated to the uLisp workspace, and is unaffected by the presence of PSRAM. The consequence is that uLisp programs requiring deep recursion may overflow the stack on the ESP32, even though they run correctly on other platforms.
In a future release of uLisp I’m considering switching it to run in a separate FreeRTOS task with a larger stack (for example 32 KB) to overcome this limitation.
Examples
Some examples on the ESP32-P4 with PSRAM:
Sudoku solver
With default 8 KB stack - won’t run.
With FreeRTOS 32 KB stack - works fine.
Infinite precision arithmetic
With default 8 KB stack - maximum calculation 2^127 (iex 2 127)
With FreeRTOS 32 KB stack - maximum calculation 2^1023 (iex 2 1023)
Testing
I need to do more testing to ensure that this approach will be compatible with all the ESP32 variants that uLisp supports. In the meantime I can post the changes you need to make to uLisp 4.9 if you’re interested in testing this yourself (it’s only four changes).