Work on asm.
This commit is contained in:
parent
aefac57b9d
commit
6b855b8ebb
13
dmc-lib/src/asm/asm_block.rs
Normal file
13
dmc-lib/src/asm/asm_block.rs
Normal 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 }
|
||||
}
|
||||
}
|
||||
16
dmc-lib/src/asm/asm_function.rs
Normal file
16
dmc-lib/src/asm/asm_function.rs
Normal 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
79
dmc-lib/src/asm/asm_instruction.rs
Normal file
79
dmc-lib/src/asm/asm_instruction.rs
Normal 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
3
dmc-lib/src/asm/mod.rs
Normal file
@ -0,0 +1,3 @@
|
||||
pub mod asm_block;
|
||||
pub mod asm_function;
|
||||
pub mod asm_instruction;
|
||||
@ -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!()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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]
|
||||
|
||||
7
dmc-lib/src/ir/assemble_context.rs
Normal file
7
dmc-lib/src/ir/assemble_context.rs
Normal file
@ -0,0 +1,7 @@
|
||||
pub struct AssembleContext {}
|
||||
|
||||
impl AssembleContext {
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,4 +18,12 @@ impl IrStringConstant {
|
||||
name: name.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn value(&self) -> &str {
|
||||
&self.value
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
use crate::ir::ir_variable::IrVariable;
|
||||
|
||||
pub enum IrLhs {
|
||||
Variable(IrVariable),
|
||||
FunctionName(String),
|
||||
}
|
||||
@ -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),
|
||||
}
|
||||
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
mod asm;
|
||||
mod ast;
|
||||
mod diagnostic;
|
||||
mod ir;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user