begin new error system, unfinished
This commit is contained in:
parent
32c2a20697
commit
532fffe725
6 changed files with 673 additions and 237 deletions
220
src/errors.rs
Normal file
220
src/errors.rs
Normal file
|
@ -0,0 +1,220 @@
|
|||
use std::f32::consts::E;
|
||||
|
||||
use crate::Context;
|
||||
|
||||
pub enum ErrorType {
|
||||
SyntaxError,
|
||||
SemanticError,
|
||||
TypeError,
|
||||
MathError,
|
||||
MachineError,
|
||||
}
|
||||
|
||||
pub enum ErrorSubType {
|
||||
//Syntax errors
|
||||
UnexpectedEnd,
|
||||
Expected,
|
||||
Unexpected,
|
||||
UnknownOperation,
|
||||
InvalidTableKeys,
|
||||
Unclosed,
|
||||
//Semantic errors
|
||||
ElseWithoutIf,
|
||||
BreakContinueWithoutLoop,
|
||||
UnexpectedOperation,
|
||||
VariableNotFound,
|
||||
VariableAlreadyExists,
|
||||
ArgumentDuplication,
|
||||
//Machine errors
|
||||
RegisterNotFound,
|
||||
MemoryOutOfBounds,
|
||||
UnknownOPCode,
|
||||
UnknownFunction,
|
||||
UnknownString,
|
||||
UnknownMemoryLocation,
|
||||
NonFunctionCall,
|
||||
//Math errors
|
||||
DivisionByZero,
|
||||
//Type errors
|
||||
InvalidType,
|
||||
WrongType,
|
||||
NonStringKey,
|
||||
}
|
||||
|
||||
pub struct ASLError {
|
||||
pub message: String,
|
||||
pub position: usize,
|
||||
pub typ: ErrorType,
|
||||
pub subtype: ErrorSubType,
|
||||
pub code: String,
|
||||
}
|
||||
|
||||
fn convert_types_to_string(typ: &ErrorType) -> String {
|
||||
match typ {
|
||||
ErrorType::SyntaxError => String::from("Syntax Error: "),
|
||||
ErrorType::TypeError => String::from("Type Error: "),
|
||||
ErrorType::MathError => String::from("Math Error: "),
|
||||
ErrorType::SemanticError => String::from("Semantic Error: "),
|
||||
ErrorType::MachineError => String::from("Machine Error: "),
|
||||
}
|
||||
}
|
||||
fn convert_types_to_short(typ: &ErrorType) -> String {
|
||||
match typ {
|
||||
ErrorType::SyntaxError => String::from("ST:"),
|
||||
ErrorType::TypeError => String::from("TP:"),
|
||||
ErrorType::MathError => String::from("MT:"),
|
||||
ErrorType::SemanticError => String::from("SM:"),
|
||||
ErrorType::MachineError => String::from("MC:"),
|
||||
}
|
||||
}
|
||||
fn convert_subtypes_to_string(stype: &ErrorSubType) -> String {
|
||||
match stype {
|
||||
ErrorSubType::UnexpectedEnd => String::from("Unexpected end"),
|
||||
ErrorSubType::UnexpectedOperation => String::from("Unexpected operation"),
|
||||
ErrorSubType::Expected => String::from("Expected"),
|
||||
ErrorSubType::Unexpected => String::from("Unexpected"),
|
||||
ErrorSubType::InvalidTableKeys => String::from("Invalid table keys"),
|
||||
ErrorSubType::Unclosed => String::from("Unclosed structure"),
|
||||
ErrorSubType::ElseWithoutIf => String::from("Else/elseif without if"),
|
||||
ErrorSubType::BreakContinueWithoutLoop => String::from("Break/continue without loop"),
|
||||
ErrorSubType::UnknownOperation => String::from("Unknown operation"),
|
||||
ErrorSubType::VariableNotFound => String::from("Variable not found"),
|
||||
ErrorSubType::VariableAlreadyExists => String::from("Variable already exists"),
|
||||
ErrorSubType::ArgumentDuplication => String::from("Argument duplication"),
|
||||
ErrorSubType::RegisterNotFound => String::from("Register not found"),
|
||||
ErrorSubType::MemoryOutOfBounds => String::from("Memory out of bounds"),
|
||||
ErrorSubType::UnknownOPCode => String::from("Unknown OP code"),
|
||||
ErrorSubType::UnknownFunction => String::from("Unknown function"),
|
||||
ErrorSubType::UnknownString => String::from("Unknown string"),
|
||||
ErrorSubType::UnknownMemoryLocation => String::from("Unknown memory location"),
|
||||
ErrorSubType::NonFunctionCall => String::from("Non-function call"),
|
||||
ErrorSubType::DivisionByZero => String::from("Division by zero"),
|
||||
ErrorSubType::InvalidType => String::from("Invalid type"),
|
||||
ErrorSubType::WrongType => String::from("Wrong type"),
|
||||
ErrorSubType::NonStringKey => String::from("Non-string key"),
|
||||
}
|
||||
}
|
||||
fn convert_subtypes_to_short(stype: &ErrorSubType) -> String {
|
||||
match stype {
|
||||
ErrorSubType::UnexpectedEnd => String::from("UE:"),
|
||||
ErrorSubType::UnexpectedOperation => String::from("UP:"),
|
||||
ErrorSubType::Expected => String::from("EX:"),
|
||||
ErrorSubType::Unexpected => String::from("UN:"),
|
||||
ErrorSubType::InvalidTableKeys => String::from("IK:"),
|
||||
ErrorSubType::Unclosed => String::from("UC:"),
|
||||
ErrorSubType::ElseWithoutIf => String::from("EW:"),
|
||||
ErrorSubType::BreakContinueWithoutLoop => String::from("BC:"),
|
||||
ErrorSubType::UnknownOperation => String::from("UO:"),
|
||||
ErrorSubType::VariableNotFound => String::from("VN:"),
|
||||
ErrorSubType::VariableAlreadyExists => String::from("VE:"),
|
||||
ErrorSubType::ArgumentDuplication => String::from("AD:"),
|
||||
ErrorSubType::RegisterNotFound => String::from("RF:"),
|
||||
ErrorSubType::MemoryOutOfBounds => String::from("MO:"),
|
||||
ErrorSubType::UnknownOPCode => String::from("OC:"),
|
||||
ErrorSubType::UnknownFunction => String::from("UF:"),
|
||||
ErrorSubType::UnknownString => String::from("US:"),
|
||||
ErrorSubType::UnknownMemoryLocation => String::from("UM:"),
|
||||
ErrorSubType::NonFunctionCall => String::from("NF:"),
|
||||
ErrorSubType::DivisionByZero => String::from("DZ:"),
|
||||
ErrorSubType::InvalidType => String::from("IT:"),
|
||||
ErrorSubType::WrongType => String::from("WT:"),
|
||||
ErrorSubType::NonStringKey => String::from("NS:"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_error(message: &str, position: usize, typ: ErrorType, stype: ErrorSubType) -> ASLError {
|
||||
let mut code = convert_types_to_short(&typ);
|
||||
code.push_str(&convert_subtypes_to_short(&stype));
|
||||
code.push_str(&position.to_string());
|
||||
ASLError {
|
||||
message: String::from(message),
|
||||
position,
|
||||
typ,
|
||||
subtype: stype,
|
||||
code,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_exact_pos(file: &String, pos: usize) -> (usize, usize) {
|
||||
let mut line = 1;
|
||||
let mut column = 1;
|
||||
for (i, c) in file.char_indices() {
|
||||
if i == pos {
|
||||
return (line, column);
|
||||
}
|
||||
if c == '\n' {
|
||||
line += 1;
|
||||
column = 1;
|
||||
} else {
|
||||
column += 1;
|
||||
}
|
||||
}
|
||||
(line, column)
|
||||
}
|
||||
fn get_sorrunding_lines(file: &String, line: usize) -> (String, String, String) {
|
||||
let lines = file.lines();
|
||||
let mut before = String::new();
|
||||
let mut current = String::new();
|
||||
let mut after = String::new();
|
||||
let mut current_line = 1;
|
||||
for l in lines {
|
||||
if current_line == line - 1 {
|
||||
before = l.to_string();
|
||||
} else if current_line == line {
|
||||
current = l.to_string();
|
||||
} else if current_line == line + 1 {
|
||||
after = l.to_string();
|
||||
break;
|
||||
}
|
||||
current_line += 1;
|
||||
}
|
||||
(before, current, after)
|
||||
}
|
||||
|
||||
pub fn print_error(error: &ASLError, ctx: &Context) {
|
||||
let mut out = String::new();
|
||||
out.push_str(&convert_types_to_string(&error.typ));
|
||||
if error.message.len() > 0 {
|
||||
out.push_str(&convert_subtypes_to_string(&error.subtype));
|
||||
} else {
|
||||
out.push_str(&error.message);
|
||||
}
|
||||
out.push_str(" at position ");
|
||||
|
||||
let (line, column) = get_exact_pos(&ctx.raw_file, error.position);
|
||||
out.push_str(&ctx.file);
|
||||
out.push_str(":");
|
||||
out.push_str(&line.to_string());
|
||||
out.push_str(":");
|
||||
out.push_str(&column.to_string());
|
||||
|
||||
out.push_str("\n");
|
||||
let (before, current, after) = get_sorrunding_lines(&ctx.raw_file, line);
|
||||
if line > 1 {
|
||||
out.push_str(&(line-1).to_string());
|
||||
out.push_str(" | ");
|
||||
} else {
|
||||
out.push_str(" | ");
|
||||
}
|
||||
out.push_str(&before);
|
||||
out.push_str("\n");
|
||||
out.push_str(&line.to_string());
|
||||
out.push_str(" | ");
|
||||
out.push_str(¤t);
|
||||
|
||||
out.push_str("\n");
|
||||
out.push_str(" ");
|
||||
out.push_str(&" ".repeat(column - 1));
|
||||
out.push_str("^ ");
|
||||
out.push_str(&error.message);
|
||||
|
||||
out.push_str("\n");
|
||||
out.push_str(&(line+1).to_string());
|
||||
out.push_str(" | ");
|
||||
out.push_str(&after);
|
||||
|
||||
out.push_str("\n");
|
||||
out.push_str("Error Code: ");
|
||||
out.push_str(&error.code);
|
||||
println!("{}", out);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue