Work on asm.

This commit is contained in:
Jesse Brault 2026-02-27 21:33:28 -06:00
parent aefac57b9d
commit 6b855b8ebb
18 changed files with 279 additions and 23 deletions

View File

@ -0,0 +1,13 @@
use crate::asm::asm_instruction::AsmInstruction;
#[derive(Debug)]
pub struct AsmBlock {
id: usize,
instructions: Vec<AsmInstruction>,
}
impl AsmBlock {
pub fn new(id: usize, instructions: Vec<AsmInstruction>) -> Self {
Self { id, instructions }
}
}

View File

@ -0,0 +1,16 @@
use crate::asm::asm_block::AsmBlock;
#[derive(Debug)]
pub struct AsmFunction {
name: String,
blocks: Vec<AsmBlock>,
}
impl AsmFunction {
pub fn new(name: &str, blocks: Vec<AsmBlock>) -> Self {
Self {
name: name.into(),
blocks,
}
}
}

View File

@ -0,0 +1,79 @@
#[derive(Debug)]
pub enum AsmInstruction {
Move(Move),
Push(Push),
Pop(Pop),
InvokePlatformStatic(InvokePlatformStatic),
LoadConstant(LoadConstant),
}
#[derive(Debug)]
pub enum Operand {
IntegerLiteral(i64),
Register(usize),
}
#[derive(Debug)]
pub struct Move {
source: Operand,
destination_register: usize,
}
impl Move {
pub fn new(source: Operand, destination_register: usize) -> Self {
Self {
source,
destination_register,
}
}
}
#[derive(Debug)]
pub struct Push {
source: Operand,
}
impl Push {
pub fn new(source: Operand) -> Self {
Self { source }
}
}
#[derive(Debug)]
pub struct Pop {
destination_register: usize,
}
impl Pop {
pub fn new(destination_register: usize) -> Self {
Self {
destination_register,
}
}
}
#[derive(Debug)]
pub struct InvokePlatformStatic {
name: String,
}
impl InvokePlatformStatic {
pub fn new(name: &str) -> Self {
Self { name: name.into() }
}
}
#[derive(Debug)]
pub struct LoadConstant {
name: String,
destination_register: usize,
}
impl LoadConstant {
pub fn new(name: &str, destination_register: usize) -> Self {
LoadConstant {
name: name.into(),
destination_register,
}
}
}

3
dmc-lib/src/asm/mod.rs Normal file
View File

@ -0,0 +1,3 @@
pub mod asm_block;
pub mod asm_function;
pub mod asm_instruction;

View File

@ -1,6 +1,7 @@
use crate::ast::expression::Expression;
use crate::ast::function::FunctionLoweringContext;
use crate::diagnostic::Diagnostic;
use crate::ir::ir_expression::IrExpression;
use crate::ir::ir_statement::IrStatement;
use crate::symbol_table::SymbolTable;
@ -33,6 +34,19 @@ impl ExpressionStatement {
pub fn lower_to_ir(&self, context: &mut FunctionLoweringContext) {
let ir_expression = self.expression.lower_to_ir(context);
context.add_statement(IrStatement::Expression(ir_expression));
match ir_expression {
IrExpression::Call(ir_call) => {
context.add_statement(IrStatement::Call(ir_call));
}
IrExpression::Constant(ir_constant) => {
unimplemented!()
}
IrExpression::IntegerLiteral(i) => {
unimplemented!()
}
IrExpression::Variable(ir_variable) => {
unimplemented!()
}
}
}
}

View File

@ -89,7 +89,7 @@ impl Function {
for constant in context.take_constants() {
irs.push(Ir::Constant(constant));
}
let ir_function = IrFunction::new(context.take_statements());
let ir_function = IrFunction::new(&self.declared_name, context.take_statements());
irs.push(Ir::Function(ir_function));
irs
}

View File

@ -12,6 +12,8 @@ pub mod string_literal;
#[cfg(test)]
mod name_tests {
use crate::ir::Ir;
use crate::ir::assemble_context::AssembleContext;
use crate::parser::parse_compilation_unit;
use crate::symbol_table::SymbolTable;
@ -31,6 +33,15 @@ mod name_tests {
for ir in &irs {
println!("{:#?}", ir);
}
for ir in &irs {
match ir {
Ir::Function(ir_function) => {
let asm_function = ir_function.assemble(&mut AssembleContext::new());
println!("{:#?}", asm_function);
}
_ => {}
}
}
}
#[test]
@ -45,6 +56,15 @@ mod name_tests {
for ir in &irs {
println!("{:#?}", ir);
}
for ir in &irs {
match ir {
Ir::Function(ir_function) => {
let asm_function = ir_function.assemble(&mut AssembleContext::new());
println!("{:#?}", asm_function);
}
_ => {}
}
}
}
#[test]

View File

@ -0,0 +1,7 @@
pub struct AssembleContext {}
impl AssembleContext {
pub fn new() -> Self {
Self {}
}
}

View File

@ -1,3 +1,6 @@
use crate::asm::asm_instruction::{AsmInstruction, LoadConstant, Move, Operand, Pop};
use crate::ir::assemble_context::AssembleContext;
use crate::ir::ir_constant::IrConstant;
use crate::ir::ir_expression::IrExpression;
use crate::ir::ir_variable::IrVariable;
@ -14,4 +17,35 @@ impl IrAssign {
value: value.into(),
}
}
pub fn assemble(&self, context: &mut AssembleContext) -> Vec<AsmInstruction> {
let mut instructions = vec![];
match self.value.as_ref() {
IrExpression::Call(ir_call) => {
instructions.append(&mut ir_call.assemble(context));
instructions.push(AsmInstruction::Pop(Pop::new(self.destination.register())));
}
IrExpression::Constant(ir_constant) => match ir_constant {
IrConstant::String(ir_string_constant) => {
instructions.push(AsmInstruction::LoadConstant(LoadConstant::new(
ir_string_constant.name(),
self.destination.register(),
)));
}
},
IrExpression::IntegerLiteral(i) => {
instructions.push(AsmInstruction::Move(Move::new(
Operand::IntegerLiteral(*i),
self.destination.register(),
)));
}
IrExpression::Variable(ir_variable) => {
instructions.push(AsmInstruction::Move(Move::new(
Operand::Register(ir_variable.register()),
self.destination.register(),
)))
}
};
instructions
}
}

View File

@ -1,3 +1,8 @@
use crate::asm::asm_instruction::{
AsmInstruction, InvokePlatformStatic, LoadConstant, Operand, Push,
};
use crate::ir::assemble_context::AssembleContext;
use crate::ir::ir_constant::IrConstant;
use crate::ir::ir_expression::IrExpression;
#[derive(Debug)]
@ -13,4 +18,36 @@ impl IrCall {
arguments,
}
}
pub fn assemble(&self, context: &mut AssembleContext) -> Vec<AsmInstruction> {
let mut instructions = vec![];
for argument in &self.arguments {
match argument {
IrExpression::Call(ir_call) => {
instructions.append(&mut ir_call.assemble(context));
}
IrExpression::Constant(ir_constant) => {
match ir_constant {
IrConstant::String(string_constant) => {
instructions.push(AsmInstruction::LoadConstant(LoadConstant::new(
string_constant.name(),
0,
)));
}
}
instructions.push(AsmInstruction::Push(Push::new(Operand::Register(0))))
}
IrExpression::IntegerLiteral(i) => {
instructions.push(AsmInstruction::Push(Push::new(Operand::IntegerLiteral(*i))));
}
IrExpression::Variable(ir_variable) => instructions.push(AsmInstruction::Push(
Push::new(Operand::Register(ir_variable.register())),
)),
}
}
instructions.push(AsmInstruction::InvokePlatformStatic(
InvokePlatformStatic::new(&self.name),
));
instructions
}
}

View File

@ -18,4 +18,12 @@ impl IrStringConstant {
name: name.into(),
}
}
pub fn value(&self) -> &str {
&self.value
}
pub fn name(&self) -> &str {
&self.name
}
}

View File

@ -1,12 +1,28 @@
use crate::asm::asm_block::AsmBlock;
use crate::asm::asm_function::AsmFunction;
use crate::ir::assemble_context::AssembleContext;
use crate::ir::ir_statement::IrStatement;
#[derive(Debug)]
pub struct IrFunction {
name: String,
statements: Vec<IrStatement>,
}
impl IrFunction {
pub fn new(statements: Vec<IrStatement>) -> Self {
Self { statements }
pub fn new(name: &str, statements: Vec<IrStatement>) -> Self {
Self {
name: name.into(),
statements,
}
}
pub fn assemble(&self, context: &mut AssembleContext) -> AsmFunction {
let mut instructions = vec![];
for statement in &self.statements {
instructions.append(&mut statement.assemble(context));
}
let blocks = vec![AsmBlock::new(0, instructions)];
AsmFunction::new(&self.name, blocks)
}
}

View File

@ -1,6 +0,0 @@
use crate::ir::ir_variable::IrVariable;
pub enum IrLhs {
Variable(IrVariable),
FunctionName(String),
}

View File

@ -1,8 +0,0 @@
use crate::ir::ir_constant::IrConstant;
use crate::ir::ir_variable::IrVariable;
pub enum IrRhs {
Constant(IrConstant),
IntegerLiteral(i64),
Variable(IrVariable),
}

View File

@ -1,8 +1,19 @@
use crate::asm::asm_instruction::AsmInstruction;
use crate::ir::assemble_context::AssembleContext;
use crate::ir::ir_assign::IrAssign;
use crate::ir::ir_expression::IrExpression;
use crate::ir::ir_call::IrCall;
#[derive(Debug)]
pub enum IrStatement {
Assign(IrAssign),
Expression(IrExpression),
Call(IrCall),
}
impl IrStatement {
pub fn assemble(&self, context: &mut AssembleContext) -> Vec<AsmInstruction> {
match self {
IrStatement::Assign(ir_assign) => ir_assign.assemble(context),
IrStatement::Call(ir_call) => ir_call.assemble(context),
}
}
}

View File

@ -1,10 +1,22 @@
#[derive(Debug)]
pub struct IrVariable {
name: String,
register: Option<usize>,
}
impl IrVariable {
pub fn new(name: &str) -> Self {
Self { name: name.into() }
Self {
name: name.into(),
register: None,
}
}
pub fn set_register(&mut self, register: usize) {
self.register = Some(register);
}
pub fn register(&self) -> usize {
0
}
}

View File

@ -1,13 +1,12 @@
use crate::ir::ir_constant::IrConstant;
use crate::ir::ir_function::IrFunction;
pub mod assemble_context;
pub mod ir_assign;
pub mod ir_call;
pub mod ir_constant;
pub mod ir_expression;
pub mod ir_function;
pub mod ir_l_value;
pub mod ir_r_value;
pub mod ir_statement;
pub mod ir_variable;

View File

@ -1,3 +1,4 @@
mod asm;
mod ast;
mod diagnostic;
mod ir;