mirror of
https://github.com/TheM1Stery/izanami.git
synced 2025-05-11 07:50:10 +00:00
refactor(function): improve error handling for native functions
This commit is contained in:
parent
42cf268899
commit
933b6e052d
@ -16,7 +16,7 @@ type InterpreterResult = Result<LiteralType, InterpreterSignal>;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct RuntimeError {
|
pub struct RuntimeError {
|
||||||
pub token: Option<Token>,
|
pub token: Token,
|
||||||
pub message: String,
|
pub message: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,14 +28,7 @@ pub struct InterpreterEnvironment {
|
|||||||
impl RuntimeError {
|
impl RuntimeError {
|
||||||
pub fn new(token: &Token, message: String) -> Self {
|
pub fn new(token: &Token, message: String) -> Self {
|
||||||
RuntimeError {
|
RuntimeError {
|
||||||
token: Some(token.clone()),
|
token: token.clone(),
|
||||||
message: message.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn no_token(message: String) -> Self {
|
|
||||||
RuntimeError {
|
|
||||||
token: None,
|
|
||||||
message: message.to_string(),
|
message: message.to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -43,6 +36,7 @@ impl RuntimeError {
|
|||||||
|
|
||||||
pub enum InterpreterSignal {
|
pub enum InterpreterSignal {
|
||||||
RuntimeError(RuntimeError),
|
RuntimeError(RuntimeError),
|
||||||
|
NativeRuntimeError { msg: String },
|
||||||
Break,
|
Break,
|
||||||
Return(LiteralType),
|
Return(LiteralType),
|
||||||
}
|
}
|
||||||
@ -64,6 +58,7 @@ impl From<InterpreterSignal> for RuntimeError {
|
|||||||
InterpreterSignal::RuntimeError(runtime_error) => runtime_error,
|
InterpreterSignal::RuntimeError(runtime_error) => runtime_error,
|
||||||
InterpreterSignal::Break => panic!("Not a runtime error"),
|
InterpreterSignal::Break => panic!("Not a runtime error"),
|
||||||
InterpreterSignal::Return(_) => panic!("Not a runtime error"),
|
InterpreterSignal::Return(_) => panic!("Not a runtime error"),
|
||||||
|
InterpreterSignal::NativeRuntimeError { .. } => panic!("Not a runtime error"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -270,7 +265,17 @@ fn evaluate(expr: &Expr, environment: &InterpreterEnvironment) -> InterpreterRes
|
|||||||
),
|
),
|
||||||
))?
|
))?
|
||||||
}
|
}
|
||||||
Ok(function.call(&arguments, environment)?)
|
let call_result = function.call(&arguments, environment).map_err(|x| match x {
|
||||||
|
InterpreterSignal::NativeRuntimeError { msg } => {
|
||||||
|
InterpreterSignal::RuntimeError(RuntimeError {
|
||||||
|
token: paren.clone(),
|
||||||
|
message: msg,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_ => x,
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(call_result?)
|
||||||
}
|
}
|
||||||
_ => Err(RuntimeError::new(
|
_ => Err(RuntimeError::new(
|
||||||
paren,
|
paren,
|
||||||
@ -358,7 +363,11 @@ fn read_input_function() -> NativeFunction {
|
|||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
io::stdin()
|
io::stdin()
|
||||||
.read_line(&mut buf)
|
.read_line(&mut buf)
|
||||||
.map_err(|_| RuntimeError::no_token("Error reading from stdin".to_string()))?;
|
.map_err(|_| InterpreterSignal::NativeRuntimeError {
|
||||||
|
msg: "Error reading from stdin".to_string(),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
buf.truncate(buf.trim_end().len());
|
||||||
|
|
||||||
Ok(LiteralType::String(buf))
|
Ok(LiteralType::String(buf))
|
||||||
};
|
};
|
||||||
|
@ -107,7 +107,5 @@ fn error(ParseError { token, msg }: &ParseError) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn runtime_error(err: &RuntimeError) {
|
fn runtime_error(err: &RuntimeError) {
|
||||||
if let Some(token) = &err.token {
|
eprintln!("{}\n[line {}]", err.message, err.token.line);
|
||||||
eprintln!("{}\n[line {}]", err.message, token.line);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -276,7 +276,7 @@ impl Parser<'_> {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
self.consume(TokenType::Semicolon, "Expect ';' after return value.");
|
self.consume(TokenType::Semicolon, "Expect ';' after return value.")?;
|
||||||
|
|
||||||
Ok(Stmt::Return { keyword, value })
|
Ok(Stmt::Return { keyword, value })
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user