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 identifier::Identifier;
pub use instruction::Instruction; pub use instruction::Instruction;
pub use lexer::{lex, LexError, Lexer}; pub use lexer::{lex, LexError, Lexer};
pub use native_function::NativeFunction; pub use native_function::{NativeFunction, NativeFunctionError};
pub use operation::Operation; pub use operation::Operation;
pub use parser::{parse, ParseError, Parser}; pub use parser::{parse, ParseError, Parser};
pub use r#type::{EnumType, FunctionType, RangeableType, StructType, Type, TypeConflict}; pub use r#type::{EnumType, FunctionType, RangeableType, StructType, Type, TypeConflict};

View File

@ -1,11 +1,12 @@
use std::{ use std::{
fmt::{self, Display, Formatter}, fmt::{self, Display, Formatter},
io::{self, stdin, stdout, Write}, io::{self, stdin, stdout, Write},
string::{self},
}; };
use serde::{Deserialize, Serialize}; 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; const PANIC: u8 = 0b0000_0000;
@ -252,7 +253,10 @@ impl NativeFunction {
Some(message) Some(message)
}; };
return Err(VmError::Panic { message, position }); return Err(VmError::NativeFunction(NativeFunctionError::Panic {
message,
position,
}));
} }
// Type conversion // Type conversion
@ -321,12 +325,12 @@ impl NativeFunction {
NativeFunction::ReadLine => { NativeFunction::ReadLine => {
let mut buffer = String::new(); let mut buffer = String::new();
stdin() stdin().read_line(&mut buffer).map_err(|io_error| {
.read_line(&mut buffer) VmError::NativeFunction(NativeFunctionError::Io {
.map_err(|io_error| VmError::Io {
error: io_error.kind(), error: io_error.kind(),
position, position,
})?; })
})?;
buffer = buffer.trim_end_matches('\n').to_string(); buffer = buffer.trim_end_matches('\n').to_string();
@ -335,9 +339,11 @@ impl NativeFunction {
NativeFunction::Write => { NativeFunction::Write => {
let to_register = instruction.a(); let to_register = instruction.a();
let mut stdout = stdout(); let mut stdout = stdout();
let map_err = |io_error: io::Error| VmError::Io { let map_err = |io_error: io::Error| {
error: io_error.kind(), VmError::NativeFunction(NativeFunctionError::Io {
position, error: io_error.kind(),
position,
})
}; };
let first_argument = to_register.saturating_sub(argument_count); let first_argument = to_register.saturating_sub(argument_count);
@ -359,9 +365,11 @@ impl NativeFunction {
} }
NativeFunction::WriteLine => { NativeFunction::WriteLine => {
let mut stdout = stdout(); let mut stdout = stdout();
let map_err = |io_error: io::Error| VmError::Io { let map_err = |io_error: io::Error| {
error: io_error.kind(), VmError::NativeFunction(NativeFunctionError::Io {
position, error: io_error.kind(),
position,
})
}; };
let first_argument = to_register.saturating_sub(argument_count); let first_argument = to_register.saturating_sub(argument_count);
@ -523,3 +531,42 @@ impl Display for NativeFunction {
write!(f, "{}", self.as_str()) 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::{ use crate::{
parse, value::Primitive, AnnotatedError, Chunk, ChunkError, DustError, FunctionType, 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> { pub fn run(source: &str) -> Result<Option<Value>, DustError> {
@ -636,10 +637,6 @@ pub enum VmError {
found: Value, found: Value,
position: Span, position: Span,
}, },
Panic {
message: Option<String>,
position: Span,
},
RegisterIndexOutOfBounds { RegisterIndexOutOfBounds {
index: usize, index: usize,
position: Span, position: Span,
@ -660,11 +657,8 @@ pub enum VmError {
}, },
// Wrappers for foreign errors // Wrappers for foreign errors
NativeFunction(NativeFunctionError),
Chunk(ChunkError), Chunk(ChunkError),
Io {
error: io::ErrorKind,
position: Span,
},
Value { Value {
error: ValueError, error: ValueError,
position: Span, position: Span,
@ -688,14 +682,13 @@ impl AnnotatedError for VmError {
Self::EmptyRegister { .. } => "Empty register", Self::EmptyRegister { .. } => "Empty register",
Self::ExpectedBoolean { .. } => "Expected boolean", Self::ExpectedBoolean { .. } => "Expected boolean",
Self::ExpectedFunction { .. } => "Expected function", Self::ExpectedFunction { .. } => "Expected function",
Self::Panic { .. } => "Explicit Panic",
Self::RegisterIndexOutOfBounds { .. } => "Register index out of bounds", Self::RegisterIndexOutOfBounds { .. } => "Register index out of bounds",
Self::InvalidInstruction { .. } => "Invalid instruction", Self::InvalidInstruction { .. } => "Invalid instruction",
Self::StackOverflow { .. } => "Stack overflow", Self::StackOverflow { .. } => "Stack overflow",
Self::StackUnderflow { .. } => "Stack underflow", Self::StackUnderflow { .. } => "Stack underflow",
Self::UndefinedVariable { .. } => "Undefined variable", Self::UndefinedVariable { .. } => "Undefined variable",
Self::Chunk(error) => error.description(), Self::Chunk(error) => error.description(),
Self::Io { .. } => "I/O error", Self::NativeFunction(error) => error.description(),
Self::Value { .. } => "Value error", Self::Value { .. } => "Value error",
} }
} }
@ -704,7 +697,6 @@ impl AnnotatedError for VmError {
match self { match self {
Self::EmptyRegister { index, .. } => Some(format!("Register {index} is empty")), Self::EmptyRegister { index, .. } => Some(format!("Register {index} is empty")),
Self::ExpectedFunction { found, .. } => Some(format!("{found} is not a function")), Self::ExpectedFunction { found, .. } => Some(format!("{found} is not a function")),
Self::Panic { message, .. } => message.clone(),
Self::RegisterIndexOutOfBounds { index, .. } => { Self::RegisterIndexOutOfBounds { index, .. } => {
Some(format!("Register {index} does not exist")) Some(format!("Register {index} does not exist"))
} }
@ -712,7 +704,7 @@ impl AnnotatedError for VmError {
Some(format!("{identifier} is not in scope")) Some(format!("{identifier} is not in scope"))
} }
Self::Chunk(error) => error.details(), Self::Chunk(error) => error.details(),
Self::Io { error, .. } => Some(error.to_string()), Self::NativeFunction(error) => error.details(),
Self::Value { error, .. } => Some(error.to_string()), Self::Value { error, .. } => Some(error.to_string()),
_ => None, _ => None,
} }
@ -724,14 +716,13 @@ impl AnnotatedError for VmError {
Self::EmptyRegister { position, .. } => *position, Self::EmptyRegister { position, .. } => *position,
Self::ExpectedBoolean { position, .. } => *position, Self::ExpectedBoolean { position, .. } => *position,
Self::ExpectedFunction { position, .. } => *position, Self::ExpectedFunction { position, .. } => *position,
Self::Panic { position, .. } => *position,
Self::RegisterIndexOutOfBounds { position, .. } => *position, Self::RegisterIndexOutOfBounds { position, .. } => *position,
Self::InvalidInstruction { position, .. } => *position, Self::InvalidInstruction { position, .. } => *position,
Self::StackUnderflow { position } => *position, Self::StackUnderflow { position } => *position,
Self::StackOverflow { position } => *position, Self::StackOverflow { position } => *position,
Self::UndefinedVariable { position, .. } => *position, Self::UndefinedVariable { position, .. } => *position,
Self::Chunk(error) => error.position(), Self::Chunk(error) => error.position(),
Self::Io { position, .. } => *position, Self::NativeFunction(error) => error.position(),
Self::Value { position, .. } => *position, Self::Value { position, .. } => *position,
} }
} }

View File

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