diff --git a/src/code_gen.rs b/src/code_gen.rs index 6b23041..5857d3e 100644 --- a/src/code_gen.rs +++ b/src/code_gen.rs @@ -1,11 +1,6 @@ -use std::{collections::HashMap, ops::AddAssign}; +use std::{iter::Sum, ops::{Add, AddAssign}}; -use color_eyre::eyre::Error; - -use crate::{ - lexer::Keyword, - parser::{LispAtom, SExpression}, -}; +use crate::ir::{Command, IRepr}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum InstructionFrom { @@ -40,144 +35,124 @@ enum InstructionTo { RegisterSP, RegisterSB, + + IncSP, + DecSP, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] -struct Command { - data_from: InstructionFrom, - data_to: InstructionTo, - data: i8, +struct Instruction { + from: InstructionFrom, + to: InstructionTo, + value: i8, } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct Scope { - variables: Vec, - stack_position: usize, +pub struct Code { + instructions: Vec, } -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct EightBitLang { - instructions: Vec, - labels: Option>, +impl From for Code { + fn from(value: IRepr) -> Self { + value.commands.into_iter().map(|x| Code::from(x)).sum() + } } -pub trait GenerateCode { - fn to_code(self, codegen_scope: &mut Scope) -> Result - where - Self: Sized; - - type Error; -} - -impl GenerateCode for SExpression { - fn to_code(self, codegen_scope: &mut Scope) -> Result { - match self { - SExpression::Atom(a) => a.to_code(codegen_scope), +impl From for Code { + fn from(value: Command) -> Self { + use Instruction as I; + use InstructionFrom as IF; + use InstructionTo as IT; + match value { + Command::PopR1 => vec![ + I::new(IF::RegisterSP, IT::RamAddressLower, 0x00), + I::new(IF::RAM, IT::RegisterA, 0x00), + I::new(IF::ROM, IT::DecSP, 0x00), + ], + Command::PopR2 => vec![ + I::new(IF::RegisterSP, IT::RamAddressLower, 0x00), + I::new(IF::RAM, IT::RegisterB, 0x00), + I::new(IF::ROM, IT::DecSP, 0x00), + ], + Command::PushInt(val) => vec![ + I::new(IF::RegisterSP, IT::RamAddressLower, 0x00), + I::new(IF::ROM, IT::RAM, val as i8), + I::new(IF::ROM, IT::IncSP, 0x00), + ], + Command::PushSum => vec![ + I::new(IF::RegisterSP, IT::RamAddressLower, 0x00), + I::new(IF::ALU, IT::RAM, 0x00), + I::new(IF::ROM, IT::IncSP, 0x00), + ], _ => todo!(), - } + }.into() } - - type Error = Error; } -impl GenerateCode for LispAtom { - fn to_code(self, codegen_scope: &mut Scope) -> Result { - match self { - LispAtom::Keyword(keyword) => keyword.to_code(codegen_scope), - LispAtom::Integer(number) => number.to_code(codegen_scope), - _ => todo!(), - } - } - - type Error = Error; -} - -impl GenerateCode for isize { - fn to_code(self, codegen_scope: &mut Scope) -> Result { - if let Err(_e) = i8::try_from(self) { - return Err(Error::msg("Yo integer too big brah")); - } - - return Ok(EightBitLang::push(self as i8, codegen_scope)); - } - - type Error = Error; -} - -impl GenerateCode for Keyword { - fn to_code(self, _codegen_scope: &mut Scope) -> Result { - match self { - _ => todo!(), - } - } - - type Error = Error; -} - -impl AddAssign for EightBitLang { +impl AddAssign for Code { fn add_assign(&mut self, mut rhs: Self) { - let mut labels = self.labels.clone().unwrap(); - if rhs.labels.is_some() || self.labels.is_some() { - if self.labels.is_none() { - labels = rhs.labels.unwrap(); - } else if rhs.labels.is_none() { - } else { - labels = HashMap::new(); - for label in rhs.labels.unwrap() { - labels.insert(label.0, label.1 + self.instructions.len()); - } - } - self.labels = Some(labels); - } self.instructions.append(&mut rhs.instructions); } } -impl From for EightBitLang { - fn from(value: Command) -> Self { +impl AddAssign for Code { + fn add_assign(&mut self, rhs: Instruction) { + self.instructions.push(rhs); + } +} + +impl Add for Code { + fn add(mut self, rhs: Self) -> Self::Output { + self += rhs; + self + } + + type Output = Self; +} + +impl Add for Code { + fn add(mut self, rhs: Instruction) -> Self::Output { + self += rhs; + self + } + + type Output = Self; +} + +impl From> for Code { + fn from(value: Vec) -> Self { Self { - instructions: vec![value], - labels: None, + instructions: value, } } } -impl EightBitLang { - fn push(value: i8, codegen_scope: &mut Scope) -> Self { - use InstructionFrom as IF; - use InstructionTo as IT; +impl Sum for Code { + fn sum>(iter: I) -> Self { + let mut sum = Self::new(); + + for i in iter { + sum += i; + } - codegen_scope.stack_position += 1; - - let mut commands = Vec::new(); - commands.push(Command::new(IF::RegisterSP, IT::RegisterA, 0x00)); - commands.push(Command::new(IF::ROM, IT::RegisterB, 0x01)); - commands.push(Command::new(IF::ALU, IT::RegisterSP, 0x00)); - commands.push(Command::new(IF::RegisterSP, IT::RamAddressLower, 0x00)); - commands.push(Command::new(IF::ROM, IT::RAM, value)); + sum + } +} +impl Code { + fn new() -> Self { Self { - instructions: commands, - labels: None, + instructions: vec![] } } } -impl Command { - fn new(data_from: InstructionFrom, data_to: InstructionTo, data: i8) -> Self { +impl Instruction { + fn new(from: InstructionFrom, to: InstructionTo, value: i8) -> Self { Self { - data_from, - data_to, - data, - } - } -} - -impl Scope { - pub fn new() -> Self { - Self { - variables: Vec::new(), - stack_position: 0, + from, + to, + value, } } } diff --git a/src/ir.rs b/src/ir.rs index 7c5e3db..8deffda 100644 --- a/src/ir.rs +++ b/src/ir.rs @@ -12,11 +12,11 @@ use crate::{ #[derive(Debug, Clone, PartialEq, Eq)] pub struct IRepr { - commands: Vec, + pub commands: Vec, } #[derive(Debug, Clone, PartialEq, Eq)] -enum Command { +pub enum Command { PushInt(isize), PushSum, PopR1, @@ -168,9 +168,6 @@ impl ToIRMacro for Macro { } } - dbg!(&commands); - dbg!(&ir_scope); - while body != NIL { match body { SExpression::Atom(_a) => todo!(), @@ -180,13 +177,12 @@ impl ToIRMacro for Macro { } } } - - dbg!(&commands); - dbg!(&ir_scope); commands += Command::Leave; - todo!() + ir_scope.stack_position = ir_scope.stack_positions.pop().unwrap(); + + Ok(commands) } _ => todo!(), } diff --git a/src/main.rs b/src/main.rs index 8b449aa..4283c01 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,12 +8,11 @@ mod error; use color_eyre::eyre::Result; // pub use error::*; -use ir::IRepr; -use lexer::TokenString; -use parser::SExpression; use crate::{ - code_gen::{EightBitLang, GenerateCode, Scope}, + code_gen::Code, + lexer::TokenString, + parser::SExpression, ir::generate_code, }; @@ -23,17 +22,19 @@ fn main() -> Result<()> { // let code = r#"(mul 2 (add 3 4))"#.to_string(); - // let code = "(add 3 4) (add 1 2)"; - let code = "(let ((a 3)) (out (add 1 a)) (out (add 2 a)))"; + let code = "(add 3 4) (add 1 2)"; + // let code = "(let ((a 3)) (out (add 1 a)) (out (add 2 a)))"; - let lexed: TokenString = dbg!((code.parse())?); + let lexed: TokenString = code.parse()?; let parsed: Vec = (lexed.try_into())?; - println!("{parsed:?}"); + for instruction in parsed.clone() { + println!("{instruction}"); + } - let code: IRepr = generate_code(parsed)?; + let code = generate_code(parsed)?; - // let code: EightBitLang = code.to_code(&mut Scope::new())?; + let code: Code = code.into(); dbg!(code); /* diff --git a/src/parser.rs b/src/parser.rs index 9dc9bd8..acd1044 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -65,8 +65,7 @@ impl SExpression { state.expression[state.index].row, state.expression[state.index].col ))), }; - - dbg!(expr) + expr } fn parse_expression(state: &mut State) -> Result { @@ -78,7 +77,7 @@ impl SExpression { } state.index += 1; - let expression_1 = dbg!(Self::parse_sexpression(state)?); + let expression_1 = Self::parse_sexpression(state)?; state.index += 1; // Is pair