Fix the reader to ignore comment lines

This commit is contained in:
Sameer Rahmani 2020-06-19 19:37:00 +01:00
parent 04fe7e6085
commit 30a7dbfce5
3 changed files with 46 additions and 9 deletions

View File

@ -27,7 +27,7 @@ impl Eq for Number {}
#[derive(Debug, Eq, PartialEq, Clone)] #[derive(Debug, Eq, PartialEq, Clone)]
pub enum Expr { pub enum Expr {
List(Vec<Expr>), List(Box<Expr>),
Symbol(String), Symbol(String),
Str(String), Str(String),
Quote(Box<Expr>), Quote(Box<Expr>),

View File

@ -1,13 +1,27 @@
extern crate llvm_sys; extern crate llvm_sys;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::string::String; use std::string::String;
pub mod ast; pub mod ast;
pub mod collections; pub mod collections;
pub mod reader; pub mod reader;
fn main() { fn main() -> io::Result<()> {
let input = String::from("(println \">>>>>\" '(+ 2 -3))"); // let input = String::from("(println \">>>>>\" '(+ 2 -3))");
println!("{:?}", reader::read_string(&input).unwrap()); // println!("{:?}", reader::read_string(&input).unwrap());
let mut f = File::open(
"/home/lxsameer/src/serene/serene/resources/benchmarks/parsers/example_code.srn",
)?;
let mut buf = String::new();
f.read_to_string(&mut buf)?;
match reader::read_string(&buf) {
Ok(v) => println!("{:?}", v),
Err(e) => println!(">> error {:?}", e),
}
Ok(())
} }

View File

@ -4,14 +4,25 @@ use std::io::{BufReader, Read};
pub type ReadResult = Result<Expr, String>; pub type ReadResult = Result<Expr, String>;
pub struct ExprReader { pub struct ExprReader {
location: i32,
read_stack: Vec<char>, read_stack: Vec<char>,
} }
impl ExprReader { impl ExprReader {
fn new() -> ExprReader { fn new() -> ExprReader {
ExprReader { read_stack: vec![] } ExprReader {
location: 0,
read_stack: vec![],
}
} }
/// Retun a single character by reading from the `reader`. ,
///
/// # Arguments:
///
/// * `reader`: The buffer to read from.
/// * `skip_whitespace`: Whether or not to skip whitespace chars. *Bear in mind that
/// if you care about the newline char you should not skip the whitespaces*.
fn get_char<T: Read>( fn get_char<T: Read>(
&mut self, &mut self,
reader: &mut BufReader<T>, reader: &mut BufReader<T>,
@ -28,7 +39,7 @@ impl ExprReader {
let mut single_char_buff = [0]; let mut single_char_buff = [0];
let bytes_read = reader.read(&mut single_char_buff); let bytes_read = reader.read(&mut single_char_buff);
match bytes_read { match bytes_read {
Ok(n) if n > 0 => {} Ok(n) if n > 0 => self.location = self.location + 1,
Ok(_) => return None, Ok(_) => return None,
Err(_) => return None, Err(_) => return None,
}; };
@ -114,7 +125,7 @@ impl ExprReader {
self.unget_char(e); self.unget_char(e);
self.read_list(reader)? self.read_list(reader)?
} }
None => return Err("Unexpected EOF, expected . or symbol".to_string()), None => return Err("Unexpected EOF while parsing a list.".to_string()),
}; };
Ok(Expr::Cons(Box::new(first), Box::new(rest))) Ok(Expr::Cons(Box::new(first), Box::new(rest)))
@ -158,8 +169,8 @@ impl ExprReader {
} }
Some(e) => { Some(e) => {
return Err(format!( return Err(format!(
"Unexpected character: got {}, expected a symbol", "Unexpected character: got '{}', expected a symbol at {}",
e e, self.location
)) ))
} }
None => return Err("Unexpected EOF".to_string()), None => return Err("Unexpected EOF".to_string()),
@ -275,6 +286,16 @@ impl ExprReader {
} }
} }
pub fn ignore_comments<T: Read>(&mut self, reader: &mut BufReader<T>) -> ReadResult {
match self.get_char(reader, false) {
Some(c) => match c {
'\n' => Ok(Expr::Comment),
_ => self.ignore_comments(reader),
},
None => Ok(Expr::Comment),
}
}
pub fn read_expr<T: Read>(&mut self, reader: &mut BufReader<T>) -> ReadResult { pub fn read_expr<T: Read>(&mut self, reader: &mut BufReader<T>) -> ReadResult {
match self.get_char(reader, true) { match self.get_char(reader, true) {
Some(c) => { Some(c) => {
@ -283,6 +304,7 @@ impl ExprReader {
'~' => self.read_unquoted_expr(reader), '~' => self.read_unquoted_expr(reader),
'`' => self.read_quasiquoted_expr(reader), '`' => self.read_quasiquoted_expr(reader),
'(' => self.read_list(reader), '(' => self.read_list(reader),
';' => self.ignore_comments(reader),
//'[' => self.read_vector(reader), //'[' => self.read_vector(reader),
//'{' => self.read_map(reader), //'{' => self.read_map(reader),
_ => { _ => {
@ -304,6 +326,7 @@ impl ExprReader {
match self.read_expr(reader) { match self.read_expr(reader) {
Ok(Expr::NoMatch) => break, Ok(Expr::NoMatch) => break,
Err(v) => return Err(v), Err(v) => return Err(v),
Ok(Expr::Comment) => continue,
Ok(v) => ast.push(v), Ok(v) => ast.push(v),
} }
} }