This commit is contained in:
Jeff 2024-08-20 04:38:15 -04:00
parent c0ab5a84a2
commit 8b5eb9977c
5 changed files with 88 additions and 30 deletions

View File

@ -37,7 +37,7 @@ pub fn analyze(source: &str) -> Result<(), DustError> {
analyzer
.analyze()
.map_err(|analysis_error| DustError::AnalysisError {
.map_err(|analysis_error| DustError::Analysis {
analysis_error,
source,
})
@ -535,7 +535,7 @@ mod tests {
assert_eq!(
analyze(source),
Err(DustError::AnalysisError {
Err(DustError::Analysis {
analysis_error: AnalysisError::TypeConflict {
actual_expression: Expression::literal(1.0, (45, 48)),
actual_type: Type::Float,
@ -555,7 +555,7 @@ mod tests {
assert_eq!(
analyze(source),
Err(DustError::AnalysisError {
Err(DustError::Analysis {
analysis_error: AnalysisError::TypeConflict {
actual_expression: Expression::literal(1.0, (45, 48)),
actual_type: Type::Float,

View File

@ -240,8 +240,8 @@ impl Expression {
))
}
pub fn r#if(r#if: IfExpression, position: Span) -> Self {
Self::If(Node::new(Box::new(r#if), position))
pub fn r#if(if_expression: IfExpression, position: Span) -> Self {
Self::If(Node::new(Box::new(if_expression), position))
}
pub fn literal<T: Into<LiteralExpression>>(into_literal: T, position: Span) -> Self {
@ -888,6 +888,39 @@ pub enum IfExpression {
},
}
impl IfExpression {
pub fn r#if(condition: Expression, if_block: Node<BlockExpression>) -> Self {
IfExpression::If {
condition,
if_block,
}
}
pub fn if_else(
condition: Expression,
if_block: Node<BlockExpression>,
else_block: Node<BlockExpression>,
) -> Self {
IfExpression::IfElse {
condition,
if_block,
r#else: ElseExpression::Block(else_block),
}
}
pub fn if_else_if(
condition: Expression,
if_block: Node<BlockExpression>,
else_if: Node<Box<IfExpression>>,
) -> Self {
IfExpression::IfElse {
condition,
if_block,
r#else: ElseExpression::If(else_if),
}
}
}
impl Display for IfExpression {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
@ -1010,8 +1043,8 @@ impl Display for LoopExpression {
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum StructExpression {
// The unit struct is omitted because it is redundant with a plain identifier
// The tuple struct is omitted because it is redundant with the call expression
// The unit struct expression is omitted because it is redundant with identifier expressions
// The tuple struct expression is omitted because it is redundant with call expression
Fields {
name: Node<Identifier>,
fields: Vec<(Node<Identifier>, Expression)>,

View File

@ -8,49 +8,74 @@ use crate::{AnalysisError, LexError, ParseError, RuntimeError};
/// corresponding source code.
#[derive(Debug, Clone, PartialEq)]
pub enum DustError<'src> {
VmError {
Runtime {
runtime_error: RuntimeError,
source: &'src str,
},
AnalysisError {
Analysis {
analysis_error: AnalysisError,
source: &'src str,
},
ParseError {
Parse {
parse_error: ParseError,
source: &'src str,
},
LexError {
Lex {
lex_error: LexError,
source: &'src str,
},
}
impl<'src> DustError<'src> {
pub fn runtime(runtime_error: RuntimeError, source: &'src str) -> Self {
DustError::Runtime {
runtime_error,
source,
}
}
pub fn analysis(analysis_error: AnalysisError, source: &'src str) -> Self {
DustError::Analysis {
analysis_error,
source,
}
}
pub fn parse(parse_error: ParseError, source: &'src str) -> Self {
DustError::Parse {
parse_error,
source,
}
}
pub fn lex(lex_error: LexError, source: &'src str) -> Self {
DustError::Lex { lex_error, source }
}
pub fn title(&self) -> &'static str {
match self {
DustError::VmError { .. } => "Runtime error",
DustError::AnalysisError { .. } => "Analysis error",
DustError::ParseError { .. } => "Parse error",
DustError::LexError { .. } => "Lex error",
DustError::Runtime { .. } => "Runtime error",
DustError::Analysis { .. } => "Analysis error",
DustError::Parse { .. } => "Parse error",
DustError::Lex { .. } => "Lex error",
}
}
pub fn position(&self) -> (usize, usize) {
match self {
DustError::VmError { runtime_error, .. } => runtime_error.position(),
DustError::AnalysisError { analysis_error, .. } => analysis_error.position(),
DustError::ParseError { parse_error, .. } => parse_error.position(),
DustError::LexError { lex_error, .. } => lex_error.position(),
DustError::Runtime { runtime_error, .. } => runtime_error.position(),
DustError::Analysis { analysis_error, .. } => analysis_error.position(),
DustError::Parse { parse_error, .. } => parse_error.position(),
DustError::Lex { lex_error, .. } => lex_error.position(),
}
}
pub fn source(&self) -> &'src str {
match self {
DustError::VmError { source, .. } => source,
DustError::AnalysisError { source, .. } => source,
DustError::ParseError { source, .. } => source,
DustError::LexError { source, .. } => source,
DustError::Runtime { source, .. } => source,
DustError::Analysis { source, .. } => source,
DustError::Parse { source, .. } => source,
DustError::Lex { source, .. } => source,
}
}
@ -71,10 +96,10 @@ impl<'src> DustError<'src> {
impl Display for DustError<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
DustError::VmError { runtime_error, .. } => write!(f, "{runtime_error}"),
DustError::AnalysisError { analysis_error, .. } => write!(f, "{analysis_error}"),
DustError::ParseError { parse_error, .. } => write!(f, "{parse_error}"),
DustError::LexError { lex_error, .. } => write!(f, "{lex_error}"),
DustError::Runtime { runtime_error, .. } => write!(f, "{runtime_error}"),
DustError::Analysis { analysis_error, .. } => write!(f, "{analysis_error}"),
DustError::Parse { parse_error, .. } => write!(f, "{parse_error}"),
DustError::Lex { lex_error, .. } => write!(f, "{lex_error}"),
}
}
}

View File

@ -61,7 +61,7 @@ pub fn parse_into<'src>(
loop {
let node = parser
.parse_statement()
.map_err(|parse_error| DustError::ParseError {
.map_err(|parse_error| DustError::Parse {
parse_error,
source,
})?;

View File

@ -61,14 +61,14 @@ pub fn run_with_context(source: &str, context: Context) -> Result<Option<Value>,
analyzer
.analyze()
.map_err(|analysis_error| DustError::AnalysisError {
.map_err(|analysis_error| DustError::Analysis {
analysis_error,
source,
})?;
let mut vm = Vm::new(abstract_syntax_tree, context);
vm.run().map_err(|runtime_error| DustError::VmError {
vm.run().map_err(|runtime_error| DustError::Runtime {
runtime_error,
source,
})