# deft/parse-forms Parse arbitrary Deft source into `%Sexpr{}` form trees without evaluating it. Unlike `deft/parse`, which accepts only data literals, this runs the full kernel parser — calls, `def`s, control flow, decorators, and map literals all come back as structured forms with source positions, so tooling (importers, graph builders, syntax tools) can inspect code without invoking the compiler. ## Syntax
[deft/parse-forms $source]
## Parameters - `$source` — Deft source text (string). Multiple top-level forms are all returned. ## Returns `%{ :forms @{%Sexpr{} ...} :errors @{%{ :line :col :message } ...} }`. Every form is a `%Sexpr{}` tagged map carrying: - `:tag` — one of `:symbol`, `:keyword`, `:string`, `:raw-string`, `:number`, `:bool`, `:nil`, `:call`, `:list`, `:map`, `:value` - `:line` / `:col` — 1-based position of the form's first token - payload — `:value` (scalars), `:items` (`:call` / `:list`, a vector of child forms), or `:pairs` (`:map`, a vector of `[key value]` vectors); `:nil` and `:value` carry no payload `:call` is a bracket `[...]` form; a non-bracket list — an infix group `(...)` or a `{ ... }` block body — is `:list`. The parser lowers some syntax before returning it: a `def` becomes `(__defproc name params body)`, typed/default/rest params become `(typed-param ...)` / `(default-typed-param ...)` / `(rest-param ...)`, a map literal becomes `(__make-map k v ...)`, and a decorator becomes `(decorator name value)`. Malformed source does not throw: the parser recovers as far as it can, returns the forms it built, and lists diagnostics in `:errors`. A lex or fatal parse failure returns `%Err{:message}` instead. ## Examples
set p [deft/parse-forms "set x [len \$xs]"]
set stmt [first $p~forms]
$stmt~tag                                    # → :list
[get [nth $stmt~items 2] :tag]               # → :call   (the [len $xs])

# A def lowers to (__defproc name params body)
set d [first [get [deft/parse-forms "def f {|a^number| \$a}"] :forms]]
[get [first $d~items] :value]                # → "__defproc"

# Malformed source: forms plus diagnostics, never an exception
set r [deft/parse-forms "set y (1 +"]
[get [first $r~errors] :message]             # → parser diagnostic text
## See Also `deft/parse`, `deft/stringify`, `deft/syntax-highlight`, `eval`