Skip to content

Commit

Permalink
Added ConcreteGlobalReference
Browse files Browse the repository at this point in the history
  • Loading branch information
IBims1NicerTobi committed Jan 14, 2025
1 parent 65e503b commit 5661676
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 51 deletions.
4 changes: 2 additions & 2 deletions src/codegen/system_verilog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ fn typ_to_declaration(mut typ: &ConcreteType, var_name: &str) -> String {
typ = content_typ;
}
match typ {
ConcreteType::Named(id) => {
let sz = get_type_name_size(*id);
ConcreteType::Named(reference) => {
let sz = get_type_name_size(reference.id);
if sz == 1 {
format!("{array_string} {var_name}")
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/codegen/vhdl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ fn typ_to_declaration(mut typ: &ConcreteType) -> String {
typ = content_typ;
}
match typ {
ConcreteType::Named(id) => {
let sz = get_type_name_size(*id);
ConcreteType::Named(reference) => {
let sz = get_type_name_size(reference.id);
if sz == 1 {
format!("{array_string} std_logic")
} else {
Expand Down
97 changes: 61 additions & 36 deletions src/instantiation/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use crate::typing::template::{GlobalReference, HowDoWeKnowTheTemplateArg};
use num::BigInt;

use crate::flattening::*;
use crate::value::{compute_binary_op, compute_unary_op, Value};
use crate::util::add_to_small_set;
use crate::value::{compute_binary_op, compute_unary_op, Value};

use crate::typing::{
abstract_type::DomainType,
Expand Down Expand Up @@ -129,7 +129,11 @@ impl<'fl> IndexMut<FlatID> for GenerationState<'fl> {
}
}

fn array_access<'v>(arr_val: &'v Value, idx: &BigInt, span: BracketSpan) -> ExecutionResult<&'v Value> {
fn array_access<'v>(
arr_val: &'v Value,
idx: &BigInt,
span: BracketSpan,
) -> ExecutionResult<&'v Value> {
let Value::Array(arr) = arr_val else {
caught_by_typecheck!("Value must be an array")
};
Expand All @@ -148,7 +152,7 @@ fn array_access<'v>(arr_val: &'v Value, idx: &BigInt, span: BracketSpan) -> Exec
}

/// Temporary intermediary struct
///
///
/// See [WireReferenceRoot]
#[derive(Debug, Clone)]
enum RealWireRefRoot {
Expand All @@ -168,12 +172,21 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
fn concretize_type(&self, typ: &WrittenType) -> ExecutionResult<ConcreteType> {
Ok(match typ {
WrittenType::Error(_) => caught_by_typecheck!("Error Type"),
WrittenType::TemplateVariable(_, template_id) => self.template_args[*template_id].unwrap_type().clone(),
WrittenType::Named(named_type) => ConcreteType::Named(named_type.id),
WrittenType::TemplateVariable(_, template_id) => {
self.template_args[*template_id].unwrap_type().clone()
}
WrittenType::Named(named_type) => {
ConcreteType::Named(crate::typing::concrete_type::ConcreteGlobalReference {
id: named_type.id,
template_args: FlatAlloc::new(),
})
}
WrittenType::Array(_, arr_box) => {
let (arr_content_typ, arr_size_wire, _bracket_span) = arr_box.deref();
let inner_typ = self.concretize_type(arr_content_typ)?;
let arr_size = self.generation_state.get_generation_integer(*arr_size_wire)?;
let arr_size = self
.generation_state
.get_generation_integer(*arr_size_wire)?;
ConcreteType::Array(Box::new((
inner_typ,
ConcreteType::Value(Value::Integer(arr_size.clone())),
Expand Down Expand Up @@ -208,7 +221,7 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
cst_ref.get_total_span().debug();
panic!("__crash_compiler Intentional ICE. This is for debugging the compiler and LSP.")
}
other => unreachable!("{other} is not a known builtin constant")
other => unreachable!("{other} is not a known builtin constant"),
}
} else {
todo!("Custom Constants");
Expand Down Expand Up @@ -286,7 +299,7 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
to_path,
num_regs,
from,
condition : self.condition_stack.clone().into_boxed_slice(),
condition: self.condition_stack.clone().into_boxed_slice(),
original_connection: original_instruction,
});
}
Expand Down Expand Up @@ -371,17 +384,12 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
}
Ok(())
}
fn compute_compile_time_wireref(
&self,
wire_ref: &WireReference,
) -> ExecutionResult<Value> {
fn compute_compile_time_wireref(&self, wire_ref: &WireReference) -> ExecutionResult<Value> {
let mut work_on_value: Value = match &wire_ref.root {
&WireReferenceRoot::LocalDecl(decl_id, _span) => {
self.generation_state.get_generation_value(decl_id)?.clone()
}
WireReferenceRoot::NamedConstant(cst) => {
self.get_named_constant_value(cst)
}
WireReferenceRoot::NamedConstant(cst) => self.get_named_constant_value(cst),
&WireReferenceRoot::SubModulePort(_) => {
todo!("Don't yet support compile time functions")
}
Expand All @@ -401,7 +409,9 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
}
fn compute_compile_time(&mut self, expression: &Expression) -> ExecutionResult<Value> {
Ok(match &expression.source {
ExpressionSource::WireRef(wire_ref) => self.compute_compile_time_wireref(wire_ref)?.clone(),
ExpressionSource::WireRef(wire_ref) => {
self.compute_compile_time_wireref(wire_ref)?.clone()
}
&ExpressionSource::UnaryOp { op, right } => {
let right_val = self.generation_state.get_generation_value(right)?;
compute_unary_op(op, right_val)
Expand Down Expand Up @@ -439,7 +449,7 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
domain: DomainID,
) -> WireID {
self.wires.alloc(RealWire {
typ : value.get_type_best_effort(&mut self.type_substitutor),
typ: value.get_type_best_effort(&mut self.type_substitutor),
source: RealWireDataSource::Constant { value },
original_instruction,
domain,
Expand Down Expand Up @@ -483,8 +493,9 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
wire_found.maps_to_wire
} else {
let port_data = &self.linker.modules[submod_instance.module_uuid].ports[port_id];
let submodule_instruction =
self.md.link_info.instructions[submod_instance.original_instruction].unwrap_submodule();
let submodule_instruction = self.md.link_info.instructions
[submod_instance.original_instruction]
.unwrap_submodule();
let source = if port_data.is_input {
RealWireDataSource::Multiplexer {
is_state: None,
Expand All @@ -499,7 +510,9 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
original_instruction: submod_instance.original_instruction,
domain: domain.unwrap_physical(),
typ: ConcreteType::Unknown(self.type_substitutor.alloc()),
name: self.unique_name_producer.get_unique_name(format!("{}_{}", submod_instance.name, port_data.name)),
name: self
.unique_name_producer
.get_unique_name(format!("{}_{}", submod_instance.name, port_data.name)),
specified_latency: CALCULATE_LATENCY_LATER,
absolute_latency: CALCULATE_LATENCY_LATER,
});
Expand Down Expand Up @@ -578,7 +591,7 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
}
};
Ok(self.wires.alloc(RealWire {
name : self.unique_name_producer.get_unique_name(""),
name: self.unique_name_producer.get_unique_name(""),
typ: ConcreteType::Unknown(self.type_substitutor.alloc()),
original_instruction,
domain,
Expand Down Expand Up @@ -637,10 +650,7 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
})
}

fn instantiate_code_block(
&mut self,
block_range: FlatIDRange,
) -> ExecutionResult<()> {
fn instantiate_code_block(&mut self, block_range: FlatIDRange) -> ExecutionResult<()> {
let mut instruction_range = block_range.into_iter();
while let Some(original_instruction) = instruction_range.next() {
let instr = &self.md.link_info.instructions[original_instruction];
Expand All @@ -649,7 +659,11 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
Instruction::SubModule(submodule) => {
let sub_module = &self.linker.modules[submodule.module_ref.id];

let name_origin = if let Some((name, _span)) = &submodule.name {name} else {""};
let name_origin = if let Some((name, _span)) = &submodule.name {
name
} else {
""
};
let port_map = sub_module.ports.map(|_| None);
let interface_call_sites = sub_module.interfaces.map(|_| Vec::new());
let mut template_args =
Expand All @@ -660,11 +674,11 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
Some(arg) => match &arg.kind {
TemplateArgKind::Type(typ) => ConcreteTemplateArg::Type(
self.concretize_type(typ)?,
HowDoWeKnowTheTemplateArg::Given
HowDoWeKnowTheTemplateArg::Given,
),
TemplateArgKind::Value(v) => ConcreteTemplateArg::Value(
self.generation_state.get_generation_value(*v)?.clone(),
HowDoWeKnowTheTemplateArg::Given
HowDoWeKnowTheTemplateArg::Given,
),
},
None => ConcreteTemplateArg::NotProvided,
Expand All @@ -675,7 +689,7 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
instance: OnceCell::new(),
port_map,
interface_call_sites,
name : self.unique_name_producer.get_unique_name(name_origin),
name: self.unique_name_producer.get_unique_name(name_origin),
module_uuid: submodule.module_ref.id,
template_args,
}))
Expand All @@ -689,10 +703,13 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
SubModuleOrWire::CompileTimeValue(value_computed)
}
DomainType::Physical(domain) => {
let wire_found = self.expression_to_real_wire(expr, original_instruction, domain)?;
let wire_found =
self.expression_to_real_wire(expr, original_instruction, domain)?;
SubModuleOrWire::Wire(wire_found)
}
DomainType::Unknown(_) => unreachable!("Domain variables have been eliminated by type checking")
DomainType::Unknown(_) => {
unreachable!("Domain variables have been eliminated by type checking")
}
},
Instruction::Write(conn) => {
self.instantiate_connection(
Expand Down Expand Up @@ -723,7 +740,8 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
for (port, arg) in
std::iter::zip(fc.func_call_inputs.iter(), fc.arguments.iter())
{
let from = self.get_wire_or_constant_as_wire(*arg, domain.unwrap_physical());
let from =
self.get_wire_or_constant_as_wire(*arg, domain.unwrap_physical());
let port_wire = self.get_submodule_port(submod_id, port, None);
self.instantiate_write_to_wire(
port_wire,
Expand All @@ -739,7 +757,8 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
Instruction::IfStatement(stm) => {
let then_range = FlatIDRange::new(stm.then_start, stm.then_end_else_start);
let else_range = FlatIDRange::new(stm.then_end_else_start, stm.else_end);
let if_condition_expr = self.md.link_info.instructions[stm.condition].unwrap_expression();
let if_condition_expr =
self.md.link_info.instructions[stm.condition].unwrap_expression();
match if_condition_expr.typ.domain {
DomainType::Generative => {
let condition_val =
Expand All @@ -753,7 +772,10 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
}
DomainType::Physical(_domain) => {
let condition_wire = self.generation_state[stm.condition].unwrap_wire();
self.condition_stack.push(ConditionStackElem{condition_wire, inverse : false});
self.condition_stack.push(ConditionStackElem {
condition_wire,
inverse: false,
});
self.instantiate_code_block(then_range)?;

if !else_range.is_empty() {
Expand All @@ -764,7 +786,9 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
// Get rid of the condition
let _ = self.condition_stack.pop().unwrap();
}
DomainType::Unknown(_) => unreachable!("Domain variables have been eliminated by type checking")
DomainType::Unknown(_) => {
unreachable!("Domain variables have been eliminated by type checking")
}
}
instruction_range.skip_to(stm.else_end);
continue;
Expand All @@ -782,7 +806,8 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
.unwrap_integer()
.clone();
if start_val > end_val {
let start_flat = &self.md.link_info.instructions[stm.start].unwrap_expression();
let start_flat =
&self.md.link_info.instructions[stm.start].unwrap_expression();
let end_flat = &self.md.link_info.instructions[stm.end].unwrap_expression();
return Err((
Span::new_overarching(start_flat.span, end_flat.span),
Expand Down
2 changes: 1 addition & 1 deletion src/to_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ impl<T: Index<TypeUUID, Output = StructType>> Display for ConcreteTypeDisplay<'_
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self.inner {
ConcreteType::Named(name) => {
f.write_str(&self.linker_types[*name].link_info.get_full_name())
f.write_str(&self.linker_types[name.id].link_info.get_full_name())
}
ConcreteType::Array(arr_box) => {
let (elem_typ, arr_size) = arr_box.deref();
Expand Down
30 changes: 21 additions & 9 deletions src/typing/concrete_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,37 @@ use crate::prelude::*;
use std::ops::Deref;

use crate::linker::get_builtin_type;
use crate::
value::Value
;
use crate::value::Value;

use super::template::ConcreteTemplateArgs;
use super::type_inference::ConcreteTypeVariableID;

pub const BOOL_CONCRETE_TYPE: ConcreteType = ConcreteType::Named(get_builtin_type("bool"));
pub const INT_CONCRETE_TYPE: ConcreteType = ConcreteType::Named(get_builtin_type("int"));
pub const BOOL_CONCRETE_TYPE: ConcreteType = ConcreteType::Named(ConcreteGlobalReference {
id: get_builtin_type("bool"),
template_args: FlatAlloc::new(),
});

pub const INT_CONCRETE_TYPE: ConcreteType = ConcreteType::Named(ConcreteGlobalReference {
id: get_builtin_type("int"),
template_args: FlatAlloc::new(),
});

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ConcreteGlobalReference<ID> {
pub id: ID,
pub template_args: ConcreteTemplateArgs,
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ConcreteType {
Named(TypeUUID),
Named(ConcreteGlobalReference<TypeUUID>),
Value(Value),
Array(Box<(ConcreteType, ConcreteType)>),
/// Referencing [ConcreteType::Unknown] is a strong code smell.
/// Referencing [ConcreteType::Unknown] is a strong code smell.
/// It is likely you should use [crate::typing::type_inference::TypeSubstitutor::unify] instead
///
///
/// It should only occur in creation `ConcreteType::Unknown(self.type_substitutor.alloc())`
Unknown(ConcreteTypeVariableID)
Unknown(ConcreteTypeVariableID),
}

impl ConcreteType {
Expand Down
2 changes: 1 addition & 1 deletion src/typing/type_inference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ impl HindleyMilner<ConcreteTypeVariableIDMarker> for ConcreteType {
fn get_hm_info(&self) -> HindleyMilnerInfo<ConcreteTypeHMInfo, ConcreteTypeVariableIDMarker> {
match self {
ConcreteType::Unknown(var_id) => HindleyMilnerInfo::TypeVar(*var_id),
ConcreteType::Named(named_id) => HindleyMilnerInfo::TypeFunc(ConcreteTypeHMInfo::Named(*named_id)),
ConcreteType::Named(named_id) => HindleyMilnerInfo::TypeFunc(ConcreteTypeHMInfo::Named(named_id.id)),
ConcreteType::Value(v) => HindleyMilnerInfo::TypeFunc(ConcreteTypeHMInfo::Value(v)),
ConcreteType::Array(_) => HindleyMilnerInfo::TypeFunc(ConcreteTypeHMInfo::Array),
}
Expand Down

0 comments on commit 5661676

Please sign in to comment.