Skip to main content

lemon/
lib.rs

1//! Lemon — the strategy DSL for the citrus backtesting engine.
2//!
3//! Lemon is a small text language for writing trading strategies. A strategy
4//! such as `close > sma(close, 2)` is *lowered* into a JSON `Expr` tree — the
5//! serializable strategy AST ([`spec::Expr`]) — which the **yuzu** engine walks
6//! against price/fundamental data to produce a position matrix. The same JSON
7//! runs identically in-browser (WASM) and in the native batch runner.
8//!
9//! This crate does no math itself: it is a **surface syntax over the `Expr`
10//! AST**. [`parse`] turns text into the JSON tree; [`format()`] renders a tree
11//! back into canonical, re-indented text (a "gofmt for lemon"). All numeric
12//! semantics live in the engine crate.
13//!
14//! # Layout
15//!
16//! - [`spec`] — the serializable [`Expr`] AST (JSON, tagged by `"op"`).
17//! - [`services`] — editor language services (diagnostics, hover, completions),
18//!   pure functions of `(source, position)` that back both the WASM boundary and
19//!   the `lemon-lsp` language server.
20//! - `dsl` (private) — the text syntax: `lex` (tokenizer), `parse` (text →
21//!   JSON), `ops` (surface-name ⇄ op-tag vocabulary), `print` (JSON → text).
22//!
23//! # Example
24//!
25//! ```
26//! let tree = lemon::parse("close > sma(close, 2)").unwrap();
27//! assert_eq!(tree["op"], "Gt");
28//! // `format` renders a tree back to canonical DSL text.
29//! let text = lemon::format(&tree);
30//! assert_eq!(text, "(close > sma(close, 2))");
31//! ```
32//!
33//! A [`ParseError`] carries a 1-based `line`/`col` and prints as
34//! `line:col: message`.
35//!
36//! # Syntax reference
37//!
38//! The author-facing language reference (lexical rules, operators and
39//! precedence, the `let`/call grammar, and the complete op table) lives in
40//! `docs/lemon.md` in the repository.
41
42mod dsl;
43pub mod envelope;
44pub mod services;
45pub mod spec;
46
47pub use dsl::{format, lint, parse, parse_analyzed, Analysis, Lint, ParseError};
48pub use envelope::{Envelope, FORMAT_VERSION};
49pub use spec::Expr;
50
51/// Machine-readable op vocabulary: the catalog of callable ops (canonical names,
52/// aliases, tags, ordered field specs, defaults, descriptions) plus the binary
53/// operators. This is the single source of truth the schema generator
54/// (`cargo run -p lemon-lang --example gen-schema`) reads to emit
55/// `schema/op-catalog.json` and `schema/lemon-spec.schema.json`.
56pub mod meta {
57    pub use crate::dsl::ops::{
58        binary_operators, field_default, function_ops, FieldInfo, OpInfo, ALL_OP_TAGS,
59    };
60}