complexpr/complexpr/src/lib.rs

121 lines
2.8 KiB
Rust
Raw Normal View History

2022-09-06 13:52:29 +00:00
use std::{rc::Rc, error::Error, fmt};
pub mod token;
pub mod expr;
pub mod lexer;
pub mod parser;
pub mod value;
pub mod eval;
pub mod interpreter;
pub mod env;
2022-09-06 13:52:29 +00:00
#[derive(Clone, Debug)]
pub struct Position {
pub pos: usize,
pub line: usize,
pub col: usize,
pub file: Option<Rc<str>>
}
2022-09-18 06:05:01 +00:00
impl fmt::Display for Position {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}:{}:{}",
self.file.as_ref().map(|x| x.as_ref()).unwrap_or("<unknown>"),
self.line,
self.col
)
}
}
2022-09-06 13:52:29 +00:00
#[derive(Debug)]
pub struct ParserError {
pub message: String,
pub pos: Position
}
#[derive(Debug)]
pub struct Stackframe {
2022-09-18 06:05:01 +00:00
pub pos: Option<Position>,
pub fn_name: Option<Rc<str>>,
}
2022-09-06 13:52:29 +00:00
#[derive(Debug)]
pub struct RuntimeError {
pub message: String,
pub stacktrace: Vec<Stackframe>,
pub last_pos: Option<Position>,
}
impl RuntimeError {
pub fn new<S>(message: S, pos: Position) -> Self
where S: Into<String> {
Self {
message: message.into(),
stacktrace: vec![],
last_pos: Some(pos)
}
}
2022-09-18 06:05:01 +00:00
pub fn new_no_pos<S>(message: S) -> Self
2022-09-13 17:31:29 +00:00
where S: Into<String> {
Self {
message: message.into(),
stacktrace: vec![],
last_pos: None
}
}
pub fn exit_fn(mut self, fn_name: Option<Rc<str>>, pos: Position) -> Self {
2022-09-18 06:05:01 +00:00
self.stacktrace.push(Stackframe { pos: self.last_pos, fn_name });
self.last_pos = Some(pos);
self
}
pub fn finish(mut self, ctx_name: Option<Rc<str>>) -> Self {
2022-09-18 06:05:01 +00:00
self.stacktrace.push(Stackframe { pos: self.last_pos, fn_name: ctx_name });
self.last_pos = None;
self
}
2022-09-06 13:52:29 +00:00
}
2022-09-16 20:05:28 +00:00
impl From<String> for RuntimeError {
fn from(s: String) -> Self {
2022-09-18 06:05:01 +00:00
Self::new_no_pos(s)
2022-09-16 20:05:28 +00:00
}
}
impl From<&str> for RuntimeError {
fn from(s: &str) -> Self {
2022-09-18 06:05:01 +00:00
Self::new_no_pos(s)
2022-09-16 20:05:28 +00:00
}
}
2022-09-14 15:16:53 +00:00
2022-09-06 13:52:29 +00:00
impl fmt::Display for ParserError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2022-09-17 23:23:54 +00:00
write!(f, "{}\n In {} at {},{}",
2022-09-06 13:52:29 +00:00
self.message,
self.pos.file.as_ref().map(|o| o.as_ref()).unwrap_or("<unknown>"),
self.pos.line,
self.pos.col
)
}
}
impl fmt::Display for RuntimeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2022-09-18 06:05:01 +00:00
write!(f, "{}", self.message)?;
for frame in &self.stacktrace {
2022-09-18 06:05:01 +00:00
let fn_name = frame.fn_name.as_ref().map(|o| o.as_ref()).unwrap_or("<anonymous fn>");
match &frame.pos {
Some(pos) => write!(f, "\n In {} at {}", fn_name, pos)?,
None => write!(f, "\n In {} at <unknown>", fn_name)?,
}
}
Ok(())
2022-09-06 13:52:29 +00:00
}
}
impl Error for ParserError {}
2022-09-11 17:02:18 +00:00
impl Error for RuntimeError {}