use crate::{
io::UnpackError,
report::{Report, Reporter},
span::{Span, Spanned},
token::TokenKind,
};
use std::{ffi::OsString, fmt, io::Write};
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub enum ParserError {
SyntaxError(String),
UnexpectedType,
InvalidDefinition,
InvalidConstantValue,
InvalidConstant,
InvalidName,
InvalidArgs,
InvalidMacroArgs,
InvalidReturnArgs,
InvalidImportPath,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct LexicalError<'a> {
pub kind: LexicalErrorKind<'a>,
pub span: Span,
}
impl<'a> LexicalError<'a> {
pub fn new(kind: LexicalErrorKind<'a>, span: Span) -> Self {
Self { kind, span }
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum LexicalErrorKind<'a> {
UnexpectedEof,
InvalidCharacter(char),
InvalidArraySize(&'a str),
InvalidPrimitiveType(&'a str),
}
impl<'a> Spanned for LexicalError<'a> {
fn span(&self) -> Span {
self.span
}
}
impl<'a, W: Write> Report<W> for LexicalError<'a> {
fn report(&self, f: &mut Reporter<'_, W>) -> std::io::Result<()> {
match self.kind {
LexicalErrorKind::InvalidCharacter(ch) => write!(f.out, "Invalid character '{}'", ch),
LexicalErrorKind::UnexpectedEof => write!(f.out, "Found unexpected EOF"),
LexicalErrorKind::InvalidArraySize(str) => {
write!(f.out, "Invalid array size: '{}'", str)
}
LexicalErrorKind::InvalidPrimitiveType(str) => {
write!(f.out, "Invalid Primitive EVM Type '{}'", str)
}
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct CodegenError {
pub kind: CodegenErrorKind,
pub span: Option<Span>,
pub token: Option<TokenKind>,
}
impl CodegenError {
pub fn new(kind: CodegenErrorKind, span: Option<Span>, token: Option<TokenKind>) -> Self {
Self { kind, span, token }
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum CodegenErrorKind {
InvalidOperator,
MissingAst,
MissingConstructor,
InvalidMacroStatement,
MissingMacroDefinition,
FailedMacroRecursion,
MissingConstantDefinition,
}
impl Spanned for CodegenError {
fn span(&self) -> Span {
self.span.unwrap()
}
}
impl<W: Write> Report<W> for CodegenError {
fn report(&self, f: &mut Reporter<'_, W>) -> std::io::Result<()> {
match self.kind {
CodegenErrorKind::InvalidOperator => write!(f.out, "Invalid operator!"),
CodegenErrorKind::MissingAst => write!(f.out, "Codegen is missing an AST!"),
CodegenErrorKind::MissingConstructor => write!(f.out, "AST missing constructor macro!"),
CodegenErrorKind::InvalidMacroStatement => write!(f.out, "Invalid Macro Statement!"),
CodegenErrorKind::MissingMacroDefinition => write!(f.out, "Missing Macro Definition!"),
CodegenErrorKind::FailedMacroRecursion => write!(f.out, "Failed Macro Recursion!"),
CodegenErrorKind::MissingConstantDefinition => {
write!(f.out, "Missing Constant Definition!")
}
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CompilerError<'a> {
LexicalError(LexicalError<'a>),
FileUnpackError(UnpackError),
ParserError(ParserError),
PathBufRead(OsString),
CodegenError(CodegenError),
}
impl<'a> fmt::Display for CompilerError<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CompilerError::LexicalError(le) => write!(f, "LexicalError({:?})", le),
CompilerError::FileUnpackError(ue) => write!(f, "FileUnpackError({:?})", ue),
CompilerError::ParserError(pe) => write!(f, "ParserError({:?})", pe),
CompilerError::PathBufRead(os_str) => write!(f, "PathBufRead({:?})", os_str),
CompilerError::CodegenError(ce) => write!(f, "CodegenError({:?})", ce),
}
}
}