Beginning
This commit is contained in:
		
							parent
							
								
									d9bea76666
								
							
						
					
					
						commit
						d81272f085
					
				
							
								
								
									
										199
									
								
								src/code_gen.rs
									
									
									
									
									
								
							
							
						
						
									
										199
									
								
								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::ir::{Command, IRepr};
 | 
				
			||||||
 | 
					 | 
				
			||||||
use crate::{
 | 
					 | 
				
			||||||
    lexer::Keyword,
 | 
					 | 
				
			||||||
    parser::{LispAtom, SExpression},
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 | 
					#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 | 
				
			||||||
enum InstructionFrom {
 | 
					enum InstructionFrom {
 | 
				
			||||||
| 
						 | 
					@ -40,144 +35,124 @@ enum InstructionTo {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    RegisterSP,
 | 
					    RegisterSP,
 | 
				
			||||||
    RegisterSB,
 | 
					    RegisterSB,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    IncSP,
 | 
				
			||||||
 | 
					    DecSP,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 | 
					#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 | 
				
			||||||
struct Command {
 | 
					struct Instruction {
 | 
				
			||||||
    data_from: InstructionFrom,
 | 
					    from: InstructionFrom,
 | 
				
			||||||
    data_to: InstructionTo,
 | 
					    to: InstructionTo,
 | 
				
			||||||
    data: i8,
 | 
					    value: i8,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone, PartialEq, Eq)]
 | 
					#[derive(Debug, Clone, PartialEq, Eq)]
 | 
				
			||||||
pub struct Scope {
 | 
					pub struct Code {
 | 
				
			||||||
    variables: Vec<String>,
 | 
					    instructions: Vec<Instruction>,
 | 
				
			||||||
    stack_position: usize,
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone, PartialEq, Eq)]
 | 
					impl From<IRepr> for Code {
 | 
				
			||||||
pub struct EightBitLang {
 | 
					    fn from(value: IRepr) -> Self {
 | 
				
			||||||
    instructions: Vec<Command>,
 | 
					        value.commands.into_iter().map(|x| Code::from(x)).sum()
 | 
				
			||||||
    labels: Option<HashMap<String, usize>>,
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub trait GenerateCode {
 | 
					impl From<Command> for Code {
 | 
				
			||||||
    fn to_code(self, codegen_scope: &mut Scope) -> Result<EightBitLang, Self::Error>
 | 
					    fn from(value: Command) -> Self {
 | 
				
			||||||
    where
 | 
					        use Instruction as I;
 | 
				
			||||||
        Self: Sized;
 | 
					        use InstructionFrom as IF;
 | 
				
			||||||
 | 
					        use InstructionTo as IT;
 | 
				
			||||||
    type Error;
 | 
					        match value {
 | 
				
			||||||
}
 | 
					            Command::PopR1 => vec![
 | 
				
			||||||
 | 
					                I::new(IF::RegisterSP, IT::RamAddressLower, 0x00),
 | 
				
			||||||
impl GenerateCode for SExpression {
 | 
					                I::new(IF::RAM, IT::RegisterA, 0x00),
 | 
				
			||||||
    fn to_code(self, codegen_scope: &mut Scope) -> Result<EightBitLang, Self::Error> {
 | 
					                I::new(IF::ROM, IT::DecSP, 0x00),
 | 
				
			||||||
        match self {
 | 
					            ],
 | 
				
			||||||
            SExpression::Atom(a) => a.to_code(codegen_scope),
 | 
					            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!(),
 | 
					            _ => todo!(),
 | 
				
			||||||
 | 
					        }.into()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    type Error = Error;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl GenerateCode for LispAtom {
 | 
					impl AddAssign for Code {
 | 
				
			||||||
    fn to_code(self, codegen_scope: &mut Scope) -> Result<EightBitLang, Self::Error> {
 | 
					 | 
				
			||||||
        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<EightBitLang, Self::Error> {
 | 
					 | 
				
			||||||
        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<EightBitLang, Self::Error> {
 | 
					 | 
				
			||||||
        match self {
 | 
					 | 
				
			||||||
            _ => todo!(),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    type Error = Error;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl AddAssign for EightBitLang {
 | 
					 | 
				
			||||||
    fn add_assign(&mut self, mut rhs: Self) {
 | 
					    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);
 | 
					        self.instructions.append(&mut rhs.instructions);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl From<Command> for EightBitLang {
 | 
					impl AddAssign<Instruction> for Code {
 | 
				
			||||||
    fn from(value: Command) -> Self {
 | 
					    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<Instruction> for Code {
 | 
				
			||||||
 | 
					    fn add(mut self, rhs: Instruction) -> Self::Output {
 | 
				
			||||||
 | 
					        self += rhs;
 | 
				
			||||||
 | 
					        self
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    type Output = Self;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl From<Vec<Instruction>> for Code {
 | 
				
			||||||
 | 
					    fn from(value: Vec<Instruction>) -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            instructions: vec![value],
 | 
					            instructions: value,
 | 
				
			||||||
            labels: None,
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl EightBitLang {
 | 
					impl Sum for Code {
 | 
				
			||||||
    fn push(value: i8, codegen_scope: &mut Scope) -> Self {
 | 
					    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
 | 
				
			||||||
        use InstructionFrom as IF;
 | 
					        let mut sum = Self::new();
 | 
				
			||||||
        use InstructionTo as IT;
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        codegen_scope.stack_position += 1;
 | 
					        for i in iter {
 | 
				
			||||||
 | 
					            sum += i;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut commands = Vec::new();
 | 
					        sum
 | 
				
			||||||
        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));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Code {
 | 
				
			||||||
 | 
					    fn new() -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            instructions: commands,
 | 
					            instructions: vec![]
 | 
				
			||||||
            labels: None,
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Command {
 | 
					impl Instruction {
 | 
				
			||||||
    fn new(data_from: InstructionFrom, data_to: InstructionTo, data: i8) -> Self {
 | 
					    fn new(from: InstructionFrom, to: InstructionTo, value: i8) -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            data_from,
 | 
					            from,
 | 
				
			||||||
            data_to,
 | 
					            to,
 | 
				
			||||||
            data,
 | 
					            value,
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Scope {
 | 
					 | 
				
			||||||
    pub fn new() -> Self {
 | 
					 | 
				
			||||||
        Self {
 | 
					 | 
				
			||||||
            variables: Vec::new(),
 | 
					 | 
				
			||||||
            stack_position: 0,
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/ir.rs
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/ir.rs
									
									
									
									
									
								
							| 
						 | 
					@ -12,11 +12,11 @@ use crate::{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone, PartialEq, Eq)]
 | 
					#[derive(Debug, Clone, PartialEq, Eq)]
 | 
				
			||||||
pub struct IRepr {
 | 
					pub struct IRepr {
 | 
				
			||||||
    commands: Vec<Command>,
 | 
					    pub commands: Vec<Command>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone, PartialEq, Eq)]
 | 
					#[derive(Debug, Clone, PartialEq, Eq)]
 | 
				
			||||||
enum Command {
 | 
					pub enum Command {
 | 
				
			||||||
    PushInt(isize),
 | 
					    PushInt(isize),
 | 
				
			||||||
    PushSum,
 | 
					    PushSum,
 | 
				
			||||||
    PopR1,
 | 
					    PopR1,
 | 
				
			||||||
| 
						 | 
					@ -168,9 +168,6 @@ impl ToIRMacro for Macro {
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                dbg!(&commands);
 | 
					 | 
				
			||||||
                dbg!(&ir_scope);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                while body != NIL {
 | 
					                while body != NIL {
 | 
				
			||||||
                    match body {
 | 
					                    match body {
 | 
				
			||||||
                        SExpression::Atom(_a) => todo!(),
 | 
					                        SExpression::Atom(_a) => todo!(),
 | 
				
			||||||
| 
						 | 
					@ -181,12 +178,11 @@ impl ToIRMacro for Macro {
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                dbg!(&commands);
 | 
					 | 
				
			||||||
                dbg!(&ir_scope);
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                commands += Command::Leave;
 | 
					                commands += Command::Leave;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                todo!()
 | 
					                ir_scope.stack_position = ir_scope.stack_positions.pop().unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Ok(commands)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            _ => todo!(),
 | 
					            _ => todo!(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										21
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								src/main.rs
									
									
									
									
									
								
							| 
						 | 
					@ -8,12 +8,11 @@ mod error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use color_eyre::eyre::Result;
 | 
					use color_eyre::eyre::Result;
 | 
				
			||||||
// pub use error::*;
 | 
					// pub use error::*;
 | 
				
			||||||
use ir::IRepr;
 | 
					 | 
				
			||||||
use lexer::TokenString;
 | 
					 | 
				
			||||||
use parser::SExpression;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
    code_gen::{EightBitLang, GenerateCode, Scope},
 | 
					    code_gen::Code,
 | 
				
			||||||
 | 
					    lexer::TokenString,
 | 
				
			||||||
 | 
					    parser::SExpression,
 | 
				
			||||||
    ir::generate_code,
 | 
					    ir::generate_code,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,17 +22,19 @@ fn main() -> Result<()> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // let code = r#"(mul 2 (add 3 4))"#.to_string();
 | 
					    // let code = r#"(mul 2 (add 3 4))"#.to_string();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // let code = "(add 3 4) (add 1 2)";
 | 
					    let code = "(add 3 4) (add 1 2)";
 | 
				
			||||||
    let code = "(let ((a 3)) (out (add 1 a)) (out (add 2 a)))";
 | 
					    // 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<SExpression> = (lexed.try_into())?;
 | 
					    let parsed: Vec<SExpression> = (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);
 | 
					    dbg!(code);
 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,8 +65,7 @@ impl SExpression {
 | 
				
			||||||
                state.expression[state.index].row, state.expression[state.index].col
 | 
					                state.expression[state.index].row, state.expression[state.index].col
 | 
				
			||||||
            ))),
 | 
					            ))),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					        expr
 | 
				
			||||||
        dbg!(expr)
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn parse_expression(state: &mut State) -> Result<Self, Error> {
 | 
					    fn parse_expression(state: &mut State) -> Result<Self, Error> {
 | 
				
			||||||
| 
						 | 
					@ -78,7 +77,7 @@ impl SExpression {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        state.index += 1;
 | 
					        state.index += 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let expression_1 = dbg!(Self::parse_sexpression(state)?);
 | 
					        let expression_1 = Self::parse_sexpression(state)?;
 | 
				
			||||||
        state.index += 1;
 | 
					        state.index += 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Is pair
 | 
					        // Is pair
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue