Add Expression trait and new cons implementation
This commit is contained in:
parent
30a7dbfce5
commit
0065c2edf1
20
src/ast.rs
20
src/ast.rs
|
@ -1,3 +1,6 @@
|
||||||
|
use crate::collections::list;
|
||||||
|
use crate::expr::Expression;
|
||||||
|
|
||||||
// Note: I kept the number implementation simple for now
|
// Note: I kept the number implementation simple for now
|
||||||
// but we need to decide on our approach to numbers, are
|
// but we need to decide on our approach to numbers, are
|
||||||
// we going to only support the 64bit variants? or should
|
// we going to only support the 64bit variants? or should
|
||||||
|
@ -27,19 +30,26 @@ impl Eq for Number {}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
pub enum Expr {
|
pub enum Expr {
|
||||||
List(Box<Expr>),
|
//List(list::List<Expr>),
|
||||||
Symbol(String),
|
Symbol(String),
|
||||||
Str(String),
|
Str(String),
|
||||||
Quote(Box<Expr>),
|
Quote(Box<Expr>),
|
||||||
Num(Number),
|
Num(Number),
|
||||||
Comment,
|
Comment,
|
||||||
Error(String),
|
Error(String),
|
||||||
Cons(Box<Expr>, Box<Expr>),
|
// Cons(Box<Expr>, Box<Expr>),
|
||||||
|
Cons(list::List<Expr>),
|
||||||
Nil,
|
Nil,
|
||||||
NoMatch,
|
NoMatch,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
impl Expr {
|
||||||
pub enum Error {
|
pub fn make_list(first: Expr, rest: Expr) -> Expr {
|
||||||
SyntaxError,
|
Expr::Cons(list::List::<Expr>::new(Box::new(first), Box::new(rest)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Expression for Expr {
|
||||||
|
fn eval() {}
|
||||||
|
fn code_gen() {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,18 @@
|
||||||
pub struct List {}
|
use crate::expr::Expression;
|
||||||
|
|
||||||
impl List {
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
pub fn h() {
|
pub struct List<T: Expression> {
|
||||||
println!("Uo")
|
first: Box<T>,
|
||||||
|
rest: Box<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Expression> List<T> {
|
||||||
|
pub fn new<S: Expression>(first: Box<S>, rest: Box<S>) -> List<S> {
|
||||||
|
List { first, rest }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Expression> Expression for List<T> {
|
||||||
|
fn eval() {}
|
||||||
|
fn code_gen() {}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
pub trait Expression {
|
||||||
|
fn eval();
|
||||||
|
fn code_gen();
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ use std::string::String;
|
||||||
|
|
||||||
pub mod ast;
|
pub mod ast;
|
||||||
pub mod collections;
|
pub mod collections;
|
||||||
|
pub mod expr;
|
||||||
pub mod reader;
|
pub mod reader;
|
||||||
|
|
||||||
fn main() -> io::Result<()> {
|
fn main() -> io::Result<()> {
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
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>;
|
||||||
|
@ -74,10 +78,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(
|
Ok(Expr::Cons(lst::List::<Expr>::new(
|
||||||
Box::new(Expr::Symbol("quote".to_string())),
|
Box::new(Expr::Symbol("quote".to_string())),
|
||||||
Box::new(rest),
|
Box::new(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 {
|
||||||
|
@ -86,27 +90,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(
|
Ok(Expr::Cons(lst::List::<Expr>::new(
|
||||||
Box::new(Expr::Symbol("unquote-splicing".to_string())),
|
Box::new(Expr::Symbol("unquote-splicing".to_string())),
|
||||||
Box::new(rest),
|
Box::new(rest),
|
||||||
))
|
)))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let rest = self.read_expr(reader)?;
|
let rest = self.read_expr(reader)?;
|
||||||
Ok(Expr::Cons(
|
Ok(Expr::Cons(lst::List::<Expr>::new(
|
||||||
Box::new(Expr::Symbol("unquote".to_string())),
|
Box::new(Expr::Symbol("unquote".to_string())),
|
||||||
Box::new(rest),
|
Box::new(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(
|
Ok(Expr::Cons(lst::List::<Expr>::new(
|
||||||
Box::new(Expr::Symbol("quasiquote".to_string())),
|
Box::new(Expr::Symbol("quasiquote".to_string())),
|
||||||
Box::new(rest),
|
Box::new(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
|
||||||
|
@ -120,6 +124,7 @@ impl ExprReader {
|
||||||
_ => return Err(e),
|
_ => return Err(e),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let rest = match self.get_char(reader, true) {
|
let rest = match self.get_char(reader, true) {
|
||||||
Some(e) => {
|
Some(e) => {
|
||||||
self.unget_char(e);
|
self.unget_char(e);
|
||||||
|
@ -128,7 +133,10 @@ 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(Box::new(first), Box::new(rest)))
|
Ok(Expr::Cons(lst::List::<Expr>::new(
|
||||||
|
Box::new(first),
|
||||||
|
Box::new(rest),
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_valid_for_identifier(&self, c: char) -> bool {
|
fn is_valid_for_identifier(&self, c: char) -> bool {
|
||||||
|
|
Loading…
Reference in New Issue