Skip to content

Commit

Permalink
[IR] adding function arguments which actually work + you can now add …
Browse files Browse the repository at this point in the history
…to variables
  • Loading branch information
Cr0a3 committed Jul 10, 2024
1 parent b5a4956 commit 3824561
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 29 deletions.
5 changes: 3 additions & 2 deletions examples/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ pub fn main() -> Result<(), Box<dyn Error>> {
let mut module = Module::new();
let mut builder = IRBuilder::new();

let ty = FunctionType::new(vec![TypeMetadata::i32, TypeMetadata::i32], TypeMetadata::i32);
let func = module.add(
"func", FunctionType::new(vec![], TypeMetadata::i32)
"add", &ty
);

let entry = func.addBlock("entry");
builder.positionAtEnd(entry);

let val = builder.BuildAdd(Type::i32(5), Type::i32(5))?;
let val = builder.BuildAdd(ty.arg(0), ty.arg(1));

builder.BuildRet( val );

Expand Down
4 changes: 2 additions & 2 deletions src/IR/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ pub struct Block {

impl Block {
/// Creates a new block
pub fn new(name: &str, _func: &Function) -> Self {
pub fn new(name: &str, func: &Function) -> Self {
Self {
//func: func.clone(),
name: name.to_string(),
nodes: vec![],
varCount: 0,
varCount: func.ty.args.len(),
}
}

Expand Down
26 changes: 20 additions & 6 deletions src/IR/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::collections::VecDeque;

use super::Block;
use super::TypeMetadata;
use super::Var;
use super::VerifyError;
use crate::Support::Colorize;

Expand Down Expand Up @@ -33,15 +34,26 @@ impl FunctionType {
ret: ret,
}
}

/// Returns the argument as a var
/// If the num doesn't exists, it panics
pub fn arg(&self, num: usize) -> Var {
for (n, meta) in &self.args {
if *n == num {
return Var { name: format!("%{}", n), ty: *meta }
}
}

todo!("display error that var doesn't exists")
}
}

/// A ir function with a known variable and arg size and count
#[derive(Debug, Clone)]
pub struct Function {
/// The function type
pub ty: FunctionType,

pub(crate) ret: TypeMetadata,

pub(crate) name: String,

pub(crate) inline: bool,
Expand All @@ -53,7 +65,6 @@ impl Function {
pub fn new(name: String, ty: FunctionType) -> Self {
Self {
ty: ty,
ret: TypeMetadata::Void,

blocks: VecDeque::new(),

Expand All @@ -77,7 +88,7 @@ impl Function {
pub fn dump(&self) -> String {
let mut string = String::new();

string += &format!("define {} @{}({}) {{\n", self.ret, self.name, {
string += &format!("define {} @{}({}) {{\n", self.ty.ret, self.name, {
let mut fmt = String::new();

for (name, metadata) in &self.ty.args {
Expand All @@ -100,11 +111,14 @@ impl Function {
pub fn dumpColored(&self) -> String {
let mut string = String::new();

string += &format!("{} {} @{}({}) {{\n", "define".blue(), self.ret.to_string().green(), self.name.cyan(), {
string += &format!("{} {} @{}({}) {{\n", "define".blue(), self.ty.ret.to_string().green(), self.name.cyan(), {
let mut fmt = String::new();

for (name, metadata) in &self.ty.args {
fmt += &format!("{} {},", metadata.to_string().blue(), format!("{}", name).green());
fmt += &format!(" {} {}, ", metadata.to_string().cyan(), format!("%{}", name).magenta());
}
if self.ty.args.len() != 0 {
fmt.remove(fmt.len() - 2); // The last comma
}

fmt
Expand Down
76 changes: 59 additions & 17 deletions src/IR/ir.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{error::Error, fmt::Debug};
use std::fmt::Debug;
use super::{FunctionType, IRBuilder, Type, TypeMetadata, Var, VerifyError};

macro_rules! IrTypeWith3 {
Expand Down Expand Up @@ -97,7 +97,7 @@ impl Ir for Return<Type> {

fn dumpColored(&self) -> String {
let metadata: TypeMetadata = self.inner1.into();
format!("{} {} {}", "ret".blue(), metadata.to_string().green(), self.inner1.val().to_string().blue())
format!("{} {} {}", "ret".blue(), metadata.to_string().cyan(), self.inner1.val().to_string().blue())
}

fn verify(&self, FuncTy: FunctionType) -> Result<(), VerifyError> {
Expand All @@ -121,7 +121,7 @@ impl Ir for Return<Var> {
}

fn dumpColored(&self) -> String {
format!("{} {} {}", "ret".blue(), self.inner1.ty.to_string().green(), self.inner1.name.to_string().blue())
format!("{} {} {}", "ret".blue(), self.inner1.ty.to_string().cyan(), self.inner1.name.to_string().magenta())
}

fn verify(&self, FuncTy: FunctionType) -> Result<(), VerifyError> {
Expand All @@ -148,17 +148,49 @@ impl Ir for Add<Type, Type, Var> {
format!("{} = {} {} {}, {}",
self.inner3.name.magenta(),
"add".blue(),
self.inner3.ty.to_string().green(),
self.inner1.val().to_string().blue(),
self.inner2.val().to_string().blue()
self.inner3.ty.to_string().cyan(),
self.inner1.val().to_string().magenta(),
self.inner2.val().to_string().magenta()
)
}

fn verify(&self, FuncTy: FunctionType) -> Result<(), VerifyError> {
let ty: TypeMetadata = self.inner1.into();
fn verify(&self, _: FunctionType) -> Result<(), VerifyError> {
Ok(())
}
}

if ty != FuncTy.ret {
Err(VerifyError::RetTyNotFnTy(ty, FuncTy.ret))?
impl Ir for Add<Var, Var, Var> {
fn clone_box(&self) -> Box<dyn Ir> {
Box::new(self.clone())
}

fn dump(&self) -> String {
format!("{} = add {} {}, {}", self.inner3.name, self.inner3.ty, self.inner1.name, self.inner2.name)
}

fn dumpColored(&self) -> String {
format!("{} = {} {} {}, {}",
self.inner3.name.magenta(),
"add".blue(),
self.inner3.ty.to_string().cyan(),
self.inner1.name.to_string().magenta(),
self.inner2.name.to_string().magenta()
)
}

fn verify(&self, _: FunctionType) -> Result<(), VerifyError> {
let op0Ty: TypeMetadata = self.inner1.ty.into();
let op1Ty: TypeMetadata = self.inner2.ty.into();
let op2Ty: TypeMetadata = self.inner3.ty.into();

if !(op0Ty == op1Ty && op1Ty == op2Ty) {
if op0Ty != op1Ty {
Err(VerifyError::Op0Op1TyNoMatch(op0Ty, op1Ty))?
} else if op1Ty != op2Ty {
Err(VerifyError::Op0Op1TyNoMatch(op1Ty, op2Ty))?
} if op0Ty != op2Ty {
Err(VerifyError::Op0Op1TyNoMatch(op0Ty, op2Ty))?
} else { todo!("unknown error variant (debug: ty0 {} ty1 {} ty2 {})", op0Ty, op1Ty, op2Ty) }
}

Ok(())
Expand Down Expand Up @@ -192,26 +224,36 @@ impl BuildReturn<Var> for IRBuilder<'_> {
/// So you can return a TypeConstant or a variable
pub trait BuildAdd<T, U> {
/// Adds to values
fn BuildAdd(&mut self, op0: T, op1: U) -> Result<Var, Box<dyn Error>>;
fn BuildAdd(&mut self, op0: T, op1: U) -> Var;
}

impl BuildAdd<Type, Type> for IRBuilder<'_> {
fn BuildAdd(&mut self, op0: Type, op1: Type) -> Result<Var, Box<dyn Error>> {
fn BuildAdd(&mut self, op0: Type, op1: Type) -> Var {
let block = self.blocks.get_mut(self.curr).expect("the IRBuilder needs to have an current block\nConsider creating one");

let op0Ty: TypeMetadata = op0.into();
let op1Ty: TypeMetadata = op1.into();

if op0Ty != op1Ty {
Err(VerifyError::Op0Op1TyNoMatch(op0Ty, op1Ty))?
}
let ty = op0Ty; // now both types need to be the same
let var = Var::new(block, ty);

block.push_ir(Add::new(op0, op1, var.clone()));

var
}
}

impl BuildAdd<Var, Var> for IRBuilder<'_> {
fn BuildAdd(&mut self, op0: Var, op1: Var) -> Var {
let block = self.blocks.get_mut(self.curr).expect("the IRBuilder needs to have an current block\nConsider creating one");

let op0Ty: TypeMetadata = op0.ty.into();

let ty = op0Ty; // now both types need to be the same
let var = Var::new(block, ty);

block.push_ir(Add::new(op0, op1, var.clone()));

Ok(var)
var
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/IR/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ impl Module {
}

/// Adds a new function to the module
pub fn add(&mut self, name: &str, ty: FunctionType) -> &mut Function {
pub fn add(&mut self, name: &str, ty: &FunctionType) -> &mut Function {
self.funcs
.insert(name.to_string(), Function::new(name.to_string(), ty));
.insert(name.to_string(), Function::new(name.to_string(), ty.to_owned()));
self.funcs.get_mut(name).unwrap()
}

Expand Down

0 comments on commit 3824561

Please sign in to comment.