HS: extend parser/runtime + new node test runner; ignore test-results/

- Parser: `--` line comments, `|` op, `result` → `the-result`, query-scoped
  `<sel> in <expr>`, `is a/an <type>` predicate, multi-`as` chaining with `|`,
  `match`/`precede` keyword aliases, `[attr]` add/toggle, between attr forms
- Runtime: per-element listener registry + hs-deactivate!, attr toggle
  variants, set-inner-html boots subtree, hs-append polymorphic on
  string/list/element, default? / array-set! / query-all-in / list-set
  via take+drop, hs-script idempotence guard
- Integration: skip reserved (me/it/event/you/yourself) when collecting vars
- Tokenizer: emit `--` comments and `|` op
- Test framework + conformance runner updates; new tests/hs-run-filtered.js
  (single-process Node runner using OCaml VM step-limit to bound infinite
  loops); generate-sx-conformance-dev.py improvements
- mcp_tree.ml + run_tests.ml: harness extensions
- .gitignore: top-level test-results/ (Playwright artifacts)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-23 07:11:07 +00:00
parent b2ae80fb21
commit 0515295317
20 changed files with 15224 additions and 8120 deletions

View File

@@ -47,9 +47,56 @@ def parse_js_value(s):
m = re.match(r'^\[(.+)\]$', s, re.DOTALL)
if m:
return parse_js_array(m.group(1))
# Empty object
if s == '{}':
return '{}'
# Object literal — convert to SX dict {:key val ...}
m = re.match(r'^\{(.+)\}$', s, re.DOTALL)
if m:
return parse_js_object(m.group(1))
return None
def parse_js_object(inner):
"""Parse JS object contents into SX dict {:key val ...}. Handles nested."""
pairs = split_js_object(inner)
if pairs is None:
return None
sx_pairs = []
for pair in pairs:
km = re.match(r'\s*["\']?(\w+)["\']?\s*:\s*(.+)$', pair.strip(), re.DOTALL)
if not km:
return None
k = km.group(1)
v = parse_js_value(km.group(2).strip())
if v is None:
return None
sx_pairs.append(f':{k} {v}')
return '{' + ' '.join(sx_pairs) + '}'
def split_js_object(s):
"""Split JS object-content by commas respecting nesting."""
items = []
depth = 0
current = ''
for ch in s:
if ch in '([{':
depth += 1
current += ch
elif ch in ')]}':
depth -= 1
current += ch
elif ch == ',' and depth == 0:
items.append(current)
current = ''
else:
current += ch
if current.strip():
items.append(current)
return items if items else None
def parse_js_array(inner):
"""Parse JS array contents into SX (list ...). Handles nested arrays."""
items = split_js_array(inner)