go: parse.sx — func type expressions (anonymous params) + 9 tests [nothing]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 20s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 20s
Adds Go func-type parsing to gp-parse-type:
func() → (list :ty-func () ())
func() int → (list :ty-func () [int])
func(int, string) → (list :ty-func [int string] ())
func(int) string → (list :ty-func [int] [string])
func() (int, error) → (list :ty-func () [int error])
gp-parse-func-type-params handles the param list inside (...);
gp-parse-func-type-results dispatches between bare single-return,
multi-return parenthesised list, or no return.
Anonymous-only — named params (`func(a int, b string)`) require a
different shape and are mainly needed for func DECLARATIONS, not for
pure func-type expressions in type position. Variadic ('...T')
deferred.
Covers nested cases: func returning func, chan of func, func with
pointer/slice operands.
parse 90/90, total 219/219.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -95,6 +95,57 @@
|
||||
:else nil)))
|
||||
(gp-args-rest)
|
||||
args)))))
|
||||
(define
|
||||
gp-parse-func-type-params
|
||||
;; Anonymous-only func-type params: caller is positioned BEFORE
|
||||
;; the opening "(". Returns a list of type AST nodes.
|
||||
;; Named params (a int, b string) are deferred — they're needed
|
||||
;; for func DECLARATIONS, not pure func-type expressions.
|
||||
(fn
|
||||
()
|
||||
(let ((params (list)))
|
||||
(when (and (= (gp-tok-type) "op") (= (gp-tok-value) "("))
|
||||
(gp-advance!))
|
||||
(cond
|
||||
(and (= (gp-tok-type) "op") (= (gp-tok-value) ")"))
|
||||
(do (gp-advance!) params)
|
||||
:else
|
||||
(do
|
||||
(let ((first (gp-parse-type)))
|
||||
(when (not (= first nil)) (append! params first)))
|
||||
(define
|
||||
gp-params-rest
|
||||
(fn
|
||||
()
|
||||
(cond
|
||||
(and (= (gp-tok-type) "op") (= (gp-tok-value) ","))
|
||||
(do
|
||||
(gp-advance!)
|
||||
(let ((t (gp-parse-type)))
|
||||
(when (not (= t nil)) (append! params t)))
|
||||
(gp-params-rest))
|
||||
(and (= (gp-tok-type) "op") (= (gp-tok-value) ")"))
|
||||
(gp-advance!)
|
||||
:else nil)))
|
||||
(gp-params-rest)
|
||||
params)))))
|
||||
(define
|
||||
gp-parse-func-type-results
|
||||
;; Zero, one, or many return types. Caller is positioned after
|
||||
;; the closing ')' of params.
|
||||
;; no return — next token is not a type-starter
|
||||
;; single return — bare type follows
|
||||
;; multi return — '(' T, T, ... ')'
|
||||
(fn
|
||||
()
|
||||
(cond
|
||||
(and (= (gp-tok-type) "op") (= (gp-tok-value) "("))
|
||||
(gp-parse-func-type-params)
|
||||
:else
|
||||
(let ((t (gp-parse-type)))
|
||||
(cond
|
||||
(= t nil) (list)
|
||||
:else (list t))))))
|
||||
(define
|
||||
gp-parse-type
|
||||
;; Go type-expression parser. Covers:
|
||||
@@ -147,6 +198,12 @@
|
||||
(and (= (gp-tok-type) "op") (= (gp-tok-value) "<-"))
|
||||
(do (gp-advance!) (list :ty-chan :send (gp-parse-type)))
|
||||
:else (list :ty-chan :both (gp-parse-type))))
|
||||
(and (= (gp-tok-type) "keyword") (= (gp-tok-value) "func"))
|
||||
(do
|
||||
(gp-advance!)
|
||||
(let ((params (gp-parse-func-type-params)))
|
||||
(let ((results (gp-parse-func-type-results)))
|
||||
(list :ty-func params results))))
|
||||
(= (gp-tok-type) "ident")
|
||||
(let ((name (gp-tok-value)))
|
||||
(gp-advance!)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"language": "go",
|
||||
"total_pass": 210,
|
||||
"total": 210,
|
||||
"total_pass": 219,
|
||||
"total": 219,
|
||||
"suites": [
|
||||
{"name":"lex","pass":129,"total":129,"status":"ok"},
|
||||
{"name":"parse","pass":81,"total":81,"status":"ok"},
|
||||
{"name":"parse","pass":90,"total":90,"status":"ok"},
|
||||
{"name":"types","pass":0,"total":0,"status":"pending"},
|
||||
{"name":"eval","pass":0,"total":0,"status":"pending"},
|
||||
{"name":"runtime","pass":0,"total":0,"status":"pending"},
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# Go-on-SX Scoreboard
|
||||
|
||||
**Total: 210 / 210 tests passing**
|
||||
**Total: 219 / 219 tests passing**
|
||||
|
||||
| | Suite | Pass | Total |
|
||||
|---|---|---|---|
|
||||
| ✅ | lex | 129 | 129 |
|
||||
| ✅ | parse | 81 | 81 |
|
||||
| ✅ | parse | 90 | 90 |
|
||||
| ⬜ | types | 0 | 0 |
|
||||
| ⬜ | eval | 0 | 0 |
|
||||
| ⬜ | runtime | 0 | 0 |
|
||||
|
||||
@@ -436,6 +436,77 @@
|
||||
:assert (ast-var "v")
|
||||
(list :ty-ptr (list :ty-slice (list :ty-name "int")))))
|
||||
|
||||
(go-parse-test
|
||||
"ty: func() (no params, no return)"
|
||||
(go-parse "v.(func())")
|
||||
(list :assert (ast-var "v") (list :ty-func (list) (list))))
|
||||
|
||||
(go-parse-test
|
||||
"ty: func() int (no params, one return)"
|
||||
(go-parse "v.(func() int)")
|
||||
(list
|
||||
:assert (ast-var "v")
|
||||
(list :ty-func (list) (list (list :ty-name "int")))))
|
||||
|
||||
(go-parse-test
|
||||
"ty: func(int)"
|
||||
(go-parse "v.(func(int))")
|
||||
(list
|
||||
:assert (ast-var "v")
|
||||
(list :ty-func (list (list :ty-name "int")) (list))))
|
||||
|
||||
(go-parse-test
|
||||
"ty: func(int, string)"
|
||||
(go-parse "v.(func(int, string))")
|
||||
(list
|
||||
:assert (ast-var "v")
|
||||
(list
|
||||
:ty-func (list (list :ty-name "int") (list :ty-name "string"))
|
||||
(list))))
|
||||
|
||||
(go-parse-test
|
||||
"ty: func(int) string"
|
||||
(go-parse "v.(func(int) string)")
|
||||
(list
|
||||
:assert (ast-var "v")
|
||||
(list
|
||||
:ty-func (list (list :ty-name "int"))
|
||||
(list (list :ty-name "string")))))
|
||||
|
||||
(go-parse-test
|
||||
"ty: func() (int, error) (multi return)"
|
||||
(go-parse "v.(func() (int, error))")
|
||||
(list
|
||||
:assert (ast-var "v")
|
||||
(list
|
||||
:ty-func (list)
|
||||
(list (list :ty-name "int") (list :ty-name "error")))))
|
||||
|
||||
(go-parse-test
|
||||
"ty: func(*T) []int (pointer param, slice return)"
|
||||
(go-parse "v.(func(*T) []int)")
|
||||
(list
|
||||
:assert (ast-var "v")
|
||||
(list
|
||||
:ty-func (list (list :ty-ptr (list :ty-name "T")))
|
||||
(list (list :ty-slice (list :ty-name "int"))))))
|
||||
|
||||
(go-parse-test
|
||||
"ty: func() func() (nested func type as return)"
|
||||
(go-parse "v.(func() func())")
|
||||
(list
|
||||
:assert (ast-var "v")
|
||||
(list :ty-func (list) (list (list :ty-func (list) (list))))))
|
||||
|
||||
(go-parse-test
|
||||
"ty: chan func() int (chan of func type)"
|
||||
(go-parse "v.(chan func() int)")
|
||||
(list
|
||||
:assert (ast-var "v")
|
||||
(list
|
||||
:ty-chan :both
|
||||
(list :ty-func (list) (list (list :ty-name "int"))))))
|
||||
|
||||
(go-parse-test "non-primary: '+'" (go-parse "+") nil)
|
||||
|
||||
(go-parse-test "non-primary: empty" (go-parse "") nil)
|
||||
|
||||
Reference in New Issue
Block a user