|
1722 | 1722 | #f)] |
1723 | 1723 | [_ (parse-list-form* d subs)]))) |
1724 | 1724 |
|
1725 | | -;; `let` — lexical binding block. |
1726 | | -(register-combiner! 'let |
1727 | | - (lambda (d subs) |
1728 | | - (match d |
1729 | | - [(list 'let bindings-form body ...) |
1730 | | - (let-form (parse-let-bindings (or (stx-ref subs 1) bindings-form)) |
1731 | | - (parse-body (or (stx-tail subs 2) body)))] |
1732 | | - [_ (parse-list-form* d subs)]))) |
1733 | | - |
1734 | | -;; `letfn` — mutually-recursive local function block. |
1735 | | -(register-combiner! 'letfn |
1736 | | - (lambda (d subs) |
1737 | | - (match d |
1738 | | - [(list 'letfn fns-form body ...) |
1739 | | - (letfn-form (parse-letfn-fns (or (stx-ref subs 1) fns-form)) |
1740 | | - (parse-body (or (stx-tail subs 2) body)))] |
1741 | | - [_ (parse-list-form* d subs)]))) |
1742 | | - |
1743 | | -;; `loop` — recur target with initial bindings. |
1744 | | -(register-combiner! 'loop |
1745 | | - (lambda (d subs) |
1746 | | - (match d |
1747 | | - [(list 'loop bindings-form body ...) |
1748 | | - (loop-form (parse-let-bindings (or (stx-ref subs 1) bindings-form)) |
1749 | | - (parse-body (or (stx-tail subs 2) body)))] |
1750 | | - [_ (parse-list-form* d subs)]))) |
1751 | | - |
1752 | | -;; `with-open` — resource-scoped binding block (auto-close on exit). |
1753 | | -(register-combiner! 'with-open |
1754 | | - (lambda (d subs) |
1755 | | - (match d |
1756 | | - [(list 'with-open bindings-form body ...) |
1757 | | - (with-open-form (parse-let-bindings (or (stx-ref subs 1) bindings-form)) |
1758 | | - (parse-body (or (stx-tail subs 2) body)))] |
1759 | | - [_ (parse-list-form* d subs)]))) |
1760 | | - |
1761 | | -;; `for` — list comprehension (clauses: bindings, :when, :let). |
1762 | | -(register-combiner! 'for |
1763 | | - (lambda (d subs) |
1764 | | - (match d |
1765 | | - [(list 'for bindings-form body ...) |
1766 | | - (for-form (parse-for-clauses (or (stx-ref subs 1) bindings-form)) |
1767 | | - (parse-body (or (stx-tail subs 2) body)))] |
1768 | | - [_ (parse-list-form* d subs)]))) |
1769 | | - |
1770 | | -;; `doseq` — side-effecting iteration (shares for-clause parsing with `for`). |
1771 | | -(register-combiner! 'doseq |
1772 | | - (lambda (d subs) |
1773 | | - (match d |
1774 | | - [(list 'doseq bindings-form body ...) |
1775 | | - (doseq-form (parse-for-clauses (or (stx-ref subs 1) bindings-form)) |
1776 | | - (parse-body (or (stx-tail subs 2) body)))] |
1777 | | - [_ (parse-list-form* d subs)]))) |
1778 | | - |
1779 | | -;; `doto` — evaluate target, thread it through side-effecting forms, return it. |
1780 | | -(register-combiner! 'doto |
1781 | | - (lambda (d subs) |
1782 | | - (match d |
1783 | | - [(list 'doto target forms ...) |
1784 | | - (doto-form (parse-expr (or (stx-ref subs 1) target)) |
1785 | | - (map parse-expr (or (stx-tail subs 2) forms)))] |
1786 | | - [_ (parse-list-form* d subs)]))) |
1787 | | - |
1788 | | -;; `unless` — removed surface (not Clojure). Pointed rejection naming when-not. |
1789 | | -(register-combiner! 'unless |
1790 | | - (lambda (d subs) |
1791 | | - (raise-parse-error 'removed-form |
1792 | | - "(unless c body...) — `unless` is not a Clojure form. Use `(when-not c body...)`."))) |
1793 | | - |
1794 | | -;; `cond` — multi-clause conditional. Single arm; parse-cond-clauses owns all |
1795 | | -;; clause-shape validation/errors. |
1796 | | -(register-combiner! 'cond |
1797 | | - (lambda (d subs) |
1798 | | - (cond-form (parse-cond-clauses (or (stx-tail subs 1) (cdr d)))))) |
1799 | | - |
1800 | | -;; `case` — removed surface. Folded into `match`. Pointed rejection. |
1801 | | -(register-combiner! 'case |
1802 | | - (lambda (d subs) |
1803 | | - (raise-parse-error 'removed-form |
1804 | | - "case removed — use (match x [v1 body] [v2 body] [_ default]) or (match x [(or v1 v2) shared-body] [_ default]); literal-only matches case-fold to target-native dispatch in emit"))) |
1805 | | - |
1806 | | -;; `fn` — anonymous function; optional `:-`/`:` return-type marker. |
1807 | | -(register-combiner! 'fn |
1808 | | - (lambda (d subs) |
1809 | | - (match d |
1810 | | - [(list 'fn params-form marker return-type body ...) |
1811 | | - #:when (annotation-marker? marker) |
1812 | | - (let-values ([(parsed rest-p) (parse-params (or (stx-ref subs 1) params-form))]) |
1813 | | - (fn-form parsed rest-p |
1814 | | - (parse-type return-type) |
1815 | | - (parse-body (or (stx-tail subs 4) body))))] |
1816 | | - [(list 'fn params-form body ...) |
1817 | | - (let-values ([(parsed rest-p) (parse-params (or (stx-ref subs 1) params-form))]) |
1818 | | - (fn-form parsed rest-p |
1819 | | - #f (parse-body (or (stx-tail subs 2) body))))] |
1820 | | - [_ (parse-list-form* d subs)]))) |
1821 | | - |
1822 | | -;; `defonce` — once-only top-level binding, optional `:-` type / docstring. |
1823 | | -(register-combiner! 'defonce |
1824 | | - (lambda (d subs) |
1825 | | - (match d |
1826 | | - [(list 'defonce (? symbol? name) ':- type-expr (? string? doc) value) |
1827 | | - (defonce-form name (parse-type type-expr) |
1828 | | - (parse-expr (or (stx-ref subs 5) value)) |
1829 | | - doc)] |
1830 | | - [(list 'defonce (? symbol? name) ':- type-expr value) |
1831 | | - (defonce-form name (parse-type type-expr) |
1832 | | - (parse-expr (or (stx-ref subs 4) value)) |
1833 | | - #f)] |
1834 | | - [(list 'defonce (? symbol? name) ': _ _) |
1835 | | - (raise-parse-error 'inline-type-annotation |
1836 | | - "(defonce ~a : ...) — bare `:` is not the inline type marker. Use `:-` for inline type annotation:\n (defonce ~a :- TYPE VALUE)" |
1837 | | - name name)] |
1838 | | - [(list 'defonce (? symbol? name) (? string? doc) value) |
1839 | | - (defonce-form name #f (parse-expr (or (stx-ref subs 3) value)) doc)] |
1840 | | - [(list 'defonce (? symbol? name) value) |
1841 | | - (defonce-form name #f (parse-expr (or (stx-ref subs 2) value)) #f)] |
1842 | | - [_ (parse-list-form* d subs)]))) |
1843 | | - |
1844 | | -;; `set!` — mutable assignment. |
1845 | | -(register-combiner! 'set! |
1846 | | - (lambda (d subs) |
1847 | | - (match d |
1848 | | - [(list 'set! target-expr val-expr) |
1849 | | - (set!-form (parse-expr (or (stx-ref subs 1) target-expr)) |
1850 | | - (parse-expr (or (stx-ref subs 2) val-expr)))] |
1851 | | - [_ (parse-list-form* d subs)]))) |
1852 | | - |
1853 | | -;; `defrecord` — typed record shape. |
1854 | | -(register-combiner! 'defrecord |
1855 | | - (lambda (d subs) |
1856 | | - (match d |
1857 | | - [(list 'defrecord (? symbol? name) fields-form) |
1858 | | - (record-form name (parse-record-fields (or (stx-ref subs 2) fields-form)))] |
1859 | | - [_ (parse-list-form* d subs)]))) |
1860 | | - |
1861 | | -;; `defenum` — keyword-variant enum. |
1862 | | -(register-combiner! 'defenum |
1863 | | - (lambda (d subs) |
1864 | | - (match d |
1865 | | - [(list 'defenum (? symbol? name) values ...) |
1866 | | - (defenum-form name (map ->datum (or (stx-tail subs 2) values)))] |
1867 | | - [_ (parse-list-form* d subs)]))) |
1868 | | - |
1869 | | -;; `defscalar` — newtype-style scalar over a backing primitive, with optional |
1870 | | -;; :where refinement predicates. |
1871 | | -(register-combiner! 'defscalar |
1872 | | - (lambda (d subs) |
1873 | | - (match d |
1874 | | - [(list 'defscalar (? symbol? name) (? symbol? backing) ':where preds ...) |
1875 | | - (defscalar-form name (->datum backing) (map parse-scalar-predicate preds))] |
1876 | | - [(list 'defscalar (? symbol? name) (? symbol? backing)) |
1877 | | - (defscalar-form name (->datum backing) '())] |
1878 | | - [_ (parse-list-form* d subs)]))) |
1879 | | - |
1880 | | -;; `deftype` — removed form; pointed rejection pointing at defrecord + extend-type. |
1881 | | -(register-combiner! 'deftype |
1882 | | - (lambda (d subs) |
1883 | | - (match d |
1884 | | - [(list 'deftype _ ...) |
1885 | | - (raise-parse-error 'removed-form |
1886 | | - "deftype removed — use (defrecord Name [fields]) for the data shape and (extend-type Name Protocol (method ...)) for protocol impls")] |
1887 | | - [_ (parse-list-form* d subs)]))) |
1888 | | - |
1889 | | -;; `extend-type` — attach protocol implementations to a type. |
1890 | | -(register-combiner! 'extend-type |
1891 | | - (lambda (d subs) |
1892 | | - (match d |
1893 | | - [(list 'extend-type (? symbol? type-name) rest ...) |
1894 | | - (extend-type-form type-name (parse-type-impls (or (stx-tail subs 2) rest)))] |
1895 | | - [_ (parse-list-form* d subs)]))) |
1896 | | - |
1897 | | -;; `comment` — Clojure (comment ...) reads-and-discards; value is nil. |
1898 | | -(register-combiner! 'comment |
1899 | | - (lambda (d subs) |
1900 | | - 'nil)) |
1901 | | - |
1902 | | -;; `target-case` — per-target branch selection; same AST as the legacy arm. |
1903 | | -(register-combiner! 'target-case |
1904 | | - (lambda (d subs) |
1905 | | - (parse-target-case (or (stx-tail subs 1) (cdr d))))) |
1906 | | - |
1907 | | -;; `try` — try/catch/finally; delegates to the unchanged parse-try-form. |
1908 | | -(register-combiner! 'try |
1909 | | - (lambda (d subs) |
1910 | | - (parse-try-form (or (stx-tail subs 1) (cdr d))))) |
1911 | | - |
1912 | 1725 | (define (parse-list-form d subs) |
1913 | 1726 | ;; Invariant: macro heads are resolved in parse-expr (and the top-level loop) |
1914 | 1727 | ;; BEFORE control reaches here, so a 'macro head must never arrive — if one |
|
1958 | 1771 | (raise-parse-error 'bad-form |
1959 | 1772 | "malformed def — expected (def NAME VALUE), (def NAME \"doc\" VALUE), (def NAME :- TYPE VALUE), or (def NAME :- TYPE \"doc\" VALUE); got: ~v" d)] |
1960 | 1773 |
|
1961 | | - ;; `defonce` success arms migrated to the compile-time combiner registry |
1962 | | - ;; (see register-combiner!). The guard arm below stays here. |
| 1774 | + [(list 'defonce (? symbol? name) ':- type-expr (? string? doc) value) |
| 1775 | + (defonce-form name (parse-type type-expr) |
| 1776 | + (parse-expr (or (stx-ref subs 5) value)) |
| 1777 | + doc)] |
| 1778 | + [(list 'defonce (? symbol? name) ':- type-expr value) |
| 1779 | + (defonce-form name (parse-type type-expr) |
| 1780 | + (parse-expr (or (stx-ref subs 4) value)) |
| 1781 | + #f)] |
| 1782 | + [(list 'defonce (? symbol? name) ': _ _) |
| 1783 | + (raise-parse-error 'inline-type-annotation |
| 1784 | + "(defonce ~a : ...) — bare `:` is not the inline type marker. Use `:-` for inline type annotation:\n (defonce ~a :- TYPE VALUE)" |
| 1785 | + name name)] |
| 1786 | + [(list 'defonce (? symbol? name) (? string? doc) value) |
| 1787 | + (defonce-form name #f (parse-expr (or (stx-ref subs 3) value)) doc)] |
| 1788 | + [(list 'defonce (? symbol? name) value) |
| 1789 | + (defonce-form name #f (parse-expr (or (stx-ref subs 2) value)) #f)] |
1963 | 1790 | [(cons 'defonce _) |
1964 | 1791 | (raise-parse-error 'bad-form |
1965 | 1792 | "malformed defonce — expected (defonce NAME VALUE), (defonce NAME \"doc\" VALUE), or (defonce NAME :- TYPE VALUE); got: ~v" d)] |
|
2122 | 1949 | "`(def NAME :- TYPE VALUE)` for top-level bindings, " |
2123 | 1950 | "`[param :- TYPE]` and `:- RET-TYPE` for defn."))] |
2124 | 1951 |
|
2125 | | - ;; `defrecord` migrated to the compile-time combiner registry (see register-combiner!). |
| 1952 | + [(list 'defrecord (? symbol? name) fields-form) |
| 1953 | + (record-form name (parse-record-fields (or (stx-ref subs 2) fields-form)))] |
2126 | 1954 |
|
2127 | 1955 | [(list 'defprotocol (? symbol? name) sigs ...) |
2128 | 1956 | (protocol-form name (map parse-protocol-method (or (stx-tail subs 2) sigs)))] |
|
2136 | 1964 | ;; the data shape; extend-type attaches protocol impls. Two distinct |
2137 | 1965 | ;; concepts, two distinct forms. |
2138 | 1966 |
|
2139 | | - ;; `extend-type` migrated to the compile-time combiner registry (see register-combiner!). |
| 1967 | + [(list 'extend-type (? symbol? type-name) rest ...) |
| 1968 | + (extend-type-form type-name (parse-type-impls (or (stx-tail subs 2) rest)))] |
2140 | 1969 |
|
2141 | 1970 | ;; flake-input: typed access to flake-input attribute paths. |
2142 | 1971 | ;; (flake-input :NAME :NAMESPACE :path ...) → |
|
2166 | 1995 | ;; their inline-annotation surface was migrated wholesale to `:-`; `fn` |
2167 | 1996 | ;; and arity-clauses retain `:` acceptance to avoid churning the existing |
2168 | 1997 | ;; corpus during the migration window. |
2169 | | - ;; `fn` migrated to the compile-time combiner registry (see register-combiner!). |
2170 | | - |
2171 | | - ;; `let` migrated to the compile-time combiner registry (see register-combiner!). |
2172 | | - |
2173 | | - ;; `letfn` migrated to the compile-time combiner registry (see register-combiner!). |
| 1998 | + [(list 'fn params-form marker return-type body ...) |
| 1999 | + #:when (annotation-marker? marker) |
| 2000 | + (let-values ([(parsed rest-p) (parse-params (or (stx-ref subs 1) params-form))]) |
| 2001 | + (fn-form parsed rest-p |
| 2002 | + (parse-type return-type) |
| 2003 | + (parse-body (or (stx-tail subs 4) body))))] |
| 2004 | + [(list 'fn params-form body ...) |
| 2005 | + (let-values ([(parsed rest-p) (parse-params (or (stx-ref subs 1) params-form))]) |
| 2006 | + (fn-form parsed rest-p |
| 2007 | + #f (parse-body (or (stx-tail subs 2) body))))] |
| 2008 | + |
| 2009 | + [(list 'let bindings-form body ...) |
| 2010 | + (let-form (parse-let-bindings (or (stx-ref subs 1) bindings-form)) |
| 2011 | + (parse-body (or (stx-tail subs 2) body)))] |
| 2012 | + |
| 2013 | + [(list 'letfn fns-form body ...) |
| 2014 | + (letfn-form (parse-letfn-fns (or (stx-ref subs 1) fns-form)) |
| 2015 | + (parse-body (or (stx-tail subs 2) body)))] |
2174 | 2016 |
|
2175 | | - ;; `loop` migrated to the compile-time combiner registry (see register-combiner!). |
| 2017 | + [(list 'loop bindings-form body ...) |
| 2018 | + (loop-form (parse-let-bindings (or (stx-ref subs 1) bindings-form)) |
| 2019 | + (parse-body (or (stx-tail subs 2) body)))] |
2176 | 2020 | [(list 'recur args ...) |
2177 | 2021 | (recur-form (map parse-expr (or (stx-tail subs 1) args)))] |
2178 | 2022 |
|
|
2544 | 2388 |
|
2545 | 2389 | ;; --- end SQL-specific forms ----------------------------------------------- |
2546 | 2390 |
|
2547 | | - ;; `set!` migrated to the compile-time combiner registry (see register-combiner!). |
| 2391 | + [(list 'set! target-expr val-expr) |
| 2392 | + (set!-form (parse-expr (or (stx-ref subs 1) target-expr)) |
| 2393 | + (parse-expr (or (stx-ref subs 2) val-expr)))] |
2548 | 2394 |
|
2549 | | - ;; `for` migrated to the compile-time combiner registry (see register-combiner!). |
| 2395 | + [(list 'for bindings-form body ...) |
| 2396 | + (for-form (parse-for-clauses (or (stx-ref subs 1) bindings-form)) |
| 2397 | + (parse-body (or (stx-tail subs 2) body)))] |
2550 | 2398 |
|
2551 | 2399 | ;; `if` migrated to the compile-time combiner registry (see register-combiner!). |
2552 | 2400 |
|
|
2562 | 2410 | ;; They are real Clojure; the -some variants test (not (nil? x)) rather |
2563 | 2411 | ;; than truthiness, exactly as in Clojure. |
2564 | 2412 |
|
2565 | | - ;; `with-open` migrated to the compile-time combiner registry (see register-combiner!). |
| 2413 | + [(list 'with-open bindings-form body ...) |
| 2414 | + (with-open-form (parse-let-bindings (or (stx-ref subs 1) bindings-form)) |
| 2415 | + (parse-body (or (stx-tail subs 2) body)))] |
2566 | 2416 |
|
2567 | | - ;; `doto` migrated to the compile-time combiner registry (see register-combiner!). |
| 2417 | + [(list 'doto target forms ...) |
| 2418 | + (doto-form (parse-expr (or (stx-ref subs 1) target)) |
| 2419 | + (map parse-expr (or (stx-tail subs 2) forms)))] |
2568 | 2420 |
|
2569 | | - ;; `comment` migrated to the compile-time combiner registry (see register-combiner!). |
| 2421 | + [(list 'comment _ ...) |
| 2422 | + 'nil] |
2570 | 2423 |
|
2571 | 2424 | ;; `do` migrated to the compile-time combiner registry (see register-combiner!). |
2572 | 2425 |
|
2573 | | - ;; `cond` migrated to the compile-time combiner registry (see register-combiner!). |
| 2426 | + [(list 'cond clauses ...) |
| 2427 | + (cond-form (parse-cond-clauses (or (stx-tail subs 1) clauses)))] |
2574 | 2428 |
|
2575 | 2429 | [(list 'condp pred-fn test-expr clauses ...) |
2576 | 2430 | (parse-condp-form (or (stx-ref subs 1) pred-fn) |
2577 | 2431 | (or (stx-ref subs 2) test-expr) |
2578 | 2432 | (or (stx-tail subs 3) clauses))] |
2579 | 2433 |
|
2580 | | - ;; `try` migrated to the compile-time combiner registry (see register-combiner!). |
| 2434 | + [(list 'try rest ...) |
| 2435 | + (parse-try-form (or (stx-tail subs 1) rest))] |
2581 | 2436 |
|
2582 | 2437 | [(list 'check expr) |
2583 | 2438 | (check-expr (parse-expr (or (stx-ref subs 1) expr)))] |
|
2591 | 2446 | (parse-expr (or (stx-ref subs 2) fallback)) |
2592 | 2447 | #f)] |
2593 | 2448 |
|
2594 | | - ;; `target-case` migrated to the compile-time combiner registry (see register-combiner!). |
| 2449 | + [(list 'target-case rest ...) |
| 2450 | + (parse-target-case (or (stx-tail subs 1) rest))] |
2595 | 2451 |
|
2596 | | - ;; `doseq` migrated to the compile-time combiner registry (see register-combiner!). |
| 2452 | + [(list 'doseq bindings-form body ...) |
| 2453 | + (doseq-form (parse-for-clauses (or (stx-ref subs 1) bindings-form)) |
| 2454 | + (parse-body (or (stx-tail subs 2) body)))] |
2597 | 2455 |
|
2598 | 2456 | ;; dotimes removed — sugar for (doseq [i (range n)] body...). |
2599 | 2457 | ;; No broader pattern reinforced; composition is transparent. |
|
2626 | 2484 | (parse-with-form (or (stx-ref subs 1) target-expr) |
2627 | 2485 | (or (stx-tail subs 2) updates))])] |
2628 | 2486 |
|
2629 | | - ;; `defenum` migrated to the compile-time combiner registry (see register-combiner!). |
| 2487 | + [(list 'defenum (? symbol? name) values ...) |
| 2488 | + (defenum-form name (map ->datum (or (stx-tail subs 2) values)))] |
2630 | 2489 |
|
2631 | 2490 | ;; (defunion :throwable Name ...) — throwable variant union. |
2632 | 2491 | ;; Routes to deferror-form internally (same structural shape; throw/catch |
|
2669 | 2528 | (raise-parse-error 'removed-form |
2670 | 2529 | "deferror removed — use (defunion :throwable Name ...) instead")] |
2671 | 2530 |
|
2672 | | - ;; `defscalar` migrated to the compile-time combiner registry (see register-combiner!). |
| 2531 | + [(list 'defscalar (? symbol? name) (? symbol? backing) ':where preds ...) |
| 2532 | + (defscalar-form name (->datum backing) (map parse-scalar-predicate preds))] |
| 2533 | + [(list 'defscalar (? symbol? name) (? symbol? backing)) |
| 2534 | + (defscalar-form name (->datum backing) '())] |
2673 | 2535 |
|
2674 | 2536 | [(list 'match target-expr clauses ...) |
2675 | 2537 | (parse-match-form (or (stx-ref subs 1) target-expr) |
|
2891 | 2753 | [(list 'defmethod _ ...) |
2892 | 2754 | (raise-parse-error 'removed-form |
2893 | 2755 | "defmethod removed — use defprotocol + extend-type for type-based dispatch")] |
2894 | | - ;; `deftype` migrated to the compile-time combiner registry (see register-combiner!). |
| 2756 | + [(list 'deftype _ ...) |
| 2757 | + (raise-parse-error 'removed-form |
| 2758 | + "deftype removed — use (defrecord Name [fields]) for the data shape and (extend-type Name Protocol (method ...)) for protocol impls")] |
2895 | 2759 | [(list 'nix-ident _ ...) |
2896 | 2760 | (raise-parse-error 'removed-form |
2897 | 2761 | "nix-ident removed — use (flake-input :NAME :NAMESPACE :path ...) for flake-input access. nix-ident was an undocumented escape hatch that bypassed the type system.")] |
2898 | 2762 | ;; inc / dec / not= live in stdlib-portable.rkt — no parse-time |
2899 | 2763 | ;; rejection. They flow through the ordinary call-form arm below. |
2900 | | - ;; `case` migrated to the compile-time combiner registry (see register-combiner!). |
| 2764 | + [(list 'case _ ...) |
| 2765 | + (raise-parse-error 'removed-form |
| 2766 | + "case removed — use (match x [v1 body] [v2 body] [_ default]) or (match x [(or v1 v2) shared-body] [_ default]); literal-only matches case-fold to target-native dispatch in emit")] |
2901 | 2767 | ;; Arity errors for the (:keyword target) form. The valid shape is |
2902 | 2768 | ;; (:k target) — exactly one positional argument. (:k) is meaningless |
2903 | 2769 | ;; (no target); (:k a b ...) was the deprecated default-on-miss form, |
|
0 commit comments