use crate::{Ast, Error}; #[derive(Debug)] pub(crate) enum Hir<'s> { Call(Box>, Vec>), If(Box<(Hir<'s>, Hir<'s>, Hir<'s>)>), Define(&'s str, Box>), Ident(&'s str), Lit(Lit<'s>), } #[derive(Debug)] pub(crate) enum Lit<'s> { Str(&'s str), Num(f64), } #[derive(Debug, Default)] pub(crate) struct Lowerer { errors: Vec, } impl Lowerer { pub(crate) fn ast<'s>(&mut self, a: &Ast<'s>) -> Option> { match a { Ast::Tree(tree) => self.tree(tree), Ast::Leaf(leaf) => self.leaf(leaf), } } fn leaf<'a>(&mut self, leaf: &'a str) -> Option> { // TODO let fst = leaf.chars().next().unwrap(); if fst == '"' { return self.str(leaf); } else if fst.is_digit(10) { return self.num(leaf); } Some(Hir::Ident(leaf)) } fn str<'a>(&mut self, leaf: &'a str) -> Option> { assert_eq!(leaf.chars().next().unwrap(), '"'); assert_eq!(leaf.chars().last().unwrap(), '"'); Some(Hir::Lit(Lit::Str(&leaf[1..leaf.len() - 1]))) } fn num<'a>(&mut self, leaf: &str) -> Option> { match leaf.parse() { Ok(n) => Some(Hir::Lit(Lit::Num(n))), Err(_) => { self.errors.push(format!("Invalid float `{}`", leaf)); None } } } fn tree<'a>(&mut self, tree: &[Ast<'a>]) -> Option> { let first = tree.first().unwrap(); if let Some(sf) = Self::get_special_form(first) { self.special_form(sf, &tree[1..]) } else { self.call(tree) } } fn get_special_form(a: &Ast<'_>) -> Option { use SpecialForm::*; let leaf = match a { Ast::Leaf(l) => *l, Ast::Tree(_) => return None, }; Some(match leaf { "define" => Define, "lambda" => Lambda, "cond" => Cond, "begin" => Begin, "when" => When, "unless" => Unless, "set" => Set, _ => return None, }) } fn special_form<'a>(&mut self, sf: SpecialForm, tree: &[Ast<'a>]) -> Option> { match sf { SpecialForm::Lambda => self.sf_lambda(tree), SpecialForm::If => self.sf_if(tree), SpecialForm::Set => self.sf_set(tree), SpecialForm::Define => self.sf_define(tree), SpecialForm::Cond => self.sf_cond(tree), SpecialForm::Case => self.sf_case(tree), SpecialForm::And => self.sf_and(tree), SpecialForm::Or => self.sf_or(tree), SpecialForm::When => self.sf_when(tree), SpecialForm::Unless => self.sf_unless(tree), SpecialForm::Begin => self.sf_begin(tree), } } fn call<'a>(&mut self, tree: &[Ast<'a>]) -> Option> { let func = tree.first().unwrap(); let args = &tree[1..]; let func = self.ast(func)?; let args = args.iter().map(|arg| self.ast(arg)).collect_opt()?; Some(Hir::Call(Box::new(func), args)) } // ===== Begin Special Forms ===== // ===== Begin Special Forms ===== fn sf_lambda<'a>(&mut self, tree: &[Ast<'a>]) -> Option> { todo!() } fn sf_if<'a>(&mut self, tree: &[Ast<'a>]) -> Option> { let [test, when, unless] = self.n_args(tree, "if")?; let test = self.ast(test)?; let when = self.ast(when)?; let unless = self.ast(unless)?; Some(Hir::If(Box::new((test, when, unless)))) } fn sf_set<'a>(&mut self, tree: &[Ast<'a>]) -> Option> { todo!() } fn sf_define<'a>(&mut self, tree: &[Ast<'a>]) -> Option> { let what = &tree[0]; let rest = &tree[1..]; match what { Ast::Tree(nameargs) => self.define_func(nameargs, rest), Ast::Leaf(name) => self.define_val(name, rest), } } fn define_func<'a>(&mut self, nameargs: &[Ast<'a>], rest: &[Ast<'a>]) -> Option> { todo!() } fn define_val<'a>(&mut self, name: &'a str, rest: &[Ast<'a>]) -> Option> { let [val] = self.n_args(rest, "define(value)")?; let val = self.ast(val)?; Some(Hir::Define(name, Box::new(val))) } fn sf_cond<'a>(&mut self, tree: &[Ast<'a>]) -> Option> { todo!() } fn sf_case<'a>(&mut self, tree: &[Ast<'a>]) -> Option> { todo!() } fn sf_and<'a>(&mut self, tree: &[Ast<'a>]) -> Option> { todo!() } fn sf_or<'a>(&mut self, tree: &[Ast<'a>]) -> Option> { todo!() } fn sf_when<'a>(&mut self, tree: &[Ast<'a>]) -> Option> { todo!() } fn sf_unless<'a>(&mut self, tree: &[Ast<'a>]) -> Option> { todo!() } fn sf_begin<'a>(&mut self, tree: &[Ast<'a>]) -> Option> { todo!() } // ===== End Special Forms ===== fn n_args<'a, 'b, const N: usize>( &mut self, tree: &'b [Ast<'a>], name: &str, ) -> Option<&'b [Ast<'a>; N]> { match tree.try_into() { Ok(arr) => Some(arr), Err(_) => { self.errors .push(format!("{} need {} args, but got {}", name, N, tree.len())); None } } } } enum SpecialForm { Lambda, If, // TODO: Define vs set. Set, Define, Cond, Case, And, Or, When, Unless, // Let, // LetStar, // Letrec, // LetrecStar, // LetValues, // LetStarValues, Begin, // Do, // Only needed if we do the lazy lib // Delay, // DelayForce, // Force, // Guard, } trait IterExt: Iterator { fn collect_opt(self) -> Option> where Self: Sized, Option>: FromIterator, { // TODO: Customize this to not early return, so we get errors from // later parts even if we know theirs already an error. self.collect() } } impl IterExt for T {}