@devaloop/devalang 0.0.1-alpha.2 → 0.0.1-alpha.3
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/Cargo.toml +46 -46
- package/README.md +7 -6
- package/docs/CHANGELOG.md +11 -6
- package/docs/ROADMAP.md +5 -1
- package/docs/TODO.md +6 -31
- package/examples/exported.deva +1 -1
- package/examples/index.deva +1 -0
- package/out-tsc/bin/devalang.exe +0 -0
- package/package.json +1 -2
- package/project-version.json +3 -3
- package/rust/cli/build.rs +57 -40
- package/rust/cli/check.rs +47 -111
- package/rust/cli/init.rs +1 -1
- package/rust/cli/mod.rs +174 -2
- package/rust/{utils/config.rs → config/loader.rs} +3 -2
- package/rust/{core/types/config.rs → config/mod.rs} +5 -5
- package/rust/core/builder/mod.rs +21 -27
- package/rust/core/debugger/lexer.rs +12 -0
- package/rust/core/debugger/mod.rs +12 -49
- package/rust/core/debugger/preprocessor.rs +23 -0
- package/rust/core/error/mod.rs +60 -0
- package/rust/core/lexer/{at.rs → handler/at.rs} +1 -1
- package/rust/core/lexer/{brace.rs → handler/brace.rs} +1 -1
- package/rust/core/lexer/{colon.rs → handler/colon.rs} +1 -1
- package/rust/core/lexer/{comment.rs → handler/comment.rs} +3 -3
- package/rust/core/lexer/{dot.rs → handler/dot.rs} +1 -1
- package/rust/core/lexer/{equal.rs → handler/equal.rs} +1 -1
- package/rust/core/lexer/{identifier.rs → handler/identifier.rs} +1 -1
- package/rust/core/lexer/{indent.rs → handler/indent.rs} +10 -5
- package/rust/core/lexer/handler/mod.rs +238 -0
- package/rust/core/lexer/{newline.rs → handler/newline.rs} +6 -10
- package/rust/core/lexer/{number.rs → handler/number.rs} +1 -1
- package/rust/core/lexer/handler/string.rs +66 -0
- package/rust/core/lexer/mod.rs +25 -14
- package/rust/core/lexer/token.rs +55 -0
- package/rust/core/mod.rs +5 -2
- package/rust/core/parser/handler/at.rs +166 -0
- package/rust/core/parser/handler/bank.rs +38 -0
- package/rust/core/parser/handler/dot.rs +112 -0
- package/rust/core/parser/handler/identifier.rs +134 -0
- package/rust/core/parser/handler/loop_.rs +55 -0
- package/rust/core/parser/handler/mod.rs +6 -0
- package/rust/core/parser/handler/tempo.rs +47 -0
- package/rust/core/parser/mod.rs +204 -166
- package/rust/core/parser/statement.rs +91 -0
- package/rust/core/preprocessor/loader.rs +105 -0
- package/rust/core/preprocessor/mod.rs +2 -24
- package/rust/core/preprocessor/module.rs +37 -56
- package/rust/core/preprocessor/processor.rs +41 -0
- package/rust/core/preprocessor/resolver.rs +372 -0
- package/rust/core/shared/duration.rs +8 -0
- package/rust/core/shared/mod.rs +2 -0
- package/rust/core/shared/value.rs +18 -0
- package/rust/core/store/export.rs +28 -0
- package/rust/core/store/global.rs +39 -0
- package/rust/core/store/import.rs +28 -0
- package/rust/core/store/mod.rs +4 -0
- package/rust/core/store/variable.rs +28 -0
- package/rust/core/utils/mod.rs +2 -0
- package/rust/core/utils/validation.rs +35 -0
- package/rust/lib.rs +0 -1
- package/rust/main.rs +17 -19
- package/rust/utils/logger.rs +69 -34
- package/rust/utils/mod.rs +3 -5
- package/templates/minimal/.devalang +1 -1
- package/templates/welcome/.devalang +1 -1
- package/rust/audio/mod.rs +0 -1
- package/rust/core/lexer/bracket.rs +0 -41
- package/rust/core/lexer/driver.rs +0 -286
- package/rust/core/lexer/quote.rs +0 -61
- package/rust/core/parser/at.rs +0 -142
- package/rust/core/parser/bank.rs +0 -42
- package/rust/core/parser/dot.rs +0 -137
- package/rust/core/parser/identifer.rs +0 -91
- package/rust/core/parser/loop_.rs +0 -62
- package/rust/core/parser/tempo.rs +0 -42
- package/rust/core/parser/variable.rs +0 -129
- package/rust/core/preprocessor/dependencies.rs +0 -54
- package/rust/core/preprocessor/resolver/at.rs +0 -24
- package/rust/core/preprocessor/resolver/bank.rs +0 -59
- package/rust/core/preprocessor/resolver/loop_.rs +0 -82
- package/rust/core/preprocessor/resolver/mod.rs +0 -113
- package/rust/core/preprocessor/resolver/tempo.rs +0 -70
- package/rust/core/preprocessor/resolver/trigger.rs +0 -176
- package/rust/core/types/cli.rs +0 -182
- package/rust/core/types/mod.rs +0 -8
- package/rust/core/types/module.rs +0 -41
- package/rust/core/types/parser.rs +0 -73
- package/rust/core/types/statement.rs +0 -105
- package/rust/core/types/store.rs +0 -116
- package/rust/core/types/token.rs +0 -83
- package/rust/core/types/variable.rs +0 -32
- package/rust/runner/executer.rs +0 -44
- package/rust/runner/mod.rs +0 -1
- /package/rust/{utils → core/utils}/path.rs +0 -0
- /package/rust/utils/{loader.rs → spinner.rs} +0 -0
package/rust/cli/mod.rs
CHANGED
|
@@ -1,4 +1,176 @@
|
|
|
1
1
|
pub mod check;
|
|
2
|
-
pub mod init;
|
|
3
2
|
pub mod build;
|
|
4
|
-
pub mod
|
|
3
|
+
pub mod init;
|
|
4
|
+
pub mod template;
|
|
5
|
+
|
|
6
|
+
use clap::{ Parser, Subcommand };
|
|
7
|
+
use crate::utils::version::get_version;
|
|
8
|
+
|
|
9
|
+
#[derive(Parser)]
|
|
10
|
+
#[command(name = "devalang")]
|
|
11
|
+
#[command(author = "Devaloop")]
|
|
12
|
+
#[command(version = get_version())]
|
|
13
|
+
#[command(about = "🦊 Devalang – A programming language for music and sound.")]
|
|
14
|
+
pub struct Cli {
|
|
15
|
+
#[arg(long, global = true)]
|
|
16
|
+
/// Skips loading the configuration file.
|
|
17
|
+
pub no_config: bool,
|
|
18
|
+
|
|
19
|
+
#[command(subcommand)]
|
|
20
|
+
pub command: Commands,
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
#[derive(Subcommand)]
|
|
24
|
+
pub enum TemplateCommand {
|
|
25
|
+
/// Lists all available templates for Devalang projects.
|
|
26
|
+
List,
|
|
27
|
+
/// Displays information about a specific template.
|
|
28
|
+
Info {
|
|
29
|
+
name: String,
|
|
30
|
+
},
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
#[derive(Subcommand)]
|
|
34
|
+
pub enum Commands {
|
|
35
|
+
/// Create a new Devalang project.
|
|
36
|
+
///
|
|
37
|
+
/// ### Arguments
|
|
38
|
+
/// - `name` - The name of the project to create.
|
|
39
|
+
/// - `template` - The template to use for the project. Defaults to "default".
|
|
40
|
+
///
|
|
41
|
+
/// ### Example
|
|
42
|
+
/// ```bash
|
|
43
|
+
/// devalang init --name my_project --template default
|
|
44
|
+
///
|
|
45
|
+
Init {
|
|
46
|
+
#[arg(short, long)]
|
|
47
|
+
/// The optional name (directory) of the project to create.
|
|
48
|
+
name: Option<String>,
|
|
49
|
+
|
|
50
|
+
#[arg(short, long)]
|
|
51
|
+
/// The template to use for the project.
|
|
52
|
+
///
|
|
53
|
+
/// ### Default value
|
|
54
|
+
/// - `default`
|
|
55
|
+
///
|
|
56
|
+
template: Option<String>,
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
Template {
|
|
60
|
+
#[command(subcommand)]
|
|
61
|
+
/// The template command to execute.
|
|
62
|
+
command: TemplateCommand,
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
/// Build the program and generate output files.
|
|
66
|
+
///
|
|
67
|
+
/// ### Arguments
|
|
68
|
+
/// - `entry` - The entry point of the program to build. Defaults to "./src".
|
|
69
|
+
/// - `output` - The directory where the output files will be generated. Defaults to "./output".
|
|
70
|
+
/// - `watch` - Whether to watch for changes and rebuild. Defaults to "true".
|
|
71
|
+
///
|
|
72
|
+
/// ### Example
|
|
73
|
+
/// ```bash
|
|
74
|
+
/// devalang build --entry ./src --output ./output --watch true
|
|
75
|
+
/// ```
|
|
76
|
+
///
|
|
77
|
+
Build {
|
|
78
|
+
#[arg(short, long)]
|
|
79
|
+
/// The entry point of the program to build.
|
|
80
|
+
///
|
|
81
|
+
entry: Option<String>,
|
|
82
|
+
|
|
83
|
+
#[arg(short, long)]
|
|
84
|
+
/// The directory where the output files will be generated.
|
|
85
|
+
///
|
|
86
|
+
output: Option<String>,
|
|
87
|
+
|
|
88
|
+
#[arg(long, default_value_t = false)]
|
|
89
|
+
/// Whether to watch for changes and rebuild.
|
|
90
|
+
///
|
|
91
|
+
/// ### Default value
|
|
92
|
+
/// - `false`
|
|
93
|
+
///
|
|
94
|
+
watch: bool,
|
|
95
|
+
|
|
96
|
+
#[arg(long, default_value = "real-time")]
|
|
97
|
+
/// The mode of compilation.
|
|
98
|
+
///
|
|
99
|
+
/// ### Default value
|
|
100
|
+
/// - `real-time`
|
|
101
|
+
///
|
|
102
|
+
/// ### Possible values
|
|
103
|
+
/// - `real-time` - Compiles files as soon as possible.
|
|
104
|
+
/// - `batch` - Compiles files one by one.
|
|
105
|
+
/// - `check` - Analyzes the code without compiling it.
|
|
106
|
+
///
|
|
107
|
+
compilation_mode: String,
|
|
108
|
+
|
|
109
|
+
#[arg(short, long, default_value_t = false)]
|
|
110
|
+
/// Whether to print debug information.
|
|
111
|
+
///
|
|
112
|
+
/// ### Default value
|
|
113
|
+
/// - `false`
|
|
114
|
+
///
|
|
115
|
+
debug: bool,
|
|
116
|
+
|
|
117
|
+
#[arg(short, long, default_value_t = false)]
|
|
118
|
+
/// Whether to compress the output files.
|
|
119
|
+
///
|
|
120
|
+
/// ### Default value
|
|
121
|
+
/// - `false`
|
|
122
|
+
///
|
|
123
|
+
compress: bool,
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
/// Analyze the program for errors and warnings.
|
|
127
|
+
///
|
|
128
|
+
/// ### Arguments
|
|
129
|
+
/// - `entry` - The entry point of the program to analyze. Defaults to "./src".
|
|
130
|
+
/// - `watch` - Whether to watch for changes and re-analyze. Defaults to "true".
|
|
131
|
+
///
|
|
132
|
+
/// ### Example
|
|
133
|
+
/// ```bash
|
|
134
|
+
/// devalang check --entry ./src --watch true --compilation-mode real-time
|
|
135
|
+
/// ```
|
|
136
|
+
Check {
|
|
137
|
+
#[arg(short, long)]
|
|
138
|
+
/// The entry point of the program to analyze.
|
|
139
|
+
///
|
|
140
|
+
entry: Option<String>,
|
|
141
|
+
|
|
142
|
+
#[arg(short, long)]
|
|
143
|
+
/// The directory where the output files will be generated.
|
|
144
|
+
///
|
|
145
|
+
output: Option<String>,
|
|
146
|
+
|
|
147
|
+
#[arg(long, default_value_t = false)]
|
|
148
|
+
/// Whether to watch for changes and re-analyze.
|
|
149
|
+
///
|
|
150
|
+
/// ### Default value
|
|
151
|
+
/// - `false`
|
|
152
|
+
///
|
|
153
|
+
watch: bool,
|
|
154
|
+
|
|
155
|
+
#[arg(short, long, default_value = "real-time")]
|
|
156
|
+
/// The mode of compilation.
|
|
157
|
+
///
|
|
158
|
+
/// ### Default value
|
|
159
|
+
/// - `real-time`
|
|
160
|
+
///
|
|
161
|
+
/// ### Possible values
|
|
162
|
+
/// - `real-time` - Analyzes files as soon as possible.
|
|
163
|
+
/// - `batch` - Analyzes files one by one.
|
|
164
|
+
/// - `check` - Analyzes the code without compiling it.
|
|
165
|
+
///
|
|
166
|
+
compilation_mode: String,
|
|
167
|
+
|
|
168
|
+
#[arg(short, long, default_value_t = false)]
|
|
169
|
+
/// Whether to print debug information.
|
|
170
|
+
///
|
|
171
|
+
/// ### Default value
|
|
172
|
+
/// - `false`
|
|
173
|
+
///
|
|
174
|
+
debug: bool,
|
|
175
|
+
},
|
|
176
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
use std::{ fs, path::Path };
|
|
2
|
-
use crate::core::types::config::DevalangConfig;
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
use crate::config::Config;
|
|
4
|
+
|
|
5
|
+
pub fn load_config(path: Option<&Path>) -> Option<Config> {
|
|
5
6
|
let config_path = path.unwrap_or_else(|| Path::new(".devalang"));
|
|
6
7
|
|
|
7
8
|
if config_path.exists() {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
+
pub mod loader;
|
|
2
|
+
|
|
1
3
|
use serde::Deserialize;
|
|
2
4
|
|
|
3
5
|
#[derive(Debug, Deserialize)]
|
|
4
|
-
pub struct
|
|
5
|
-
pub defaults:
|
|
6
|
+
pub struct Config {
|
|
7
|
+
pub defaults: ConfigDefaults,
|
|
6
8
|
}
|
|
7
9
|
|
|
8
10
|
#[derive(Debug, Deserialize)]
|
|
9
|
-
pub struct
|
|
11
|
+
pub struct ConfigDefaults {
|
|
10
12
|
pub entry: Option<String>,
|
|
11
|
-
|
|
12
13
|
pub output: Option<String>,
|
|
13
|
-
|
|
14
14
|
pub watch: Option<bool>,
|
|
15
15
|
}
|
package/rust/core/builder/mod.rs
CHANGED
|
@@ -1,37 +1,31 @@
|
|
|
1
|
-
use crate::core::
|
|
2
|
-
use std::fs::
|
|
1
|
+
use crate::core::parser::statement::Statement;
|
|
2
|
+
use std::{ collections::HashMap, fs::create_dir_all };
|
|
3
3
|
use std::io::Write;
|
|
4
4
|
|
|
5
|
-
pub
|
|
6
|
-
let mut ast_string = String::new();
|
|
5
|
+
pub struct Builder {}
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
})
|
|
13
|
-
.unwrap_or_else(|err| {
|
|
14
|
-
eprintln!("Error serializing AST: {}", err);
|
|
15
|
-
std::process::exit(1);
|
|
16
|
-
});
|
|
7
|
+
impl Builder {
|
|
8
|
+
pub fn new() -> Self {
|
|
9
|
+
Builder {}
|
|
10
|
+
}
|
|
17
11
|
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
pub fn build_ast(&self, modules: &HashMap<String, Vec<Statement>>) {
|
|
13
|
+
let output_path = "./output";
|
|
20
14
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
for (name, statements) in modules {
|
|
16
|
+
let formatted_name = name.split("/").last().unwrap_or(name);
|
|
17
|
+
let formatted_name = formatted_name.replace(".deva", "");
|
|
24
18
|
|
|
25
|
-
|
|
19
|
+
create_dir_all(format!("{}/ast", output_path)).expect("Failed to create AST directory");
|
|
26
20
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
21
|
+
let file_path = format!("{}/ast/{}.json", output_path, formatted_name);
|
|
22
|
+
let mut file = std::fs::File::create(file_path).expect("Failed to create AST file");
|
|
30
23
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
let content = serde_json
|
|
25
|
+
::to_string_pretty(&statements)
|
|
26
|
+
.expect("Failed to serialize AST");
|
|
34
27
|
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
file.write_all(content.as_bytes()).expect("Failed to write AST to file");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
37
31
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
use crate::core::{ debugger::Debugger, lexer::token::Token };
|
|
2
|
+
|
|
3
|
+
pub fn write_lexer_log_file(output_dir: &str, file_name: &str, tokens: Vec<Token>) {
|
|
4
|
+
let debugger = Debugger::new();
|
|
5
|
+
let mut content = String::new();
|
|
6
|
+
|
|
7
|
+
for token in tokens {
|
|
8
|
+
content.push_str(&format!("{:?}\n", token));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
debugger.write_log_file(output_dir, file_name, &content);
|
|
12
|
+
}
|
|
@@ -1,57 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
pub mod preprocessor;
|
|
2
|
+
pub mod lexer;
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
4
|
+
use std::io::Write;
|
|
5
|
+
|
|
6
|
+
pub struct Debugger {}
|
|
6
7
|
|
|
7
8
|
impl Debugger {
|
|
8
|
-
pub fn new(
|
|
9
|
-
Debugger {
|
|
10
|
-
module: module.clone(),
|
|
11
|
-
}
|
|
9
|
+
pub fn new() -> Self {
|
|
10
|
+
Debugger {}
|
|
12
11
|
}
|
|
13
12
|
|
|
14
|
-
pub fn
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
let lexer_path = format!("{}{}", output_dir, LEXER_FILENAME);
|
|
19
|
-
let statements_path = format!("{}{}", output_dir, STATEMENTS_FILENAME);
|
|
20
|
-
|
|
21
|
-
// Collect debug information
|
|
22
|
-
let tokens = self.module.tokens
|
|
23
|
-
.iter()
|
|
24
|
-
.map(|token| format!("{:?}", token))
|
|
25
|
-
.collect::<Vec<String>>();
|
|
26
|
-
let statements = resolved_statements
|
|
27
|
-
.iter()
|
|
28
|
-
.map(|stmt| format!("{:?}", stmt))
|
|
29
|
-
.collect::<Vec<String>>();
|
|
13
|
+
pub fn write_log_file(&self, path: &str, filename: &str, content: &str) {
|
|
14
|
+
std::fs::create_dir_all(path).expect("Failed to create directory");
|
|
15
|
+
let file_path = format!("{}/{}", path, filename);
|
|
16
|
+
let mut file = std::fs::File::create(file_path).expect("Failed to create file");
|
|
30
17
|
|
|
31
|
-
|
|
32
|
-
clear_debug_directory(output_dir);
|
|
33
|
-
create_debug_directory(output_dir);
|
|
34
|
-
|
|
35
|
-
// Writing files
|
|
36
|
-
write_tokens_debug_to_file(&tokens, &lexer_path);
|
|
37
|
-
write_statements_debug_to_file(&statements, &statements_path);
|
|
18
|
+
file.write_all(content.as_bytes()).expect("Failed to write to file");
|
|
38
19
|
}
|
|
39
20
|
}
|
|
40
|
-
|
|
41
|
-
fn clear_debug_directory(path: &str) {
|
|
42
|
-
std::fs::remove_dir_all(path);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
fn create_debug_directory(path: &str) {
|
|
46
|
-
std::fs::create_dir_all(path);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
fn write_statements_debug_to_file(statements: &Vec<String>, path: &str) {
|
|
50
|
-
let content = statements.join("\n");
|
|
51
|
-
std::fs::write(path, content).expect("Unable to write statements to file");
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
fn write_tokens_debug_to_file(tokens: &Vec<String>, path: &str) {
|
|
55
|
-
let content = tokens.join("\n");
|
|
56
|
-
std::fs::write(path, content).expect("Unable to write tokens to file");
|
|
57
|
-
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
use std::collections::HashMap;
|
|
2
|
+
use crate::core::{ debugger::Debugger, parser::statement::Statement };
|
|
3
|
+
|
|
4
|
+
pub fn write_preprocessor_log_file(
|
|
5
|
+
output_dir: &str,
|
|
6
|
+
file_name: &str,
|
|
7
|
+
statements: HashMap<String, Vec<Statement>>
|
|
8
|
+
) {
|
|
9
|
+
let debugger = Debugger::new();
|
|
10
|
+
let mut content = String::new();
|
|
11
|
+
|
|
12
|
+
for (path, stmts) in statements {
|
|
13
|
+
content.push_str(&format!("--- Resolved Statements for {} ---\n", path));
|
|
14
|
+
|
|
15
|
+
for stmt in stmts {
|
|
16
|
+
content.push_str(&format!("{:?}\n", stmt));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
content.push_str("\n");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
debugger.write_log_file(output_dir, file_name, &content);
|
|
23
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
use crate::core::parser::{ statement::{ Statement, StatementKind }, Parser };
|
|
2
|
+
|
|
3
|
+
pub struct ErrorHandler {
|
|
4
|
+
errors: Vec<Error>,
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
pub struct Error {
|
|
8
|
+
pub message: String,
|
|
9
|
+
pub line: usize,
|
|
10
|
+
pub column: usize,
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
impl ErrorHandler {
|
|
14
|
+
pub fn new() -> Self {
|
|
15
|
+
Self { errors: Vec::new() }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
pub fn add_error(&mut self, message: String, line: usize, column: usize) {
|
|
19
|
+
let error_statement = Error {
|
|
20
|
+
message,
|
|
21
|
+
line,
|
|
22
|
+
column,
|
|
23
|
+
};
|
|
24
|
+
self.errors.push(error_statement);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
pub fn has_errors(&self) -> bool {
|
|
28
|
+
!self.errors.is_empty()
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
pub fn get_errors(&self) -> &Vec<Error> {
|
|
32
|
+
&self.errors
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
pub fn clear_errors(&mut self) {
|
|
36
|
+
self.errors.clear();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
pub fn detect_from_statements(&mut self, parser: &mut Parser, statements: &[Statement]) {
|
|
40
|
+
for stmt in statements {
|
|
41
|
+
match &stmt.kind {
|
|
42
|
+
StatementKind::Unknown => {
|
|
43
|
+
self.add_error(
|
|
44
|
+
"Unknown statement".to_string(),
|
|
45
|
+
stmt.line,
|
|
46
|
+
stmt.column
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
StatementKind::Error { message } => {
|
|
50
|
+
self.add_error(
|
|
51
|
+
message.clone(),
|
|
52
|
+
stmt.line,
|
|
53
|
+
stmt.column
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
_ => {}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
use crate::core::
|
|
1
|
+
use crate::core::lexer::token::{Token, TokenKind};
|
|
2
2
|
|
|
3
3
|
pub fn handle_comment_lexer(
|
|
4
4
|
char: char,
|
|
@@ -21,8 +21,8 @@ pub fn handle_comment_lexer(
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
tokens.push(Token {
|
|
24
|
-
kind: TokenKind::Comment
|
|
25
|
-
lexeme:
|
|
24
|
+
kind: TokenKind::Comment,
|
|
25
|
+
lexeme: comment.trim().to_string(),
|
|
26
26
|
line: *line,
|
|
27
27
|
column: *column,
|
|
28
28
|
indent: *current_indent,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
use crate::core::
|
|
1
|
+
use crate::core::lexer::token::{ Token, TokenKind };
|
|
2
2
|
|
|
3
3
|
pub fn handle_indent_lexer(
|
|
4
4
|
chars: &mut std::iter::Peekable<std::str::Chars>,
|
|
@@ -7,19 +7,26 @@ pub fn handle_indent_lexer(
|
|
|
7
7
|
tokens: &mut Vec<Token>,
|
|
8
8
|
line: &mut usize,
|
|
9
9
|
column: &mut usize
|
|
10
|
-
)
|
|
10
|
+
) {
|
|
11
11
|
*current_indent = 0;
|
|
12
|
+
let mut col = *column;
|
|
12
13
|
|
|
13
14
|
while let Some(&c) = chars.peek() {
|
|
14
15
|
if c == ' ' {
|
|
15
16
|
*current_indent += 1;
|
|
16
17
|
chars.next();
|
|
17
|
-
|
|
18
|
+
col += 1;
|
|
19
|
+
} else if c == '\t' {
|
|
20
|
+
*current_indent += 4; // tabulation = 4 espaces
|
|
21
|
+
chars.next();
|
|
22
|
+
col += 4;
|
|
18
23
|
} else {
|
|
19
24
|
break;
|
|
20
25
|
}
|
|
21
26
|
}
|
|
22
27
|
|
|
28
|
+
*column = col;
|
|
29
|
+
|
|
23
30
|
let last_indent = *indent_stack.last().unwrap();
|
|
24
31
|
if *current_indent > last_indent {
|
|
25
32
|
indent_stack.push(*current_indent);
|
|
@@ -42,6 +49,4 @@ pub fn handle_indent_lexer(
|
|
|
42
49
|
});
|
|
43
50
|
}
|
|
44
51
|
}
|
|
45
|
-
|
|
46
|
-
(tokens.clone(), indent_stack.clone(), *line, *column)
|
|
47
52
|
}
|