go: parse.sx — statements (return / short-decl / assign / block) + 9 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
First slice of Phase 2 statements. Replaces the func-decl ':body'
sentinel with real (:block STMTS) parsing.
gp-parse-stmt dispatches on the leading token:
return [exprs] — (list :return EXPRS)
{ ... } — nested block (recurses into block-body)
lhs := exprs — (list :short-decl LHS-LIST EXPRS)
lhs = exprs — (list :assign LHS-LIST EXPRS)
lhs OP= expr — (list :assign-op OP LHS-LIST [EXPR])
expr — bare expression statement
var/const/type/func keywords — fall through to gp-parse-decl
LHS may be a comma-separated list. Compound-assign covers all 11 Go
forms (+= -= *= /= %= &= |= ^= <<= >>= &^=).
gp-parse-block-body iterates: skips semis, terminates on '}', and for
non-trivial tokens calls gp-parse-stmt. **Two progress guards** added
to avoid infinite loops on unsupported syntax:
* gp-block-body-loop force-advances one token if gp-parse-stmt
returns nil without consuming.
* gp-parse-composite-elems does the same when its expr parser
returns nil — fixes a hang on '`if true {`x := 1`}`' where the
parser was misreading `if true{...}` as a composite literal then
spinning on `:=` inside the brace body.
Existing func/method decl tests updated from the ':body' sentinel to
the new (:block STMTS) shape. Old `gp-skip-block!` left as dead code
(removed once control-flow stmts make the misinterpretation issue
moot).
Control-flow stmts (if/for/switch/select/defer/go/break/continue) and
channel send (`ch <- v`) deferred to subsequent iterations.
parse 141/141, total 270/270.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -778,7 +778,7 @@
|
||||
(go-parse-test
|
||||
"fdecl: func main() {}"
|
||||
(go-parse "func main() {}")
|
||||
(list :func-decl "main" (list) (list) :body))
|
||||
(list :func-decl "main" (list) (list) (list :block (list))))
|
||||
|
||||
(go-parse-test
|
||||
"fdecl: func add(x, y int) int { return x + y }"
|
||||
@@ -787,7 +787,11 @@
|
||||
:func-decl "add"
|
||||
(list (list :field (list "x" "y") (list :ty-name "int")))
|
||||
(list (list :ty-name "int"))
|
||||
:body))
|
||||
(list :block
|
||||
(list
|
||||
(list :return
|
||||
(list
|
||||
(ast-app (ast-var "+") (list (ast-var "x") (ast-var "y")))))))))
|
||||
|
||||
(go-parse-test
|
||||
"fdecl: func with multi-group params"
|
||||
@@ -798,7 +802,7 @@
|
||||
(list :field (list "x") (list :ty-name "int"))
|
||||
(list :field (list "y") (list :ty-name "string")))
|
||||
(list)
|
||||
:body))
|
||||
(list :block (list))))
|
||||
|
||||
(go-parse-test
|
||||
"fdecl: func with multi-return"
|
||||
@@ -807,7 +811,7 @@
|
||||
:func-decl "divmod"
|
||||
(list (list :field (list "a" "b") (list :ty-name "int")))
|
||||
(list (list :ty-name "int") (list :ty-name "int"))
|
||||
:body))
|
||||
(list :block (list))))
|
||||
|
||||
(go-parse-test
|
||||
"fdecl: func with no body (signature only)"
|
||||
@@ -826,7 +830,8 @@
|
||||
"String"
|
||||
(list)
|
||||
(list (list :ty-name "string"))
|
||||
:body))
|
||||
(list :block
|
||||
(list (list :return (list (list :select (ast-var "p") "x")))))))
|
||||
|
||||
(go-parse-test
|
||||
"mdecl: method on value receiver"
|
||||
@@ -836,12 +841,75 @@
|
||||
"Len"
|
||||
(list)
|
||||
(list (list :ty-name "int"))
|
||||
:body))
|
||||
(list :block (list (list :return (list (ast-literal "0")))))))
|
||||
|
||||
(go-parse-test
|
||||
"fdecl: nested braces in body (skipped opaquely)"
|
||||
(go-parse "func nested() { if true { x := 1; { y := 2 } } }")
|
||||
(list :func-decl "nested" (list) (list) :body))
|
||||
"fdecl: body with return"
|
||||
(go-parse "func ret() { return 42 }")
|
||||
(list :func-decl "ret" (list) (list)
|
||||
(list :block (list (list :return (list (ast-literal "42")))))))
|
||||
|
||||
(go-parse-test
|
||||
"stmt: short-decl x := 5"
|
||||
(go-parse "x := 5")
|
||||
(list :short-decl (list (ast-var "x")) (list (ast-literal "5"))))
|
||||
|
||||
(go-parse-test
|
||||
"stmt: short-decl multi a, b := 1, 2"
|
||||
(go-parse "a, b := 1, 2")
|
||||
(list
|
||||
:short-decl (list (ast-var "a") (ast-var "b"))
|
||||
(list (ast-literal "1") (ast-literal "2"))))
|
||||
|
||||
(go-parse-test
|
||||
"stmt: assign x = 5"
|
||||
(go-parse "x = 5")
|
||||
(list :assign (list (ast-var "x")) (list (ast-literal "5"))))
|
||||
|
||||
(go-parse-test
|
||||
"stmt: compound assign x += 1"
|
||||
(go-parse "x += 1")
|
||||
(list :assign-op "+=" (list (ast-var "x")) (list (ast-literal "1"))))
|
||||
|
||||
(go-parse-test
|
||||
"stmt: return (no value)"
|
||||
(go-parse "return")
|
||||
(list :return (list)))
|
||||
|
||||
(go-parse-test
|
||||
"stmt: return x + y"
|
||||
(go-parse "return x + y")
|
||||
(list
|
||||
:return (list (ast-app (ast-var "+") (list (ast-var "x") (ast-var "y"))))))
|
||||
|
||||
(go-parse-test
|
||||
"stmt: return multi a, b"
|
||||
(go-parse "return a, b")
|
||||
(list :return (list (ast-var "a") (ast-var "b"))))
|
||||
|
||||
(go-parse-test
|
||||
"stmt: function body with multiple stmts"
|
||||
(go-parse "func f() { x := 1; y := 2; return x + y }")
|
||||
(list
|
||||
:func-decl "f"
|
||||
(list)
|
||||
(list)
|
||||
(list
|
||||
:block (list
|
||||
(list :short-decl (list (ast-var "x")) (list (ast-literal "1")))
|
||||
(list :short-decl (list (ast-var "y")) (list (ast-literal "2")))
|
||||
(list
|
||||
:return (list
|
||||
(ast-app (ast-var "+") (list (ast-var "x") (ast-var "y")))))))))
|
||||
|
||||
(go-parse-test
|
||||
"stmt: expression statement (just a call)"
|
||||
(go-parse "func g() { f(x) }")
|
||||
(list
|
||||
:func-decl "g"
|
||||
(list)
|
||||
(list)
|
||||
(list :block (list (ast-app (ast-var "f") (list (ast-var "x")))))))
|
||||
|
||||
(go-parse-test "non-primary: '+'" (go-parse "+") nil)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user