Skip to content

Commit 3a14ffb

Browse files
Mini Lisp interpreter in OMC + display_frame_name for trace stability
A working Scheme dialect implemented entirely in OMC. ~430 lines. Demonstrates pattern matching under load (every Lisp form is a match arm in lisp_eval) and stress-tests every recent feature. Forms: define, lambda, if, let, quote (and `'`), begin Builtins: + - * / = < > <= >=, car cdr cons list, null? pair?, not, display, newline. 11 sample programs run to completion in the demo, including: - higher-order map written in the Lisp itself - fact(10) = 3628800 via real recursion - real lexical closures: ((lambda (n) (lambda (x) (+ x n))) 5) - quoted lists, nested let, multi-form programs with comments - try/catch around lisp_run catching "undefined: ghost" Architectural notes from writing it: * OMC dicts pass by value, so an env passed as a parameter can't be mutated by the callee. The fix that worked: env is a closure PAIR [lookup_fn, define_fn] capturing a shared dict by Rc<RefCell> through the closure environment. All env ops go through the closures; mutations stick across function boundaries. This is the same trick the log_analyzer counter table used at smaller scale, now load-bearing. * `break` works inside match arms: tokenizer's nested-loop sentinel workarounds vanished once I remembered OMC has it. Worth a README mention. Bonus: display_frame_name() in interpreter.rs collapses internal auto-generated lambda identifiers (`__rt_lambda_N` from tree-walk, `__lambda_N` from compiler) to "<lambda>" in stack traces. Without this the tree-walk and VM produced cosmetically-different traces (different counter values) on identical Lisp programs. Used by both invoke_user_function (tree-walk) and run_function (VM). 42/42 functional examples produce identical output under tree-walk and VM. 92/92 unit tests pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 2eb2c0c commit 3a14ffb

3 files changed

Lines changed: 635 additions & 3 deletions

File tree

0 commit comments

Comments
 (0)