add pretty diagnostics

This commit is contained in:
Romain Paquet 2024-07-03 19:59:12 +02:00
parent e157bf036a
commit f415c4abbe
12 changed files with 1037 additions and 603 deletions

View file

@ -1,9 +1,11 @@
pub mod expr;
pub use expr::Expr;
pub use expr::{BinaryExpression, Expr, SExpr};
use crate::typing::Type;
use std::path::Path;
use ariadne;
use std::{fmt::Display, path::Path};
#[derive(Debug, PartialEq, Clone)]
pub enum BinaryOperator {
@ -20,6 +22,22 @@ pub enum BinaryOperator {
NotEqual,
}
impl Display for BinaryOperator {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
BinaryOperator::And => "&&",
BinaryOperator::Or => "||",
BinaryOperator::Add => "+",
BinaryOperator::Sub => "-",
BinaryOperator::Mul => "*",
BinaryOperator::Div => "/",
BinaryOperator::Modulo => "%",
BinaryOperator::Equal => "==",
BinaryOperator::NotEqual => "!=",
})
}
}
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum UnaryOperator {
Not,
@ -27,12 +45,32 @@ pub enum UnaryOperator {
pub type Identifier = String;
#[derive(Debug, PartialEq)]
pub struct Location {
pub line_col: (usize, usize),
pub type SourceId = u32;
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct Span {
pub source: SourceId,
pub start: usize,
pub end: usize,
}
#[derive(Debug, PartialEq, Clone, Default)]
impl ariadne::Span for Span {
type SourceId = SourceId;
fn source(&self) -> &Self::SourceId {
&self.source
}
fn start(&self) -> usize {
self.start
}
fn end(&self) -> usize {
self.end
}
}
#[derive(Debug, PartialEq, Clone, Default, Eq, Hash)]
pub struct ModulePath {
components: Vec<String>,
}
@ -65,7 +103,7 @@ impl From<&Path> for ModulePath {
.map(|component| match component {
std::path::Component::Normal(n) => {
if meta.is_file() {
n.to_str().unwrap().split(".").nth(0).unwrap().to_string()
n.to_str().unwrap().split('.').nth(0).unwrap().to_string()
} else if meta.is_dir() {
n.to_str().unwrap().to_string()
} else {
@ -91,22 +129,51 @@ impl From<&str> for ModulePath {
#[derive(Eq, PartialEq, Debug)]
pub struct Import(pub String);
#[derive(Debug, PartialEq)]
pub struct ReturnStatement {
pub expr: Option<SExpr>,
pub span: Span,
}
#[derive(Debug, PartialEq)]
pub enum Statement {
DeclareStatement(Identifier, Box<Expr>),
AssignStatement(Identifier, Box<Expr>),
ReturnStatement(Option<Expr>),
CallStatement(Box<Call>),
UseStatement(Box<Import>),
IfStatement(Box<Expr>, Box<Block>),
WhileStatement(Box<Expr>, Box<Block>),
DeclareStatement {
lhs: Identifier,
rhs: Box<SExpr>,
span: Span,
},
AssignStatement {
lhs: Identifier,
rhs: Box<SExpr>,
span: Span,
},
ReturnStatement(ReturnStatement),
CallStatement {
call: Box<Call>,
span: Span,
},
UseStatement {
import: Box<Import>,
span: Span,
},
IfStatement {
condition: Box<SExpr>,
then_block: Box<Block>,
span: Span,
},
WhileStatement {
condition: Box<SExpr>,
loop_block: Box<Block>,
span: Span,
},
}
#[derive(Debug, PartialEq)]
pub struct Block {
pub statements: Vec<Statement>,
pub value: Option<Expr>,
pub value: Option<SExpr>,
pub typ: Type,
pub span: Option<Span>,
}
impl Block {
@ -115,6 +182,7 @@ impl Block {
typ: Type::Unit,
statements: Vec::with_capacity(0),
value: None,
span: None,
}
}
}
@ -129,8 +197,9 @@ pub struct FunctionDefinition {
pub name: Identifier,
pub parameters: Vec<Parameter>,
pub return_type: Option<Type>,
pub return_type_span: Option<Span>,
pub body: Box<Block>,
pub location: Location,
pub span: Span,
}
#[derive(Debug, PartialEq, Default)]
@ -159,8 +228,8 @@ impl Module {
#[derive(Debug, PartialEq)]
pub struct Call {
pub callee: Box<Expr>,
pub args: Vec<Expr>,
pub callee: Box<SExpr>,
pub args: Vec<SExpr>,
pub typ: Type,
}