Skip to main content

meow_meow_script/
token.rs

1use crate::ast::Span;
2
3// -----------------------------------------------------------------------------
4// Lexical tokens
5// -----------------------------------------------------------------------------
6
7/// Unit suffix on a numeric literal in MMS source (e.g. `50%`, `20gu`,
8/// `30deg`). Bare numbers without a suffix tokenize as `Number(f64)` and
9/// do not carry a unit. When a unit suffix is present, the lexer emits
10/// `Dimension(f64, Unit)` instead.
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
12pub enum Unit {
13    /// `%` — percentage (relative to the consumer's reference, e.g.
14    /// container inline-axis width for layout consumers).
15    Percent,
16    /// `gu` — glyph units (cat-engine's intrinsic layout unit).
17    GlyphUnits,
18    /// `wu` — world units (cat-engine's renderer-frame unit). A layout
19    /// consumer converts to/from glyph units via the nearest LayoutRoot's
20    /// `unit_scale`.
21    WorldUnits,
22    /// `deg` — degrees (forward-compatible; no current consumer).
23    Degrees,
24    /// `rad` — radians (forward-compatible; no current consumer).
25    Radians,
26}
27
28#[derive(Debug, Clone, PartialEq)]
29pub enum TokenKind {
30    Ident(String),
31    String(String),
32    Number(f64),
33    /// Numeric literal with a unit suffix: `50%`, `20gu`, `30deg`, `0.5rad`.
34    Dimension(f64, Unit),
35
36    Let,
37    If,
38    Else,
39    Return,
40    True,
41    False,
42    Null,
43
44    LBrace,
45    RBrace,
46    LParen,
47    RParen,
48    LBracket,
49    RBracket,
50
51    Comma,
52    Dot,
53    Eq,
54    Semicolon,
55
56    Plus,
57    Minus,
58    Star,
59    Slash,
60    Percent,
61    EqEq,
62    BangEq,
63    Lt,
64    Gt,
65    LtEq,
66    GtEq,
67    Arrow,
68    AmpAmp,
69    PipePipe,
70    PipeGt,
71    Bang,
72    Fn,
73    For,
74    While,
75    In,
76    Break,
77    Continue,
78    Export,
79    Import,
80    From,
81    As,
82
83    Eof,
84}
85
86#[derive(Debug, Clone, PartialEq)]
87pub struct Token {
88    pub kind: TokenKind,
89    pub span: Span,
90}
91
92#[derive(Debug, Clone, PartialEq)]
93pub struct TokenizeError {
94    pub message: String,
95    pub span: Span,
96}
97
98// -----------------------------------------------------------------------------
99// Component type shortforms
100// -----------------------------------------------------------------------------
101
102#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
103pub struct ComponentShortformEntry {
104    pub short: &'static str,
105    pub full: &'static str,
106}
107
108/// Mapping of short component identifiers (used in `.mms`) to the canonical
109/// component type name that the host registry resolves.
110///
111/// Notes:
112/// - This list is intentionally curated (not auto-derived) so we can keep it
113///   stable and ergonomic.
114/// - Shortforms are case-sensitive.
115pub const COMPONENT_SHORTFORMS: &[ComponentShortformEntry] = &[
116    // User-provided core set
117    ComponentShortformEntry {
118        short: "I",
119        full: "Input",
120    },
121    ComponentShortformEntry {
122        short: "T",
123        full: "Transform",
124    },
125    ComponentShortformEntry {
126        short: "R",
127        full: "Renderable",
128    },
129    ComponentShortformEntry {
130        short: "C",
131        full: "Color",
132    },
133    ComponentShortformEntry {
134        short: "RC",
135        full: "Raycast",
136    },
137    ComponentShortformEntry {
138        short: "A",
139        full: "Animation",
140    },
141    ComponentShortformEntry {
142        short: "KF",
143        full: "Keyframe",
144    },
145    ComponentShortformEntry {
146        short: "AC",
147        full: "Action",
148    },
149    ComponentShortformEntry {
150        short: "BG",
151        full: "Background",
152    },
153    ComponentShortformEntry {
154        short: "OV",
155        full: "Overlay",
156    },
157    ComponentShortformEntry {
158        short: "OP",
159        full: "Opacity",
160    },
161    ComponentShortformEntry {
162        short: "BGC",
163        full: "BackgroundColor",
164    },
165    ComponentShortformEntry {
166        short: "TXT",
167        full: "Text",
168    },
169    ComponentShortformEntry {
170        short: "C3D",
171        full: "Camera3D",
172    },
173    ComponentShortformEntry {
174        short: "C2D",
175        full: "Camera2D",
176    },
177    ComponentShortformEntry {
178        short: "PL",
179        full: "PointLight",
180    },
181    ComponentShortformEntry {
182        short: "DL",
183        full: "DirectionalLight",
184    },
185    ComponentShortformEntry {
186        short: "AL",
187        full: "AmbientLight",
188    },
189    ComponentShortformEntry {
190        short: "ED",
191        full: "Editor",
192    },
193    ComponentShortformEntry {
194        short: "GZM",
195        full: "Gizmo",
196    },
197    // Proposed additions based on existing engine components
198    ComponentShortformEntry {
199        short: "GLTF",
200        full: "GLTF",
201    },
202    ComponentShortformEntry {
203        short: "UV",
204        full: "UV",
205    },
206    ComponentShortformEntry {
207        short: "EM",
208        full: "Emissive",
209    },
210    ComponentShortformEntry {
211        short: "CK",
212        full: "Clock",
213    },
214    ComponentShortformEntry {
215        short: "PTR",
216        full: "Pointer",
217    },
218    ComponentShortformEntry {
219        short: "COL",
220        full: "Collision",
221    },
222    ComponentShortformEntry {
223        short: "COLS",
224        full: "CollisionShape",
225    },
226    ComponentShortformEntry {
227        short: "GVT",
228        full: "Gravity",
229    },
230    ComponentShortformEntry {
231        short: "KIN",
232        full: "KineticResponse",
233    },
234    ComponentShortformEntry {
235        short: "LQ",
236        full: "LightQuantization",
237    },
238    ComponentShortformEntry {
239        short: "TC",
240        full: "TransparentCutout",
241    },
242    ComponentShortformEntry {
243        short: "SM",
244        full: "SkinnedMesh",
245    },
246    ComponentShortformEntry {
247        short: "XR",
248        full: "XR",
249    },
250    ComponentShortformEntry {
251        short: "CXR",
252        full: "CameraXR",
253    },
254    ComponentShortformEntry {
255        short: "CTLXR",
256        full: "ControllerXR",
257    },
258    ComponentShortformEntry {
259        short: "AVC",
260        full: "AvatarControl",
261    },
262    ComponentShortformEntry {
263        short: "MESH",
264        full: "Mesh",
265    },
266    ComponentShortformEntry {
267        short: "NV",
268        full: "NormalVis",
269    },
270    // Audio graph-ish components (optional; names kept explicit)
271    ComponentShortformEntry {
272        short: "AOUT",
273        full: "AudioOutput",
274    },
275    ComponentShortformEntry {
276        short: "AOSC",
277        full: "AudioOscillator",
278    },
279    ComponentShortformEntry {
280        short: "AG",
281        full: "AudioGain",
282    },
283    ComponentShortformEntry {
284        short: "AMIX",
285        full: "AudioMix",
286    },
287    ComponentShortformEntry {
288        short: "ALIM",
289        full: "AudioLimiter",
290    },
291    ComponentShortformEntry {
292        short: "ABUF",
293        full: "AudioBufferSize",
294    },
295    ComponentShortformEntry {
296        short: "ALPF",
297        full: "AudioLowPassFilter",
298    },
299    ComponentShortformEntry {
300        short: "AHPF",
301        full: "AudioHighPassFilter",
302    },
303    ComponentShortformEntry {
304        short: "ABPF",
305        full: "AudioBandPassFilter",
306    },
307    // Routing
308    ComponentShortformEntry {
309        short: "SRU",
310        full: "SignalRouteUpward",
311    },
312    // Music
313    ComponentShortformEntry {
314        short: "NOTE",
315        full: "MusicNote",
316    },
317];
318
319pub fn expand_component_shortform(ident: &str) -> Option<&'static str> {
320    COMPONENT_SHORTFORMS
321        .iter()
322        .find(|e| e.short == ident)
323        .map(|e| e.full)
324}
325
326pub fn shortform_for_component(full: &str) -> Option<&'static str> {
327    COMPONENT_SHORTFORMS
328        .iter()
329        .find(|e| e.full == full)
330        .map(|e| e.short)
331}