Add MCP server to AST tool

Integrates the MCP server functionality into the AST tool binary. This
allows the tool to act as a server for LLM integration, enabling
communication over stdio. The server can list available bindings and
execute scripts.
This commit is contained in:
2026-03-25 14:03:22 +01:00
parent 6042415dfc
commit 641a19e736
6 changed files with 386 additions and 2 deletions
+122 -2
View File
@@ -147,11 +147,11 @@ The Myc runtime environment provides a collection of built-in functions and macr
(do
;; Create a series with a typed layout (Struct-of-Arrays under the hood)
(def my_ticks (series {:price :float :volume :int :msg :text}))
(push my_ticks {:price 10.5 :volume 100 :msg "A"})
(push my_ticks {:price 11.2 :volume 200 :msg "B"})
(push my_ticks {:price 15.5 :volume 300 :msg "C"})
;; Extract the price series specifically
(def prices (.price my_ticks))
@@ -159,3 +159,123 @@ The Myc runtime environment provides a collection of built-in functions and macr
(+ (prices 0) (prices 1)) ;; Output: 26.7
)
```
## 8. Common Mistakes & Pitfalls
This section is especially relevant for LLMs generating Myc code.
### Wrong keywords from other Lisps
| Wrong (Clojure/Scheme) | Correct Myc |
|---|---|
| `(let [x 1] ...)` | `(do (def x 1) ...)` |
| `(begin ...)` | `(do ...)` |
| `(lambda [x] ...)` | `(fn [x] ...)` |
| `(define x 1)` | `(def x 1)` |
| `(set! x 2)` | `(assign x 2)` |
| `(cond ...)` | nested `(if ...)` |
| `(not= a b)` | `(<> a b)` |
### Series indexing is reversed
Index `0` is the **most recently pushed** item, not the oldest. This is the opposite of normal array indexing:
```clojure
(push s {:v 1})
(push s {:v 2})
(push s {:v 3})
;; ((.v s) 0) => 3 (newest)
;; ((.v s) 1) => 2
;; ((.v s) 2) => 1 (oldest)
```
### Record keys must be keywords, not strings
```clojure
;; WRONG:
{"price" 10.5}
;; CORRECT:
{:price 10.5}
```
### `again` is only valid inside `fn`
`(again ...)` jumps back to the enclosing `fn`. Using it outside a function is a compile error.
```clojure
;; WRONG — top-level again:
(again 1 2)
;; CORRECT — inside fn:
(fn [n] (if (= n 0) "done" (again (- n 1))))
```
### `check_syntax` accepts only a single expression
The `check_syntax` tool uses the single-expression compiler pass. Wrap multiple expressions in `(do ...)`:
```clojure
;; WRONG:
(def x 1) (+ x 2)
;; CORRECT:
(do (def x 1) (+ x 2))
```
### Field accessors are functions, not property syntax
```clojure
;; WRONG — not valid syntax:
user.name
;; CORRECT — field accessor called as a function:
(.name user)
;; Also correct — extract accessor first, then call:
(def get-name .name)
(get-name user)
```
**Recursive Function with Tail-Call Optimization:**
```clojure
(do
;; Factorial using explicit TCO via (again ...) — like Clojure's recur
(def factorial
(fn [n acc]
(if (= n 0)
acc
(again (- n 1) (* acc n)))))
(factorial 10 1) ;; Output: 3628800
)
```
**Macro Definition:**
```clojure
(do
;; Define a macro that inverts a condition
(macro unless [c body]
`(if ~c ... ~body))
(unless false "executed") ;; Output: "executed"
)
```
**Series with while Loop:**
```clojure
(do
(def ticks (series {:price :float}))
(def i 0)
;; Push 5 prices into the series
(while (< i 5)
(do
(push ticks {:price (* i 1.5)})
(assign i (+ i 1))))
;; Read back the two most recent prices
(def p (.price ticks))
(+ (p 0) (p 1)) ;; newest + second-newest
)
```