go: types.sx — func-decl + stmt-level dispatch + 7 tests [nothing]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 31s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 31s
Phase 3 cont. Adds:
* go-check-func-decl — binds the function in the outer ctx (recursive
self-reference will work once call-checking lands), extends the
body's ctx with each :field param group via go-ctx-extend-field
(the binding-group shape's *third* consumer in the type checker;
five total across parser+typer when counted with struct fields,
var-decls, const-decls, func params, method receivers).
* go-check-stmt — dispatches on :return / :assign / :var-decl /
:const-decl / :short-decl / :type-decl / :block; falls back to
go-synth for expression statements.
* go-check-block — threads ctx through stmts so that decls inside
the block extend the ctx for subsequent stmts.
* go-check-return-list — each return expr assignable to the
corresponding declared result type; mismatch counts are typed.
* go-check-assign / go-check-assign-pairs — RHS assignable to LHS
synthesised type, count mismatch typed.
* Helpers: go-decl-params-to-ty-list (flattens :field NAMES TYPE to
a flat list of N types), go-extend-with-params (folds extend-field
over a param-group list), go-repeat-ty.
Coverage tests:
func empty() {} → ok
func add(x, y int) int { return x + y } → ok
func bad() int { return "hi" } → typed error
func sig(x int) int → signature-only binds
func sumsq(x, y int) int { return x*x + y*y } → params visible
func two() int { var x int = 1; var y int = 2; → nested decl
return x + y }
func g() int { var x int; x = 5; return x } → assign verified
types 47/47, total 352/352.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"language": "go",
|
"language": "go",
|
||||||
"total_pass": 345,
|
"total_pass": 352,
|
||||||
"total": 345,
|
"total": 352,
|
||||||
"suites": [
|
"suites": [
|
||||||
{"name":"lex","pass":129,"total":129,"status":"ok"},
|
{"name":"lex","pass":129,"total":129,"status":"ok"},
|
||||||
{"name":"parse","pass":176,"total":176,"status":"ok"},
|
{"name":"parse","pass":176,"total":176,"status":"ok"},
|
||||||
{"name":"types","pass":40,"total":40,"status":"ok"},
|
{"name":"types","pass":47,"total":47,"status":"ok"},
|
||||||
{"name":"eval","pass":0,"total":0,"status":"pending"},
|
{"name":"eval","pass":0,"total":0,"status":"pending"},
|
||||||
{"name":"runtime","pass":0,"total":0,"status":"pending"},
|
{"name":"runtime","pass":0,"total":0,"status":"pending"},
|
||||||
{"name":"stdlib","pass":0,"total":0,"status":"pending"},
|
{"name":"stdlib","pass":0,"total":0,"status":"pending"},
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
# Go-on-SX Scoreboard
|
# Go-on-SX Scoreboard
|
||||||
|
|
||||||
**Total: 345 / 345 tests passing**
|
**Total: 352 / 352 tests passing**
|
||||||
|
|
||||||
| | Suite | Pass | Total |
|
| | Suite | Pass | Total |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| ✅ | lex | 129 | 129 |
|
| ✅ | lex | 129 | 129 |
|
||||||
| ✅ | parse | 176 | 176 |
|
| ✅ | parse | 176 | 176 |
|
||||||
| ✅ | types | 40 | 40 |
|
| ✅ | types | 47 | 47 |
|
||||||
| ⬜ | eval | 0 | 0 |
|
| ⬜ | eval | 0 | 0 |
|
||||||
| ⬜ | runtime | 0 | 0 |
|
| ⬜ | runtime | 0 | 0 |
|
||||||
| ⬜ | stdlib | 0 | 0 |
|
| ⬜ | stdlib | 0 | 0 |
|
||||||
|
|||||||
@@ -264,6 +264,68 @@
|
|||||||
(list (go-ctx-lookup ctx "a") (go-ctx-lookup ctx "b")))
|
(list (go-ctx-lookup ctx "a") (go-ctx-lookup ctx "b")))
|
||||||
(list (list :ty-name "int") (list :ty-name "int")))
|
(list (list :ty-name "int") (list :ty-name "int")))
|
||||||
|
|
||||||
|
(go-types-test
|
||||||
|
"fdecl: func empty() — binds empty to func type"
|
||||||
|
(go-ctx-lookup
|
||||||
|
(go-check-decl go-ctx-empty (go-parse "func empty() {}"))
|
||||||
|
"empty")
|
||||||
|
(list :ty-func (list) (list)))
|
||||||
|
|
||||||
|
(go-types-test
|
||||||
|
"fdecl: func add(x, y int) int { return x + y } — ok"
|
||||||
|
(go-ctx-lookup
|
||||||
|
(go-check-decl
|
||||||
|
go-ctx-empty
|
||||||
|
(go-parse "func add(x, y int) int { return x + y }"))
|
||||||
|
"add")
|
||||||
|
(list
|
||||||
|
:ty-func (list (list :ty-name "int") (list :ty-name "int"))
|
||||||
|
(list (list :ty-name "int"))))
|
||||||
|
|
||||||
|
(go-types-test
|
||||||
|
"fdecl: func bad() int { return \"hi\" } — type error"
|
||||||
|
(go-check-decl go-ctx-empty (go-parse "func bad() int { return \"hi\" }"))
|
||||||
|
(list
|
||||||
|
:type-error :mismatch
|
||||||
|
(list :ty-name "int")
|
||||||
|
(list :ty-untyped-string)))
|
||||||
|
|
||||||
|
(go-types-test
|
||||||
|
"fdecl: signature-only (no body)"
|
||||||
|
(go-ctx-lookup
|
||||||
|
(go-check-decl go-ctx-empty (go-parse "func sig(x int) int"))
|
||||||
|
"sig")
|
||||||
|
(list :ty-func (list (list :ty-name "int")) (list (list :ty-name "int"))))
|
||||||
|
|
||||||
|
(go-types-test
|
||||||
|
"fdecl: param-bound — body sees x and y"
|
||||||
|
(go-ctx-lookup
|
||||||
|
(go-check-decl
|
||||||
|
go-ctx-empty
|
||||||
|
(go-parse "func sumsq(x, y int) int { return x*x + y*y }"))
|
||||||
|
"sumsq")
|
||||||
|
(list :ty-func
|
||||||
|
(list (list :ty-name "int") (list :ty-name "int"))
|
||||||
|
(list (list :ty-name "int"))))
|
||||||
|
|
||||||
|
(go-types-test
|
||||||
|
"fdecl: nested decl in body extends ctx for later stmts"
|
||||||
|
(go-ctx-lookup
|
||||||
|
(go-check-decl
|
||||||
|
go-ctx-empty
|
||||||
|
(go-parse "func two() int { var x int = 1; var y int = 2; return x + y }"))
|
||||||
|
"two")
|
||||||
|
(list :ty-func (list) (list (list :ty-name "int"))))
|
||||||
|
|
||||||
|
(go-types-test
|
||||||
|
"fdecl: assign inside body — type-checks RHS vs LHS"
|
||||||
|
(go-ctx-lookup
|
||||||
|
(go-check-decl
|
||||||
|
go-ctx-empty
|
||||||
|
(go-parse "func g() int { var x int; x = 5; return x }"))
|
||||||
|
"g")
|
||||||
|
(list :ty-func (list) (list (list :ty-name "int"))))
|
||||||
|
|
||||||
(define
|
(define
|
||||||
go-types-test-summary
|
go-types-test-summary
|
||||||
(str "types " go-types-test-pass "/" go-types-test-count))
|
(str "types " go-types-test-pass "/" go-types-test-count))
|
||||||
|
|||||||
144
lib/go/types.sx
144
lib/go/types.sx
@@ -415,4 +415,148 @@
|
|||||||
(and (list? decl) (= (first decl) :type-decl))
|
(and (list? decl) (= (first decl) :type-decl))
|
||||||
(let ((name (nth decl 1)) (ty (nth decl 2)))
|
(let ((name (nth decl 1)) (ty (nth decl 2)))
|
||||||
(go-ctx-extend ctx name ty))
|
(go-ctx-extend ctx name ty))
|
||||||
|
(and (list? decl) (= (first decl) :func-decl))
|
||||||
|
(go-check-func-decl ctx decl)
|
||||||
:else ctx)))
|
:else ctx)))
|
||||||
|
|
||||||
|
;; ── function-decl checking ──────────────────────────────────────
|
||||||
|
|
||||||
|
(define
|
||||||
|
go-repeat-ty
|
||||||
|
(fn (n ty acc)
|
||||||
|
(cond
|
||||||
|
(<= n 0) acc
|
||||||
|
:else (go-repeat-ty (- n 1) ty (cons ty acc)))))
|
||||||
|
|
||||||
|
(define
|
||||||
|
go-decl-params-to-ty-list
|
||||||
|
;; Flatten (:field NAMES TYPE) param groups into a list of types,
|
||||||
|
;; one entry per name. For func-type signatures.
|
||||||
|
(fn (params)
|
||||||
|
(cond
|
||||||
|
(or (= params nil) (= (len params) 0)) (list)
|
||||||
|
:else
|
||||||
|
(let ((field (first params)))
|
||||||
|
(let ((names (nth field 1)) (ty (nth field 2)))
|
||||||
|
(let ((rest-tys (go-decl-params-to-ty-list (rest params))))
|
||||||
|
(go-repeat-ty (len names) ty rest-tys)))))))
|
||||||
|
|
||||||
|
(define
|
||||||
|
go-extend-with-params
|
||||||
|
;; Extend CTX with every binding in every (:field NAMES TYPE) param group.
|
||||||
|
(fn (ctx params)
|
||||||
|
(cond
|
||||||
|
(or (= params nil) (= (len params) 0)) ctx
|
||||||
|
:else
|
||||||
|
(go-extend-with-params
|
||||||
|
(go-ctx-extend-field ctx (first params))
|
||||||
|
(rest params)))))
|
||||||
|
|
||||||
|
(define
|
||||||
|
go-check-return-list
|
||||||
|
;; Each EXPR assignable to the corresponding RESULTS type.
|
||||||
|
;; v0: lengths must match; multi-return funcs deferred.
|
||||||
|
(fn (ctx exprs results)
|
||||||
|
(cond
|
||||||
|
(and (= (len exprs) 0) (= (len results) 0)) :ok
|
||||||
|
(not (= (len exprs) (len results)))
|
||||||
|
(list :type-error :return-count-mismatch
|
||||||
|
(len exprs) (len results))
|
||||||
|
:else
|
||||||
|
(let ((r (go-check ctx (first exprs) (first results))))
|
||||||
|
(cond
|
||||||
|
(go-type-error? r) r
|
||||||
|
:else (go-check-return-list ctx (rest exprs) (rest results)))))))
|
||||||
|
|
||||||
|
(define
|
||||||
|
go-check-assign
|
||||||
|
(fn (ctx stmt)
|
||||||
|
(let ((lhs-list (nth stmt 1)) (rhs-list (nth stmt 2)))
|
||||||
|
(cond
|
||||||
|
(not (= (len lhs-list) (len rhs-list)))
|
||||||
|
(list :type-error :assign-count-mismatch
|
||||||
|
(len lhs-list) (len rhs-list))
|
||||||
|
:else (go-check-assign-pairs ctx lhs-list rhs-list)))))
|
||||||
|
|
||||||
|
(define
|
||||||
|
go-check-assign-pairs
|
||||||
|
(fn (ctx lhs-list rhs-list)
|
||||||
|
(cond
|
||||||
|
(= (len lhs-list) 0) :ok
|
||||||
|
:else
|
||||||
|
(let ((lhs-ty (go-synth ctx (first lhs-list))))
|
||||||
|
(cond
|
||||||
|
(go-type-error? lhs-ty) lhs-ty
|
||||||
|
:else
|
||||||
|
(let ((r (go-check ctx (first rhs-list) lhs-ty)))
|
||||||
|
(cond
|
||||||
|
(go-type-error? r) r
|
||||||
|
:else
|
||||||
|
(go-check-assign-pairs ctx (rest lhs-list)
|
||||||
|
(rest rhs-list)))))))))
|
||||||
|
|
||||||
|
(define
|
||||||
|
go-check-stmt
|
||||||
|
;; Returns either an extended CTX (decls), :ok (sealed stmts), or
|
||||||
|
;; :type-error. RESULTS is the enclosing func's declared return types
|
||||||
|
;; (used by :return).
|
||||||
|
(fn (ctx stmt results)
|
||||||
|
(cond
|
||||||
|
(and (list? stmt) (= (first stmt) :var-decl))
|
||||||
|
(go-check-decl ctx stmt)
|
||||||
|
(and (list? stmt) (= (first stmt) :const-decl))
|
||||||
|
(go-check-decl ctx stmt)
|
||||||
|
(and (list? stmt) (= (first stmt) :short-decl))
|
||||||
|
(go-check-decl ctx stmt)
|
||||||
|
(and (list? stmt) (= (first stmt) :type-decl))
|
||||||
|
(go-check-decl ctx stmt)
|
||||||
|
(and (list? stmt) (= (first stmt) :return))
|
||||||
|
(let ((exprs (nth stmt 1)))
|
||||||
|
(let ((err (go-check-return-list ctx exprs results)))
|
||||||
|
(cond (go-type-error? err) err :else ctx)))
|
||||||
|
(and (list? stmt) (= (first stmt) :block))
|
||||||
|
(let ((err (go-check-block ctx (nth stmt 1) results)))
|
||||||
|
(cond (go-type-error? err) err :else ctx))
|
||||||
|
(and (list? stmt) (= (first stmt) :assign))
|
||||||
|
(let ((err (go-check-assign ctx stmt)))
|
||||||
|
(cond (go-type-error? err) err :else ctx))
|
||||||
|
:else
|
||||||
|
(let ((t (go-synth ctx stmt)))
|
||||||
|
(cond (go-type-error? t) t :else ctx)))))
|
||||||
|
|
||||||
|
(define
|
||||||
|
go-check-block
|
||||||
|
;; Thread ctx through stmts; if any stmt is a decl, its extension
|
||||||
|
;; propagates to subsequent stmts. Returns :ok or :type-error.
|
||||||
|
(fn (ctx stmts results)
|
||||||
|
(cond
|
||||||
|
(or (= stmts nil) (= (len stmts) 0)) :ok
|
||||||
|
:else
|
||||||
|
(let ((r (go-check-stmt ctx (first stmts) results)))
|
||||||
|
(cond
|
||||||
|
(go-type-error? r) r
|
||||||
|
:else (go-check-block r (rest stmts) results))))))
|
||||||
|
|
||||||
|
(define
|
||||||
|
go-check-func-decl
|
||||||
|
;; Bind the function in the outer ctx (so recursion works), extend
|
||||||
|
;; ctx with params, check the body. Returns the outer ctx with the
|
||||||
|
;; function bound, or :type-error.
|
||||||
|
(fn (ctx decl)
|
||||||
|
(let ((name (nth decl 1)) (params (nth decl 2))
|
||||||
|
(results (nth decl 3)) (body (nth decl 4)))
|
||||||
|
(let ((fn-ty
|
||||||
|
(list :ty-func
|
||||||
|
(go-decl-params-to-ty-list params) results)))
|
||||||
|
(let ((ctx-with-fn (go-ctx-extend ctx name fn-ty)))
|
||||||
|
(cond
|
||||||
|
(= body nil) ctx-with-fn
|
||||||
|
(and (list? body) (= (first body) :block))
|
||||||
|
(let ((body-ctx
|
||||||
|
(go-extend-with-params ctx-with-fn params)))
|
||||||
|
(let ((err
|
||||||
|
(go-check-block body-ctx (nth body 1) results)))
|
||||||
|
(cond
|
||||||
|
(go-type-error? err) err
|
||||||
|
:else ctx-with-fn)))
|
||||||
|
:else ctx-with-fn))))))
|
||||||
|
|||||||
@@ -234,8 +234,11 @@ Progress-log line → push `origin/loops/go`.
|
|||||||
the extended context or a `:type-error`. Untyped synthesized types
|
the extended context or a `:type-error`. Untyped synthesized types
|
||||||
get their default-type (`untyped-int → int`, `untyped-float →
|
get their default-type (`untyped-int → int`, `untyped-float →
|
||||||
float64`, etc.) when bound in inferred-type decls.
|
float64`, etc.) when bound in inferred-type decls.
|
||||||
- [ ] Function declaration: extend ctx with params via `:field` group,
|
- [x] Function declaration: extends ctx with each `:field` param group,
|
||||||
check body, verify return-list types match signature.
|
checks block body (decls thread through, returns verify against
|
||||||
|
signature, assignments verify RHS assignable to LHS). The function
|
||||||
|
itself is bound in the body's ctx so recursion will work once
|
||||||
|
call-checking lands. Signature-only (no body) just binds.
|
||||||
- [ ] Call type-checking (synth callee, check args against param types,
|
- [ ] Call type-checking (synth callee, check args against param types,
|
||||||
synth result).
|
synth result).
|
||||||
- [ ] Composite type element checking (slice / map / chan).
|
- [ ] Composite type element checking (slice / map / chan).
|
||||||
@@ -243,7 +246,7 @@ Progress-log line → push `origin/loops/go`.
|
|||||||
- [ ] Short variable declaration `:=` (synth RHS into LHS bindings).
|
- [ ] Short variable declaration `:=` (synth RHS into LHS bindings).
|
||||||
- Defer: generics (Phase 7), full conversion rules, type assertions,
|
- Defer: generics (Phase 7), full conversion rules, type assertions,
|
||||||
type switches.
|
type switches.
|
||||||
- **Acceptance:** types/ suite at 60+ tests. Current: 40/40. Chisel note
|
- **Acceptance:** types/ suite at 60+ tests. Current: 47/47. Chisel note
|
||||||
`shapes-static-types-bidirectional` — sister-plan design diary is the
|
`shapes-static-types-bidirectional` — sister-plan design diary is the
|
||||||
cross-language record.
|
cross-language record.
|
||||||
|
|
||||||
@@ -544,6 +547,19 @@ Minimal repro: see `lib/go/lex.sx#gl-oct-digit?` and `#gl-match-op`.
|
|||||||
|
|
||||||
_Newest first. Append one dated entry per commit._
|
_Newest first. Append one dated entry per commit._
|
||||||
|
|
||||||
|
- 2026-05-27 — Phase 3 cont.: function-declaration checking +
|
||||||
|
statement-level dispatch. `go-check-func-decl` binds the function in
|
||||||
|
the outer ctx (so the body can see itself), extends the body's ctx
|
||||||
|
with each `:field` param group via `go-ctx-extend-field` (the
|
||||||
|
binding-group shape's third consumer in the type checker — now
|
||||||
|
five total across parser+typer combined), then runs `go-check-block`
|
||||||
|
through every statement. `go-check-stmt` dispatches on `:return`,
|
||||||
|
`:assign`, `:var-decl`/`:const-decl`/`:short-decl`/`:type-decl`,
|
||||||
|
`:block`, falling back to `go-synth` for expression statements.
|
||||||
|
Return-list and assign-pair count mismatches are typed errors. +7
|
||||||
|
tests, types 47/47, total 352/352. `[nothing]` — pure Go-side
|
||||||
|
composition; the kit-relevant insights are already in the sister-
|
||||||
|
plan diary.
|
||||||
- 2026-05-27 — Phase 3 cont.: declaration checking — `var`/`const`/`type`
|
- 2026-05-27 — Phase 3 cont.: declaration checking — `var`/`const`/`type`
|
||||||
+ short-decl `:=`. `go-check-decl` returns the extended context (or a
|
+ short-decl `:=`. `go-check-decl` returns the extended context (or a
|
||||||
`:type-error`). New helpers: `go-default-type` (untyped-int → int,
|
`:type-error`). New helpers: `go-default-type` (untyped-int → int,
|
||||||
|
|||||||
Reference in New Issue
Block a user