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::expression::Expression;
|
||||||
use crate::ast::function::FunctionLoweringContext;
|
use crate::ast::function::FunctionLoweringContext;
|
||||||
use crate::diagnostic::Diagnostic;
|
use crate::diagnostic::Diagnostic;
|
||||||
|
use crate::ir::ir_expression::IrExpression;
|
||||||
use crate::ir::ir_statement::IrStatement;
|
use crate::ir::ir_statement::IrStatement;
|
||||||
use crate::symbol_table::SymbolTable;
|
use crate::symbol_table::SymbolTable;
|
||||||
|
|
||||||
@ -33,6 +34,19 @@ impl ExpressionStatement {
|
|||||||
|
|
||||||
pub fn lower_to_ir(&self, context: &mut FunctionLoweringContext) {
|
pub fn lower_to_ir(&self, context: &mut FunctionLoweringContext) {
|
||||||
let ir_expression = self.expression.lower_to_ir(context);
|
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() {
|
for constant in context.take_constants() {
|
||||||
irs.push(Ir::Constant(constant));
|
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.push(Ir::Function(ir_function));
|
||||||
irs
|
irs
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,8 @@ pub mod string_literal;
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod name_tests {
|
mod name_tests {
|
||||||
|
use crate::ir::Ir;
|
||||||
|
use crate::ir::assemble_context::AssembleContext;
|
||||||
use crate::parser::parse_compilation_unit;
|
use crate::parser::parse_compilation_unit;
|
||||||
use crate::symbol_table::SymbolTable;
|
use crate::symbol_table::SymbolTable;
|
||||||
|
|
||||||
@ -31,6 +33,15 @@ mod name_tests {
|
|||||||
for ir in &irs {
|
for ir in &irs {
|
||||||
println!("{:#?}", ir);
|
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]
|
#[test]
|
||||||
@ -45,6 +56,15 @@ mod name_tests {
|
|||||||
for ir in &irs {
|
for ir in &irs {
|
||||||
println!("{:#?}", ir);
|
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]
|
#[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_expression::IrExpression;
|
||||||
use crate::ir::ir_variable::IrVariable;
|
use crate::ir::ir_variable::IrVariable;
|
||||||
|
|
||||||
@ -14,4 +17,35 @@ impl IrAssign {
|
|||||||
value: value.into(),
|
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;
|
use crate::ir::ir_expression::IrExpression;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -13,4 +18,36 @@ impl IrCall {
|
|||||||
arguments,
|
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(),
|
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;
|
use crate::ir::ir_statement::IrStatement;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct IrFunction {
|
pub struct IrFunction {
|
||||||
|
name: String,
|
||||||
statements: Vec<IrStatement>,
|
statements: Vec<IrStatement>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IrFunction {
|
impl IrFunction {
|
||||||
pub fn new(statements: Vec<IrStatement>) -> Self {
|
pub fn new(name: &str, statements: Vec<IrStatement>) -> Self {
|
||||||
Self { statements }
|
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_assign::IrAssign;
|
||||||
use crate::ir::ir_expression::IrExpression;
|
use crate::ir::ir_call::IrCall;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum IrStatement {
|
pub enum IrStatement {
|
||||||
Assign(IrAssign),
|
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)]
|
#[derive(Debug)]
|
||||||
pub struct IrVariable {
|
pub struct IrVariable {
|
||||||
name: String,
|
name: String,
|
||||||
|
register: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IrVariable {
|
impl IrVariable {
|
||||||
pub fn new(name: &str) -> Self {
|
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_constant::IrConstant;
|
||||||
use crate::ir::ir_function::IrFunction;
|
use crate::ir::ir_function::IrFunction;
|
||||||
|
|
||||||
|
pub mod assemble_context;
|
||||||
pub mod ir_assign;
|
pub mod ir_assign;
|
||||||
pub mod ir_call;
|
pub mod ir_call;
|
||||||
pub mod ir_constant;
|
pub mod ir_constant;
|
||||||
pub mod ir_expression;
|
pub mod ir_expression;
|
||||||
pub mod ir_function;
|
pub mod ir_function;
|
||||||
pub mod ir_l_value;
|
|
||||||
pub mod ir_r_value;
|
|
||||||
pub mod ir_statement;
|
pub mod ir_statement;
|
||||||
pub mod ir_variable;
|
pub mod ir_variable;
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
mod asm;
|
||||||
mod ast;
|
mod ast;
|
||||||
mod diagnostic;
|
mod diagnostic;
|
||||||
mod ir;
|
mod ir;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user