go: types.sx — call type-checking + 8 tests; recursive funcs now type [nothing]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 36s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 36s
Phase 3 cont. The expression-synth :app dispatch is now bifurcated:
* go-is-binop-call? — head is :var with an operator name AND 2 args
AND the operator is in one of the binop tables. Short-circuits to
go-synth-binop as before.
* Everything else routes to go-synth-call.
go-synth-call:
1. Synth the callee. Must produce a (list :ty-func PARAMS RESULTS).
Otherwise → (:type-error :not-callable TYPE).
2. Arity-check args vs params. Mismatch → (:type-error :arity-mismatch).
3. go-check-args-against: each arg assignable to corresponding param
(untyped-constant flow works — `f(42)` accepts the untyped int
into an int param).
4. Result by count:
0 results → (list :ty-void)
1 result → that result directly
N results → (list :ty-tuple TYPES) for multi-return
The recursive case lights up: go-check-func-decl binds the function
in its own body's ctx before checking. So:
func fib(n int) int { return fib(n) + fib(n) }
now type-checks because `fib` resolves inside the body, synth-call
sees its `:ty-func` and verifies the recursive call. Multi-return
functions destructure into `:ty-tuple` which short-decl will need to
consume next iteration.
types 55/55, total 360/360.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -253,15 +253,67 @@
|
||||
(cond
|
||||
(= t nil) (list :type-error :unbound name)
|
||||
:else t)))))
|
||||
;; (:app (:var OP) [LHS RHS]) — binary operator
|
||||
(and (list? expr) (= (first expr) :app)
|
||||
(list? (nth expr 1)) (= (first (nth expr 1)) :var)
|
||||
(= (len (nth expr 2)) 2))
|
||||
(let ((op (nth (nth expr 1) 1))
|
||||
(args (nth expr 2)))
|
||||
(go-synth-binop ctx op (first args) (nth args 1)))
|
||||
;; (:app HEAD ARGS) — function application:
|
||||
;; binop if HEAD is :var with an operator name + 2 args
|
||||
;; else: general function call
|
||||
(and (list? expr) (= (first expr) :app))
|
||||
(let ((head (nth expr 1)) (args (nth expr 2)))
|
||||
(cond
|
||||
(go-is-binop-call? head args)
|
||||
(go-synth-binop ctx (nth head 1) (first args) (nth args 1))
|
||||
:else (go-synth-call ctx head args)))
|
||||
:else (list :type-error :unsupported-synth expr))))
|
||||
|
||||
(define
|
||||
go-is-binop-call?
|
||||
(fn (head args)
|
||||
(and (list? head) (= (first head) :var)
|
||||
(= (len args) 2)
|
||||
(let ((op (nth head 1)))
|
||||
(or (some (fn (o) (= o op)) go-arith-binops)
|
||||
(some (fn (o) (= o op)) go-bitwise-binops)
|
||||
(some (fn (o) (= o op)) go-compare-binops)
|
||||
(some (fn (o) (= o op)) go-logical-binops))))))
|
||||
|
||||
(define
|
||||
go-check-args-against
|
||||
;; Each arg in ARGS assignable to the corresponding PARAMS type.
|
||||
;; Caller already verified arities match.
|
||||
(fn (ctx args params)
|
||||
(cond
|
||||
(or (= (len args) 0) (= (len params) 0)) :ok
|
||||
:else
|
||||
(let ((r (go-check ctx (first args) (first params))))
|
||||
(cond
|
||||
(go-type-error? r) r
|
||||
:else (go-check-args-against ctx (rest args) (rest params)))))))
|
||||
|
||||
(define
|
||||
go-synth-call
|
||||
;; Synth a function call. Returns the result type, or :type-error.
|
||||
;; 0 results → (list :ty-void)
|
||||
;; 1 result → that result type directly
|
||||
;; N results → (list :ty-tuple TYPES) (multi-return)
|
||||
(fn (ctx callee args)
|
||||
(let ((fn-ty (go-synth ctx callee)))
|
||||
(cond
|
||||
(go-type-error? fn-ty) fn-ty
|
||||
(not (and (list? fn-ty) (= (first fn-ty) :ty-func)))
|
||||
(list :type-error :not-callable fn-ty)
|
||||
:else
|
||||
(let ((params (nth fn-ty 1)) (results (nth fn-ty 2)))
|
||||
(cond
|
||||
(not (= (len args) (len params)))
|
||||
(list :type-error :arity-mismatch
|
||||
(len params) (len args))
|
||||
:else
|
||||
(let ((err (go-check-args-against ctx args params)))
|
||||
(cond
|
||||
(go-type-error? err) err
|
||||
(= (len results) 0) (list :ty-void)
|
||||
(= (len results) 1) (first results)
|
||||
:else (list :ty-tuple results)))))))))
|
||||
|
||||
(define
|
||||
go-synth-binop
|
||||
(fn (ctx op lhs rhs)
|
||||
|
||||
Reference in New Issue
Block a user