Expand description
Evaluator for Milkdrop expressions.
MilkEvaluator is the entry point. Most callers go through
MilkEvaluator::eval (single expression), MilkEvaluator::compile +
MilkEvaluator::eval_compiled (precompiled hot path), or
MilkEvaluator::eval_equation_list (paren-balance-aware join over a
preset’s flat equation list).
The crate’s internals are split across:
preprocess— the regex-driven preprocessing pipeline that turns MD2 EEL2 source into somethingevalexprwill parse.rewriters— AST-style rewriters consumed bypreprocess_expression.gmegabuf—gmegabuf/megabufwrite rewrite.joiner— multi-equation join logic and top-levelloop/exec/whileinterceptors.
Modules§
- gmegabuf 🔒
gmegabuf/megabufwrite rewrite for the preprocess pipeline.- joiner 🔒
- Multi-equation join logic and top-level call interceptors.
- preprocess 🔒
- Regex-driven preprocessing pipeline.
- rewriters 🔒
- AST-style rewriters consumed by
super::MilkEvaluator::preprocess_expression.
Structs§
- Evaluation
Stats - Aggregate stats returned by
MilkEvaluator::eval_equation_list. - Milk
Evaluator - Evaluator for Milkdrop expressions.
- Shape
Instance - One iteration of a custom-shape (
shapecode_N) per-instance loop. MD2 shape per-frame equations can mutate any of these fields and the next instance’s loop body sees the seed values fresh from the preset’s scalar block — instances do NOT carry state across each other (unlikeWavePoint). Persistent state across instances lives inq*/t*channels. - Wave
Point - One iteration of a custom-wave (or custom-shape) per-point loop. The same
struct is used for input (caller seeds the loop variables) and output
(evaluator reads
x,y,r,g,b,aback from the context after running the equations).sample,value1,value2are inputs only.
Functions§
- contains_
top_ 🔒level_ byte - Generic “byte at depth 0” check.
- contains_
top_ 🔒level_ comma trueifscontains a,at paren depth 0.- contains_
top_ 🔒level_ comparison trueifscontains a comparison operator (> < >= <= == !=) at paren depth 0.- is_
builtin_ 🔒ident trueifnameis a registered builtin identifier we should leave alone in the auto-init pass. Centralised so the preprocess and case-normalising helpers stay in sync.- is_
ident_ 🔒byte truewhenbis an ASCII identifier byte ([A-Za-z0-9_]).- is_
paren_ 🔒func_ call_ open trueif the(at byte offsetparen_posopens a function-call arg list (preceded by an identifier or digit, modulo whitespace) rather than a standalone grouping expression.- match_
close_ 🔒paren - Find the matching
)for the(atopen. Returns the byte offset of the closer orNoneif unbalanced. - split_
top_ 🔒level_ byte - Generic “split on byte at depth 0”.
- split_
top_ 🔒level_ commas - Split
inneron each top-level,(commas at paren depth 0). Always returns at least one element (the wholeinnerif no top-level comma).