Recover agent-loop progress: lua/prolog/forth/erlang/haskell phases 1-2
Salvaged from worktree-agent-* branches killed during sx-tree MCP outage: - lua: tokenizer + parser + phase-2 transpile (~157 tests) - prolog: tokenizer + parser + unification (72 tests, plan update lost to WIP) - forth: phase-1 reader/interpreter + phase-2 colon/VARIABLE (134 tests) - erlang: tokenizer + parser (114 tests) - haskell: tokenizer + parse tests (43 tests) Cherry-picked file contents only, not branch history, to avoid pulling in unrelated ocaml-vm merge commits that were in those branches' bases.
This commit is contained in:
113
lib/erlang/parser-module.sx
Normal file
113
lib/erlang/parser-module.sx
Normal file
@@ -0,0 +1,113 @@
|
||||
;; Erlang module parser — reads top-level forms and builds a module AST.
|
||||
;;
|
||||
;; Depends on parser-core.sx, parser.sx, parser-expr.sx.
|
||||
|
||||
(define
|
||||
er-parse-module
|
||||
(fn
|
||||
(src)
|
||||
(let
|
||||
((st (er-state-make (er-tokenize src)))
|
||||
(mod-ref (list nil))
|
||||
(attrs (list))
|
||||
(functions (list)))
|
||||
(er-parse-module-loop st mod-ref attrs functions)
|
||||
{:functions functions :type "module" :attrs attrs :name (nth mod-ref 0)})))
|
||||
|
||||
(define
|
||||
er-parse-module-loop
|
||||
(fn
|
||||
(st mod-ref attrs functions)
|
||||
(when
|
||||
(not (er-at-eof? st))
|
||||
(er-parse-top-form st mod-ref attrs functions)
|
||||
(er-parse-module-loop st mod-ref attrs functions))))
|
||||
|
||||
(define
|
||||
er-parse-top-form
|
||||
(fn
|
||||
(st mod-ref attrs functions)
|
||||
(cond
|
||||
(er-is? st "op" "-")
|
||||
(do
|
||||
(er-advance! st)
|
||||
(let
|
||||
((attr-name (er-cur-value st)))
|
||||
(er-advance! st)
|
||||
(let
|
||||
((args (er-parse-attr-args st)))
|
||||
(er-expect! st "punct" ".")
|
||||
(cond
|
||||
(= attr-name "module")
|
||||
(set-nth! mod-ref 0 (get (nth args 0) :value))
|
||||
:else (append! attrs {:args args :name attr-name})))))
|
||||
(= (er-cur-type st) "atom")
|
||||
(append! functions (er-parse-function st))
|
||||
:else (error
|
||||
(str
|
||||
"Erlang parse (top): unexpected "
|
||||
(er-cur-type st)
|
||||
" '"
|
||||
(er-cur-value st)
|
||||
"' at pos "
|
||||
(get (er-cur st) :pos))))))
|
||||
|
||||
(define
|
||||
er-parse-attr-args
|
||||
(fn
|
||||
(st)
|
||||
(er-expect! st "punct" "(")
|
||||
(if
|
||||
(er-is? st "punct" ")")
|
||||
(do (er-advance! st) (list))
|
||||
(let
|
||||
((args (list (er-parse-attr-arg st))))
|
||||
(er-parse-attr-args-tail st args)))))
|
||||
|
||||
(define
|
||||
er-parse-attr-args-tail
|
||||
(fn
|
||||
(st args)
|
||||
(cond
|
||||
(er-is? st "punct" ",")
|
||||
(do
|
||||
(er-advance! st)
|
||||
(append! args (er-parse-attr-arg st))
|
||||
(er-parse-attr-args-tail st args))
|
||||
(er-is? st "punct" ")")
|
||||
(do (er-advance! st) args)
|
||||
:else (error (str "Erlang parse attr: got '" (er-cur-value st) "'")))))
|
||||
|
||||
;; Attribute args often contain `Name/Arity` pairs — parse as a
|
||||
;; general expression so the caller can interpret the shape.
|
||||
(define er-parse-attr-arg (fn (st) (er-parse-expr-prec st 0)))
|
||||
|
||||
(define
|
||||
er-parse-function
|
||||
(fn
|
||||
(st)
|
||||
(let
|
||||
((name (er-cur-value st)))
|
||||
(er-advance! st)
|
||||
(let
|
||||
((clauses (list (er-parse-fun-clause st name))))
|
||||
(er-parse-function-tail st name clauses)
|
||||
(er-expect! st "punct" ".")
|
||||
(let ((arity (len (get (nth clauses 0) :patterns)))) {:arity arity :clauses clauses :type "function" :name name})))))
|
||||
|
||||
(define
|
||||
er-parse-function-tail
|
||||
(fn
|
||||
(st name clauses)
|
||||
(when
|
||||
(er-is? st "punct" ";")
|
||||
(let
|
||||
((save (get st :idx)))
|
||||
(er-advance! st)
|
||||
(if
|
||||
(and (= (er-cur-type st) "atom") (= (er-cur-value st) name))
|
||||
(do
|
||||
(er-advance! st)
|
||||
(append! clauses (er-parse-fun-clause st name))
|
||||
(er-parse-function-tail st name clauses))
|
||||
(dict-set! st :idx save))))))
|
||||
Reference in New Issue
Block a user