Commit graph

13 commits

Author SHA1 Message Date
Stephen Dennis
11f1a3671b Fix parser noeval percent handling 2026-04-04 17:48:22 -06:00
Stephen Dennis
986163f133 Demote exploratory mux213 parser oracle 2026-03-23 14:32:54 -06:00
Stephen Dennis
d4d0b4d75f Add parser escape oracles 2026-03-21 12:01:17 -06:00
Stephen Dennis
2ed1a959f0 Align parser study with engine behavior 2026-03-21 05:23:57 -06:00
Stephen Dennis
96208e94dc Fix parser profile regressions 2026-03-21 04:28:44 -06:00
Stephen Dennis
d5ce149d1a Add parser percent-substitution matrix and fix noeval brace-group backslash handling
Root cause confirmed via debugger: 2.13's mux_exec() backslash handler
(eval.cpp line 2439) has no EV_EVAL guard — it runs unconditionally on
every pass. When brace-group arguments go through FN_NOEVAL functions
like switch(), the text passes through mux_exec() twice: once for noeval
arg collection (stripping one backslash layer) and once for evaluation.
This two-pass behavior turns \\% into \% then into literal %.

The 2.14 AST scanner tokenizes once greedily — \\ becomes one ESC token
and % becomes one SUBST token, evaluated independently. This produces
\<space> instead of % for the bboard case.

Fix: add noevalPass() and evalNoevalArg() to the parser prototype.
For brace-group args to FN_NOEVAL functions, strip one backslash layer
via noevalPass(), re-tokenize, then evaluate. This replicates 2.13's
unconditional backslash consumption.

Changes:
- docs/parser-percent-matrix.md: complete semantic matrix of all %
  forms across 2.13, 2.14, and PennMUSH with confirmed root cause
- parser/eval.cpp: full % substitution coverage (pronouns, color stubs,
  caller, objid, moniker, hash forms, etc.), noevalPass/evalNoevalArg
  for two-pass brace-group handling in if/switch/case
- parser/mux_parse.h: tokenizer support for hash forms (##/#@/#$),
  Penn %$ stack vars, %w attrs, %iL, angle-bracket helper
- parser/test_eval.sh: 123 tests (was 86), cross-profile escape+percent
  tests including the confirmed bboard divergence case

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 04:17:43 -06:00
Stephen Dennis
12adef906b Add parser compatibility study profiles 2026-03-21 03:08:02 -06:00
Stephen Dennis
0f8745cbaf Optimize hir_opt.cpp with commutative CSE and update eval utility
- hir_opt.cpp: Normalize commutative binary ops (ADD, MUL, etc.) in CSE to improve redundancy detection.
- parser/eval.cpp: Add IF and EVAL support to study tool for better Issue 2 verification.
2026-03-15 23:13:25 -06:00
Stephen Dennis
cf541c85c3 Optimize hir_cse, fix shutdown SIGABRT, and expand JIT scratch ring
- hir_opt.cpp: Replace O(N^2) CSE scan with unordered_map hash table.
- dbt_compile.cpp: Add dbt_compile_cleanup() to release persistent JIT state.
- dbt_compile.cpp: Expand JIT guest memory to 512KB and output scratch ring to 32 slots (256KB).
- engine_com.cpp: Call dbt_compile_cleanup() during server shutdown.
- parser/eval.cpp: Implement EV_FCHECK stripping and mandatory eval logic to match engine.
2026-03-15 22:33:58 -06:00
Stephen Dennis
edab4b7548 Add eval flag support to AST evaluator
Evaluator now respects EV_EVAL, EV_FCHECK, EV_FMAND, EV_NOFCHECK,
and EV_STRIP_CURLY flags matching mux_exec behavior:
- %-substitutions only resolved when EV_EVAL set
- Function calls only dispatched when EV_FCHECK set
- [...] brackets force EV_FCHECK | EV_FMAND on contents
- {...} braces pass through raw when EV_STRIP_CURLY not set
- {...} with EV_STRIP_CURLY strips braces, disables EV_FCHECK

82 tests passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 10:06:59 -07:00
Stephen Dennis
f124a8cd22 Factor shared tokenizer/parser/AST into mux_parse.h
Extract duplicated tokenizer, parser, and AST code from three study
tools into a shared header. Each tool is now a thin main() wrapper.
Added ast_raw_text() utility for source reconstruction. No behavioral
changes — 78 tests still pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 10:06:59 -07:00
Stephen Dennis
fe8321dd1a Implement proper FN_NOEVAL deferred evaluation in AST evaluator
Rework control flow functions (if, switch, case, cand, cor, iter, lit,
@@) to use deferred evaluation: handlers receive unevaluated AST
subtrees and call eval() selectively. This eliminates the need for
replace_tokens() and ##/#@/#$ text substitution.

Key proof: iter(10 20 30,[add(%i0,1)]) correctly produces "11 21 31"
by pushing %i0 onto the iterator stack and evaluating the body subtree
per item. Nested iterators work via %i0/%i1 stack depth.

Add PARSER_REPLACE.md design document for mux_exec replacement
architecture. 78 tests passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 10:06:59 -07:00
Stephen Dennis
60f668bfd9 Add AST evaluator with 50+ builtin functions
Stage 3 of parser study: tree-walking evaluator that demonstrates
pure-expression MUX softcode CAN be evaluated from an AST. Implements
arithmetic, string, list, comparison, boolean, register, and control
flow functions. Includes 64-test harness.

Key finding: FN_NOEVAL functions (iter, switch, if) need deferred
argument evaluation — the evaluator must pass unevaluated AST subtrees
rather than pre-evaluated strings. Solvable but requires a different
dispatch mechanism than simple string-in/string-out handlers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 10:06:59 -07:00