- fixed some clippy lints

- updated comments in compiler codegen
- deleted old dsa compiler outputs
- settings for zed
This commit is contained in:
2026-02-14 11:05:15 +00:00
parent 201b18069b
commit 7ccbd9258f
16 changed files with 138 additions and 641 deletions
+49 -56
View File
@@ -83,34 +83,27 @@ impl CodeGenerator {
let mut block = IB::new();
block.extend(vec![
I::comment("GENERATED BY DSC COMPILER"),
I::comment(format!(
"Generated at {}\n",
I::global_comment(format!(
"GENERATED BY DSC COMPILER
Generated at {}",
datetime.format("%Y-%m-%d %H:%M:%S")
)),
I::comment("Imports"),
I::Newline,
I::global_comment("Imports"),
]);
block.extend(
self.imports
.iter()
.map(|(_name, instruction)| instruction.clone())
.collect::<Vec<_>>(),
);
block.push(I::comment(""));
block.push(I::comment("Globals & Reserved Memory"));
block.extend(
self.globals
.iter()
.map(|(_name, instruction)| instruction.clone())
.collect::<Vec<_>>(),
);
block.extend(self.imports.values().cloned().collect::<Vec<_>>());
block.extend(vec![
I::comment(""),
I::comment("Entry Point"),
I::Newline,
I::global_comment("Globals & Reserved Memory"),
]);
block.extend(self.globals.values().cloned().collect::<Vec<_>>());
block.extend(vec![
I::Newline,
I::global_comment("Entry Point"),
I::db_word("stack", 0x10000),
I::db_string("message", "Process Exited with code:"),
// init function for stack setup.
@@ -127,8 +120,9 @@ impl CodeGenerator {
I::call("print::print_hex_word"),
I::pop(Register::Zero),
I::Hlt,
I::Newline,
// default return block boilerplate
I::comment("Return"),
I::global_comment("Return"),
I::label("_ret"),
I::mov(Register::Bpr, Register::Spr),
I::pop(Register::Bpr),
@@ -199,11 +193,8 @@ impl CodeGenerator {
.collect::<Vec<String>>()
.join(", ");
code.push(I::comment(format!(
"fn {name}({fmtparams}) -> {return_type}"
)));
code.extend(vec![
I::global_comment(format!("fn {name}({fmtparams}) -> {return_type}")),
I::label(name),
I::push(Register::Bpr),
I::mov(Register::Spr, Register::Bpr),
@@ -233,6 +224,8 @@ impl CodeGenerator {
code.push(I::jmp("_ret"));
}
code.insert(0, I::Newline);
code
}
@@ -336,19 +329,19 @@ impl CodeGenerator {
I::sub(var_reg, result_reg, temp_reg)
}
AssignmentOperator::MulAssign => {
return Err(CompilerError::Unimplemented(format!(
"TODO: implement multiplication for assignment"
)));
return Err(CompilerError::Unimplemented(
"TODO: implement multiplication for assignment".to_string(),
));
}
AssignmentOperator::DivAssign => {
return Err(CompilerError::Unimplemented(format!(
"TODO: write proper div function for DSA"
)));
return Err(CompilerError::Unimplemented(
"TODO: write proper div function for DSA".to_string(),
));
}
AssignmentOperator::ModAssign => {
return Err(CompilerError::Unimplemented(format!(
"TODO: write proper mod function for DSA"
)));
return Err(CompilerError::Unimplemented(
"TODO: write proper mod function for DSA".to_string(),
));
}
AssignmentOperator::AndAssign => {
I::and(var_reg, result_reg, temp_reg)
@@ -428,7 +421,7 @@ impl CodeGenerator {
code.append(self.generate_statement(s, func_body)?);
}
if then_stmt.len() == 0 {
if then_stmt.is_empty() {
code.push(I::Nop);
}
@@ -440,7 +433,7 @@ impl CodeGenerator {
code.append(self.generate_statement(s, func_body)?);
}
if else_stmt.len() == 0 {
if else_stmt.is_empty() {
code.push(I::Nop);
}
@@ -620,9 +613,9 @@ impl CodeGenerator {
code.push(I::pop(Register::Zero));
}
BinaryOperator::Div => {
return Err(CompilerError::Unimplemented(format!(
"TODO: write proper div function for DSA"
)));
return Err(CompilerError::Unimplemented(
"TODO: write proper div function for DSA".to_string(),
));
// self.include("maths", "./lib/maths/core.dsa");
// // Call divide function
// code.push(format!("\tpush {}", right_reg));
@@ -632,9 +625,9 @@ impl CodeGenerator {
// code.push("\tpop zero".to_string());
}
BinaryOperator::Mod => {
return Err(CompilerError::Unimplemented(format!(
"TODO: write proper mod function for DSA"
)));
return Err(CompilerError::Unimplemented(
"TODO: write proper mod function for DSA".to_string(),
));
// self.include("maths", "./lib/maths/core.dsa");
// // Call modulo function
// code.push(format!("\tpush {}", right_reg));
@@ -653,14 +646,14 @@ impl CodeGenerator {
code.push(I::xor(left_reg, right_reg, result_reg));
}
BinaryOperator::LogicalAnd => {
return Err(CompilerError::Unimplemented(format!(
"assembler/ISA does not yet support logical and!"
)));
return Err(CompilerError::Unimplemented(
"assembler/ISA does not yet support logical and!".to_string(),
));
}
BinaryOperator::LogicalOr => {
return Err(CompilerError::Unimplemented(format!(
"assembler/ISA does not yet support logical or!"
)));
return Err(CompilerError::Unimplemented(
"assembler/ISA does not yet support logical or!".to_string(),
));
}
BinaryOperator::LeftShift => {
code.push(I::shl(left_reg, right_reg, 0, result_reg));
@@ -816,9 +809,9 @@ impl CodeGenerator {
code.push(I::not(operand_reg, result_reg));
}
UnaryOperator::LogicalNot => {
return Err(CompilerError::Unimplemented(format!(
"Assembler/ISA does not yet support logical not"
)));
return Err(CompilerError::Unimplemented(
"Assembler/ISA does not yet support logical not".to_string(),
));
}
_ => {
return Err(CompilerError::Generic(format!(
@@ -932,9 +925,9 @@ impl CodeGenerator {
expr,
field_name,
type_id,
} => Err(CompilerError::Unimplemented(format!(
"Structs are not yet implemented!"
))),
} => Err(CompilerError::Unimplemented(
"Structs are not yet implemented!".to_string(),
)),
Expression::TypeCast {
expr,
+33 -5
View File
@@ -60,7 +60,11 @@ impl From<Instruction> for InsBlock {
pub enum Instruction {
// Labels and comments
Label(Label),
Comment(String),
Comment {
text: String,
top_level: bool,
},
Newline,
// Data Directives
Db {
@@ -287,7 +291,20 @@ impl fmt::Display for Instruction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Label(l) => write!(f, "{}:", l),
Self::Comment(c) => write!(f, "// {}", c),
Self::Newline => write!(f, ""), /* empty string as newlines are inserted */
// automatically.
Self::Comment { text, top_level } => write!(
f,
"{}",
text.lines()
.map(|line| format!(
"{}// {}",
if *top_level { "" } else { " " },
line.trim(),
))
.collect::<Vec<String>>()
.join("\n")
),
Self::Include { name, path } => write!(f, "include {name}: \"{}\"", path),
@@ -455,6 +472,7 @@ impl fmt::Display for Instruction {
}
}
}
impl Instruction {
// data directives
pub fn db_string(label: impl Into<String>, data: impl Into<String>) -> Self {
@@ -590,7 +608,7 @@ impl Instruction {
}
pub fn iadd(src: Register, value: i64) -> Self {
let imm = Imm(value.abs() as u32);
let imm = Imm(value.unsigned_abs() as u32);
if value < 0 {
Self::ISub {
@@ -608,7 +626,7 @@ impl Instruction {
}
pub fn iadd_dest(src: Register, value: i32, dest: Register) -> Self {
let imm = Imm(value.abs() as u32);
let imm = Imm(value.unsigned_abs());
if value < 0 {
Self::ISub {
@@ -702,7 +720,17 @@ impl Instruction {
// Utilities
pub fn comment(text: impl Into<String>) -> Self {
Self::Comment(text.into())
Self::Comment {
text: text.into(),
top_level: false,
}
}
pub fn global_comment(text: impl Into<String>) -> Self {
Self::Comment {
text: text.into(),
top_level: true,
}
}
pub fn include(name: impl Into<String>, path: impl Into<String>) -> Self {
+7 -19
View File
@@ -186,8 +186,7 @@ impl RegisterAllocator {
// Update location to register
self.variable_locations
.insert(var_name.to_string(), location);
self.register_contents
.insert(reg.clone(), var_name.to_string());
self.register_contents.insert(reg, var_name.to_string());
return Ok((reg, code));
}
@@ -197,8 +196,7 @@ impl RegisterAllocator {
let (reg, code) = self.alloc_temp()?;
self.variable_locations
.insert(var_name.to_string(), Location::register(reg));
self.register_contents
.insert(reg.clone(), var_name.to_string());
self.register_contents.insert(reg, var_name.to_string());
Ok((reg, code))
}
@@ -225,11 +223,12 @@ impl RegisterAllocator {
// Check if variable already has a location
if let Some(location) = self.variable_locations.get(var_name) {
// if the variable exists in a register we write to that.
if let Some(reg) = location.register {
if reg == *source_reg {
match location.register {
Some(reg) if reg == *source_reg => {
block.push(Instruction::mov(*source_reg, reg));
return block;
}
_ => (),
}
// if the variable exists on the stack but not a register we write here.
@@ -263,7 +262,7 @@ impl RegisterAllocator {
self.variable_locations
.insert(var_name.to_string(), Location::register(free_reg));
self.register_contents
.insert(free_reg.clone(), var_name.to_string());
.insert(free_reg, var_name.to_string());
self.in_use[free_reg as usize].1 = true;
block.push(Instruction::mov(*source_reg, free_reg));
@@ -428,17 +427,6 @@ impl RegisterAllocator {
.collect();
}
/// Mark a variable as dead (no longer needed)
/// Frees its register if it's in one
// pub fn _free_var(&mut self, var_name: &str) {
// if let Some(Location::Register(reg)) = self.variable_locations.get(var_name) {
// let reg = reg.clone();
// self.register_contents.remove(&reg);
// self.in_use.insert(reg, false);
// }
// self.variable_locations.remove(var_name);
// }
/// Get list of registers that contain variables and are in use
/// These need to be saved before function calls
pub fn get_caller_saved_registers(&self) -> Vec<Register> {
@@ -450,7 +438,7 @@ impl RegisterAllocator {
.unwrap_or(&(Register::Null, false))
.1
})
.map(|(reg, _)| reg.clone())
.map(|(reg, _)| *reg)
.collect()
}
}
+7 -6
View File
@@ -592,8 +592,7 @@ impl<'a> Lexer<'a> {
if c.is_ascii_digit() {
self.advance();
num_str.push(c);
} else if c == '_'
&& self.peek_second().map_or(false, |ch| ch.is_ascii_digit())
} else if c == '_' && self.peek_second().is_some_and(|ch| ch.is_ascii_digit())
{
// Allow underscores as separators only between digits
self.advance();
@@ -611,10 +610,11 @@ impl<'a> Lexer<'a> {
let mut num_str = String::new();
// Read the first hex digit (current character)
if let Some(c) = self.current {
if c.is_ascii_hexdigit() {
match self.current {
Some(c) if c.is_ascii_hexdigit() => {
num_str.push(c);
}
_ => (),
}
while let Some(c) = self.peek() {
@@ -640,10 +640,11 @@ impl<'a> Lexer<'a> {
let mut num_str = String::new();
// Read the first binary digit (current character)
if let Some(c) = self.current {
if c == '0' || c == '1' {
match self.current {
Some(c) if c == '0' || c == '1' => {
num_str.push(c);
}
_ => (),
}
while let Some(c) = self.peek() {
+2 -2
View File
@@ -123,7 +123,7 @@ impl Parser {
}
let _ = expect_tt!(self.next()?, RightBrace)?;
return ParseResult::Accept(Declaration::Struct { name, fields });
ParseResult::Accept(Declaration::Struct { name, fields })
}
fn parse_func(&mut self) -> ParseResult<Declaration, CompilerError> {
@@ -403,7 +403,7 @@ impl Parser {
let expr = self.parse_expression()?;
let _ = expect_tt!(self.next()?, Semicolon)?;
return ParseResult::Accept(Statement::Expression { expr });
ParseResult::Accept(Statement::Expression { expr })
}
fn parse_expression(&mut self) -> ParseResult<Expression, CompilerError> {
-2
View File
@@ -1,7 +1,5 @@
use std::path::Path;
use compiler;
fn main() {
// read from input file: syntax "c_compiler <src.c> [output.dsa]"
let args: Vec<String> = std::env::args().collect();