go: parse.sx — multi-form file parsing + 7 e2e tests; PHASE 2 COMPLETE [nothing]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 28s

Final Phase 2 sub-deliverable. go-parse now handles whole Go files:

  - Empty source → nil
  - Single top-level form → that form (backward-compatible with ~169
    existing single-stmt / single-decl tests)
  - Multiple forms → (list :file FORMS), the canonical Go file shape

Implementation: gp-parse-all loops gp-parse-top until eof, tolerating
ASI semis between forms, then returns based on form count.

End-to-end test set (asserts the top-level decl-tag sequence via a
new decl-tags helper, not the full AST tree — that'd be unwieldy):

  - hello-world             :package :import :func-decl
  - recursive fibonacci     :package :func-decl
  - FizzBuzz                :package :import :func-decl
  - goroutine ping-pong     :package :func-decl :func-decl
  - struct + method         :package :type-decl :method-decl :func-decl
  - interface + method      :package :type-decl :type-decl :method-decl
  - defer + select + range  :package :func-decl

Type-switch (`switch v := x.(type) { ... }`) is the one syntactic
shape still deferred from Phase 2; doesn't gate Phase 3.

**Phase 2 (parser) is complete.** parse 176/176, total 305/305. Next:
Phase 3 — bidirectional type checker. The sister-plan diary for
static-types-bidirectional already has the :field binding-group
insight; Phase 3 will add the synth/check shape that emerges.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-27 20:34:16 +00:00
parent 44fb231391
commit 2404a593bd
5 changed files with 116 additions and 12 deletions

View File

@@ -1175,4 +1175,34 @@
(= (gp-tok-value) "func")))
(gp-parse-decl)
:else (gp-parse-stmt))))
(gp-parse-top))))
(define
gp-parse-all
;; Parse all top-level forms until eof. Returns:
;; nil — empty input
;; single form — backward-compatible with single-stmt
;; /single-decl tests; ~169 of them.
;; (list :file FORMS) — multiple forms (canonical Go file shape)
(fn
()
(let ((forms (list)))
(define
gp-all-loop
(fn
()
(cond
(= (gp-tok-type) "eof") nil
(= (gp-tok-type) "semi")
(do (gp-advance!) (gp-all-loop))
:else
(do
(let ((saved-idx gp-idx))
(let ((d (gp-parse-top)))
(when (not (= d nil)) (append! forms d)))
(when (= gp-idx saved-idx) (gp-advance!)))
(gp-all-loop)))))
(gp-all-loop)
(cond
(= (len forms) 0) nil
(= (len forms) 1) (first forms)
:else (list :file forms)))))
(gp-parse-all))))