diff --git a/compiler/src/backend/dsa/codegen.rs b/compiler/src/backend/dsa/codegen.rs index 4ca3c8e..ae85ba1 100644 --- a/compiler/src/backend/dsa/codegen.rs +++ b/compiler/src/backend/dsa/codegen.rs @@ -5,12 +5,14 @@ use std::time::SystemTime; use chrono::{DateTime, Local}; use super::registers::RegisterAllocator; +use crate::backend::dsa::instruction::CodeGen; use crate::backend::dsa::registers::Register; +use crate::backend::dsa::variable::{ScopeKind, ScopeManager}; use crate::{block, comment, dsa}; use crate::model::{ AssignmentOperator, BinaryOperator, Call, CompilerError, ConstExpr, Declaration, - Dependency, Expression, Program, Statement, TypeId, UnaryOperator, Variable, + Dependency, Expression, Name, Program, Statement, TypeId, UnaryOperator, Variable, }; pub struct CodeGenerator { @@ -52,6 +54,50 @@ impl CodeGenerator { } pub fn generate(&mut self) -> Result { + // let mut codegen = CodeGen::new(); + // let mut scope_mgr = ScopeManager::new(); + // scope_mgr.enter_scope(ScopeKind::Global); + // scope_mgr.enter_scope(ScopeKind::Function); + + // let point_type = TypeId::Struct { + // name: Name::new("Point", None), + // fields: vec![TypeId::U32, TypeId::U32], + // generics: vec![], + // }; + + // let p_var = scope_mgr.declare_var("p".into(), point_type)?; + // scope_mgr.allocate_var(p_var, false)?; // Force stack (struct too big) + + // // Access p.x (offset 0, size 4) + // let (x_reg, load_block) = scope_mgr.access_member(p_var, 0, 4)?; + // codegen.emit_block(load_block); + + // // Store to p.y (offset 4, size 4) + // let value_reg = Register::Rg0; // assume value is here + // let store_block = scope_mgr.store_member(p_var, 4, 4, value_reg)?; + // codegen.emit_block(store_block); + + // scope_mgr.enter_scope(ScopeKind::Loop); + // let pointer = scope_mgr + // .declare_var("pointer".into(), TypeId::Ptr(Box::new(TypeId::U32)))?; + // scope_mgr.allocate_var(pointer, true)?; + + // scope_mgr.enter_scope(ScopeKind::Function); + // let var2 = scope_mgr.declare_var("var2".into(), TypeId::U32)?; + // scope_mgr.allocate_var(var2, true)?; + // let array = scope_mgr.declare_var( + // "pointer".into(), + // TypeId::Array { + // r#type: Box::new(TypeId::U32), + // size: 10, + // }, + // )?; + // scope_mgr.allocate_var(array, false)?; + + // println!("{}", scope_mgr); + + // return Ok(String::new()); + // always include the print library for debugging! self.include("print", "./lib/io/print.dsa"); diff --git a/compiler/src/backend/dsa/mod.rs b/compiler/src/backend/dsa/mod.rs index 8ee13d7..9b7ed48 100644 --- a/compiler/src/backend/dsa/mod.rs +++ b/compiler/src/backend/dsa/mod.rs @@ -1,7 +1,10 @@ use crate::model::{CompilerError, Program}; mod codegen; +mod instruction; mod registers; +mod scope; +mod variable; pub fn generate_code(ast: &Program) -> Result { let mut codegen = codegen::CodeGenerator::new(ast.clone()); diff --git a/compiler/src/backend/dsa/registers.rs b/compiler/src/backend/dsa/registers.rs index 2436b8c..7539182 100644 --- a/compiler/src/backend/dsa/registers.rs +++ b/compiler/src/backend/dsa/registers.rs @@ -501,6 +501,7 @@ impl RegisterAllocator { #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum Register { + // general purpose Rg0 = 0, Rg1 = 1, Rg2 = 2, @@ -517,8 +518,68 @@ pub enum Register { Rgd = 13, Rge = 14, Rgf = 15, - Zero = 16, - Null = 17, + + // special + Bpr, + Spr, + Ret, + Acc, + + // read only + Pcx, + Zero, + + // null + Null, +} + +impl Register { + pub fn get_gp() -> [Register; 16] { + [ + Register::Rg0, + Register::Rg1, + Register::Rg2, + Register::Rg3, + Register::Rg4, + Register::Rg5, + Register::Rg6, + Register::Rg7, + Register::Rg8, + Register::Rg9, + Register::Rga, + Register::Rgb, + Register::Rgc, + Register::Rgd, + Register::Rge, + Register::Rgf, + ] + } + + pub fn is_gp(&self) -> bool { + (*self as u8) < 16 + } + + pub fn from_index(idx: usize) -> Register { + match idx { + 0 => Register::Rg0, + 1 => Register::Rg1, + 2 => Register::Rg2, + 3 => Register::Rg3, + 4 => Register::Rg4, + 5 => Register::Rg5, + 6 => Register::Rg6, + 7 => Register::Rg7, + 8 => Register::Rg8, + 9 => Register::Rg9, + 10 => Register::Rga, + 11 => Register::Rgb, + 12 => Register::Rgc, + 13 => Register::Rgd, + 14 => Register::Rge, + 15 => Register::Rgf, + _ => unreachable!("this function shouldn't ever be called with idx>15"), + } + } } impl fmt::Display for Register { @@ -540,7 +601,15 @@ impl fmt::Display for Register { Self::Rgd => write!(f, "rgd"), Self::Rge => write!(f, "rge"), Self::Rgf => write!(f, "rgf"), + + Self::Acc => write!(f, "acc"), + Self::Ret => write!(f, "ret"), + Self::Bpr => write!(f, "bpr"), + Self::Spr => write!(f, "spr"), + Self::Zero => write!(f, "zero"), + Self::Pcx => write!(f, "pcx"), + Self::Null => write!(f, "null"), } } diff --git a/compiler/src/model.rs b/compiler/src/model.rs index 83969b7..6b00fa4 100644 --- a/compiler/src/model.rs +++ b/compiler/src/model.rs @@ -19,6 +19,14 @@ pub struct Name { pub name: String, pub namespace: Option, } +impl Name { + pub fn new(name: impl Into, namespace: Option) -> Self { + Self { + name: name.into(), + namespace, + } + } +} #[derive(Debug, Clone)] pub struct Program {