diff --git a/compiler/astoir_mir/src/blocks/hints.rs b/compiler/astoir_mir/src/blocks/hints.rs index b2012459..16552c57 100644 --- a/compiler/astoir_mir/src/blocks/hints.rs +++ b/compiler/astoir_mir/src/blocks/hints.rs @@ -28,6 +28,14 @@ impl MIRValueHint { } } + pub fn get_type(&self) -> BaseResult { + match self { + MIRValueHint::Pointer(e) => Ok(e.clone()), + MIRValueHint::Value(e) => Ok(e.clone()), + _ => Err(BaseError::critical("Cannot use get_type on an non typed hint".to_string())) + } + } + pub fn as_pointer(&self) -> BaseResult { match self { MIRValueHint::Pointer(e) => Ok(e.clone()), diff --git a/compiler/astoir_mir/src/vals/refer.rs b/compiler/astoir_mir/src/vals/refer.rs index c7c3c805..60e68590 100644 --- a/compiler/astoir_mir/src/vals/refer.rs +++ b/compiler/astoir_mir/src/vals/refer.rs @@ -63,6 +63,17 @@ impl MIRVariableReference { return Ok(true); } + pub fn get_hint(&self) -> usize { + return match self { + Self::PointerReference(e) => { + let clone: BaseMIRValue = e.clone().into(); + + return clone.get_ssa_index(); + }, + Self::SSAReference(e) => *e + } + } + pub fn is_pointer_ref(&self) -> bool { return match self { Self::PointerReference(_) => true, diff --git a/compiler/astoir_mir_lowering/src/control/forloop.rs b/compiler/astoir_mir_lowering/src/control/forloop.rs index a0debf06..2cae06c8 100644 --- a/compiler/astoir_mir_lowering/src/control/forloop.rs +++ b/compiler/astoir_mir_lowering/src/control/forloop.rs @@ -31,7 +31,7 @@ pub fn lower_hir_for_loop(block: MIRBlockReference, node: Box, ctx: &mu build_unconditional_branch(&mut ctx.mir_ctx, cond_ref)?; ctx.mir_ctx.writer.move_end(cond_ref); - let cond_val = lower_hir_value(block, condition, ctx)?; + let cond_val = lower_hir_value(block, condition, ctx, None)?; build_conditional_branch(&mut ctx.mir_ctx, cond_val.as_int()?, body_ref, exit_ref)?; diff --git a/compiler/astoir_mir_lowering/src/control/ifstatement.rs b/compiler/astoir_mir_lowering/src/control/ifstatement.rs index fab7729f..e93b8bad 100644 --- a/compiler/astoir_mir_lowering/src/control/ifstatement.rs +++ b/compiler/astoir_mir_lowering/src/control/ifstatement.rs @@ -51,7 +51,7 @@ pub fn lower_hir_if_statement(block: MIRBlockReference, node: Box, ctx: HIRIfBranch::IfBranch { cond, body } => { ctx.mir_ctx.writer.move_end(block); - let val = lower_hir_value(block, cond, ctx)?.as_int()?; + let val = lower_hir_value(block, cond, ctx, None)?.as_int()?; build_conditional_branch(&mut ctx.mir_ctx, val, branch_blocks[branch_ind], branch_blocks[branch_ind + 1])?; @@ -67,7 +67,7 @@ pub fn lower_hir_if_statement(block: MIRBlockReference, node: Box, ctx: HIRIfBranch::ElseIfBranch { cond, body } => { ctx.mir_ctx.writer.move_end(branch_blocks[branch_ind]); - let val = lower_hir_value(branch_blocks[branch_ind], cond, ctx)?.as_int()?; + let val = lower_hir_value(branch_blocks[branch_ind], cond, ctx, None)?.as_int()?; build_conditional_branch(&mut ctx.mir_ctx, val, branch_blocks[branch_ind + 1], branch_blocks[branch_ind + 2])?; diff --git a/compiler/astoir_mir_lowering/src/funcs.rs b/compiler/astoir_mir_lowering/src/funcs.rs index 0d9a4ea2..40c37a6c 100644 --- a/compiler/astoir_mir_lowering/src/funcs.rs +++ b/compiler/astoir_mir_lowering/src/funcs.rs @@ -66,7 +66,7 @@ pub fn lower_hir_function_call(block: MIRBlockReference, node: Box, ctx let mut i = 0; for arg in arguments { let t = &ctx.mir_ctx.functions[func_name].arguments[i].clone(); - let mir_val = lower_hir_value(block, arg, ctx)?; + let mir_val = lower_hir_value(block, arg, ctx, None)?; if !mir_val.vtype.can_transmute(t) { return Err(BaseError::err(IR_FUNCTION_INVALID_ARGUMENTS!().to_string())) diff --git a/compiler/astoir_mir_lowering/src/math.rs b/compiler/astoir_mir_lowering/src/math.rs index bb5aeb02..38ba0ed7 100644 --- a/compiler/astoir_mir_lowering/src/math.rs +++ b/compiler/astoir_mir_lowering/src/math.rs @@ -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)?; - let right_val = lower_hir_value(block, right, ctx)?; + let left_val = lower_hir_value(block, left, ctx, None)?; + let right_val = lower_hir_value(block, right, ctx, None)?; let val = match left_val.vtype.base { diff --git a/compiler/astoir_mir_lowering/src/values/booleans.rs b/compiler/astoir_mir_lowering/src/values/booleans.rs index bfc59a06..b71fc221 100644 --- a/compiler/astoir_mir_lowering/src/values/booleans.rs +++ b/compiler/astoir_mir_lowering/src/values/booleans.rs @@ -7,8 +7,8 @@ use crate::{MIRLoweringContext, values::lower_hir_value}; pub fn lower_hir_boolean_operator(block: MIRBlockReference, node: Box, ctx: &mut MIRLoweringContext) -> BaseResult { if let HIRNode::BooleanOperator { left, right, operator } = *node { - let a = lower_hir_value(block, left, ctx)?.as_int()?; - let b = lower_hir_value(block, right, ctx)?.as_int()?; + let a = lower_hir_value(block, left, ctx, None)?.as_int()?; + let b = lower_hir_value(block, right, ctx, None)?.as_int()?; let val = match operator { ComparingOperator::Equal => build_comp_eq(&mut ctx.mir_ctx, a, b)?, @@ -27,7 +27,7 @@ pub fn lower_hir_boolean_operator(block: MIRBlockReference, node: Box, pub fn lowering_hir_boolean_condition(block: MIRBlockReference, node: Box, ctx: &mut MIRLoweringContext) -> BaseResult { if let HIRNode::BooleanCondition { value, negation } = *node { - let mut val = lower_hir_value(block, value, ctx)?.as_int()?; + let mut val = lower_hir_value(block, value, ctx, None)?.as_int()?; if negation { val = build_bitwise_not(&mut ctx.mir_ctx, val)?; diff --git a/compiler/astoir_mir_lowering/src/values/consts.rs b/compiler/astoir_mir_lowering/src/values/consts.rs index 1d4e633f..b00b2e6e 100644 --- a/compiler/astoir_mir_lowering/src/values/consts.rs +++ b/compiler/astoir_mir_lowering/src/values/consts.rs @@ -1,21 +1,28 @@ use astoir_hir::{nodes::HIRNode}; use astoir_mir::{builder::{build_signed_int_const, build_static_string_const, build_unsigned_int_const}, vals::base::BaseMIRValue}; +use astoir_typing::compacted::CompactedType; use compiler_errors::{IR_INVALID_NODE_TYPE, errs::{BaseResult, base::BaseError}}; use crate::MIRLoweringContext; -pub fn lower_hir_literal(node: Box, ctx: &mut MIRLoweringContext) -> BaseResult { +pub fn lower_hir_literal(node: Box, ctx: &mut MIRLoweringContext, t: Option) -> BaseResult { match *node { - HIRNode::IntegerLiteral { value, int_type } => { - let t = &ctx.hir_ctx.type_storage.types[int_type]; - - if t.is_signed() { - let val = build_signed_int_const(&mut ctx.mir_ctx, value, t.get_size()?)?; + HIRNode::IntegerLiteral { value, int_type } => { + let base; + + if t.is_some() { + base = t.unwrap().base; + } else { + base = ctx.hir_ctx.type_storage.types[int_type].clone(); + } + + if base.is_signed() { + let val = build_signed_int_const(&mut ctx.mir_ctx, value, base.get_size()?)?; return Ok(val.into()); } - let val = build_unsigned_int_const(&mut ctx.mir_ctx, value as u128, t.get_size()?)?; + let val = build_unsigned_int_const(&mut ctx.mir_ctx, value as u128, base.get_size()?)?; return Ok(val.into()); }, diff --git a/compiler/astoir_mir_lowering/src/values/mod.rs b/compiler/astoir_mir_lowering/src/values/mod.rs index b7817f22..67715aeb 100644 --- a/compiler/astoir_mir_lowering/src/values/mod.rs +++ b/compiler/astoir_mir_lowering/src/values/mod.rs @@ -1,5 +1,6 @@ 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 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}; @@ -7,9 +8,9 @@ use crate::{MIRLoweringContext, math::lower_hir_math_operation, values::{boolean pub mod consts; pub mod booleans; -pub fn lower_hir_value(block: MIRBlockReference, node: Box, ctx: &mut MIRLoweringContext) -> BaseResult { +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), + HIRNode::IntegerLiteral { .. } | HIRNode::StringLiteral { .. } => return lower_hir_literal(node, ctx, expected), 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()), diff --git a/compiler/astoir_mir_lowering/src/vars.rs b/compiler/astoir_mir_lowering/src/vars.rs index 719bc9f2..7107be77 100644 --- a/compiler/astoir_mir_lowering/src/vars.rs +++ b/compiler/astoir_mir_lowering/src/vars.rs @@ -2,16 +2,21 @@ use astoir_hir::{nodes::HIRNode}; use astoir_mir::{blocks::{MIRBlockVariableSSAHint, MIRBlockVariableType, refer::MIRBlockReference}, vals::{base::BaseMIRValue, refer::MIRVariableReference}}; +use astoir_typing::compacted::CompactedType; use compiler_errors::{IR_INVALID_NODE_TYPE, errs::{BaseResult, base::BaseError}}; use crate::{MIRLoweringContext, values::lower_hir_value}; pub fn lower_hir_variable_declaration(block_id: MIRBlockReference, node: Box, ctx: &mut MIRLoweringContext) -> BaseResult { - if let HIRNode::VarDeclaration { variable, var_type: _, default_val } = *node { - //let lowered = CompactedType::from(var_type); + if let HIRNode::VarDeclaration { variable, var_type, default_val } = *node { + let lowered = CompactedType::from(var_type); if default_val.is_some() { - let val = lower_hir_value(block_id, default_val.unwrap(), ctx)?; + let val = lower_hir_value(block_id, default_val.unwrap(), ctx, Some(lowered.clone()))?; + + if val.vtype.can_transmute(&lowered) { + // TODO: allow transmutation here + } ctx.mir_ctx.blocks[block_id].variables.insert(variable, MIRBlockVariableSSAHint { kind: MIRBlockVariableType::SSA, hint: Some(val) }); } else { @@ -52,10 +57,12 @@ pub fn lower_hir_variable_reference_value(block: MIRBlockReference, node: Box, ctx: &mut MIRLoweringContext) -> BaseResult { if let HIRNode::VarAssigment { variable, val } = *node { - let val = lower_hir_value(block, val, ctx)?; - let variable_ref = ctx.mir_ctx.blocks[block].get_variable_ref(variable)?; + let hint = ctx.mir_ctx.ssa_hints.get_hint(variable_ref.get_hint())?; + + let val = lower_hir_value(block, val, ctx, Some(hint.get_type()?))?; + variable_ref.write(block, &mut ctx.mir_ctx, val)?; return Ok(true); }