diff --git a/src/protocol/inputsource.rs b/src/protocol/inputsource.rs deleted file mode 100644 index 2a12406576d403fccc1a83a713ac1af31e32dd04..0000000000000000000000000000000000000000 --- a/src/protocol/inputsource.rs +++ /dev/null @@ -1,305 +0,0 @@ -use std::fmt; -use std::fs::File; -use std::io; -use std::path::Path; - -use backtrace::Backtrace; - -#[derive(Debug, Clone)] -pub struct InputSource { - pub(crate) filename: String, - pub(crate) input: Vec, - line: usize, - column: usize, - offset: usize, -} - -static STD_LIB_PDL: &'static [u8] = b" -primitive forward(in i, out o) { - while(true) synchronous put(o, get(i)); -} -primitive sync(in i, out o) { - while(true) synchronous if(fires(i)) put(o, get(i)); -} -primitive alternator(in i, out l, out r) { - while(true) { - synchronous if(fires(i)) put(l, get(i)); - synchronous if(fires(i)) put(r, get(i)); - } -} -primitive replicator(in i, out l, out r) { - while(true) synchronous { - if(fires(i)) { - msg m = get(i); - put(l, m); - put(r, m); - } - } -} -primitive merger(in l, in r, out o) { - while(true) synchronous { - if(fires(l)) put(o, get(l)); - else if(fires(r)) put(o, get(r)); - } -} -"; - -impl InputSource { - // Constructors - pub fn new(filename: S, reader: &mut R) -> io::Result { - let mut vec = Vec::new(); - reader.read_to_end(&mut vec)?; - vec.extend(STD_LIB_PDL.to_vec()); - Ok(InputSource { - filename: filename.to_string(), - input: vec, - line: 1, - column: 1, - offset: 0, - }) - } - // Constructor helpers - pub fn from_file(path: &Path) -> io::Result { - let filename = path.file_name(); - match filename { - Some(filename) => { - let mut f = File::open(path)?; - InputSource::new(filename.to_string_lossy(), &mut f) - } - None => Err(io::Error::new(io::ErrorKind::NotFound, "Invalid path")), - } - } - pub fn from_string(string: &str) -> io::Result { - let buffer = Box::new(string); - let mut bytes = buffer.as_bytes(); - InputSource::new(String::new(), &mut bytes) - } - pub fn from_buffer(buffer: &[u8]) -> io::Result { - InputSource::new(String::new(), &mut Box::new(buffer)) - } - // Internal methods - pub fn pos(&self) -> InputPosition { - InputPosition { line: self.line, column: self.column, offset: self.offset } - } - pub fn seek(&mut self, pos: InputPosition) { - debug_assert!(pos.offset < self.input.len()); - self.line = pos.line; - self.column = pos.column; - self.offset = pos.offset; - } - pub fn is_eof(&self) -> bool { - self.next() == None - } - - pub fn next(&self) -> Option { - if self.offset < self.input.len() { - Some(self.input[self.offset]) - } else { - None - } - } - - pub fn lookahead(&self, pos: usize) -> Option { - let offset_pos = self.offset + pos; - if offset_pos < self.input.len() { - Some(self.input[offset_pos]) - } else { - None - } - } - - pub fn has(&self, to_compare: &[u8]) -> bool { - if self.offset + to_compare.len() <= self.input.len() { - for idx in 0..to_compare.len() { - if to_compare[idx] != self.input[self.offset + idx] { - return false; - } - } - - true - } else { - false - } - } - - pub fn consume(&mut self) { - match self.next() { - Some(x) if x == b'\r' && self.lookahead(1) != Some(b'\n') || x == b'\n' => { - self.line += 1; - self.offset += 1; - self.column = 1; - } - Some(_) => { - self.offset += 1; - self.column += 1; - } - None => {} - } - } -} - -impl fmt::Display for InputSource { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.pos().fmt(f) - } -} - -#[derive(Debug, Clone, Copy)] -pub struct InputPosition { - pub line: usize, - pub column: usize, - pub offset: usize, -} - -impl InputPosition { - fn context<'a>(&self, source: &'a InputSource) -> &'a [u8] { - let start = self.offset - (self.column - 1); - let mut end = self.offset; - while end < source.input.len() { - let cur = (*source.input)[end]; - if cur == b'\n' || cur == b'\r' { - break; - } - end += 1; - } - &source.input[start..end] - } -} - -impl Default for InputPosition { - fn default() -> Self { - Self{ line: 1, column: 1, offset: 0 } - } -} - -impl fmt::Display for InputPosition { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}:{}", self.line, self.column) - } -} - -#[derive(Debug)] -pub enum ParseErrorType { - Info, - Error -} - -#[derive(Debug)] -pub struct ParseErrorStatement { - pub(crate) error_type: ParseErrorType, - pub(crate) position: InputPosition, - pub(crate) filename: String, - pub(crate) context: String, - pub(crate) message: String, -} - -impl ParseErrorStatement { - fn from_source(error_type: ParseErrorType, source: &InputSource, position: InputPosition, msg: &str) -> Self { - // Seek line start and end - let line_start = position.offset - (position.column - 1); - let mut line_end = position.offset; - while line_end < source.input.len() && source.input[line_end] != b'\n' { - line_end += 1; - } - - // Compensate for '\r\n' - if line_end > line_start && source.input[line_end - 1] == b'\r' { - line_end -= 1; - } - - Self{ - error_type, - position, - filename: source.filename.clone(), - context: String::from_utf8_lossy(&source.input[line_start..line_end]).to_string(), - message: msg.to_string() - } - } -} - -impl fmt::Display for ParseErrorStatement { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // Write message - match self.error_type { - ParseErrorType::Info => write!(f, " INFO: ")?, - ParseErrorType::Error => write!(f, "ERROR: ")?, - } - writeln!(f, "{}", &self.message)?; - - // Write originating file/line/column - if self.filename.is_empty() { - writeln!(f, " +- at {}:{}", self.position.line, self.position.column)?; - } else { - writeln!(f, " +- at {}:{}:{}", self.filename, self.position.line, self.position.column)?; - } - - // Write source context - writeln!(f, " | ")?; - writeln!(f, " | {}", self.context)?; - - // Write underline indicating where the error ocurred - debug_assert!(self.position.column <= self.context.chars().count()); - let mut arrow = String::with_capacity(self.context.len() + 3); - arrow.push_str(" | "); - let mut char_col = 1; - for char in self.context.chars() { - if char_col == self.position.column { break; } - if char == '\t' { - arrow.push('\t'); - } else { - arrow.push(' '); - } - - char_col += 1; - } - arrow.push('^'); - writeln!(f, "{}", arrow)?; - - Ok(()) - } -} - -#[derive(Debug)] -pub struct ParseError { - pub(crate) statements: Vec -} - -impl fmt::Display for ParseError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if self.statements.is_empty() { - return Ok(()) - } - - self.statements[0].fmt(f)?; - for statement in self.statements.iter().skip(1) { - writeln!(f)?; - statement.fmt(f)?; - } - - Ok(()) - } -} - -impl ParseError { - pub fn empty() -> Self { - Self{ statements: Vec::new() } - } - - pub fn new_error(source: &InputSource, position: InputPosition, msg: &str) -> Self { - Self{ statements: vec!(ParseErrorStatement::from_source(ParseErrorType::Error, source, position, msg))} - } - - pub fn with_prefixed(mut self, error_type: ParseErrorType, source: &InputSource, position: InputPosition, msg: &str) -> Self { - self.statements.insert(0, ParseErrorStatement::from_source(error_type, source, position, msg)); - self - } - - pub fn with_postfixed(mut self, error_type: ParseErrorType, source: &InputSource, position: InputPosition, msg: &str) -> Self { - self.statements.push(ParseErrorStatement::from_source(error_type, source, position, msg)); - self - } - - pub fn with_postfixed_info(self, source: &InputSource, position: InputPosition, msg: &str) -> Self { - self.with_postfixed(ParseErrorType::Info, source, position, msg) - } -}