Skip to content

Commit c741332

Browse files
committed
refactor: errors and begin work on transpiler
1 parent ff0fd08 commit c741332

File tree

17 files changed

+304
-200
lines changed

17 files changed

+304
-200
lines changed

packages/cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ version = "0.1.0"
44
edition = "2021"
55

66
[dependencies]
7-
lang_engine = { workspace = true, features = ["cli"] }
7+
lang_engine = { workspace = true, features = [] }
88

99
# logging
1010
log = { workspace = true }

packages/engine/Cargo.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,14 @@ edition = "2021"
66
[dependencies]
77
log = { workspace = true }
88
thiserror = { workspace = true }
9-
colored = { workspace = true, optional = true }
9+
colored = { workspace = true }
1010
lang_macro = { workspace = true }
1111

1212
[dev-dependencies]
1313
pretty_assertions = { workspace = true }
1414

1515
[features]
16-
default = ["cli"]
17-
cli = ["dep:colored"]
16+
default = []
1817
no-color = ["colored/no-color"]
1918

2019
[lib]

packages/engine/src/component.rs

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
use std::iter::Peekable;
1+
use std::{fmt::Display, iter::Peekable};
22

3-
use crate::error::ErrorList;
3+
use crate::error::SourceFile;
44

5-
pub trait ComponentErrors {
6-
fn fetch_errors(&self) -> &ErrorList;
5+
pub trait ComponentErrors<E>
6+
where E: Display {
7+
8+
fn fetch_errors(&self) -> &Vec<E>;
79

810
fn has_errors(&self) -> bool {
911
!self.fetch_errors().is_empty()
@@ -15,22 +17,7 @@ pub trait ComponentErrors {
1517
}
1618
}
1719

18-
#[cfg(feature = "cli")]
19-
fn source(&self) -> &crate::error::SourceFile;
20-
21-
#[cfg(feature = "cli")]
22-
fn get_source_sliced(&self, start: crate::cursor::Cursor, end: crate::cursor::Cursor) -> crate::error::SourceFile {
23-
let source_file = self.source();
24-
25-
let start_index = start.index() as usize;
26-
let end_index = end.index() as usize;
27-
28-
let code = &source_file.as_ref().1;
29-
30-
let source = &code[start_index..end_index.min(code.len())];
31-
32-
Box::from((source_file.as_ref().0.clone(), source.to_string()))
33-
}
20+
fn source(&self) -> &SourceFile;
3421
}
3522

3623
pub trait ComponentIter<'a, C, T, I> where

packages/engine/src/error.rs

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,60 @@
1-
#[cfg(feature = "cli")]
21
use colored::Colorize;
32

4-
use crate::lexer::tokens::LexerTokenKind;
3+
use crate::cursor::Cursor;
54

6-
#[derive(thiserror::Error, PartialEq, Eq, Debug, Clone)]
5+
#[derive(thiserror::Error, Debug)]
76
pub enum EngineErrorKind {
87
#[error("{0}")]
98
LexerError(#[from] crate::lexer::LexerError),
109
#[error("{0}")]
1110
ParserError(#[from] crate::parser::ParserError),
12-
#[error("failed to get value as '{0}' from literal '{1}'")]
13-
LiteralExtractionError(LexerTokenKind, LexerTokenKind),
11+
#[error(transparent)]
12+
Io(#[from] std::io::Error),
13+
#[error("exec error")]
14+
ExecError,
15+
#[error("expected file")]
16+
ExpectedFileError,
1417
#[error("an unreachable error has occurred. this shouldn't ever happen")]
1518
Unreachable,
1619
#[error("an unknown error has occurred")]
1720
UnknownError,
1821
}
1922

2023
pub type EngineResult<T> = std::result::Result<T, EngineErrorKind>;
21-
pub type ErrorList = Vec<EngineErrorKind>;
2224

23-
#[cfg(feature = "cli")]
24-
pub(super) type SourceFile = Box<(Option<std::path::PathBuf>, String)>;
25+
#[derive(Debug, Clone, PartialEq, Eq)]
26+
pub struct SourceFile {
27+
path: String,
28+
code: String,
29+
}
30+
31+
impl SourceFile {
32+
pub fn from(code: String, path: Option<String>) -> Self {
33+
Self {
34+
code,
35+
path: path.unwrap_or(String::from("virtual"))
36+
}
37+
}
38+
39+
pub fn get_path(&self) -> &str {
40+
&self.path
41+
}
42+
43+
pub fn get_code(&self) -> &str {
44+
&self.code
45+
}
46+
47+
pub fn sliced(&self, start: Cursor, end: Cursor) -> SourceFile {
48+
let start_index = start.index() as usize;
49+
let end_index = end.index() as usize;
50+
51+
let code = self.get_code();
52+
let slice = &code[start_index..end_index.min(code.len())];
53+
54+
SourceFile::from(slice.to_string(), Some(self.path.clone()))
55+
}
56+
}
2557

26-
#[cfg(feature = "cli")]
2758
pub trait CodeError<T>
2859
where T: lang_macro::EnumVariantsTrait + ToString {
2960
fn kind(&self) -> &T;
@@ -39,8 +70,8 @@ where T: lang_macro::EnumVariantsTrait + ToString {
3970
self.kind().to_string().bold(),
4071
)?;
4172

42-
let (path, source) = *self.source_file().clone();
43-
let (path, source) = (path.map_or("VM".to_string(), |path| path.to_string_lossy().to_string()), source);
73+
let path = self.source_file().get_path();
74+
let code = self.source_file().get_code();
4475

4576
writeln!(f,
4677
" {} {}",
@@ -73,7 +104,7 @@ where T: lang_macro::EnumVariantsTrait + ToString {
73104
" ".repeat(max_line_len - line_len),
74105
line,
75106
"|".bright_blue().bold(),
76-
source.trim()
107+
code.trim()
77108
)?;
78109
}
79110

packages/engine/src/lexer/error.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
#[cfg(feature = "cli")]
21
use std::fmt::Display;
3-
4-
#[cfg(feature = "cli")]
52
use crate::error::{CodeError, SourceFile};
63

74
use crate::cursor::Cursor;
85

9-
#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq, lang_macro::EnumVariants)]
6+
use super::tokens::LexerTokenKind;
7+
8+
#[derive(thiserror::Error, Debug, lang_macro::EnumVariants, PartialEq, Eq, Clone)]
109
pub enum LexerErrorKind {
1110
#[error("unexpected end of input")]
1211
UnexpectedEnd,
@@ -16,31 +15,28 @@ pub enum LexerErrorKind {
1615
IntegerOverflow(String),
1716
#[error("expected character '{expected}' but found {found:?}")]
1817
ExpectedCharacter { expected: String, found: Option<char> },
18+
#[error("failed to get value as '{0}' from literal '{1}'")]
19+
LiteralExtractionError(LexerTokenKind, LexerTokenKind),
1920
#[error("unknown token")]
2021
UnknownToken
2122
}
2223

23-
#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq)]
24-
#[cfg_attr(not(feature = "cli"), error("{kind}"))]
24+
#[derive(thiserror::Error, Debug, PartialEq, Eq, Clone)]
2525
pub struct LexerError {
2626
pub kind: LexerErrorKind,
2727
pub start: Cursor,
2828
pub end: Cursor,
29-
30-
#[cfg(feature = "cli")]
3129
pub source_file: SourceFile,
3230
}
3331

34-
pub(super) type LexerResult<T> = std::result::Result<T, LexerErrorKind>;
32+
pub type LexerResult<T> = std::result::Result<T, LexerErrorKind>;
3533

36-
#[cfg(feature = "cli")]
3734
impl Display for LexerError {
3835
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3936
self.format_error(f)
4037
}
4138
}
4239

43-
#[cfg(feature = "cli")]
4440
impl CodeError<LexerErrorKind> for LexerError {
4541
fn kind(&self) -> &LexerErrorKind {
4642
&self.kind

packages/engine/src/lexer/mod.rs

Lines changed: 17 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ use error::LexerResult;
44
use tokens::{LexerLiteral, LexerToken, LexerTokenKind, LexerTokenList};
55

66
use crate::{
7-
component::{ComponentErrors, ComponentIter},
8-
constants::{MAX_I32_LEN, MAX_I64_LEN},
9-
error::{EngineErrorKind, ErrorList},
10-
cursor::Cursor,
7+
component::{ComponentErrors, ComponentIter}, cursor::Cursor, error::SourceFile
118
};
129

1310
pub use error::{LexerError, LexerErrorKind};
@@ -17,54 +14,35 @@ pub mod tokens;
1714

1815
pub struct Lexer<'a> {
1916
chars: Peekable<Chars<'a>>,
20-
errors: ErrorList,
17+
errors: Vec<LexerError>,
2118
cursor: Cursor,
2219
tokens: LexerTokenList,
2320
max_int_len: u8,
24-
25-
#[cfg(feature = "cli")]
26-
source: crate::error::SourceFile,
21+
source_file: &'a SourceFile,
2722
}
2823

2924
impl<'a> Lexer<'a> {
3025
pub fn create(
31-
input: &'a str,
32-
#[cfg(feature = "cli")] path: Option<std::path::PathBuf>,
26+
source_file: &'a SourceFile,
3327
) -> Self {
3428
Self::create_bits(
35-
input,
36-
#[cfg(feature = "cli")]
37-
path,
38-
MAX_I64_LEN,
39-
)
40-
}
41-
42-
pub fn create_32b(
43-
input: &'a str,
44-
#[cfg(feature = "cli")] path: Option<std::path::PathBuf>,
45-
) -> Self {
46-
Self::create_bits(
47-
input,
48-
#[cfg(feature = "cli")]
49-
path,
50-
MAX_I32_LEN,
29+
source_file,
30+
#[cfg(target_pointer_width = "32")] crate::constants::MAX_I32_LEN,
31+
#[cfg(target_pointer_width = "64")] crate::constants::MAX_I64_LEN,
5132
)
5233
}
5334

5435
pub fn create_bits(
55-
input: &'a str,
56-
#[cfg(feature = "cli")] path: Option<std::path::PathBuf>,
36+
source_file: &'a SourceFile,
5737
max_int_len: u8,
5838
) -> Self {
5939
let lexer = Self {
60-
chars: input.trim().chars().peekable(),
61-
errors: ErrorList::new(),
40+
chars: source_file.get_code().trim().chars().peekable(),
41+
errors: Vec::new(),
6242
cursor: Cursor::create(),
6343
tokens: LexerTokenList::new(),
6444
max_int_len,
65-
66-
#[cfg(feature = "cli")]
67-
source: Box::from((path, input.to_string())),
45+
source_file,
6846
};
6947

7048
debug!("created lexer");
@@ -253,13 +231,12 @@ impl<'a> Lexer<'a> {
253231
start: Cursor,
254232
err: LexerErrorKind
255233
) {
256-
self.errors.push(EngineErrorKind::LexerError(LexerError {
257-
#[cfg(feature = "cli")]
258-
source_file: self.get_source_sliced(start, self.cursor),
234+
self.errors.push(LexerError {
235+
source_file: self.source().sliced(start, self.cursor),
259236
start,
260237
end: self.cursor,
261238
kind: err,
262-
}))
239+
})
263240
}
264241

265242
/// Consumes a single-line comment (aka skips to the end of the line and returns nothing)
@@ -487,14 +464,13 @@ impl<'a> Lexer<'a> {
487464
}
488465
}
489466

490-
impl ComponentErrors for Lexer<'_> {
491-
fn fetch_errors(&self) -> &ErrorList {
467+
impl ComponentErrors<LexerError> for Lexer<'_> {
468+
fn fetch_errors(&self) -> &Vec<LexerError> {
492469
&self.errors
493470
}
494471

495-
#[cfg(feature = "cli")]
496472
fn source(&self) -> &crate::error::SourceFile {
497-
&self.source
473+
self.source_file
498474
}
499475
}
500476

packages/engine/src/lexer/tokens.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ use std::fmt::Display;
22

33
use lang_macro::EnumVariantsTrait;
44

5-
use crate::{
6-
error::{EngineErrorKind, EngineResult},
7-
cursor::Cursor,
8-
};
5+
use crate::cursor::Cursor;
6+
7+
use super::{error::LexerResult, LexerErrorKind};
98

109
#[repr(u8)]
1110
#[derive(lang_macro::EnumVariants, Debug, PartialEq, Eq, Clone)]
@@ -182,51 +181,51 @@ pub struct LexerToken {
182181
}
183182

184183
impl LexerToken {
185-
pub fn as_identifier(&self) -> EngineResult<&String> {
184+
pub fn as_identifier(&self) -> LexerResult<&String> {
186185
self.value
187186
.as_ref()
188187
.and_then(|v| v.as_identifier())
189-
.ok_or(EngineErrorKind::LiteralExtractionError(
188+
.ok_or(LexerErrorKind::LiteralExtractionError(
190189
LexerTokenKind::Identifier,
191190
self.kind.clone(),
192191
))
193192
}
194193

195-
pub fn as_string(&self) -> EngineResult<&String> {
194+
pub fn as_string(&self) -> LexerResult<&String> {
196195
self.value
197196
.as_ref()
198197
.and_then(|v| v.as_string())
199-
.ok_or(EngineErrorKind::LiteralExtractionError(
198+
.ok_or(LexerErrorKind::LiteralExtractionError(
200199
LexerTokenKind::String,
201200
self.kind.clone(),
202201
))
203202
}
204203

205-
pub fn as_integer(&self) -> EngineResult<&isize> {
204+
pub fn as_integer(&self) -> LexerResult<&isize> {
206205
self.value
207206
.as_ref()
208207
.and_then(|v| v.as_integer())
209-
.ok_or(EngineErrorKind::LiteralExtractionError(
208+
.ok_or(LexerErrorKind::LiteralExtractionError(
210209
LexerTokenKind::Integer,
211210
self.kind.clone(),
212211
))
213212
}
214213

215-
pub fn as_boolean(&self) -> EngineResult<&bool> {
214+
pub fn as_boolean(&self) -> LexerResult<&bool> {
216215
self.value
217216
.as_ref()
218217
.and_then(|v| v.as_boolean())
219-
.ok_or(EngineErrorKind::LiteralExtractionError(
218+
.ok_or(LexerErrorKind::LiteralExtractionError(
220219
LexerTokenKind::Boolean,
221220
self.kind.clone(),
222221
))
223222
}
224223

225-
pub fn as_shell_command(&self) -> EngineResult<&ShellCommand> {
224+
pub fn as_shell_command(&self) -> LexerResult<&ShellCommand> {
226225
self.value
227226
.as_ref()
228227
.and_then(|v| v.as_shell_command())
229-
.ok_or(EngineErrorKind::LiteralExtractionError(
228+
.ok_or(LexerErrorKind::LiteralExtractionError(
230229
LexerTokenKind::ShellCommand,
231230
self.kind.clone(),
232231
))

0 commit comments

Comments
 (0)