diff --git a/src/ast.rs b/src/ast.rs index 2085012..a2f91f1 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -27,7 +27,7 @@ impl Eq for Number {} #[derive(Debug, Eq, PartialEq, Clone)] pub enum Expr { - List(Vec), + List(Box), Symbol(String), Str(String), Quote(Box), diff --git a/src/main.rs b/src/main.rs index c65056f..df6ccc2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,27 @@ extern crate llvm_sys; +use std::fs::File; +use std::io; +use std::io::prelude::*; use std::string::String; pub mod ast; pub mod collections; pub mod reader; -fn main() { - let input = String::from("(println \">>>>>\" '(+ 2 -3))"); +fn main() -> io::Result<()> { + // 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(()) } diff --git a/src/reader.rs b/src/reader.rs index f33013a..2e6d11b 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -4,14 +4,25 @@ use std::io::{BufReader, Read}; pub type ReadResult = Result; pub struct ExprReader { + location: i32, read_stack: Vec, } impl 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( &mut self, reader: &mut BufReader, @@ -28,7 +39,7 @@ impl ExprReader { let mut single_char_buff = [0]; let bytes_read = reader.read(&mut single_char_buff); match bytes_read { - Ok(n) if n > 0 => {} + Ok(n) if n > 0 => self.location = self.location + 1, Ok(_) => return None, Err(_) => return None, }; @@ -114,7 +125,7 @@ impl ExprReader { self.unget_char(e); 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))) @@ -158,8 +169,8 @@ impl ExprReader { } Some(e) => { return Err(format!( - "Unexpected character: got {}, expected a symbol", - e + "Unexpected character: got '{}', expected a symbol at {}", + e, self.location )) } None => return Err("Unexpected EOF".to_string()), @@ -275,6 +286,16 @@ impl ExprReader { } } + pub fn ignore_comments(&mut self, reader: &mut BufReader) -> 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(&mut self, reader: &mut BufReader) -> ReadResult { match self.get_char(reader, true) { Some(c) => { @@ -283,6 +304,7 @@ impl ExprReader { '~' => self.read_unquoted_expr(reader), '`' => self.read_quasiquoted_expr(reader), '(' => self.read_list(reader), + ';' => self.ignore_comments(reader), //'[' => self.read_vector(reader), //'{' => self.read_map(reader), _ => { @@ -304,6 +326,7 @@ impl ExprReader { match self.read_expr(reader) { Ok(Expr::NoMatch) => break, Err(v) => return Err(v), + Ok(Expr::Comment) => continue, Ok(v) => ast.push(v), } }