Create Expr function helpers to create different Expr variants
This commit is contained in:
parent
0065c2edf1
commit
2a98d4b771
13
src/ast.rs
13
src/ast.rs
|
@ -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 {
|
||||||
|
|
|
@ -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(),
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue