devalang_wasm/language/syntax/tokens/
mod.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
4pub enum Keyword {
5 At,
6 Tempo,
7 Bank,
8 Pattern,
9 Loop,
10 Function,
11 As,
12 On,
13 Emit,
14 Synth,
15 Use,
16 Let,
17 Automate,
18 Trigger,
19 Sleep,
20 Call,
21 Spawn,
22 Group,
23 Include,
24 Export,
25 Import,
26 Routing,
27 Bind,
28 Fx,
29 Node,
30 Sidechain,
31 If,
32 Else,
33 ElseIf,
34 Print,
35}
36
37#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
38#[serde(tag = "kind", rename_all = "snake_case")]
39pub enum TokenKind {
40 Keyword(Keyword),
41 Identifier,
42 Number,
43 String,
44 Boolean,
45 Duration,
46 Arrow,
47 Colon,
48 Comma,
49 Equals,
50 Dot,
51 Slash,
52 Plus,
53 Asterisk,
54 Minus,
55 DoubleEquals,
56 NotEquals,
57 GreaterEqual,
58 LessEqual,
59 Greater,
60 Less,
61 LBrace,
62 RBrace,
63 LBracket,
64 RBracket,
65 LParen,
66 RParen,
67 Newline,
68 Indent,
69 Dedent,
70 Comment,
71 Eof,
72 Unknown,
73 Error(String),
74}
75
76impl TokenKind {
77 pub fn is_keyword(&self, keyword: Keyword) -> bool {
78 matches!(self, TokenKind::Keyword(k) if *k == keyword)
79 }
80}
81
82#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
83pub struct Token {
84 pub kind: TokenKind,
85 pub lexeme: String,
86 pub indent: usize,
87 pub line: usize,
88 pub column: usize,
89}
90
91impl Token {
92 pub fn new(
93 kind: TokenKind,
94 lexeme: impl Into<String>,
95 indent: usize,
96 line: usize,
97 column: usize,
98 ) -> Self {
99 Self {
100 kind,
101 lexeme: lexeme.into(),
102 indent,
103 line,
104 column,
105 }
106 }
107
108 pub fn is_error(&self) -> bool {
109 matches!(self.kind, TokenKind::Error(_))
110 }
111}
112
113pub fn keyword_from_ident(ident: &str) -> Option<Keyword> {
114 match ident.to_lowercase().as_str() {
115 "at" => Some(Keyword::At),
116 "bpm" | "tempo" => Some(Keyword::Tempo),
117 "bank" => Some(Keyword::Bank),
118 "pattern" => Some(Keyword::Pattern),
119 "loop" => Some(Keyword::Loop),
120 "fn" | "function" => Some(Keyword::Function),
121 "as" => Some(Keyword::As),
122 "on" => Some(Keyword::On),
123 "emit" => Some(Keyword::Emit),
124 "synth" => Some(Keyword::Synth),
125 "use" => Some(Keyword::Use),
126 "let" => Some(Keyword::Let),
127 "automate" => Some(Keyword::Automate),
128 "trigger" => Some(Keyword::Trigger),
129 "sleep" | "rest" | "wait" => Some(Keyword::Sleep),
130 "call" => Some(Keyword::Call),
131 "spawn" => Some(Keyword::Spawn),
132 "group" => Some(Keyword::Group),
133 "include" => Some(Keyword::Include),
134 "export" => Some(Keyword::Export),
135 "import" => Some(Keyword::Import),
136 "routing" => Some(Keyword::Routing),
137 "bind" => Some(Keyword::Bind),
138 "fx" | "pipeline" => Some(Keyword::Fx),
139 "node" => Some(Keyword::Node),
140 "sidechain" => Some(Keyword::Sidechain),
141 "if" => Some(Keyword::If),
142 "else" => Some(Keyword::Else),
143 "elseif" | "else_if" | "elif" => Some(Keyword::ElseIf),
144 "print" => Some(Keyword::Print),
145 _ => None,
146 }
147}