Change the list implementation to remove the generic type from it

This commit is contained in:
Sameer Rahmani 2020-09-14 21:46:52 +01:00
parent f880169e68
commit fa9c51e71c
5 changed files with 39 additions and 14 deletions

View File

@ -24,14 +24,14 @@ pub enum Expr {
Num(Number), Num(Number),
Comment, Comment,
Error(String), Error(String),
Cons(List<Expr>), Cons(Box<List>),
Nil, Nil,
NoMatch, NoMatch,
} }
impl Expr { impl Expr {
pub fn make_list(first: Expr, rest: Expr) -> Expr { pub fn make_list(first: Expr, rest: Expr) -> Expr {
Expr::Cons(List::<Expr>::new(Box::new(first), Box::new(rest))) Expr::Cons(Box::new(List::new(first, rest)))
} }
pub fn make_symbol(v: String) -> Expr { pub fn make_symbol(v: String) -> Expr {

View File

@ -14,10 +14,9 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
use crate::ast::Expr;
use crate::compiler::Compiler; use crate::compiler::Compiler;
use crate::types::{ExprResult, List}; use crate::types::{ExprResult, List};
pub fn def<'a>(compiler: &'a Compiler, args: &'a List<Expr>) -> ExprResult<'a> { pub fn def<'a>(compiler: &'a Compiler, args: &'a List) -> ExprResult<'a> {
Err("Not implemented".to_string()) Err("Not implemented".to_string())
} }

View File

@ -49,7 +49,7 @@ fn main() -> io::Result<()> {
f.read_to_string(&mut buf)?; f.read_to_string(&mut buf)?;
match reader::read_string(&buf) { match reader::read_string(&buf) {
Ok(v) => { Ok(v) => {
println!("AST: {:?}", v); println!("AST: {:#?}", v);
let g = compiler::compile(&compiler, v); let g = compiler::compile(&compiler, v);
println!("GEN: {:?}", g) println!("GEN: {:?}", g)
} }

View File

@ -24,10 +24,15 @@ pub struct Namespace<'ctx> {
/// think of modules as compilation units. Object files if you prefer. /// think of modules as compilation units. Object files if you prefer.
/// This way we should be able to hot swap the namespaces. /// This way we should be able to hot swap the namespaces.
pub module: Module<'ctx>, pub module: Module<'ctx>,
/// Root scope of the namespace
scope: Scope<'ctx>, scope: Scope<'ctx>,
// The option of the current function being compiled /// The option of the current function being compiled
current_fn_opt: Option<FunctionValue<'ctx>>, current_fn_opt: Option<FunctionValue<'ctx>>,
// Current scope of the namespace, for example when we're processing
// a let form, this field would refer to the scope of that let form.
//current_scope_opt: Option<Scope<'ctx>>,
} }
impl<'ctx> Namespace<'ctx> { impl<'ctx> Namespace<'ctx> {
@ -37,6 +42,7 @@ impl<'ctx> Namespace<'ctx> {
//scope: Scope::new(None), //scope: Scope::new(None),
current_fn_opt: None, current_fn_opt: None,
scope: Scope::new(None), scope: Scope::new(None),
//current_scope_opt: None,
} }
} }
/// Get a defined function given its name. /// Get a defined function given its name.

View File

@ -13,23 +13,43 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
use crate::ast::Expr;
use crate::compiler::Compiler; use crate::compiler::Compiler;
use crate::types::core::{ExprResult, Expression}; use crate::types::core::{ExprResult, Expression};
#[derive(Debug, Eq, PartialEq, Clone)] #[derive(Debug, Eq, PartialEq, Clone)]
pub struct List<T: Expression> { pub struct List {
first: Box<T>, first: Expr,
rest: Box<T>, rest: Expr,
length: u64,
} }
impl<T: Expression> List<T> { impl List {
pub fn new<S: Expression>(first: Box<S>, rest: Box<S>) -> List<S> { pub fn new(first: Expr, rest: Expr) -> List {
List { first, rest } // The order of field definition is important here.
// If we move the `length` after `rest` we're going
// to break the ownership rule of rust because `rest: rest`
// is going to move it to the new list and we can not
// borrow it afterward.
List {
length: match &rest {
Expr::Cons(v) => v.length + 1,
_ => {
if let Expr::Nil = first {
0
} else {
1
}
}
},
first,
rest,
}
} }
} }
impl<T: Expression> Expression for List<T> { impl Expression for List {
fn eval() {} fn eval() {}
fn code_gen<'ctx>(&self, compiler: &'ctx Compiler) -> ExprResult<'ctx> { fn code_gen<'ctx>(&self, compiler: &'ctx Compiler) -> ExprResult<'ctx> {
Err("Not implemented on list".to_string()) Err("Not implemented on list".to_string())