From 67edffeb5cf724e0c71c2b2b3cef32edc5280611 Mon Sep 17 00:00:00 2001 From: Zffu <103074097+Zffu@users.noreply.github.com> Date: Tue, 17 Mar 2026 15:27:03 +0100 Subject: [PATCH 1/7] =?UTF-8?q?=C3=83feat:=20added=20expected=20type=20par?= =?UTF-8?q?am=20to=20math=20parsing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- compiler/astoir_mir_lowering/src/math.rs | 8 ++++---- compiler/astoir_mir_lowering/src/values/mod.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/astoir_mir_lowering/src/math.rs b/compiler/astoir_mir_lowering/src/math.rs index 38ba0ed7..ddfc4bdd 100644 --- a/compiler/astoir_mir_lowering/src/math.rs +++ b/compiler/astoir_mir_lowering/src/math.rs @@ -1,12 +1,12 @@ use astoir_hir::{nodes::HIRNode}; use astoir_mir::{blocks::{refer::MIRBlockReference}, builder::{build_float_add, build_float_div, build_float_mul, build_float_sub, build_int_add, build_int_div, build_int_mul, build_int_sub}, vals::base::BaseMIRValue}; -use astoir_typing::base::BaseType; +use astoir_typing::{base::BaseType, compacted::CompactedType}; use compiler_errors::{IR_INVALID_NODE_TYPE, IR_REQ_VARIABLE_ASSIGN, errs::{BaseResult, base::BaseError}}; use lexer::toks::math::MathOperator; use crate::{MIRLoweringContext, values::lower_hir_value, vars::lower_hir_variable_reference}; -pub fn lower_hir_math_operation(block: MIRBlockReference, node: Box, ctx: &mut MIRLoweringContext) -> BaseResult { +pub fn lower_hir_math_operation(block: MIRBlockReference, node: Box, ctx: &mut MIRLoweringContext, expected: Option) -> BaseResult { if let HIRNode::MathOperation { left, right, operation, assignment } = *node { if assignment && !left.is_variable_reference() { return Err(BaseError::err(IR_REQ_VARIABLE_ASSIGN!().to_string())) @@ -20,8 +20,8 @@ pub fn lower_hir_math_operation(block: MIRBlockReference, node: Box, ct ptr = None } - let left_val = lower_hir_value(block, left, ctx, None)?; - let right_val = lower_hir_value(block, right, ctx, None)?; + let left_val = lower_hir_value(block, left, ctx, expected.clone())?; + let right_val = lower_hir_value(block, right, ctx, expected)?; let val = match left_val.vtype.base { diff --git a/compiler/astoir_mir_lowering/src/values/mod.rs b/compiler/astoir_mir_lowering/src/values/mod.rs index 67715aeb..77640d3e 100644 --- a/compiler/astoir_mir_lowering/src/values/mod.rs +++ b/compiler/astoir_mir_lowering/src/values/mod.rs @@ -14,7 +14,7 @@ pub fn lower_hir_value(block: MIRBlockReference, node: Box, ctx: &mut M HIRNode::VariableReference { .. } => return lower_hir_variable_reference_value(block, node, ctx), HIRNode::BooleanCondition { .. } => return Ok(lowering_hir_boolean_condition(block, node, ctx)?.into()), HIRNode::BooleanOperator { .. } => return Ok(lower_hir_boolean_operator(block, node, ctx)?.into()), - HIRNode::MathOperation { .. } => return Ok(lower_hir_math_operation(block, node, ctx)?), + HIRNode::MathOperation { .. } => return Ok(lower_hir_math_operation(block, node, ctx, expected)?), _ => return Err(BaseError::err(IR_INVALID_NODE_TYPE!().to_string())) } From 2120266dca13afb0502309ac254e703e9577c7fe Mon Sep 17 00:00:00 2001 From: Zffu <103074097+Zffu@users.noreply.github.com> Date: Tue, 17 Mar 2026 15:31:53 +0100 Subject: [PATCH 2/7] feat: passed expected type to most of the lowering functions involving variables & math --- compiler/astoir_mir_lowering/src/body.rs | 2 +- .../astoir_mir_lowering/src/control/forloop.rs | 2 +- compiler/astoir_mir_lowering/src/values/mod.rs | 2 +- compiler/astoir_mir_lowering/src/vars.rs | 16 +++++++++++++++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/compiler/astoir_mir_lowering/src/body.rs b/compiler/astoir_mir_lowering/src/body.rs index c61afc18..51730d4b 100644 --- a/compiler/astoir_mir_lowering/src/body.rs +++ b/compiler/astoir_mir_lowering/src/body.rs @@ -13,7 +13,7 @@ pub fn lower_hir_body_member(block: MIRBlockReference, node: Box, ctx: return Err(BaseError::err(MATH_OP_NO_ASSIGN!().to_string())) } - lower_hir_math_operation(block, node, ctx)?; + lower_hir_math_operation(block, node, ctx, None)?; return Ok(true); }, diff --git a/compiler/astoir_mir_lowering/src/control/forloop.rs b/compiler/astoir_mir_lowering/src/control/forloop.rs index 2cae06c8..cd330198 100644 --- a/compiler/astoir_mir_lowering/src/control/forloop.rs +++ b/compiler/astoir_mir_lowering/src/control/forloop.rs @@ -21,7 +21,7 @@ pub fn lower_hir_for_loop(block: MIRBlockReference, node: Box, ctx: &mu ctx.mir_ctx.writer.move_end(body_ref); lower_hir_body(body_ref, body, ctx)?; - lower_hir_math_operation(body_ref, incrementation, ctx)?; + lower_hir_math_operation(body_ref, incrementation, ctx, None)?; build_unconditional_branch(&mut ctx.mir_ctx, header_ref)?; diff --git a/compiler/astoir_mir_lowering/src/values/mod.rs b/compiler/astoir_mir_lowering/src/values/mod.rs index 77640d3e..90818555 100644 --- a/compiler/astoir_mir_lowering/src/values/mod.rs +++ b/compiler/astoir_mir_lowering/src/values/mod.rs @@ -11,7 +11,7 @@ pub mod booleans; pub fn lower_hir_value(block: MIRBlockReference, node: Box, ctx: &mut MIRLoweringContext, expected: Option) -> BaseResult { match *node { HIRNode::IntegerLiteral { .. } | HIRNode::StringLiteral { .. } => return lower_hir_literal(node, ctx, expected), - HIRNode::VariableReference { .. } => return lower_hir_variable_reference_value(block, node, ctx), + HIRNode::VariableReference { .. } => return lower_hir_variable_reference_value(block, node, ctx, expected), HIRNode::BooleanCondition { .. } => return Ok(lowering_hir_boolean_condition(block, node, ctx)?.into()), HIRNode::BooleanOperator { .. } => return Ok(lower_hir_boolean_operator(block, node, ctx)?.into()), HIRNode::MathOperation { .. } => return Ok(lower_hir_math_operation(block, node, ctx, expected)?), diff --git a/compiler/astoir_mir_lowering/src/vars.rs b/compiler/astoir_mir_lowering/src/vars.rs index 7107be77..94239f2e 100644 --- a/compiler/astoir_mir_lowering/src/vars.rs +++ b/compiler/astoir_mir_lowering/src/vars.rs @@ -1,5 +1,7 @@ //! Variable related lowering +use std::f32::consts::E; + use astoir_hir::{nodes::HIRNode}; use astoir_mir::{blocks::{MIRBlockVariableSSAHint, MIRBlockVariableType, refer::MIRBlockReference}, vals::{base::BaseMIRValue, refer::MIRVariableReference}}; use astoir_typing::compacted::CompactedType; @@ -49,9 +51,21 @@ pub fn lower_hir_variable_reference(block: MIRBlockReference, node: &Box, ctx: &mut MIRLoweringContext) -> BaseResult { +pub fn lower_hir_variable_reference_value(block: MIRBlockReference, node: Box, ctx: &mut MIRLoweringContext, expected: Option) -> BaseResult { let ptr = lower_hir_variable_reference(block, &node, ctx)?; + let read = ptr.read(block, &mut ctx.mir_ctx)?; + + if expected.is_some() { + let expected = expected.unwrap(); + + if !read.vtype.can_transmute(&expected) { + return Err(BaseError::err("Cannot transmute to given type!".to_string())); + } + + + } + return Ok(ptr.read(block, &mut ctx.mir_ctx)?); } From f9e2cdff73110dd2a070c8b68fc3c0c934957cd6 Mon Sep 17 00:00:00 2001 From: Zffu <103074097+Zffu@users.noreply.github.com> Date: Tue, 17 Mar 2026 15:50:42 +0100 Subject: [PATCH 3/7] feat: added transmutation --- compiler/astoir_mir/src/lib.rs | 3 +- compiler/astoir_mir/src/transmutation.rs | 43 ++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 compiler/astoir_mir/src/transmutation.rs diff --git a/compiler/astoir_mir/src/lib.rs b/compiler/astoir_mir/src/lib.rs index ebbe1c84..9317d9e4 100644 --- a/compiler/astoir_mir/src/lib.rs +++ b/compiler/astoir_mir/src/lib.rs @@ -7,4 +7,5 @@ pub mod blocks; pub mod builder; pub mod funcs; pub mod ctx; -pub mod inst_writer; \ No newline at end of file +pub mod inst_writer; +pub mod transmutation; \ No newline at end of file diff --git a/compiler/astoir_mir/src/transmutation.rs b/compiler/astoir_mir/src/transmutation.rs new file mode 100644 index 00000000..8f58a37b --- /dev/null +++ b/compiler/astoir_mir/src/transmutation.rs @@ -0,0 +1,43 @@ +//! Declarations for type transmutation in Quickfall. + +use astoir_typing::base::BaseType; +use compiler_errors::errs::{BaseResult, base::BaseError}; + +use crate::{builder::{build_downcast_int, build_upcast_int}, ctx::MIRContext, vals::base::BaseMIRValue}; + +/// Performs transmutation on the given value to try to get the targeted type. +pub fn transmute_value(val: BaseMIRValue, target: BaseType, ctx: &mut MIRContext) -> BaseResult { + if val.vtype.base.is_integer() != target.is_integer() || val.vtype.base.is_floating() != target.is_floating() || val.vtype.base.is_signed() != target.is_signed() { + return Err(BaseError::err("Cannot transmute value!".to_string())); + } + + if target.is_integer() { + let sz = val.vtype.base.get_size()?; + let newsz = target.get_size()?; + + if sz == newsz { + return Ok(val); + } + + if sz > newsz { + let res = build_downcast_int(ctx, val.as_int()?, newsz)?; + + return Ok(res.into()); + } else { + let res = build_upcast_int(ctx, val.as_int()?, newsz)?; + + return Ok(res.into()); + } + } + + if target.is_floating() { + let sz = val.vtype.base.get_floating_size()?; + let newsz = target.get_floating_size()?; + + // TODO: change this since floats cannot have two sizes for now + + return Ok(val); + } + + return Err(BaseError::err("Cannot transmute value!".to_string())); +} \ No newline at end of file From f31be9a09f397f9dd671a5d7decca7299b333e90 Mon Sep 17 00:00:00 2001 From: Zffu <103074097+Zffu@users.noreply.github.com> Date: Tue, 17 Mar 2026 15:57:54 +0100 Subject: [PATCH 4/7] feat: added transmutation to func ret type --- compiler/astoir_mir/src/builder.rs | 4 ++-- compiler/astoir_mir/src/insts/val.rs | 2 +- compiler/astoir_mir/src/transmutation.rs | 6 +++--- compiler/astoir_mir_lowering/src/funcs.rs | 24 +++++++++++++++++++---- compiler/astoir_mir_lowering/src/vars.rs | 4 ++-- compiler/compiler_errors/src/errors.rs | 7 +++++++ 6 files changed, 35 insertions(+), 12 deletions(-) diff --git a/compiler/astoir_mir/src/builder.rs b/compiler/astoir_mir/src/builder.rs index 6e0775be..e97ae528 100644 --- a/compiler/astoir_mir/src/builder.rs +++ b/compiler/astoir_mir/src/builder.rs @@ -388,7 +388,7 @@ pub fn build_static_string_const(ctx: &mut MIRContext, raw: String) -> BaseResul return res.as_ptr(); } -pub fn build_call(ctx: &mut MIRContext, func: usize, ind: usize, args: Vec) -> BaseResult { +pub fn build_call(ctx: &mut MIRContext, func: usize, ind: usize, args: Vec) -> BaseResult> { let func = &ctx.functions[func]; for(arg, t) in args.iter().zip(func.arguments.iter()) { @@ -397,7 +397,7 @@ pub fn build_call(ctx: &mut MIRContext, func: usize, ind: usize, args: Vec + pub val: Option } impl InstructionValue { diff --git a/compiler/astoir_mir/src/transmutation.rs b/compiler/astoir_mir/src/transmutation.rs index 8f58a37b..051810aa 100644 --- a/compiler/astoir_mir/src/transmutation.rs +++ b/compiler/astoir_mir/src/transmutation.rs @@ -1,14 +1,14 @@ //! Declarations for type transmutation in Quickfall. use astoir_typing::base::BaseType; -use compiler_errors::errs::{BaseResult, base::BaseError}; +use compiler_errors::{IR_TRANSMUTATION, errs::{BaseResult, base::BaseError}}; use crate::{builder::{build_downcast_int, build_upcast_int}, ctx::MIRContext, vals::base::BaseMIRValue}; /// Performs transmutation on the given value to try to get the targeted type. pub fn transmute_value(val: BaseMIRValue, target: BaseType, ctx: &mut MIRContext) -> BaseResult { if val.vtype.base.is_integer() != target.is_integer() || val.vtype.base.is_floating() != target.is_floating() || val.vtype.base.is_signed() != target.is_signed() { - return Err(BaseError::err("Cannot transmute value!".to_string())); + return Err(BaseError::err(IR_TRANSMUTATION!().to_string())); } if target.is_integer() { @@ -39,5 +39,5 @@ pub fn transmute_value(val: BaseMIRValue, target: BaseType, ctx: &mut MIRContext return Ok(val); } - return Err(BaseError::err("Cannot transmute value!".to_string())); + return Err(BaseError::err(IR_TRANSMUTATION!().to_string())); } \ No newline at end of file diff --git a/compiler/astoir_mir_lowering/src/funcs.rs b/compiler/astoir_mir_lowering/src/funcs.rs index 40c37a6c..05e72ef9 100644 --- a/compiler/astoir_mir_lowering/src/funcs.rs +++ b/compiler/astoir_mir_lowering/src/funcs.rs @@ -1,7 +1,7 @@ use astoir_hir::{nodes::HIRNode}; -use astoir_mir::{blocks::refer::MIRBlockReference, builder::build_call, funcs::MIRFunction, vals::base::BaseMIRValue}; +use astoir_mir::{blocks::refer::MIRBlockReference, builder::build_call, funcs::MIRFunction, transmutation::transmute_value, vals::base::BaseMIRValue}; use astoir_typing::compacted::CompactedType; -use compiler_errors::{IR_FUNCTION_INVALID_ARGUMENTS, IR_INVALID_NODE_TYPE, errs::{BaseResult, base::BaseError}}; +use compiler_errors::{IR_FUNCTION_INVALID_ARGUMENTS, IR_INVALID_NODE_TYPE, IR_TRANSMUTATION, errs::{BaseResult, base::BaseError}}; use crate::{MIRLoweringContext, body::lower_hir_body, values::lower_hir_value}; @@ -59,7 +59,7 @@ pub fn lower_hir_shadow_decl(node: Box, ctx: &mut MIRLoweringContext) - return Err(BaseError::err(IR_INVALID_NODE_TYPE!().to_string())) } -pub fn lower_hir_function_call(block: MIRBlockReference, node: Box, ctx: &mut MIRLoweringContext) -> BaseResult { +pub fn lower_hir_function_call(block: MIRBlockReference, node: Box, ctx: &mut MIRLoweringContext, expected: Option) -> BaseResult> { if let HIRNode::FunctionCall { func_name, arguments } = *node { let mut args = vec![]; @@ -77,7 +77,23 @@ pub fn lower_hir_function_call(block: MIRBlockReference, node: Box, ctx i += 1; } - return build_call(&mut ctx.mir_ctx, func_name, func_name, args); + let res = build_call(&mut ctx.mir_ctx, func_name, func_name, args)?; + + if res.is_some() { + let res = res.unwrap(); + + if expected.is_some() { + let expected = expected.unwrap(); + + if !res.vtype.can_transmute(&expected) { + return Err(BaseError::err(IR_TRANSMUTATION!().to_string())) + } + + return Ok(Some(transmute_value(res, expected.base, &mut ctx.mir_ctx)?)); + } + } + + return Ok(None); } return Err(BaseError::err(IR_INVALID_NODE_TYPE!().to_string())) diff --git a/compiler/astoir_mir_lowering/src/vars.rs b/compiler/astoir_mir_lowering/src/vars.rs index 94239f2e..8bdbd818 100644 --- a/compiler/astoir_mir_lowering/src/vars.rs +++ b/compiler/astoir_mir_lowering/src/vars.rs @@ -3,7 +3,7 @@ use std::f32::consts::E; use astoir_hir::{nodes::HIRNode}; -use astoir_mir::{blocks::{MIRBlockVariableSSAHint, MIRBlockVariableType, refer::MIRBlockReference}, vals::{base::BaseMIRValue, refer::MIRVariableReference}}; +use astoir_mir::{blocks::{MIRBlockVariableSSAHint, MIRBlockVariableType, refer::MIRBlockReference}, transmutation::transmute_value, vals::{base::BaseMIRValue, refer::MIRVariableReference}}; use astoir_typing::compacted::CompactedType; use compiler_errors::{IR_INVALID_NODE_TYPE, errs::{BaseResult, base::BaseError}}; @@ -63,7 +63,7 @@ pub fn lower_hir_variable_reference_value(block: MIRBlockReference, node: Box { + "Type transmutation failed here. This type cannot be inherently casted into the required one" + }; +} + #[macro_export] macro_rules! IR_OBTAIN_COND { () => { From 66467776506840b4c8e430ff71946c258d37361e Mon Sep 17 00:00:00 2001 From: Zffu <103074097+Zffu@users.noreply.github.com> Date: Tue, 17 Mar 2026 16:00:09 +0100 Subject: [PATCH 5/7] feat: added function lowering in values & body --- compiler/astoir_mir_lowering/src/body.rs | 7 ++++++- compiler/astoir_mir_lowering/src/values/mod.rs | 13 +++++++++++-- compiler/compiler_errors/src/errors.rs | 7 +++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/compiler/astoir_mir_lowering/src/body.rs b/compiler/astoir_mir_lowering/src/body.rs index 51730d4b..c35fb986 100644 --- a/compiler/astoir_mir_lowering/src/body.rs +++ b/compiler/astoir_mir_lowering/src/body.rs @@ -2,7 +2,7 @@ use astoir_hir::nodes::HIRNode; use astoir_mir::blocks::{refer::MIRBlockReference}; use compiler_errors::{IR_INVALID_NODE_TYPE, MATH_OP_NO_ASSIGN, errs::{BaseResult, base::BaseError}}; -use crate::{MIRLoweringContext, control::{forloop::lower_hir_for_loop, ifstatement::lower_hir_if_statement}, math::lower_hir_math_operation, vars::{lower_hir_variable_assignment, lower_hir_variable_declaration}}; +use crate::{MIRLoweringContext, control::{forloop::lower_hir_for_loop, ifstatement::lower_hir_if_statement}, funcs::lower_hir_function_call, math::lower_hir_math_operation, vars::{lower_hir_variable_assignment, lower_hir_variable_declaration}}; pub fn lower_hir_body_member(block: MIRBlockReference, node: Box, ctx: &mut MIRLoweringContext) -> BaseResult { return match *node { @@ -20,6 +20,11 @@ pub fn lower_hir_body_member(block: MIRBlockReference, node: Box, ctx: HIRNode::ForBlock { .. } => lower_hir_for_loop(block, node, ctx), HIRNode::IfStatement { .. } => lower_hir_if_statement(block, node, ctx), + HIRNode::FunctionCall { .. } => { + lower_hir_function_call(block, node, ctx, None)?; + + return Ok(true) + }, _ => return Err(BaseError::err(IR_INVALID_NODE_TYPE!().to_string())) } diff --git a/compiler/astoir_mir_lowering/src/values/mod.rs b/compiler/astoir_mir_lowering/src/values/mod.rs index 90818555..efd2b4db 100644 --- a/compiler/astoir_mir_lowering/src/values/mod.rs +++ b/compiler/astoir_mir_lowering/src/values/mod.rs @@ -1,9 +1,9 @@ use astoir_hir::{nodes::HIRNode}; use astoir_mir::{blocks::{refer::MIRBlockReference}, vals::base::BaseMIRValue}; use astoir_typing::compacted::CompactedType; -use compiler_errors::{IR_INVALID_NODE_TYPE, errs::{BaseResult, base::BaseError}}; +use compiler_errors::{EXPECTED_VAL_FUNC, IR_INVALID_NODE_TYPE, errs::{BaseResult, base::BaseError}}; -use crate::{MIRLoweringContext, math::lower_hir_math_operation, values::{booleans::{lower_hir_boolean_operator, lowering_hir_boolean_condition}, consts::lower_hir_literal}, vars::lower_hir_variable_reference_value}; +use crate::{MIRLoweringContext, funcs::lower_hir_function_call, math::lower_hir_math_operation, values::{booleans::{lower_hir_boolean_operator, lowering_hir_boolean_condition}, consts::lower_hir_literal}, vars::lower_hir_variable_reference_value}; pub mod consts; pub mod booleans; @@ -15,6 +15,15 @@ pub fn lower_hir_value(block: MIRBlockReference, node: Box, ctx: &mut M HIRNode::BooleanCondition { .. } => return Ok(lowering_hir_boolean_condition(block, node, ctx)?.into()), HIRNode::BooleanOperator { .. } => return Ok(lower_hir_boolean_operator(block, node, ctx)?.into()), HIRNode::MathOperation { .. } => return Ok(lower_hir_math_operation(block, node, ctx, expected)?), + HIRNode::FunctionCall { .. } => { + let res = lower_hir_function_call(block, node, ctx, expected)?; + + if res.is_none() { + return Err(BaseError::err(EXPECTED_VAL_FUNC!().to_string())); + } + + return Ok(res.unwrap()); + } _ => return Err(BaseError::err(IR_INVALID_NODE_TYPE!().to_string())) } diff --git a/compiler/compiler_errors/src/errors.rs b/compiler/compiler_errors/src/errors.rs index 70740909..46d21288 100644 --- a/compiler/compiler_errors/src/errors.rs +++ b/compiler/compiler_errors/src/errors.rs @@ -228,6 +228,13 @@ macro_rules! VARIABLE_REQ_VALUE { }; } +#[macro_export] +macro_rules! EXPECTED_VAL_FUNC { + () => { + "Function call is used as a value here! The function must return a value." + }; +} + #[macro_export] macro_rules! IR_VALUE_TYPE_TRANSMUTE { () => { From 417fad8734960146091811b0d6bc5018c6041247 Mon Sep 17 00:00:00 2001 From: Zffu <103074097+Zffu@users.noreply.github.com> Date: Tue, 17 Mar 2026 16:10:16 +0100 Subject: [PATCH 6/7] feat: added block held instructions for inst -> val tracking --- compiler/astoir_mir/src/blocks/mod.rs | 41 +++++++++++++++++------- compiler/astoir_mir/src/ctx.rs | 13 ++++---- compiler/astoir_mir/src/inst_writer.rs | 1 + compiler/astoir_mir_lowering/src/math.rs | 4 ++- 4 files changed, 41 insertions(+), 18 deletions(-) diff --git a/compiler/astoir_mir/src/blocks/mod.rs b/compiler/astoir_mir/src/blocks/mod.rs index 8836d251..a53f3b2a 100644 --- a/compiler/astoir_mir/src/blocks/mod.rs +++ b/compiler/astoir_mir/src/blocks/mod.rs @@ -2,7 +2,7 @@ use std::{collections::HashMap, fmt::Display}; use compiler_errors::errs::{BaseResult, base::BaseError}; -use crate::{blocks::{refer::MIRBlockReference}, builder::build_phi, ctx::MIRContext, insts::{MIRInstruction}, vals::{base::BaseMIRValue, refer::MIRVariableReference}}; +use crate::{blocks::refer::MIRBlockReference, builder::build_phi, ctx::MIRContext, inst_writer::BlockPosition, insts::MIRInstruction, vals::{base::BaseMIRValue, refer::MIRVariableReference}}; pub mod refer; pub mod hints; @@ -32,9 +32,15 @@ impl PartialEq for MIRBlockVariableSSAHint { } } +#[derive(Clone)] +pub enum MIRBlockHeldInstruction { + Valueless(MIRInstruction), + Valued(MIRInstruction, usize) +} + /// Represents a function block or a branch. pub struct MIRBlock { - instructions: Vec, + instructions: Vec, /// The block references that will merge into this one pub merge_blocks: Vec, @@ -84,15 +90,19 @@ impl MIRBlock { return Ok(MIRVariableReference::from(unpacked.as_ptr()?)); } - pub fn append(&mut self, instruction: MIRInstruction) { - self.instructions.push(instruction.clone()); - } - - pub fn append_start(&mut self, instruction: MIRInstruction) { - if self.instructions.is_empty() { - self.instructions.push(instruction.clone()); - } else { - self.instructions.insert(0, instruction.clone()); + pub fn append(&mut self, instruction: MIRBlockHeldInstruction, pos: &BlockPosition) { + match pos { + BlockPosition::END => { + self.instructions.push(instruction.clone()); + }, + + BlockPosition::START => { + if self.instructions.is_empty() { + self.instructions.push(instruction.clone()); + } else { + self.instructions.insert(0, instruction.clone()); + } + } } } @@ -157,4 +167,13 @@ impl Display for MIRBlock { Ok(()) } +} + +impl Display for MIRBlockHeldInstruction { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Valued(a, b) => write!(f, "#{} = {}", *b, a), + Self::Valueless(a) => write!(f, "{}", a) + } + } } \ No newline at end of file diff --git a/compiler/astoir_mir/src/ctx.rs b/compiler/astoir_mir/src/ctx.rs index 8b78ff06..4f92a4be 100644 --- a/compiler/astoir_mir/src/ctx.rs +++ b/compiler/astoir_mir/src/ctx.rs @@ -2,7 +2,7 @@ use std::fmt::Display; use compiler_errors::errs::BaseResult; -use crate::{blocks::{MIRBlock, hints::{HintStorage, MIRValueHint}, refer::MIRBlockReference}, builder::build_phi, funcs::MIRFunction, inst_writer::{BlockPosition, InstructionWriterPosition}, insts::{MIRInstruction, val::InstructionValue}, vals::{base::BaseMIRValue}}; +use crate::{blocks::{MIRBlock, MIRBlockHeldInstruction, hints::{HintStorage, MIRValueHint}, refer::MIRBlockReference}, builder::build_phi, funcs::MIRFunction, inst_writer::{BlockPosition, InstructionWriterPosition}, insts::{MIRInstruction, val::InstructionValue}, vals::base::BaseMIRValue}; pub struct MIRContext { @@ -35,25 +35,26 @@ impl MIRContext { } pub fn append_inst(&mut self, inst: MIRInstruction) -> InstructionValue { - match self.writer.curr_inst { - BlockPosition::START => self.blocks[self.writer.curr_block].append_start(inst.clone()), - BlockPosition::END => self.blocks[self.writer.curr_block].append(inst.clone()) - }; - if inst.has_return(self) { let ret = inst.get_return_type(self); if !inst.should_hint() { let hint_ind = self.ssa_hints.vec.len(); + self.blocks[self.writer.curr_block].append(MIRBlockHeldInstruction::Valued(inst.clone(), hint_ind), &self.writer.curr_inst); + return InstructionValue::new(Some(BaseMIRValue::new(hint_ind, ret))) } let hint_ind = self.ssa_hints.append_hint(MIRValueHint::Value(ret.clone())); + self.blocks[self.writer.curr_block].append(MIRBlockHeldInstruction::Valued(inst.clone(), hint_ind), &self.writer.curr_inst); + return InstructionValue::new(Some(BaseMIRValue::new(hint_ind, ret))); } + self.blocks[self.writer.curr_block].append(MIRBlockHeldInstruction::Valueless(inst.clone()), &self.writer.curr_inst); + return InstructionValue::new(None); } diff --git a/compiler/astoir_mir/src/inst_writer.rs b/compiler/astoir_mir/src/inst_writer.rs index 4111a0ce..c3d38224 100644 --- a/compiler/astoir_mir/src/inst_writer.rs +++ b/compiler/astoir_mir/src/inst_writer.rs @@ -2,6 +2,7 @@ use crate::{blocks::refer::MIRBlockReference}; +#[derive(Clone)] pub enum BlockPosition { START, END diff --git a/compiler/astoir_mir_lowering/src/math.rs b/compiler/astoir_mir_lowering/src/math.rs index ddfc4bdd..c77ecd2a 100644 --- a/compiler/astoir_mir_lowering/src/math.rs +++ b/compiler/astoir_mir_lowering/src/math.rs @@ -36,8 +36,10 @@ pub fn lower_hir_math_operation(block: MIRBlockReference, node: Box, ct if assignment { let v = ptr.unwrap(); - v.write(block, &mut ctx.mir_ctx, val)?; + v.write(block, &mut ctx.mir_ctx, val.clone())?; } + + return Ok(val) } return Err(BaseError::err(IR_INVALID_NODE_TYPE!().to_string())) From 385442abf7379043d268da2c23f25541426c0519 Mon Sep 17 00:00:00 2001 From: Zffu <103074097+Zffu@users.noreply.github.com> Date: Tue, 17 Mar 2026 16:13:25 +0100 Subject: [PATCH 7/7] fix: fixed a bug where values for transmutation were appearing before the actual values --- compiler/astoir_mir/src/ctx.rs | 2 +- compiler/astoir_mir_lowering/src/funcs.rs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/astoir_mir/src/ctx.rs b/compiler/astoir_mir/src/ctx.rs index 4f92a4be..9d0d4edd 100644 --- a/compiler/astoir_mir/src/ctx.rs +++ b/compiler/astoir_mir/src/ctx.rs @@ -15,7 +15,7 @@ pub struct MIRContext { impl MIRContext { pub fn new() -> Self { - MIRContext { functions: vec![], ssa_hints: HintStorage::new(), blocks: vec![], writer: InstructionWriterPosition { curr_block: 0, curr_inst: BlockPosition::START } } + MIRContext { functions: vec![], ssa_hints: HintStorage::new(), blocks: vec![], writer: InstructionWriterPosition { curr_block: 0, curr_inst: BlockPosition::END } } } pub fn create_block(&mut self) -> MIRBlockReference { diff --git a/compiler/astoir_mir_lowering/src/funcs.rs b/compiler/astoir_mir_lowering/src/funcs.rs index 05e72ef9..6255b8f4 100644 --- a/compiler/astoir_mir_lowering/src/funcs.rs +++ b/compiler/astoir_mir_lowering/src/funcs.rs @@ -22,7 +22,9 @@ pub fn lower_hir_function_decl(node: Box, cctx: &mut MIRLoweringContext } let mut func = MIRFunction::new(format!("func_{}", func_name), args, ret_type, requires_this); - let block =func.append_entry_block(&mut cctx.mir_ctx)?; + let block = func.append_entry_block(&mut cctx.mir_ctx)?; + + cctx.mir_ctx.writer.move_end(block); lower_hir_body(block, body, cctx)?;