@devaloop/devalang 0.0.1-alpha.1 → 0.0.1-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.devalang +4 -0
- package/Cargo.toml +3 -2
- package/README.md +30 -6
- package/docs/CHANGELOG.md +53 -0
- package/docs/COMMANDS.md +29 -6
- package/docs/CONFIG.md +28 -0
- package/docs/ROADMAP.md +1 -1
- package/docs/TODO.md +43 -15
- package/examples/index.deva +1 -1
- package/out-tsc/bin/devalang.exe +0 -0
- package/package.json +2 -2
- package/project-version.json +3 -3
- package/rust/cli/build.rs +58 -5
- package/rust/cli/check.rs +73 -17
- package/rust/cli/init.rs +77 -0
- package/rust/cli/mod.rs +2 -1
- package/rust/cli/template.rs +56 -0
- package/rust/core/lexer/at.rs +21 -0
- package/rust/core/lexer/brace.rs +41 -0
- package/rust/core/lexer/bracket.rs +41 -0
- package/rust/core/lexer/colon.rs +21 -0
- package/rust/core/lexer/comment.rs +30 -0
- package/rust/core/lexer/dot.rs +21 -0
- package/rust/core/lexer/driver.rs +286 -0
- package/rust/core/lexer/equal.rs +32 -0
- package/rust/core/lexer/identifier.rs +38 -0
- package/rust/core/lexer/indent.rs +47 -0
- package/rust/core/lexer/mod.rs +14 -333
- package/rust/core/lexer/newline.rs +23 -0
- package/rust/core/lexer/number.rs +31 -0
- package/rust/core/lexer/quote.rs +61 -0
- package/rust/core/parser/dot.rs +48 -18
- package/rust/core/preprocessor/module.rs +1 -1
- package/rust/core/types/cli.rs +53 -31
- package/rust/core/types/config.rs +15 -0
- package/rust/core/types/mod.rs +2 -1
- package/rust/main.rs +30 -19
- package/rust/utils/config.rs +13 -0
- package/rust/utils/file.rs +35 -0
- package/rust/utils/mod.rs +4 -1
- package/rust/utils/watcher.rs +25 -0
- package/templates/minimal/.devalang +4 -0
- package/templates/minimal/src/index.deva +2 -0
- package/templates/welcome/.devalang +4 -0
- package/templates/welcome/README.md +185 -0
- package/templates/welcome/samples/kick-808.wav +0 -0
- package/templates/welcome/src/index.deva +13 -0
- package/templates/welcome/src/variables.deva +5 -0
- package/rust/cli/new.rs +0 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
use include_dir::{ include_dir, Dir, DirEntry };
|
|
2
|
+
|
|
3
|
+
use crate::utils::file::format_file_size;
|
|
4
|
+
|
|
5
|
+
static TEMPLATES_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/templates");
|
|
6
|
+
|
|
7
|
+
pub fn handle_template_list_command() {
|
|
8
|
+
let available_templates = get_available_templates();
|
|
9
|
+
|
|
10
|
+
println!("📦 Available templates ({}) :\n", available_templates.len());
|
|
11
|
+
|
|
12
|
+
for dir in available_templates {
|
|
13
|
+
println!("• {}", dir);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
println!("\nUsage : devalang init --name <project-name> --template <template-name>");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
pub fn handle_template_info_command(name: String) {
|
|
20
|
+
let template_dir = TEMPLATES_DIR.get_dir(name.clone()).unwrap_or_else(|| {
|
|
21
|
+
println!("❌ The template '{}' is not found.", name);
|
|
22
|
+
|
|
23
|
+
std::process::exit(1);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
let mut file_count = 0;
|
|
27
|
+
let mut dir_count = 0;
|
|
28
|
+
let mut total_size: u64 = 0;
|
|
29
|
+
|
|
30
|
+
fn walk(dir: &Dir, file_count: &mut u32, dir_count: &mut u32, total_size: &mut u64) {
|
|
31
|
+
for entry in dir.entries() {
|
|
32
|
+
match entry {
|
|
33
|
+
DirEntry::File(file) => {
|
|
34
|
+
*file_count += 1;
|
|
35
|
+
*total_size += file.contents().len() as u64;
|
|
36
|
+
}
|
|
37
|
+
DirEntry::Dir(subdir) => {
|
|
38
|
+
*dir_count += 1;
|
|
39
|
+
walk(subdir, file_count, dir_count, total_size);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
walk(template_dir, &mut file_count, &mut dir_count, &mut total_size);
|
|
46
|
+
|
|
47
|
+
println!("📦 Template : {}", name);
|
|
48
|
+
println!("📂 Content : {file_count} file(s), {dir_count} folder(s)");
|
|
49
|
+
println!("💾 Size : {}", format_file_size(total_size));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
pub fn get_available_templates() -> Vec<String> {
|
|
53
|
+
TEMPLATES_DIR.dirs()
|
|
54
|
+
.map(|dir| dir.path().file_name().unwrap().to_string_lossy().to_string())
|
|
55
|
+
.collect()
|
|
56
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
use crate::core::types::token::{ Token, TokenKind };
|
|
2
|
+
|
|
3
|
+
pub fn handle_at_lexer(
|
|
4
|
+
char: char,
|
|
5
|
+
chars: &mut std::iter::Peekable<std::str::Chars>,
|
|
6
|
+
current_indent: &mut usize,
|
|
7
|
+
indent_stack: &mut Vec<usize>,
|
|
8
|
+
tokens: &mut Vec<Token>,
|
|
9
|
+
line: &mut usize,
|
|
10
|
+
column: &mut usize
|
|
11
|
+
) {
|
|
12
|
+
tokens.push(Token {
|
|
13
|
+
kind: TokenKind::At,
|
|
14
|
+
lexeme: char.to_string(),
|
|
15
|
+
line: *line,
|
|
16
|
+
column: *column,
|
|
17
|
+
indent: *current_indent,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
*column += 1;
|
|
21
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
use crate::core::types::token::{ Token, TokenKind };
|
|
2
|
+
|
|
3
|
+
pub fn handle_rbrace_lexer(
|
|
4
|
+
char: char,
|
|
5
|
+
chars: &mut std::iter::Peekable<std::str::Chars>,
|
|
6
|
+
current_indent: &mut usize,
|
|
7
|
+
indent_stack: &mut Vec<usize>,
|
|
8
|
+
tokens: &mut Vec<Token>,
|
|
9
|
+
line: &mut usize,
|
|
10
|
+
column: &mut usize
|
|
11
|
+
) {
|
|
12
|
+
tokens.push(Token {
|
|
13
|
+
kind: TokenKind::RBrace,
|
|
14
|
+
lexeme: char.to_string(),
|
|
15
|
+
line: *line,
|
|
16
|
+
column: *column,
|
|
17
|
+
indent: *current_indent,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
*column += 1;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
pub fn handle_lbrace_lexer(
|
|
24
|
+
char: char,
|
|
25
|
+
chars: &mut std::iter::Peekable<std::str::Chars>,
|
|
26
|
+
current_indent: &mut usize,
|
|
27
|
+
indent_stack: &mut Vec<usize>,
|
|
28
|
+
tokens: &mut Vec<Token>,
|
|
29
|
+
line: &mut usize,
|
|
30
|
+
column: &mut usize
|
|
31
|
+
) {
|
|
32
|
+
tokens.push(Token {
|
|
33
|
+
kind: TokenKind::LBrace,
|
|
34
|
+
lexeme: char.to_string(),
|
|
35
|
+
line: *line,
|
|
36
|
+
column: *column,
|
|
37
|
+
indent: *current_indent,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
*column += 1;
|
|
41
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
use crate::core::types::token::{ Token, TokenKind };
|
|
2
|
+
|
|
3
|
+
pub fn handle_rbracket_lexer(
|
|
4
|
+
char: char,
|
|
5
|
+
chars: &mut std::iter::Peekable<std::str::Chars>,
|
|
6
|
+
current_indent: &mut usize,
|
|
7
|
+
indent_stack: &mut Vec<usize>,
|
|
8
|
+
tokens: &mut Vec<Token>,
|
|
9
|
+
line: &mut usize,
|
|
10
|
+
column: &mut usize
|
|
11
|
+
) {
|
|
12
|
+
tokens.push(Token {
|
|
13
|
+
kind: TokenKind::RBracket,
|
|
14
|
+
lexeme: char.to_string(),
|
|
15
|
+
line: *line,
|
|
16
|
+
column: *column,
|
|
17
|
+
indent: *current_indent,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
*column += 1;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
pub fn handle_lbracket_lexer(
|
|
24
|
+
char: char,
|
|
25
|
+
chars: &mut std::iter::Peekable<std::str::Chars>,
|
|
26
|
+
current_indent: &mut usize,
|
|
27
|
+
indent_stack: &mut Vec<usize>,
|
|
28
|
+
tokens: &mut Vec<Token>,
|
|
29
|
+
line: &mut usize,
|
|
30
|
+
column: &mut usize
|
|
31
|
+
) {
|
|
32
|
+
tokens.push(Token {
|
|
33
|
+
kind: TokenKind::LBracket,
|
|
34
|
+
lexeme: char.to_string(),
|
|
35
|
+
line: *line,
|
|
36
|
+
column: *column,
|
|
37
|
+
indent: *current_indent,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
*column += 1;
|
|
41
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
use crate::core::types::token::{Token, TokenKind};
|
|
2
|
+
|
|
3
|
+
pub fn handle_colon_lexer(
|
|
4
|
+
char: char,
|
|
5
|
+
chars: &mut std::iter::Peekable<std::str::Chars>,
|
|
6
|
+
current_indent: &mut usize,
|
|
7
|
+
indent_stack: &mut Vec<usize>,
|
|
8
|
+
tokens: &mut Vec<Token>,
|
|
9
|
+
line: &mut usize,
|
|
10
|
+
column: &mut usize
|
|
11
|
+
) {
|
|
12
|
+
tokens.push(Token {
|
|
13
|
+
kind: TokenKind::Colon,
|
|
14
|
+
lexeme: char.to_string(),
|
|
15
|
+
line: *line,
|
|
16
|
+
column: *column,
|
|
17
|
+
indent: *current_indent,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
*column += 1;
|
|
21
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
use crate::core::types::token::{ Token, TokenKind };
|
|
2
|
+
|
|
3
|
+
pub fn handle_comment_lexer(
|
|
4
|
+
char: char,
|
|
5
|
+
chars: &mut std::iter::Peekable<std::str::Chars>,
|
|
6
|
+
current_indent: &mut usize,
|
|
7
|
+
indent_stack: &mut Vec<usize>,
|
|
8
|
+
tokens: &mut Vec<Token>,
|
|
9
|
+
line: &mut usize,
|
|
10
|
+
column: &mut usize
|
|
11
|
+
) {
|
|
12
|
+
let mut comment = String::new();
|
|
13
|
+
|
|
14
|
+
while let Some(&c) = chars.peek() {
|
|
15
|
+
if c == '\n' {
|
|
16
|
+
break;
|
|
17
|
+
}
|
|
18
|
+
comment.push(c);
|
|
19
|
+
chars.next();
|
|
20
|
+
*column += 1;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
tokens.push(Token {
|
|
24
|
+
kind: TokenKind::Comment(comment.trim().to_string()),
|
|
25
|
+
lexeme: char.to_string(),
|
|
26
|
+
line: *line,
|
|
27
|
+
column: *column,
|
|
28
|
+
indent: *current_indent,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
use crate::core::types::token::{Token, TokenKind};
|
|
2
|
+
|
|
3
|
+
pub fn handle_dot_lexer(
|
|
4
|
+
char: char,
|
|
5
|
+
chars: &mut std::iter::Peekable<std::str::Chars>,
|
|
6
|
+
current_indent: &mut usize,
|
|
7
|
+
indent_stack: &mut Vec<usize>,
|
|
8
|
+
tokens: &mut Vec<Token>,
|
|
9
|
+
line: &mut usize,
|
|
10
|
+
column: &mut usize
|
|
11
|
+
) {
|
|
12
|
+
tokens.push(Token {
|
|
13
|
+
kind: TokenKind::Dot,
|
|
14
|
+
lexeme: char.to_string(),
|
|
15
|
+
line: *line,
|
|
16
|
+
column: *column,
|
|
17
|
+
indent: *current_indent,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
*column += 1;
|
|
21
|
+
}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
use crate::core::{
|
|
4
|
+
lexer::{
|
|
5
|
+
at::handle_at_lexer,
|
|
6
|
+
brace::{ handle_lbrace_lexer, handle_rbrace_lexer },
|
|
7
|
+
colon::handle_colon_lexer,
|
|
8
|
+
comment::handle_comment_lexer,
|
|
9
|
+
equal::handle_equal_lexer,
|
|
10
|
+
newline::handle_newline_lexer,
|
|
11
|
+
bracket::{ handle_lbracket_lexer, handle_rbracket_lexer },
|
|
12
|
+
dot::handle_dot_lexer,
|
|
13
|
+
identifier::handle_identifier_lexer,
|
|
14
|
+
indent::handle_indent_lexer,
|
|
15
|
+
number::handle_number_lexer,
|
|
16
|
+
quote::{ handle_double_quote_lexer, handle_single_quote_lexer },
|
|
17
|
+
},
|
|
18
|
+
types::token::{ Token, TokenKind },
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
pub fn lex(input: String) -> Vec<Token> {
|
|
22
|
+
let mut tokens = Vec::new();
|
|
23
|
+
|
|
24
|
+
let mut line = 1;
|
|
25
|
+
let mut column = 1;
|
|
26
|
+
|
|
27
|
+
let mut indent_stack: Vec<usize> = vec![0];
|
|
28
|
+
let mut current_indent = 0;
|
|
29
|
+
let mut at_line_start = true;
|
|
30
|
+
|
|
31
|
+
let mut chars = input.chars().peekable();
|
|
32
|
+
|
|
33
|
+
while let Some(_) = chars.peek() {
|
|
34
|
+
if at_line_start {
|
|
35
|
+
let (new_tokens, new_indent_stack, new_line, new_column) = handle_indent_lexer(
|
|
36
|
+
&mut chars,
|
|
37
|
+
&mut current_indent,
|
|
38
|
+
&mut indent_stack,
|
|
39
|
+
&mut tokens,
|
|
40
|
+
&mut line,
|
|
41
|
+
&mut column
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
// Update the main tokens vector and indent stack
|
|
45
|
+
tokens = new_tokens;
|
|
46
|
+
indent_stack = new_indent_stack;
|
|
47
|
+
line = new_line;
|
|
48
|
+
column = new_column;
|
|
49
|
+
|
|
50
|
+
// Reset at_line_start flag
|
|
51
|
+
at_line_start = false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Read the next character
|
|
55
|
+
let Some(ch) = chars.next() else {
|
|
56
|
+
break;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// Newline handling
|
|
60
|
+
if ch == '\n' {
|
|
61
|
+
handle_newline_lexer(
|
|
62
|
+
ch,
|
|
63
|
+
&mut chars,
|
|
64
|
+
&mut tokens,
|
|
65
|
+
&mut line,
|
|
66
|
+
&mut column,
|
|
67
|
+
&mut at_line_start,
|
|
68
|
+
&mut current_indent
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if ch == ' ' || ch == '\t' {
|
|
75
|
+
column += if ch == '\t' { 4 } else { 1 };
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if ch == '#' {
|
|
80
|
+
handle_comment_lexer(
|
|
81
|
+
ch,
|
|
82
|
+
&mut chars,
|
|
83
|
+
&mut current_indent,
|
|
84
|
+
&mut indent_stack,
|
|
85
|
+
&mut tokens,
|
|
86
|
+
&mut line,
|
|
87
|
+
&mut column
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if ch == ':' {
|
|
94
|
+
handle_colon_lexer(
|
|
95
|
+
ch,
|
|
96
|
+
&mut chars,
|
|
97
|
+
&mut current_indent,
|
|
98
|
+
&mut indent_stack,
|
|
99
|
+
&mut tokens,
|
|
100
|
+
&mut line,
|
|
101
|
+
&mut column
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if ch == '=' {
|
|
108
|
+
handle_equal_lexer(
|
|
109
|
+
ch,
|
|
110
|
+
&mut chars,
|
|
111
|
+
&mut current_indent,
|
|
112
|
+
&mut indent_stack,
|
|
113
|
+
&mut tokens,
|
|
114
|
+
&mut line,
|
|
115
|
+
&mut column
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if ch == '[' {
|
|
122
|
+
handle_lbracket_lexer(
|
|
123
|
+
ch,
|
|
124
|
+
&mut chars,
|
|
125
|
+
&mut current_indent,
|
|
126
|
+
&mut indent_stack,
|
|
127
|
+
&mut tokens,
|
|
128
|
+
&mut line,
|
|
129
|
+
&mut column
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if ch == ']' {
|
|
136
|
+
handle_rbracket_lexer(
|
|
137
|
+
ch,
|
|
138
|
+
&mut chars,
|
|
139
|
+
&mut current_indent,
|
|
140
|
+
&mut indent_stack,
|
|
141
|
+
&mut tokens,
|
|
142
|
+
&mut line,
|
|
143
|
+
&mut column
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if ch == '{' {
|
|
150
|
+
handle_lbrace_lexer(
|
|
151
|
+
ch,
|
|
152
|
+
&mut chars,
|
|
153
|
+
&mut current_indent,
|
|
154
|
+
&mut indent_stack,
|
|
155
|
+
&mut tokens,
|
|
156
|
+
&mut line,
|
|
157
|
+
&mut column
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if ch == '}' {
|
|
164
|
+
handle_rbrace_lexer(
|
|
165
|
+
ch,
|
|
166
|
+
&mut chars,
|
|
167
|
+
&mut current_indent,
|
|
168
|
+
&mut indent_stack,
|
|
169
|
+
&mut tokens,
|
|
170
|
+
&mut line,
|
|
171
|
+
&mut column
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if ch == '"' {
|
|
178
|
+
handle_double_quote_lexer(
|
|
179
|
+
ch,
|
|
180
|
+
&mut chars,
|
|
181
|
+
&mut current_indent,
|
|
182
|
+
&mut indent_stack,
|
|
183
|
+
&mut tokens,
|
|
184
|
+
&mut line,
|
|
185
|
+
&mut column
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if ch == '\'' {
|
|
192
|
+
handle_single_quote_lexer(
|
|
193
|
+
ch,
|
|
194
|
+
&mut chars,
|
|
195
|
+
&mut current_indent,
|
|
196
|
+
&mut indent_stack,
|
|
197
|
+
&mut tokens,
|
|
198
|
+
&mut line,
|
|
199
|
+
&mut column
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if ch == '.' {
|
|
206
|
+
handle_dot_lexer(
|
|
207
|
+
ch,
|
|
208
|
+
&mut chars,
|
|
209
|
+
&mut current_indent,
|
|
210
|
+
&mut indent_stack,
|
|
211
|
+
&mut tokens,
|
|
212
|
+
&mut line,
|
|
213
|
+
&mut column
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if ch == '@' {
|
|
220
|
+
handle_at_lexer(
|
|
221
|
+
ch,
|
|
222
|
+
&mut chars,
|
|
223
|
+
&mut current_indent,
|
|
224
|
+
&mut indent_stack,
|
|
225
|
+
&mut tokens,
|
|
226
|
+
&mut line,
|
|
227
|
+
&mut column
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if ch.is_ascii_digit() {
|
|
234
|
+
handle_number_lexer(
|
|
235
|
+
ch,
|
|
236
|
+
&mut chars,
|
|
237
|
+
&mut current_indent,
|
|
238
|
+
&mut indent_stack,
|
|
239
|
+
&mut tokens,
|
|
240
|
+
&mut line,
|
|
241
|
+
&mut column
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if ch.is_ascii_alphabetic() {
|
|
248
|
+
handle_identifier_lexer(
|
|
249
|
+
ch,
|
|
250
|
+
&mut chars,
|
|
251
|
+
&mut current_indent,
|
|
252
|
+
&mut indent_stack,
|
|
253
|
+
&mut tokens,
|
|
254
|
+
&mut line,
|
|
255
|
+
&mut column
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Skip unknown char
|
|
262
|
+
column += 1;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
while indent_stack.len() > 1 {
|
|
266
|
+
indent_stack.pop();
|
|
267
|
+
current_indent = *indent_stack.last().unwrap();
|
|
268
|
+
tokens.push(Token {
|
|
269
|
+
kind: TokenKind::Dedent,
|
|
270
|
+
lexeme: String::new(),
|
|
271
|
+
line,
|
|
272
|
+
column,
|
|
273
|
+
indent: current_indent,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
tokens.push(Token {
|
|
278
|
+
kind: TokenKind::EOF,
|
|
279
|
+
lexeme: String::new(),
|
|
280
|
+
line: line + 1, // EOF is considered to be on the next line
|
|
281
|
+
column: 0, // EOF has no column
|
|
282
|
+
indent: 0, // EOF has no indent
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
tokens
|
|
286
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
use crate::core::types::token::{Token, TokenKind};
|
|
2
|
+
|
|
3
|
+
pub fn handle_equal_lexer(
|
|
4
|
+
char: char,
|
|
5
|
+
chars: &mut std::iter::Peekable<std::str::Chars>,
|
|
6
|
+
current_indent: &mut usize,
|
|
7
|
+
indent_stack: &mut Vec<usize>,
|
|
8
|
+
tokens: &mut Vec<Token>,
|
|
9
|
+
line: &mut usize,
|
|
10
|
+
column: &mut usize
|
|
11
|
+
) {
|
|
12
|
+
if let Some('=') = chars.peek() {
|
|
13
|
+
chars.next();
|
|
14
|
+
tokens.push(Token {
|
|
15
|
+
kind: TokenKind::DoubleEquals,
|
|
16
|
+
lexeme: char.to_string(),
|
|
17
|
+
line: *line,
|
|
18
|
+
column: *column,
|
|
19
|
+
indent: *current_indent,
|
|
20
|
+
});
|
|
21
|
+
*column += 2;
|
|
22
|
+
} else {
|
|
23
|
+
tokens.push(Token {
|
|
24
|
+
kind: TokenKind::Equals,
|
|
25
|
+
lexeme: char.to_string(),
|
|
26
|
+
line: *line,
|
|
27
|
+
column: *column,
|
|
28
|
+
indent: *current_indent,
|
|
29
|
+
});
|
|
30
|
+
*column += 1;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
use crate::core::types::token::{ Token, TokenKind };
|
|
2
|
+
|
|
3
|
+
pub fn handle_identifier_lexer(
|
|
4
|
+
char: char,
|
|
5
|
+
chars: &mut std::iter::Peekable<std::str::Chars>,
|
|
6
|
+
current_indent: &mut usize,
|
|
7
|
+
indent_stack: &mut Vec<usize>,
|
|
8
|
+
tokens: &mut Vec<Token>,
|
|
9
|
+
line: &mut usize,
|
|
10
|
+
column: &mut usize
|
|
11
|
+
) {
|
|
12
|
+
let mut ident = char.to_string();
|
|
13
|
+
|
|
14
|
+
while let Some(&c) = chars.peek() {
|
|
15
|
+
if c.is_ascii_alphanumeric() || c == '_' {
|
|
16
|
+
ident.push(c);
|
|
17
|
+
chars.next();
|
|
18
|
+
*column += 1;
|
|
19
|
+
} else {
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let kind = match ident.as_str() {
|
|
25
|
+
"bank" => TokenKind::Bank,
|
|
26
|
+
"bpm" => TokenKind::Tempo,
|
|
27
|
+
"loop" => TokenKind::Loop,
|
|
28
|
+
_ => TokenKind::Identifier,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
tokens.push(Token {
|
|
32
|
+
kind: kind.clone(),
|
|
33
|
+
lexeme: ident,
|
|
34
|
+
line: *line,
|
|
35
|
+
column: *column,
|
|
36
|
+
indent: *current_indent,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
use crate::core::types::token::{ Token, TokenKind };
|
|
2
|
+
|
|
3
|
+
pub fn handle_indent_lexer(
|
|
4
|
+
chars: &mut std::iter::Peekable<std::str::Chars>,
|
|
5
|
+
current_indent: &mut usize,
|
|
6
|
+
indent_stack: &mut Vec<usize>,
|
|
7
|
+
tokens: &mut Vec<Token>,
|
|
8
|
+
line: &mut usize,
|
|
9
|
+
column: &mut usize
|
|
10
|
+
) -> (Vec<Token>, Vec<usize>, usize, usize) {
|
|
11
|
+
*current_indent = 0;
|
|
12
|
+
|
|
13
|
+
while let Some(&c) = chars.peek() {
|
|
14
|
+
if c == ' ' {
|
|
15
|
+
*current_indent += 1;
|
|
16
|
+
chars.next();
|
|
17
|
+
*column += 1;
|
|
18
|
+
} else {
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let last_indent = *indent_stack.last().unwrap();
|
|
24
|
+
if *current_indent > last_indent {
|
|
25
|
+
indent_stack.push(*current_indent);
|
|
26
|
+
tokens.push(Token {
|
|
27
|
+
kind: TokenKind::Indent,
|
|
28
|
+
lexeme: String::new(),
|
|
29
|
+
line: *line,
|
|
30
|
+
column: *column,
|
|
31
|
+
indent: *current_indent,
|
|
32
|
+
});
|
|
33
|
+
} else {
|
|
34
|
+
while *current_indent < *indent_stack.last().unwrap() {
|
|
35
|
+
indent_stack.pop();
|
|
36
|
+
tokens.push(Token {
|
|
37
|
+
kind: TokenKind::Dedent,
|
|
38
|
+
lexeme: String::new(),
|
|
39
|
+
line: *line,
|
|
40
|
+
column: *column,
|
|
41
|
+
indent: *current_indent,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
(tokens.clone(), indent_stack.clone(), *line, *column)
|
|
47
|
+
}
|