Create Expr function helpers to create different Expr variants

This commit is contained in:
Sameer Rahmani 2020-06-20 16:25:05 +01:00
parent 0065c2edf1
commit 2a98d4b771
2 changed files with 37 additions and 29 deletions

View File

@ -33,7 +33,6 @@ pub enum Expr {
//List(list::List<Expr>), //List(list::List<Expr>),
Symbol(String), Symbol(String),
Str(String), Str(String),
Quote(Box<Expr>),
Num(Number), Num(Number),
Comment, Comment,
Error(String), Error(String),
@ -47,6 +46,18 @@ impl Expr {
pub fn make_list(first: Expr, rest: Expr) -> Expr { pub fn make_list(first: Expr, rest: Expr) -> Expr {
Expr::Cons(list::List::<Expr>::new(Box::new(first), Box::new(rest))) Expr::Cons(list::List::<Expr>::new(Box::new(first), Box::new(rest)))
} }
pub fn make_symbol(v: String) -> Expr {
Expr::Symbol(v)
}
pub fn make_string(v: String) -> Expr {
Expr::Str(v)
}
pub fn make_number(n: Number) -> Expr {
Expr::Num(n)
}
} }
impl Expression for Expr { impl Expression for Expr {

View File

@ -1,8 +1,4 @@
use crate::ast::{Expr, Number}; use crate::ast::{Expr, Number};
// Lst::List is the actual list implementation while
// ast::Expr::List is a variant holding the actual
// implementation.
use crate::collections::list as lst;
use std::io::{BufReader, Read}; use std::io::{BufReader, Read};
pub type ReadResult = Result<Expr, String>; pub type ReadResult = Result<Expr, String>;
@ -78,10 +74,10 @@ impl ExprReader {
fn read_quoted_expr<T: Read>(&mut self, reader: &mut BufReader<T>) -> ReadResult { fn read_quoted_expr<T: Read>(&mut self, reader: &mut BufReader<T>) -> ReadResult {
let rest = self.read_expr(reader)?; let rest = self.read_expr(reader)?;
Ok(Expr::Cons(lst::List::<Expr>::new( Ok(Expr::make_list(
Box::new(Expr::Symbol("quote".to_string())), Expr::make_symbol("quote".to_string()),
Box::new(rest), rest,
))) ))
} }
fn read_unquoted_expr<T: Read>(&mut self, reader: &mut BufReader<T>) -> ReadResult { fn read_unquoted_expr<T: Read>(&mut self, reader: &mut BufReader<T>) -> ReadResult {
@ -90,27 +86,27 @@ impl ExprReader {
// Move forward in the buffer since we peeked it // Move forward in the buffer since we peeked it
let _ = self.get_char(reader, true); let _ = self.get_char(reader, true);
let rest = self.read_expr(reader)?; let rest = self.read_expr(reader)?;
Ok(Expr::Cons(lst::List::<Expr>::new( Ok(Expr::make_list(
Box::new(Expr::Symbol("unquote-splicing".to_string())), Expr::make_symbol("unquote-splicing".to_string()),
Box::new(rest), rest,
))) ))
} }
_ => { _ => {
let rest = self.read_expr(reader)?; let rest = self.read_expr(reader)?;
Ok(Expr::Cons(lst::List::<Expr>::new( Ok(Expr::make_list(
Box::new(Expr::Symbol("unquote".to_string())), Expr::make_symbol("unquote".to_string()),
Box::new(rest), rest,
))) ))
} }
} }
} }
fn read_quasiquoted_expr<T: Read>(&mut self, reader: &mut BufReader<T>) -> ReadResult { fn read_quasiquoted_expr<T: Read>(&mut self, reader: &mut BufReader<T>) -> ReadResult {
let rest = self.read_expr(reader)?; let rest = self.read_expr(reader)?;
Ok(Expr::Cons(lst::List::<Expr>::new( Ok(Expr::make_list(
Box::new(Expr::Symbol("quasiquote".to_string())), Expr::make_symbol("quasiquote".to_string()),
Box::new(rest), rest,
))) ))
} }
// TODO: We might want to replace Cons with an actual List struct // TODO: We might want to replace Cons with an actual List struct
@ -133,10 +129,7 @@ impl ExprReader {
None => return Err("Unexpected EOF while parsing a list.".to_string()), None => return Err("Unexpected EOF while parsing a list.".to_string()),
}; };
Ok(Expr::Cons(lst::List::<Expr>::new( Ok(Expr::make_list(first, rest))
Box::new(first),
Box::new(rest),
)))
} }
fn is_valid_for_identifier(&self, c: char) -> bool { fn is_valid_for_identifier(&self, c: char) -> bool {
@ -195,7 +188,7 @@ impl ExprReader {
} }
} }
Ok(Expr::Symbol(symbol)) Ok(Expr::make_symbol(symbol))
} }
fn read_escape_char<T: Read>(&mut self, reader: &mut BufReader<T>) -> Option<char> { fn read_escape_char<T: Read>(&mut self, reader: &mut BufReader<T>) -> Option<char> {
@ -232,7 +225,7 @@ impl ExprReader {
None => return Err("Unexpected EOF while scanning a string".to_string()), None => return Err("Unexpected EOF while scanning a string".to_string()),
} }
} }
Ok(Expr::Str(string)) Ok(Expr::make_string(string))
} }
fn read_number<T: Read>(&mut self, reader: &mut BufReader<T>, neg: bool) -> ReadResult { fn read_number<T: Read>(&mut self, reader: &mut BufReader<T>, neg: bool) -> ReadResult {
@ -257,9 +250,13 @@ impl ExprReader {
} }
} }
if is_double { if is_double {
Ok(Expr::Num(Number::Float(string.parse::<f64>().unwrap()))) Ok(Expr::make_number(Number::Float(
string.parse::<f64>().unwrap(),
)))
} else { } else {
Ok(Expr::Num(Number::Integer(string.parse::<i64>().unwrap()))) Ok(Expr::make_number(Number::Integer(
string.parse::<i64>().unwrap(),
)))
} }
} }