lemonlang 0.0.3

an experimental, modern, purely safe, programming language.
use crate::{
	diag::{self, Diag, Severity},
	range::Range,
};

#[derive(Debug, Clone)]
pub enum EngineError {
	StackOverflow { fn_name: String },
	StackUnderflow,
	RegisterNotFound { reg: usize },
	UninitializedRegister { reg: usize },
	DivisionByZero { location: String },
	InvalidInstruction { instr: String },
	ComptimeError { message: String },
}

impl EngineError {
	pub fn stack_overflow(fn_name: String) -> Diag {
		Self::StackOverflow { fn_name }.into()
	}

	pub fn stack_underflow() -> Diag {
		Self::StackUnderflow.into()
	}

	pub fn register_not_found(reg: usize) -> Diag {
		Self::RegisterNotFound { reg }.into()
	}

	pub fn uninitialized_register(reg: usize) -> Diag {
		Self::UninitializedRegister { reg }.into()
	}

	pub fn division_by_zero(location: String) -> Diag {
		Self::DivisionByZero { location }.into()
	}

	pub fn invalid_instruction(instr: String) -> Diag {
		Self::InvalidInstruction { instr }.into()
	}

	pub fn comptime_error(message: String) -> Diag {
		Self::ComptimeError { message }.into()
	}
}
impl From<EngineError> for diag::Diag {
	fn from(err: EngineError) -> Self {
		match err {
			EngineError::StackOverflow { fn_name } => {
				let text = format!("stack overflow in function '{}'", fn_name);
				diag::Diag::new(Severity::Err, text, Range::default())
			}
			EngineError::StackUnderflow => {
				let text = "stack underflow".to_string();
				diag::Diag::new(Severity::Err, text, Range::default())
			}
			EngineError::RegisterNotFound { reg } => {
				let text = format!("register not found '{}'", reg);
				diag::Diag::new(Severity::Err, text, Range::default())
			}
			EngineError::UninitializedRegister { reg } => {
				let text = format!("register '{}' is not initialized", reg);
				diag::Diag::new(Severity::Err, text, Range::default())
			}
			EngineError::DivisionByZero { location } => {
				let text = format!("division by zero at '{}'", location);
				diag::Diag::new(Severity::Err, text, Range::default())
			}
			EngineError::InvalidInstruction { instr } => {
				let text = format!("invalid instruction '{}'", instr);
				diag::Diag::new(Severity::Err, text, Range::default())
			}
			EngineError::ComptimeError { message } => {
				let text = format!("comptime error: {}", message);
				diag::Diag::new(Severity::Err, text, Range::default())
			}
		}
	}
}