spec: match special form — ADT constructor pattern matching (20 tests)
Extends match-pattern in spec/evaluator.sx with an ADT case: when the pattern is (CtorName var...) and the value is an ADT dict (:_adt true), check :_ctor matches, arity matches, then recursively bind field patterns. Supports nested patterns, wildcard _, variable binding, and zero-arg ctors. Changes step-sf-match to route no-clause errors through raise-eval-frame instead of direct error, allowing guard to catch non-exhaustive matches. 40/40 ADT tests pass (20 define-type + 20 match). Zero regressions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2736,6 +2736,17 @@
|
||||
(= value (nth pattern 1))
|
||||
(symbol? pattern)
|
||||
(do (env-bind! env (symbol-name pattern) value) true)
|
||||
(and (list? pattern) (not (empty? pattern)) (symbol? (first pattern)) (dict? value) (get value :_adt))
|
||||
(let
|
||||
((ctor-name (symbol-name (first pattern)))
|
||||
(field-patterns (rest pattern))
|
||||
(fields (get value :_fields)))
|
||||
(and
|
||||
(= (get value :_ctor) ctor-name)
|
||||
(= (len field-patterns) (len fields))
|
||||
(every?
|
||||
(fn (pair) (match-pattern (first pair) (nth pair 1) env))
|
||||
(zip field-patterns fields))))
|
||||
(and (dict? pattern) (dict? value))
|
||||
(every?
|
||||
(fn (k) (match-pattern (get pattern k) (get value k) env))
|
||||
@@ -2780,7 +2791,7 @@
|
||||
((result (match-find-clause val clauses env)))
|
||||
(if
|
||||
(nil? result)
|
||||
(error (str "match: no clause matched " (inspect val)))
|
||||
(make-cek-value (str "match: no clause matched " (inspect val)) env (kont-push (make-raise-eval-frame env false) kont))
|
||||
(make-cek-state (nth result 1) (first result) kont))))))
|
||||
|
||||
(define
|
||||
|
||||
Reference in New Issue
Block a user