mirror of
https://github.com/MorizzG/rlox.git
synced 2025-12-06 04:12:42 +00:00
67 lines
1.7 KiB
Rust
67 lines
1.7 KiB
Rust
use itertools::Itertools;
|
|
use rlox2_frontend::lexer::{CodePos, LexerError};
|
|
use thiserror::Error;
|
|
|
|
use crate::{Opcode, Value};
|
|
|
|
#[derive(Error, Debug)]
|
|
pub enum CompilerError {
|
|
#[error("Missing closing parenthesis at {code_pos}")]
|
|
MissingRightParen { code_pos: CodePos },
|
|
#[error("{msg}")]
|
|
Todo { msg: String },
|
|
}
|
|
|
|
#[derive(Error, Debug)]
|
|
pub enum RuntimeError {
|
|
#[error("Opcopde {opcode} had invalid operand {operand}")]
|
|
UnaryInvalidOperand { opcode: Opcode, operand: Value },
|
|
#[error("Opcopde {opcode} had invalid operands {left} and {right}")]
|
|
BinaryInvalidOperand {
|
|
opcode: Opcode,
|
|
left: Value,
|
|
right: Value,
|
|
},
|
|
#[error("Division by zero")]
|
|
DivisionByZero,
|
|
}
|
|
|
|
#[derive(Error, Debug)]
|
|
pub enum LoxError {
|
|
#[error("{0}", format_multiple_errors(inner))]
|
|
LexerError { inner: Vec<LexerError> },
|
|
#[error("{inner}")]
|
|
CompileError { inner: CompilerError },
|
|
#[error("{inner}")]
|
|
RuntimeError { inner: RuntimeError },
|
|
#[error("Called exit() with exit code {exit_code}")]
|
|
Exit { exit_code: i32 },
|
|
}
|
|
|
|
impl From<Vec<LexerError>> for LoxError {
|
|
fn from(lexer_errs: Vec<LexerError>) -> Self {
|
|
LoxError::LexerError { inner: lexer_errs }
|
|
}
|
|
}
|
|
|
|
impl From<CompilerError> for LoxError {
|
|
fn from(compile_err: CompilerError) -> Self {
|
|
LoxError::CompileError { inner: compile_err }
|
|
}
|
|
}
|
|
|
|
impl From<RuntimeError> for LoxError {
|
|
fn from(runtime_err: RuntimeError) -> Self {
|
|
LoxError::RuntimeError { inner: runtime_err }
|
|
}
|
|
}
|
|
|
|
fn format_multiple_errors(errs: &[impl std::error::Error]) -> String {
|
|
let msg = if errs.len() == 1 {
|
|
errs[0].to_string()
|
|
} else {
|
|
errs.iter().map(|err| err.to_string()).join("\n")
|
|
};
|
|
|
|
msg
|
|
}
|