Add (param :as type) annotations to all fn/lambda params across SX spec
Extend the type annotation system from defcomp-only to fn/lambda params: - Infrastructure: sf-lambda, py/js-collect-params-loop, and bootstrap_py.py now recognize (name :as type) in param lists, extracting just the name - bootstrap_py.py: add _extract_param_name() helper, fix _emit_for_each_stmt - 521 type annotations across 22 .sx spec files (eval, types, adapters, transpilers, engine, orchestration, deps, signals, router, prove, etc.) - Zero behavioral change: annotations are metadata for static analysis only - All bootstrappers (Python, JS, G1) pass, 81/81 spec tests pass Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -253,7 +253,7 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-mangle
|
||||
(fn (name)
|
||||
(fn ((name :as string))
|
||||
(let ((renamed (get py-renames name)))
|
||||
(if (not (nil? renamed))
|
||||
renamed
|
||||
@@ -279,7 +279,7 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-quote-string
|
||||
(fn (s)
|
||||
(fn ((s :as string))
|
||||
;; Produce a Python repr-style string literal
|
||||
(str "'" (replace (replace (replace (replace s "\\" "\\\\") "'" "\\'") "\n" "\\n") "\t" "\\t") "'")))
|
||||
|
||||
@@ -292,11 +292,11 @@
|
||||
(list "+" "-" "*" "/" "=" "!=" "<" ">" "<=" ">=" "mod"))
|
||||
|
||||
(define py-infix?
|
||||
(fn (op)
|
||||
(fn ((op :as string))
|
||||
(some (fn (x) (= x op)) py-infix-ops)))
|
||||
|
||||
(define py-op-symbol
|
||||
(fn (op)
|
||||
(fn ((op :as string))
|
||||
(case op
|
||||
"=" "=="
|
||||
"!=" "!="
|
||||
@@ -309,7 +309,7 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-find-nested-set-vars
|
||||
(fn (body)
|
||||
(fn ((body :as list))
|
||||
;; Returns a list of mangled variable names that are set! from within
|
||||
;; nested fn/lambda bodies
|
||||
(let ((result (list)))
|
||||
@@ -318,7 +318,7 @@
|
||||
result))))
|
||||
|
||||
(define py-scan-set-vars
|
||||
(fn (node in-nested result)
|
||||
(fn (node (in-nested :as boolean) (result :as list))
|
||||
(when (and (list? node) (not (empty? node)))
|
||||
(let ((head (first node)))
|
||||
(cond
|
||||
@@ -353,7 +353,7 @@
|
||||
(py-has-set? body))))
|
||||
|
||||
(define py-has-set?
|
||||
(fn (nodes)
|
||||
(fn ((nodes :as list))
|
||||
(some (fn (node)
|
||||
(and (list? node)
|
||||
(not (empty? node))
|
||||
@@ -372,7 +372,7 @@
|
||||
(py-expr-with-cells expr (list))))
|
||||
|
||||
(define py-expr-with-cells
|
||||
(fn (expr cell-vars)
|
||||
(fn (expr (cell-vars :as list))
|
||||
(cond
|
||||
;; Bool MUST come before number check (Python: bool is subclass of int)
|
||||
(= (type-of expr) "boolean")
|
||||
@@ -417,7 +417,7 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-emit-native-dict
|
||||
(fn (d cell-vars)
|
||||
(fn ((d :as dict) (cell-vars :as list))
|
||||
(let ((items (keys d)))
|
||||
(str "{" (join ", " (map (fn (k)
|
||||
(str (py-quote-string k) ": " (py-expr-with-cells (get d k) cell-vars)))
|
||||
@@ -429,7 +429,7 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-emit-list
|
||||
(fn (expr cell-vars)
|
||||
(fn (expr (cell-vars :as list))
|
||||
(let ((head (first expr))
|
||||
(args (rest expr)))
|
||||
(if (not (= (type-of head) "symbol"))
|
||||
@@ -548,7 +548,7 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-emit-fn
|
||||
(fn (expr cell-vars)
|
||||
(fn (expr (cell-vars :as list))
|
||||
(let ((params (nth expr 1))
|
||||
(body (rest (rest expr)))
|
||||
(param-strs (py-collect-params params)))
|
||||
@@ -562,11 +562,11 @@
|
||||
"\n)[-1])"))))))
|
||||
|
||||
(define py-collect-params
|
||||
(fn (params)
|
||||
(fn ((params :as list))
|
||||
(py-collect-params-loop params 0 (list))))
|
||||
|
||||
(define py-collect-params-loop
|
||||
(fn (params i result)
|
||||
(fn ((params :as list) (i :as number) (result :as list))
|
||||
(if (>= i (len params))
|
||||
result
|
||||
(let ((p (nth params i)))
|
||||
@@ -574,13 +574,25 @@
|
||||
;; &rest marker
|
||||
(and (= (type-of p) "symbol") (= (symbol-name p) "&rest"))
|
||||
(if (< (+ i 1) (len params))
|
||||
(py-collect-params-loop params (+ i 2)
|
||||
(append result (str "*" (py-mangle (symbol-name (nth params (+ i 1)))))))
|
||||
(let ((rp (nth params (+ i 1))))
|
||||
(py-collect-params-loop params (+ i 2)
|
||||
(append result (str "*" (py-mangle
|
||||
(if (and (= (type-of rp) "list") (= (len rp) 3)
|
||||
(= (type-of (nth rp 1)) "keyword")
|
||||
(= (keyword-name (nth rp 1)) "as"))
|
||||
(symbol-name (first rp))
|
||||
(if (= (type-of rp) "symbol") (symbol-name rp) (str rp))))))))
|
||||
(py-collect-params-loop params (+ i 1) result))
|
||||
;; Normal param
|
||||
(= (type-of p) "symbol")
|
||||
(py-collect-params-loop params (+ i 1)
|
||||
(append result (py-mangle (symbol-name p))))
|
||||
;; Annotated param: (name :as type) → extract name
|
||||
(and (= (type-of p) "list") (= (len p) 3)
|
||||
(= (type-of (nth p 1)) "keyword")
|
||||
(= (keyword-name (nth p 1)) "as"))
|
||||
(py-collect-params-loop params (+ i 1)
|
||||
(append result (py-mangle (symbol-name (first p)))))
|
||||
;; Something else
|
||||
:else
|
||||
(py-collect-params-loop params (+ i 1)
|
||||
@@ -592,7 +604,7 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-emit-let
|
||||
(fn (expr cell-vars)
|
||||
(fn (expr (cell-vars :as list))
|
||||
(let ((bindings (nth expr 1))
|
||||
(body (rest (rest expr))))
|
||||
(let ((assignments (py-parse-bindings bindings cell-vars)))
|
||||
@@ -603,7 +615,7 @@
|
||||
(py-wrap-let-bindings assignments body-str cell-vars))))))
|
||||
|
||||
(define py-parse-bindings
|
||||
(fn (bindings cell-vars)
|
||||
(fn (bindings (cell-vars :as list))
|
||||
(if (and (list? bindings) (not (empty? bindings)))
|
||||
(if (list? (first bindings))
|
||||
;; Scheme-style: ((name val) ...)
|
||||
@@ -618,7 +630,7 @@
|
||||
(list))))
|
||||
|
||||
(define py-parse-clojure-bindings
|
||||
(fn (bindings i result cell-vars)
|
||||
(fn (bindings (i :as number) (result :as list) (cell-vars :as list))
|
||||
(if (>= i (- (len bindings) 1))
|
||||
result
|
||||
(let ((vname (if (= (type-of (nth bindings i)) "symbol")
|
||||
@@ -629,7 +641,7 @@
|
||||
cell-vars)))))
|
||||
|
||||
(define py-wrap-let-bindings
|
||||
(fn (assignments body-str cell-vars)
|
||||
(fn ((assignments :as list) (body-str :as string) (cell-vars :as list))
|
||||
(if (empty? assignments)
|
||||
body-str
|
||||
(let ((binding (last assignments))
|
||||
@@ -649,7 +661,7 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-emit-when
|
||||
(fn (expr cell-vars)
|
||||
(fn (expr (cell-vars :as list))
|
||||
(let ((cond-e (py-expr-with-cells (nth expr 1) cell-vars))
|
||||
(body-parts (rest (rest expr))))
|
||||
(if (= (len body-parts) 1)
|
||||
@@ -663,7 +675,7 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-emit-cond
|
||||
(fn (clauses cell-vars)
|
||||
(fn ((clauses :as list) (cell-vars :as list))
|
||||
(if (empty? clauses)
|
||||
"NIL"
|
||||
;; Detect scheme vs clojure style
|
||||
@@ -681,7 +693,7 @@
|
||||
(and (= (type-of test) "keyword") (= (keyword-name test) "else")))))
|
||||
|
||||
(define py-cond-scheme
|
||||
(fn (clauses cell-vars)
|
||||
(fn ((clauses :as list) (cell-vars :as list))
|
||||
(if (empty? clauses)
|
||||
"NIL"
|
||||
(let ((clause (first clauses))
|
||||
@@ -694,7 +706,7 @@
|
||||
") else " (py-cond-scheme (rest clauses) cell-vars) ")"))))))
|
||||
|
||||
(define py-cond-clojure
|
||||
(fn (clauses cell-vars)
|
||||
(fn ((clauses :as list) (cell-vars :as list))
|
||||
(if (< (len clauses) 2)
|
||||
"NIL"
|
||||
(let ((test (first clauses))
|
||||
@@ -711,17 +723,17 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-emit-case
|
||||
(fn (args cell-vars)
|
||||
(fn ((args :as list) (cell-vars :as list))
|
||||
(let ((match-expr (py-expr-with-cells (first args) cell-vars))
|
||||
(clauses (rest args)))
|
||||
(str "_sx_case(" match-expr ", [" (py-case-pairs clauses cell-vars) "])"))))
|
||||
|
||||
(define py-case-pairs
|
||||
(fn (clauses cell-vars)
|
||||
(fn ((clauses :as list) (cell-vars :as list))
|
||||
(py-case-pairs-loop clauses 0 (list) cell-vars)))
|
||||
|
||||
(define py-case-pairs-loop
|
||||
(fn (clauses i result cell-vars)
|
||||
(fn ((clauses :as list) (i :as number) (result :as list) (cell-vars :as list))
|
||||
(if (>= i (- (len clauses) 1))
|
||||
(join ", " result)
|
||||
(let ((test (nth clauses i))
|
||||
@@ -738,28 +750,28 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-emit-and
|
||||
(fn (args cell-vars)
|
||||
(fn ((args :as list) (cell-vars :as list))
|
||||
(let ((parts (map (fn (x) (py-expr-with-cells x cell-vars)) args)))
|
||||
(if (= (len parts) 1)
|
||||
(first parts)
|
||||
(py-and-chain parts)))))
|
||||
|
||||
(define py-and-chain
|
||||
(fn (parts)
|
||||
(fn ((parts :as list))
|
||||
(if (= (len parts) 1)
|
||||
(first parts)
|
||||
(let ((p (first parts)))
|
||||
(str "(" p " if not sx_truthy(" p ") else " (py-and-chain (rest parts)) ")")))))
|
||||
|
||||
(define py-emit-or
|
||||
(fn (args cell-vars)
|
||||
(fn ((args :as list) (cell-vars :as list))
|
||||
(if (= (len args) 1)
|
||||
(py-expr-with-cells (first args) cell-vars)
|
||||
(let ((parts (map (fn (x) (py-expr-with-cells x cell-vars)) args)))
|
||||
(py-or-chain parts)))))
|
||||
|
||||
(define py-or-chain
|
||||
(fn (parts)
|
||||
(fn ((parts :as list))
|
||||
(if (= (len parts) 1)
|
||||
(first parts)
|
||||
(let ((p (first parts)))
|
||||
@@ -771,7 +783,7 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-emit-do
|
||||
(fn (args cell-vars)
|
||||
(fn ((args :as list) (cell-vars :as list))
|
||||
(if (= (len args) 1)
|
||||
(py-expr-with-cells (first args) cell-vars)
|
||||
(str "_sx_begin(" (join ", " (map (fn (e) (py-expr-with-cells e cell-vars)) args)) ")"))))
|
||||
@@ -782,11 +794,11 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-emit-dict-literal
|
||||
(fn (pairs cell-vars)
|
||||
(fn ((pairs :as list) (cell-vars :as list))
|
||||
(str "{" (py-dict-pairs-str pairs 0 (list) cell-vars) "}")))
|
||||
|
||||
(define py-dict-pairs-str
|
||||
(fn (pairs i result cell-vars)
|
||||
(fn ((pairs :as list) (i :as number) (result :as list) (cell-vars :as list))
|
||||
(if (>= i (- (len pairs) 1))
|
||||
(join ", " result)
|
||||
(let ((key (nth pairs i))
|
||||
@@ -805,7 +817,7 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-emit-infix
|
||||
(fn (op args cell-vars)
|
||||
(fn ((op :as string) (args :as list) (cell-vars :as list))
|
||||
(let ((py-op (py-op-symbol op)))
|
||||
(if (and (= (len args) 1) (= op "-"))
|
||||
(str "(-" (py-expr-with-cells (first args) cell-vars) ")")
|
||||
@@ -839,15 +851,15 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-pad
|
||||
(fn (indent)
|
||||
(fn ((indent :as number))
|
||||
(join "" (map (fn (i) " ") (range 0 indent)))))
|
||||
|
||||
(define py-statement
|
||||
(fn (expr indent)
|
||||
(fn (expr (indent :as number))
|
||||
(py-statement-with-cells expr indent (list))))
|
||||
|
||||
(define py-statement-with-cells
|
||||
(fn (expr indent cell-vars)
|
||||
(fn (expr (indent :as number) (cell-vars :as list))
|
||||
(let ((pad (py-pad indent)))
|
||||
(if (and (list? expr) (not (empty? expr))
|
||||
(= (type-of (first expr)) "symbol"))
|
||||
@@ -889,7 +901,7 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-emit-define
|
||||
(fn (expr indent cell-vars)
|
||||
(fn (expr (indent :as number) (cell-vars :as list))
|
||||
(let ((pad (py-pad indent))
|
||||
(name (if (= (type-of (nth expr 1)) "symbol")
|
||||
(symbol-name (nth expr 1))
|
||||
@@ -911,7 +923,7 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-emit-define-as-def
|
||||
(fn (name fn-expr indent)
|
||||
(fn ((name :as string) fn-expr (indent :as number))
|
||||
(let ((pad (py-pad indent))
|
||||
(params (nth fn-expr 1))
|
||||
(body (rest (rest fn-expr)))
|
||||
@@ -932,13 +944,13 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-emit-body-stmts
|
||||
(fn (body lines indent cell-vars)
|
||||
(fn ((body :as list) (lines :as list) (indent :as number) (cell-vars :as list))
|
||||
(let ((pad (py-pad indent))
|
||||
(total (len body)))
|
||||
(py-emit-body-stmts-loop body lines indent cell-vars 0 total pad))))
|
||||
|
||||
(define py-emit-body-stmts-loop
|
||||
(fn (body lines indent cell-vars i total pad)
|
||||
(fn ((body :as list) (lines :as list) (indent :as number) (cell-vars :as list) (i :as number) (total :as number) (pad :as string))
|
||||
(when (< i total)
|
||||
(let ((expr (nth body i))
|
||||
(is-last (= i (- total 1))))
|
||||
@@ -968,7 +980,7 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-emit-let-as-stmts
|
||||
(fn (expr lines indent is-last cell-vars)
|
||||
(fn (expr (lines :as list) (indent :as number) (is-last :as boolean) (cell-vars :as list))
|
||||
(let ((pad (py-pad indent))
|
||||
(bindings (nth expr 1))
|
||||
(body (rest (rest expr))))
|
||||
@@ -981,7 +993,7 @@
|
||||
(for-each (fn (b) (py-emit-stmt-recursive b lines indent cell-vars)) body))))))
|
||||
|
||||
(define py-emit-binding-assignments
|
||||
(fn (bindings lines indent cell-vars)
|
||||
(fn (bindings (lines :as list) (indent :as number) (cell-vars :as list))
|
||||
(let ((pad (py-pad indent)))
|
||||
(when (and (list? bindings) (not (empty? bindings)))
|
||||
(if (list? (first bindings))
|
||||
@@ -1002,7 +1014,7 @@
|
||||
(py-emit-clojure-binding-assignments bindings lines indent 0 cell-vars))))))
|
||||
|
||||
(define py-emit-clojure-binding-assignments
|
||||
(fn (bindings lines indent i cell-vars)
|
||||
(fn (bindings (lines :as list) (indent :as number) (i :as number) (cell-vars :as list))
|
||||
(let ((pad (py-pad indent)))
|
||||
(when (< i (- (len bindings) 1))
|
||||
(let ((vname (if (= (type-of (nth bindings i)) "symbol")
|
||||
@@ -1024,7 +1036,7 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-emit-stmt-recursive
|
||||
(fn (expr lines indent cell-vars)
|
||||
(fn (expr (lines :as list) (indent :as number) (cell-vars :as list))
|
||||
(let ((pad (py-pad indent)))
|
||||
(if (not (and (list? expr) (not (empty? expr))))
|
||||
(append! lines (py-statement-with-cells expr indent cell-vars))
|
||||
@@ -1082,7 +1094,7 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-emit-cond-stmt
|
||||
(fn (expr lines indent cell-vars)
|
||||
(fn (expr (lines :as list) (indent :as number) (cell-vars :as list))
|
||||
(let ((pad (py-pad indent))
|
||||
(clauses (rest expr)))
|
||||
;; Detect scheme vs clojure
|
||||
@@ -1094,7 +1106,7 @@
|
||||
(py-cond-stmt-clojure clauses lines indent 0 true cell-vars))))))
|
||||
|
||||
(define py-cond-stmt-scheme
|
||||
(fn (clauses lines indent first-clause cell-vars)
|
||||
(fn ((clauses :as list) (lines :as list) (indent :as number) (first-clause :as boolean) (cell-vars :as list))
|
||||
(let ((pad (py-pad indent)))
|
||||
(when (not (empty? clauses))
|
||||
(let ((clause (first clauses))
|
||||
@@ -1111,7 +1123,7 @@
|
||||
(py-cond-stmt-scheme (rest clauses) lines indent false cell-vars)))))))
|
||||
|
||||
(define py-cond-stmt-clojure
|
||||
(fn (clauses lines indent i first-clause cell-vars)
|
||||
(fn ((clauses :as list) (lines :as list) (indent :as number) (i :as number) (first-clause :as boolean) (cell-vars :as list))
|
||||
(let ((pad (py-pad indent)))
|
||||
(when (< i (- (len clauses) 1))
|
||||
(let ((test (nth clauses i))
|
||||
@@ -1132,7 +1144,7 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-emit-when-stmt
|
||||
(fn (expr indent cell-vars)
|
||||
(fn (expr (indent :as number) (cell-vars :as list))
|
||||
(let ((pad (py-pad indent))
|
||||
(cond-e (py-expr-with-cells (nth expr 1) cell-vars))
|
||||
(body-parts (rest (rest expr))))
|
||||
@@ -1146,7 +1158,7 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-emit-for-each-stmt
|
||||
(fn (expr indent cell-vars)
|
||||
(fn (expr (indent :as number) (cell-vars :as list))
|
||||
(let ((pad (py-pad indent))
|
||||
(fn-expr (nth expr 1))
|
||||
(coll-expr (nth expr 2))
|
||||
@@ -1175,7 +1187,7 @@
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define py-translate-file
|
||||
(fn (defines)
|
||||
(fn ((defines :as list))
|
||||
(join "\n" (map (fn (pair)
|
||||
(let ((name (first pair))
|
||||
(expr (nth pair 1)))
|
||||
|
||||
Reference in New Issue
Block a user