Language

Grammar

This is the grammar accepted by the current metadata parser. It is intentionally line-oriented and incomplete.

This is the grammar accepted by the current metadata parser. It is intentionally line-oriented and incomplete.

file        = line*
line        = blank | comment | packageDecl | annotation | importDecl | useDecl | blockDecl | goDecl | actionDecl | apiDecl | unsupportedBlock | other
blank       = whitespace*
comment     = whitespace* "//" text

packageDecl = "package" whitespace+ ident
annotation  = "@" ident value
importDecl  = "import" (whitespace+ ident)? whitespace+ string
useDecl     = "use" whitespace+ ident whitespace+ string
blockDecl   = ("paths" | "build" | "load" | "view" | "style") whitespace* "{"
goDecl  = "go" (whitespace+ blockName)? whitespace* "{"
actionDecl  = "act" whitespace+ ident whitespace+ "POST" whitespace+ string
apiDecl     = "api" whitespace+ ident whitespace+ apiMethod whitespace+ string
unsupportedBlock = blockName text "{"
apiMethod   = "GET" | "POST" | "PUT" | "PATCH" | "DELETE"

ident       = letterOrUnderscore (letter | digit | "_")*
blockName   = letterOrUnderscore (letter | digit | "_" | "." | "-")*

The parser currently scans each trimmed line independently. It records declarations and captures raw body text for paths {}, build {}, load {}, go {}, go target {}, view {}, and style {} blocks until their closing }. CSS braces inside style {} and Go braces inside go {} do not close those blocks early. Go block bodies are parsed as Go during semantic validation. act and api declarations name exact exported Go handler symbols; behavior lives in normal same-package Go handlers. gowdk build parses the first literal paths {} and build {} subsets at app-generation time:

literalReturn = "=>" whitespace* "{" literalField ("," literalField)* "}"
literalField  = ident ":" string
buildCall     = "=>" whitespace* ident "." ident "()"

Unknown or malformed annotations fail at parse time. Unsupported top-level block declarations fail when they have an identifier-like first token and a trailing {. SPA builds also accept the first imported buildCall subset when the page declares the referenced import.

Default go {} blocks can provide no-argument build-data functions for build { => LocalFunc() }. Saved default go {} blocks are type-checked with sibling Go files in the same package during validation. go ssr {} can provide generated SSR load handlers when request-time rendering is enabled. Generated app source writes default go {} and go ssr {} blocks under gowdk_go/. Page-level go client {} blocks that export GOWDKMount<PageID> with //go:wasmexport compile to client-side Go WASM and emit a page mount loader. Targets such as addon.contracts are preserved for lane-specific extraction. Configured addons that implement gowdk.GoBlockConsumer can validate go addon.<name> {} blocks and emit generated app Go files.

Old act name { ... } and api name { ... } forms are rejected with migration diagnostics.

It validates first-slice action fragment targets, captures their body text, and the generated embedded app can serve the first rendered action fragment response for partial POSTs. It does not validate broader statement syntax, full markup syntax, expressions, or most block body contents.

The canonical AST, recovery, and semantic-analysis model lives in the language docs in this directory; implementation remains incremental.