1
0

Add native function errors

This commit is contained in:
Jeff 2024-10-30 09:32:46 -04:00
parent 382d43ef77
commit bd23853657
4 changed files with 69 additions and 31 deletions

View File

@ -18,7 +18,7 @@ pub use formatter::{format, Formatter};
pub use identifier::Identifier;
pub use instruction::Instruction;
pub use lexer::{lex, LexError, Lexer};
pub use native_function::NativeFunction;
pub use native_function::{NativeFunction, NativeFunctionError};
pub use operation::Operation;
pub use parser::{parse, ParseError, Parser};
pub use r#type::{EnumType, FunctionType, RangeableType, StructType, Type, TypeConflict};

View File

@ -1,11 +1,12 @@
use std::{
fmt::{self, Display, Formatter},
io::{self, stdin, stdout, Write},
string::{self},
};
use serde::{Deserialize, Serialize};
use crate::{Instruction, Primitive, Span, Value, Vm, VmError};
use crate::{AnnotatedError, Instruction, Primitive, Span, Value, Vm, VmError};
const PANIC: u8 = 0b0000_0000;
@ -252,7 +253,10 @@ impl NativeFunction {
Some(message)
};
return Err(VmError::Panic { message, position });
return Err(VmError::NativeFunction(NativeFunctionError::Panic {
message,
position,
}));
}
// Type conversion
@ -321,12 +325,12 @@ impl NativeFunction {
NativeFunction::ReadLine => {
let mut buffer = String::new();
stdin()
.read_line(&mut buffer)
.map_err(|io_error| VmError::Io {
stdin().read_line(&mut buffer).map_err(|io_error| {
VmError::NativeFunction(NativeFunctionError::Io {
error: io_error.kind(),
position,
})?;
})
})?;
buffer = buffer.trim_end_matches('\n').to_string();
@ -335,9 +339,11 @@ impl NativeFunction {
NativeFunction::Write => {
let to_register = instruction.a();
let mut stdout = stdout();
let map_err = |io_error: io::Error| VmError::Io {
error: io_error.kind(),
position,
let map_err = |io_error: io::Error| {
VmError::NativeFunction(NativeFunctionError::Io {
error: io_error.kind(),
position,
})
};
let first_argument = to_register.saturating_sub(argument_count);
@ -359,9 +365,11 @@ impl NativeFunction {
}
NativeFunction::WriteLine => {
let mut stdout = stdout();
let map_err = |io_error: io::Error| VmError::Io {
error: io_error.kind(),
position,
let map_err = |io_error: io::Error| {
VmError::NativeFunction(NativeFunctionError::Io {
error: io_error.kind(),
position,
})
};
let first_argument = to_register.saturating_sub(argument_count);
@ -523,3 +531,42 @@ impl Display for NativeFunction {
write!(f, "{}", self.as_str())
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum NativeFunctionError {
ExpectedArgumentCount {
expected: usize,
found: usize,
position: Span,
},
Panic {
message: Option<String>,
position: Span,
},
Parse {
error: string::ParseError,
position: Span,
},
Io {
error: io::ErrorKind,
position: Span,
},
}
impl AnnotatedError for NativeFunctionError {
fn title() -> &'static str {
todo!()
}
fn description(&self) -> &'static str {
todo!()
}
fn details(&self) -> Option<String> {
todo!()
}
fn position(&self) -> Span {
todo!()
}
}

View File

@ -1,8 +1,9 @@
use std::{cmp::Ordering, io, mem::replace};
use std::{cmp::Ordering, mem::replace};
use crate::{
parse, value::Primitive, AnnotatedError, Chunk, ChunkError, DustError, FunctionType,
Identifier, Instruction, NativeFunction, Operation, Span, Type, Value, ValueError,
Identifier, Instruction, NativeFunction, NativeFunctionError, Operation, Span, Type, Value,
ValueError,
};
pub fn run(source: &str) -> Result<Option<Value>, DustError> {
@ -636,10 +637,6 @@ pub enum VmError {
found: Value,
position: Span,
},
Panic {
message: Option<String>,
position: Span,
},
RegisterIndexOutOfBounds {
index: usize,
position: Span,
@ -660,11 +657,8 @@ pub enum VmError {
},
// Wrappers for foreign errors
NativeFunction(NativeFunctionError),
Chunk(ChunkError),
Io {
error: io::ErrorKind,
position: Span,
},
Value {
error: ValueError,
position: Span,
@ -688,14 +682,13 @@ impl AnnotatedError for VmError {
Self::EmptyRegister { .. } => "Empty register",
Self::ExpectedBoolean { .. } => "Expected boolean",
Self::ExpectedFunction { .. } => "Expected function",
Self::Panic { .. } => "Explicit Panic",
Self::RegisterIndexOutOfBounds { .. } => "Register index out of bounds",
Self::InvalidInstruction { .. } => "Invalid instruction",
Self::StackOverflow { .. } => "Stack overflow",
Self::StackUnderflow { .. } => "Stack underflow",
Self::UndefinedVariable { .. } => "Undefined variable",
Self::Chunk(error) => error.description(),
Self::Io { .. } => "I/O error",
Self::NativeFunction(error) => error.description(),
Self::Value { .. } => "Value error",
}
}
@ -704,7 +697,6 @@ impl AnnotatedError for VmError {
match self {
Self::EmptyRegister { index, .. } => Some(format!("Register {index} is empty")),
Self::ExpectedFunction { found, .. } => Some(format!("{found} is not a function")),
Self::Panic { message, .. } => message.clone(),
Self::RegisterIndexOutOfBounds { index, .. } => {
Some(format!("Register {index} does not exist"))
}
@ -712,7 +704,7 @@ impl AnnotatedError for VmError {
Some(format!("{identifier} is not in scope"))
}
Self::Chunk(error) => error.details(),
Self::Io { error, .. } => Some(error.to_string()),
Self::NativeFunction(error) => error.details(),
Self::Value { error, .. } => Some(error.to_string()),
_ => None,
}
@ -724,14 +716,13 @@ impl AnnotatedError for VmError {
Self::EmptyRegister { position, .. } => *position,
Self::ExpectedBoolean { position, .. } => *position,
Self::ExpectedFunction { position, .. } => *position,
Self::Panic { position, .. } => *position,
Self::RegisterIndexOutOfBounds { position, .. } => *position,
Self::InvalidInstruction { position, .. } => *position,
Self::StackUnderflow { position } => *position,
Self::StackOverflow { position } => *position,
Self::UndefinedVariable { position, .. } => *position,
Self::Chunk(error) => error.position(),
Self::Io { position, .. } => *position,
Self::NativeFunction(error) => error.position(),
Self::Value { position, .. } => *position,
}
}

View File

@ -24,10 +24,10 @@ fn panic() {
assert_eq!(
run(source),
Err(DustError::Runtime {
error: VmError::Panic {
error: VmError::NativeFunction(NativeFunctionError::Panic {
message: Some("Goodbye world! 42".to_string()),
position: Span(0, 27)
},
}),
source
})
)