refactor: migrate syntax errors into new struct
This commit is contained in:
parent
fef5ee8041
commit
b59d014383
@ -29,6 +29,7 @@
|
|||||||
- [x] Typecheck for loops
|
- [x] Typecheck for loops
|
||||||
- [x] Typecheck while loops
|
- [x] Typecheck while loops
|
||||||
- [x] Include Ariadne for error reporting
|
- [x] Include Ariadne for error reporting
|
||||||
|
- [x] Migrate lexic errors to new error interface
|
||||||
|
|
||||||
|
|
||||||
## v0.1.1
|
## v0.1.1
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
-- A map of error codes to error messages
|
-- A map of error codes to error messages
|
||||||
|
0x000000: Incomplete string
|
||||||
0x000001: Incomplete string
|
0x000001: Invalid hex number
|
||||||
|
0x000002: Invalid octal number
|
||||||
|
0x000003: Invalid binary number
|
||||||
|
0x000004: Invalid floating point number
|
||||||
|
0x000005: Invalid scientific number
|
||||||
|
0x000006: Incomplete multiline comment
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ impl Transpilable for PPrimary<'_> {
|
|||||||
PPrimary::FloatingLiteral(value) => value.to_string(),
|
PPrimary::FloatingLiteral(value) => value.to_string(),
|
||||||
PPrimary::StringLiteral(value) => format!("\"{}\"", value),
|
PPrimary::StringLiteral(value) => format!("\"{}\"", value),
|
||||||
PPrimary::Variable(name) => format!("${}", name),
|
PPrimary::Variable(name) => format!("${}", name),
|
||||||
PPrimary::Symbol(name) => format!("{}", name),
|
// PPrimary::Symbol(name) => format!("{}", name),
|
||||||
PPrimary::BoolLiteral(bool) => {
|
PPrimary::BoolLiteral(bool) => {
|
||||||
if *bool {
|
if *bool {
|
||||||
String::from("true")
|
String::from("true")
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
//! Contains constants that point to error messages
|
//! Contains constants that point to error messages
|
||||||
|
|
||||||
pub const LEX_INCOMPLETE_STRING: u32 = 0;
|
pub const LEX_INCOMPLETE_STRING: u32 = 0;
|
||||||
|
pub const LEX_INVALID_HEX_NUMBER: u32 = 1;
|
||||||
|
pub const LEX_INVALID_OCTAL_NUMBER: u32 = 2;
|
||||||
|
pub const LEX_INVALID_BINARY_NUMBER: u32 = 3;
|
||||||
|
pub const LEX_INVALID_FLOATING_NUMBER: u32 = 4;
|
||||||
|
pub const LEX_INVALID_SCIENTIFIC_NUMBER: u32 = 5;
|
||||||
|
pub const LEX_INCOMPLETE_MULTILINE_COMMENT: u32 = 6;
|
||||||
|
@ -31,7 +31,7 @@ impl PrintableError for LexError {
|
|||||||
.with_color(Color::Red),
|
.with_color(Color::Red),
|
||||||
)
|
)
|
||||||
.finish();
|
.finish();
|
||||||
report.eprint(("sample.thp", Source::from(source)));
|
report.eprint(("sample.thp", Source::from(source))).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
use std::ops::Range;
|
||||||
|
|
||||||
|
use ariadne::{Label, Report, ReportKind, Source};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use self::semantic_error::SemanticError;
|
use self::semantic_error::SemanticError;
|
||||||
@ -56,7 +59,7 @@ pub struct SyntaxError {
|
|||||||
impl PrintableError for MistiError {
|
impl PrintableError for MistiError {
|
||||||
fn get_error_str(&self, chars: &Vec<char>) -> String {
|
fn get_error_str(&self, chars: &Vec<char>) -> String {
|
||||||
match self {
|
match self {
|
||||||
Self::Lex(err) => panic!("REMOVED: manually generating an error message"),
|
Self::Lex(_) => panic!("REMOVED: manually generating an error message"),
|
||||||
Self::Syntax(err) => err.get_error_str(chars),
|
Self::Syntax(err) => err.get_error_str(chars),
|
||||||
Self::Semantic(err) => err.get_error_str(chars),
|
Self::Semantic(err) => err.get_error_str(chars),
|
||||||
}
|
}
|
||||||
@ -70,3 +73,26 @@ impl PrintableError for MistiError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PrintableError for ErrorContainer {
|
||||||
|
fn get_error_str(&self, _: &Vec<char>) -> String {
|
||||||
|
panic!("REMOVED: manually generating an error message")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_ariadne(&self, source: &String) {
|
||||||
|
let mut report: ariadne::ReportBuilder<'_, (&str, Range<usize>)> =
|
||||||
|
Report::build(ReportKind::Error, "sample.thp", self.error_offset);
|
||||||
|
|
||||||
|
for label in self.labels.iter() {
|
||||||
|
let l = Label::new(("sample.thp", label.start..label.end))
|
||||||
|
.with_message(label.message.clone());
|
||||||
|
report = report.with_label(l)
|
||||||
|
}
|
||||||
|
|
||||||
|
report
|
||||||
|
.with_code(self.error_code)
|
||||||
|
.finish()
|
||||||
|
.eprint(("sample.thp", Source::from(source)))
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -41,6 +41,6 @@ impl PrintableError for SemanticError {
|
|||||||
)
|
)
|
||||||
.finish();
|
.finish();
|
||||||
|
|
||||||
report.eprint(("sample.thp", Source::from(source)));
|
report.eprint(("sample.thp", Source::from(source))).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ impl PrintableError for SyntaxError {
|
|||||||
)
|
)
|
||||||
.finish();
|
.finish();
|
||||||
|
|
||||||
report.eprint(("sample.thp", Source::from(source)));
|
report.eprint(("sample.thp", Source::from(source))).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ mod utils;
|
|||||||
|
|
||||||
pub mod token;
|
pub mod token;
|
||||||
|
|
||||||
use crate::error_handling::{ErrorContainer, ErrorLabel, LexError, MistiError};
|
use crate::error_handling::{ErrorContainer, ErrorLabel, MistiError};
|
||||||
use token::Token;
|
use token::Token;
|
||||||
|
|
||||||
use self::token::TokenType;
|
use self::token::TokenType;
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
use super::token::Token;
|
use super::token::Token;
|
||||||
use crate::{
|
use crate::{
|
||||||
error_handling::LexError,
|
error_handling::{
|
||||||
|
error_messages::LEX_INCOMPLETE_MULTILINE_COMMENT, ErrorContainer, ErrorLabel,
|
||||||
|
},
|
||||||
lexic::{utils, LexResult},
|
lexic::{utils, LexResult},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -40,12 +42,21 @@ pub fn scan_multiline(chars: &Vec<char>, start_pos: usize) -> LexResult {
|
|||||||
),
|
),
|
||||||
Err(last_position) => {
|
Err(last_position) => {
|
||||||
// Throw an error: Incomplete multiline comment
|
// Throw an error: Incomplete multiline comment
|
||||||
LexResult::Err(LexError {
|
let label = ErrorLabel {
|
||||||
position: start_pos,
|
message: String::from("The code ends here without closing the multiline comment"),
|
||||||
// TODO: add an end_position
|
// This is minus 1 so we are pointing at something, and not at EOF
|
||||||
end_position: last_position,
|
start: last_position - 1,
|
||||||
reason: "Unfinished multiline commend".into(),
|
end: last_position,
|
||||||
})
|
};
|
||||||
|
let econtainer = ErrorContainer {
|
||||||
|
error_code: LEX_INCOMPLETE_MULTILINE_COMMENT,
|
||||||
|
error_offset: last_position,
|
||||||
|
labels: vec![label],
|
||||||
|
note: None,
|
||||||
|
help: Some(String::from("End the multiline comment with `*/`")),
|
||||||
|
};
|
||||||
|
|
||||||
|
LexResult::Err(econtainer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,7 +239,7 @@ mod tests {
|
|||||||
let result = scan_multiline(&input, 0);
|
let result = scan_multiline(&input, 0);
|
||||||
match result {
|
match result {
|
||||||
LexResult::Err(error) => {
|
LexResult::Err(error) => {
|
||||||
assert_eq!(0, error.position)
|
assert_eq!(error.error_code, LEX_INCOMPLETE_MULTILINE_COMMENT);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
panic!("Expected an error scannning an incomplete multiline comment")
|
panic!("Expected an error scannning an incomplete multiline comment")
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
use crate::error_handling::LexError;
|
use crate::error_handling::error_messages::{
|
||||||
|
LEX_INVALID_BINARY_NUMBER, LEX_INVALID_FLOATING_NUMBER, LEX_INVALID_HEX_NUMBER,
|
||||||
|
LEX_INVALID_OCTAL_NUMBER, LEX_INVALID_SCIENTIFIC_NUMBER,
|
||||||
|
};
|
||||||
|
use crate::error_handling::{ErrorContainer, ErrorLabel};
|
||||||
use crate::lexic::{token::Token, utils, LexResult};
|
use crate::lexic::{token::Token, utils, LexResult};
|
||||||
|
|
||||||
/// Function to scan an int/float
|
/// Function to scan an int/float
|
||||||
@ -57,11 +61,22 @@ fn scan_hex(chars: &[char], start_pos: usize, current: String) -> LexResult {
|
|||||||
let (t, next) = scan_hex_digits(chars, start_pos + 1, utils::str_append(current, *c));
|
let (t, next) = scan_hex_digits(chars, start_pos + 1, utils::str_append(current, *c));
|
||||||
LexResult::Some(t, next)
|
LexResult::Some(t, next)
|
||||||
}
|
}
|
||||||
_ => LexResult::Err(LexError {
|
_ => {
|
||||||
position: start_pos,
|
let label = ErrorLabel {
|
||||||
end_position: start_pos + 1,
|
message: String::from("The hex number ends here, without any digit"),
|
||||||
reason: String::from("Tried to scan an incomplete hex value"),
|
start: start_pos,
|
||||||
}),
|
end: start_pos + 1,
|
||||||
|
};
|
||||||
|
let econtainer = ErrorContainer {
|
||||||
|
error_code: LEX_INVALID_HEX_NUMBER,
|
||||||
|
error_offset: start_pos,
|
||||||
|
labels: vec![label],
|
||||||
|
note: None,
|
||||||
|
help: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
LexResult::Err(econtainer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,12 +97,21 @@ fn scan_octal(chars: &[char], start_pos: usize) -> LexResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if token_vec.is_empty() {
|
if token_vec.is_empty() {
|
||||||
LexResult::Err(LexError {
|
let label = ErrorLabel {
|
||||||
|
message: String::from("The octal number ends here, without any digit"),
|
||||||
|
start: current_pos,
|
||||||
|
end: current_pos + 1,
|
||||||
|
};
|
||||||
|
let econtainer = ErrorContainer {
|
||||||
|
error_code: LEX_INVALID_OCTAL_NUMBER,
|
||||||
// minus 2 to account for the opening '0o'
|
// minus 2 to account for the opening '0o'
|
||||||
position: start_pos - 2,
|
error_offset: current_pos - 2,
|
||||||
end_position: current_pos,
|
labels: vec![label],
|
||||||
reason: String::from("Found an incomplete octal number"),
|
note: None,
|
||||||
})
|
help: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
LexResult::Err(econtainer)
|
||||||
} else {
|
} else {
|
||||||
let octal_numbers = format!("0o{}", token_vec.iter().collect::<String>());
|
let octal_numbers = format!("0o{}", token_vec.iter().collect::<String>());
|
||||||
let new_token = Token::new_int(octal_numbers, start_pos - 2);
|
let new_token = Token::new_int(octal_numbers, start_pos - 2);
|
||||||
@ -113,12 +137,21 @@ fn scan_binary(chars: &[char], start_pos: usize) -> LexResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if token_vec.is_empty() {
|
if token_vec.is_empty() {
|
||||||
LexResult::Err(LexError {
|
let label = ErrorLabel {
|
||||||
|
message: String::from("The binary number ends here, without any digit"),
|
||||||
|
start: current_pos,
|
||||||
|
end: current_pos + 1,
|
||||||
|
};
|
||||||
|
let econtainer = ErrorContainer {
|
||||||
|
error_code: LEX_INVALID_BINARY_NUMBER,
|
||||||
// minus 2 to account for the opening '0b'
|
// minus 2 to account for the opening '0b'
|
||||||
position: start_pos - 2,
|
error_offset: current_pos - 2,
|
||||||
end_position: current_pos,
|
labels: vec![label],
|
||||||
reason: String::from("Found an incomplete binary number"),
|
note: None,
|
||||||
})
|
help: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
LexResult::Err(econtainer)
|
||||||
} else {
|
} else {
|
||||||
let octal_numbers = format!("0b{}", token_vec.iter().collect::<String>());
|
let octal_numbers = format!("0b{}", token_vec.iter().collect::<String>());
|
||||||
let new_token = Token::new_int(octal_numbers, start_pos - 2);
|
let new_token = Token::new_int(octal_numbers, start_pos - 2);
|
||||||
@ -135,18 +168,45 @@ fn scan_binary(chars: &[char], start_pos: usize) -> LexResult {
|
|||||||
fn scan_double(chars: &Vec<char>, start_pos: usize, current: String) -> LexResult {
|
fn scan_double(chars: &Vec<char>, start_pos: usize, current: String) -> LexResult {
|
||||||
match chars.get(start_pos) {
|
match chars.get(start_pos) {
|
||||||
Some(c) if utils::is_digit(*c) => scan_double_impl(chars, start_pos, current),
|
Some(c) if utils::is_digit(*c) => scan_double_impl(chars, start_pos, current),
|
||||||
Some(_) => LexResult::Err(LexError {
|
Some(_) => {
|
||||||
position: start_pos,
|
let label = ErrorLabel {
|
||||||
end_position: start_pos + 1,
|
message: String::from("The floating number ends here, without any digit"),
|
||||||
reason: String::from(
|
start: start_pos,
|
||||||
"The character after the dot when scanning a double is not a number.",
|
end: start_pos + 1,
|
||||||
|
};
|
||||||
|
let econtainer = ErrorContainer {
|
||||||
|
error_code: LEX_INVALID_FLOATING_NUMBER,
|
||||||
|
// minus 2 to account for the opening '0b'
|
||||||
|
error_offset: start_pos,
|
||||||
|
labels: vec![label],
|
||||||
|
note: Some(String::from(
|
||||||
|
"Floating point numbers must always have at least 1 digit after the period",
|
||||||
|
)),
|
||||||
|
help: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
LexResult::Err(econtainer)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let label = ErrorLabel {
|
||||||
|
message: String::from(
|
||||||
|
"The code ends here, without completing the floating point number",
|
||||||
),
|
),
|
||||||
}),
|
start: start_pos,
|
||||||
_ => LexResult::Err(LexError {
|
end: start_pos + 1,
|
||||||
position: start_pos,
|
};
|
||||||
end_position: start_pos + 1,
|
let econtainer = ErrorContainer {
|
||||||
reason: String::from("EOF when scanning a double number."),
|
error_code: LEX_INVALID_FLOATING_NUMBER,
|
||||||
}),
|
error_offset: start_pos,
|
||||||
|
labels: vec![label],
|
||||||
|
note: Some(String::from(
|
||||||
|
"Floating point numbers must always have at least 1 digit after the period",
|
||||||
|
)),
|
||||||
|
help: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
LexResult::Err(econtainer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,13 +250,24 @@ fn scan_scientific(chars: &Vec<char>, start_pos: usize, current: String) -> LexR
|
|||||||
let (t, next) = scan_digits(chars, start_pos + 2, new_value);
|
let (t, next) = scan_digits(chars, start_pos + 2, new_value);
|
||||||
LexResult::Some(t, next)
|
LexResult::Some(t, next)
|
||||||
}
|
}
|
||||||
_ => LexResult::Err(LexError {
|
_ => {
|
||||||
position: start_pos,
|
let label = ErrorLabel {
|
||||||
end_position: start_pos + 1,
|
message: String::from("The scientific number ends here, incorrectly"),
|
||||||
reason: String::from(
|
start: start_pos,
|
||||||
"The characters after 'e' are not + or -, or are not followed by a number",
|
end: start_pos + 1,
|
||||||
),
|
};
|
||||||
}),
|
let econtainer = ErrorContainer {
|
||||||
|
error_code: LEX_INVALID_SCIENTIFIC_NUMBER,
|
||||||
|
error_offset: start_pos,
|
||||||
|
labels: vec![label],
|
||||||
|
note: Some(String::from(
|
||||||
|
"Scientific numbers must always have a sign (+ or -) and a digit afterwards: `3.22e+2`"
|
||||||
|
)),
|
||||||
|
help: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
LexResult::Err(econtainer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,7 +405,7 @@ mod tests {
|
|||||||
|
|
||||||
match scan(&input, start_pos) {
|
match scan(&input, start_pos) {
|
||||||
LexResult::Err(reason) => {
|
LexResult::Err(reason) => {
|
||||||
assert_eq!("Tried to scan an incomplete hex value", reason.reason)
|
assert_eq!(reason.error_code, LEX_INVALID_HEX_NUMBER)
|
||||||
}
|
}
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
@ -383,9 +454,8 @@ mod tests {
|
|||||||
let result = scan(&input, 0);
|
let result = scan(&input, 0);
|
||||||
match result {
|
match result {
|
||||||
LexResult::Err(error) => {
|
LexResult::Err(error) => {
|
||||||
assert_eq!(error.position, 0);
|
assert_eq!(error.error_offset, 0);
|
||||||
assert_eq!(error.end_position, 2);
|
assert_eq!(error.error_code, LEX_INVALID_OCTAL_NUMBER)
|
||||||
assert_eq!(error.reason, "Found an incomplete octal number");
|
|
||||||
}
|
}
|
||||||
_ => panic!("Expected an error, got {:?}", result),
|
_ => panic!("Expected an error, got {:?}", result),
|
||||||
}
|
}
|
||||||
@ -412,9 +482,8 @@ mod tests {
|
|||||||
let result = scan(&input, 0);
|
let result = scan(&input, 0);
|
||||||
match result {
|
match result {
|
||||||
LexResult::Err(error) => {
|
LexResult::Err(error) => {
|
||||||
assert_eq!(error.position, 0);
|
assert_eq!(error.error_offset, 0);
|
||||||
assert_eq!(error.end_position, 2);
|
assert_eq!(error.error_code, LEX_INVALID_BINARY_NUMBER)
|
||||||
assert_eq!(error.reason, "Found an incomplete binary number");
|
|
||||||
}
|
}
|
||||||
_ => panic!("Expected an error, got {:?}", result),
|
_ => panic!("Expected an error, got {:?}", result),
|
||||||
}
|
}
|
||||||
@ -453,10 +522,7 @@ mod tests {
|
|||||||
let start_pos = 0;
|
let start_pos = 0;
|
||||||
|
|
||||||
match scan(&input, start_pos) {
|
match scan(&input, start_pos) {
|
||||||
LexResult::Err(reason) => assert_eq!(
|
LexResult::Err(reason) => assert_eq!(reason.error_code, LEX_INVALID_FLOATING_NUMBER),
|
||||||
"The character after the dot when scanning a double is not a number.",
|
|
||||||
reason.reason
|
|
||||||
),
|
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,9 +530,7 @@ mod tests {
|
|||||||
let start_pos = 0;
|
let start_pos = 0;
|
||||||
|
|
||||||
match scan(&input, start_pos) {
|
match scan(&input, start_pos) {
|
||||||
LexResult::Err(reason) => {
|
LexResult::Err(reason) => assert_eq!(reason.error_code, LEX_INVALID_FLOATING_NUMBER),
|
||||||
assert_eq!("EOF when scanning a double number.", reason.reason)
|
|
||||||
}
|
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -567,10 +631,7 @@ mod tests {
|
|||||||
|
|
||||||
match scan(&input, start_pos) {
|
match scan(&input, start_pos) {
|
||||||
LexResult::Err(reason) => {
|
LexResult::Err(reason) => {
|
||||||
assert_eq!(
|
assert_eq!(reason.error_code, LEX_INVALID_SCIENTIFIC_NUMBER)
|
||||||
"The characters after 'e' are not + or -, or are not followed by a number",
|
|
||||||
reason.reason
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
_ => panic!("Expected an error"),
|
_ => panic!("Expected an error"),
|
||||||
}
|
}
|
||||||
@ -583,10 +644,7 @@ mod tests {
|
|||||||
|
|
||||||
match scan(&input, start_pos) {
|
match scan(&input, start_pos) {
|
||||||
LexResult::Err(reason) => {
|
LexResult::Err(reason) => {
|
||||||
assert_eq!(
|
assert_eq!(reason.error_code, LEX_INVALID_SCIENTIFIC_NUMBER)
|
||||||
"The characters after 'e' are not + or -, or are not followed by a number",
|
|
||||||
reason.reason
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
_ => panic!("Expected an error"),
|
_ => panic!("Expected an error"),
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,6 @@ pub enum PPrimary<'a> {
|
|||||||
///
|
///
|
||||||
/// This is a $variable
|
/// This is a $variable
|
||||||
Variable(&'a String),
|
Variable(&'a String),
|
||||||
/// This is a symbol, e.g. a function name
|
// This is a symbol, e.g. a function name
|
||||||
Symbol(&'a String),
|
// Symbol(&'a String),
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
|
||||||
use colored::Colorize;
|
|
||||||
|
|
||||||
use crate::codegen::Transpilable;
|
use crate::codegen::Transpilable;
|
||||||
use crate::error_handling::PrintableError;
|
use crate::error_handling::PrintableError;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
error_handling::{semantic_error::SemanticError, MistiError},
|
error_handling::{semantic_error::SemanticError, MistiError},
|
||||||
semantic::symbol_table::SymbolTable,
|
semantic::symbol_table::SymbolTable,
|
||||||
syntax::ast::{Expression, Positionable},
|
syntax::ast::Expression,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{Type, Typed};
|
use super::{Type, Typed};
|
||||||
|
Loading…
Reference in New Issue
Block a user