Skip to content

Commit

Permalink
Rework Types. AbstractType no longer has array size field
Browse files Browse the repository at this point in the history
  • Loading branch information
VonTum committed Apr 22, 2024
1 parent 628f635 commit 6ffa7fb
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 78 deletions.
12 changes: 6 additions & 6 deletions src/flattening/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
instantiation::InstantiationList,
linker::{ConstantUUID, FileUUID, GlobalResolver, LinkInfo, Linker, ModuleUUID, NameElem, NamedConstant, NamedType, ResolvedGlobals, ResolvedNameElem, TypeUUIDMarker},
parser::{Cursor, Documentation},
typing::{get_binary_operator_types, typecheck, typecheck_is_array_indexer, typecheck_unary_operator, Type, WrittenType, BOOL_TYPE, INT_TYPE},
typing::{get_binary_operator_types, typecheck, typecheck_is_array_indexer, typecheck_unary_operator, AbstractType, WrittenType, BOOL_TYPE, INT_TYPE},
value::Value
};

Expand Down Expand Up @@ -295,7 +295,7 @@ const IS_GEN_UNINIT : bool = false;

#[derive(Debug)]
pub struct WireInstance {
pub typ : Type,
pub typ : AbstractType,
pub is_compiletime : bool,
pub span : Span,
pub is_declared_in_this_module : bool,
Expand All @@ -305,7 +305,7 @@ pub struct WireInstance {
#[derive(Debug)]
pub struct Declaration {
pub typ_expr : WrittenType,
pub typ : Type,
pub typ : AbstractType,
pub is_declared_in_this_module : bool,
pub name_span : Span,
pub name : String,
Expand Down Expand Up @@ -384,7 +384,7 @@ impl Instruction {
sm
}

pub fn for_each_embedded_type<F : FnMut(&Type, Span)>(&self, f : &mut F) {
pub fn for_each_embedded_type<F : FnMut(&AbstractType, Span)>(&self, f : &mut F) {
match self {
Instruction::SubModule(_) | Instruction::Write(_) | Instruction::IfStatement(_) | Instruction::ForStatement(_) => {}
Instruction::Declaration(decl) => {
Expand Down Expand Up @@ -739,7 +739,7 @@ impl<'l> FlatteningContext<'l> {
};

let wire_instance = WireInstance{
typ : Type::Unknown,
typ : AbstractType::Unknown,
is_compiletime : IS_GEN_UNINIT,
span: expr_span,
source,
Expand Down Expand Up @@ -858,7 +858,7 @@ impl<'l> FlatteningContext<'l> {
};
for leftover_to in to_iter {
if let Ok(to) = leftover_to {
let err_id = self.instructions.alloc(Instruction::Wire(WireInstance{typ : Type::Error, is_compiletime : true, span : func_call_span, is_declared_in_this_module : self.is_declared_in_this_module, source : WireSource::Constant(Value::Error)}));
let err_id = self.instructions.alloc(Instruction::Wire(WireInstance{typ : AbstractType::Error, is_compiletime : true, span : func_call_span, is_declared_in_this_module : self.is_declared_in_this_module, source : WireSource::Constant(Value::Error)}));
self.instructions.alloc(Instruction::Write(Write{from: err_id, to}));
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/flattening/typechecking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl<'l, 'instr> TypeCheckingContext<'l, 'instr> {
/*
==== Typechecking ====
*/
fn typecheck_wire_is_of_type(&self, wire : &WireInstance, expected : &Type, context : &str) {
fn typecheck_wire_is_of_type(&self, wire : &WireInstance, expected : &AbstractType, context : &str) {
typecheck(&wire.typ, wire.span, expected, context, self.linker_types, &self.errors);
}

Expand Down Expand Up @@ -79,7 +79,7 @@ impl<'l, 'instr> TypeCheckingContext<'l, 'instr> {
self.typecheck_wire_is_of_type(latency_spec_wire, &INT_TYPE, "latency specifier");
}

decl.typ.for_each_generative_input(&mut |param_id| {
decl.typ_expr.for_each_generative_input(&mut |param_id| {
self.typecheck_wire_is_of_type(self.instructions[param_id].extract_wire(), &INT_TYPE, "Array size");
});
}
Expand Down Expand Up @@ -119,15 +119,15 @@ impl<'l, 'instr> TypeCheckingContext<'l, 'instr> {
if let Some(typ) = typecheck_is_array_indexer(&arr_wire.typ, arr_wire.span, self.linker_types, &self.errors) {
typ.clone()
} else {
Type::Error
AbstractType::Error
}
}
WireSource::Constant(value) => {
value.get_type_of_constant()
}
&WireSource::NamedConstant(id) => {
let NamedConstant::Builtin{name:_, typ, val:_} = &self.linker_constants[id];
typ.clone()
typ.into()
}
};
let Instruction::Wire(w) = &mut self.instructions[elem_id] else {unreachable!()};
Expand Down Expand Up @@ -185,7 +185,7 @@ impl<'l, 'instr> TypeCheckingContext<'l, 'instr> {
self.must_be_compiletime(self.instructions[latency_specifier].extract_wire(), "Latency specifier");
}

decl.typ.for_each_generative_input(&mut |param_id| {
decl.typ_expr.for_each_generative_input(&mut |param_id| {
self.must_be_compiletime(self.instructions[param_id].extract_wire(), "Array size");
});
}
Expand Down Expand Up @@ -274,7 +274,7 @@ impl<'l, 'instr> TypeCheckingContext<'l, 'instr> {
}
}
Instruction::Declaration(decl) => {
decl.typ.for_each_generative_input(&mut |id| instance_fanins[inst_id].push(id));
decl.typ_expr.for_each_generative_input(&mut |id| instance_fanins[inst_id].push(id));
}
Instruction::Wire(wire) => {
wire.source.for_each_input_wire(&mut |id| instance_fanins[inst_id].push(id));
Expand Down
64 changes: 53 additions & 11 deletions src/instantiation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,18 @@ use std::{cell::RefCell, cmp::max, iter::zip, ops::Deref, rc::Rc};

use num::BigInt;

use crate::{arena_alloc::{FlatAlloc, UUIDMarker, UUIDRange, UUID}, compiler_top::instantiate, errors::ErrorCollector, file_position::Span, flattening::{BinaryOperator, ConnectionWritePathElement, ConnectionWritePathElementComputed, FlatID, FlatIDMarker, FlatIDRange, FlattenedModule, IdentifierType, Instruction, InterfacePorts, UnaryOperator, WireInstance, WireSource, Write, WriteModifiers}, instantiation::latency_algorithm::{convert_fanin_to_fanout, solve_latencies, FanInOut, LatencyCountingError}, linker::{Linker, NamedConstant}, list_of_lists::ListOfLists, typing::{ConcreteType, Type, BOOL_CONCRETE_TYPE, INT_CONCRETE_TYPE}, value::{compute_binary_op, compute_unary_op, Value}};
use crate::{
arena_alloc::{FlatAlloc, UUIDMarker, UUIDRange, UUID},
compiler_top::instantiate,
errors::ErrorCollector,
file_position::Span,
flattening::{BinaryOperator, ConnectionWritePathElement, ConnectionWritePathElementComputed, FlatID, FlatIDMarker, FlatIDRange, FlattenedModule, IdentifierType, Instruction, InterfacePorts, UnaryOperator, WireInstance, WireSource, Write, WriteModifiers},
instantiation::latency_algorithm::{convert_fanin_to_fanout, solve_latencies, FanInOut, LatencyCountingError},
linker::{Linker, NamedConstant},
list_of_lists::ListOfLists,
typing::{typecheck_concrete_binary_operator, typecheck_concrete_unary_operator, ConcreteType, WrittenType, BOOL_CONCRETE_TYPE, INT_CONCRETE_TYPE},
value::{compute_binary_op, compute_unary_op, Value}
};

use self::latency_algorithm::SpecifiedLatency;

Expand Down Expand Up @@ -198,15 +209,15 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
self.extract_integer_from_value(val, span)
}

fn concretize_type(&self, typ : &Type, span : Span) -> Option<ConcreteType> {
fn concretize_type(&self, typ : &WrittenType) -> Option<ConcreteType> {
match typ {
Type::Error | Type::Unknown => unreachable!("Bad types should be caught in flattening: {}", typ.to_string(&self.linker.types)),
Type::Named(id) => {
WrittenType::Error(_) => unreachable!("Bad types should be caught in flattening: {}", typ.to_string(&self.linker.types)),
WrittenType::Named(_, id) => {
Some(ConcreteType::Named(*id))
}
Type::Array(arr_box) => {
let (arr_content_typ, arr_size_wire) = arr_box.deref();
let inner_typ = self.concretize_type(arr_content_typ, span);
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.extract_integer_from_generative(*arr_size_wire);
Some(ConcreteType::Array(Box::new((inner_typ?, arr_size?))))
}
Expand Down Expand Up @@ -350,8 +361,9 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
SubModuleOrWire::Wire(w) => Some(*w),
SubModuleOrWire::CompileTimeValue(v) => {
let value = v.clone();
let Instruction::Wire(wire) = &self.flattened.instructions[flat_id] else {unreachable!()};
let typ = self.concretize_type(&wire.typ, wire.span)?;
//let wire = self.flattened.instructions[flat_id].extract_wire();
//let typ = self.concretize_type(&wire.typ)?;
let typ = v.get_concrete_type_of_constant();
let name = self.get_unique_name();
Some(self.wires.alloc(RealWire{source : RealWireDataSource::Constant{value}, original_wire : flat_id, typ, name, absolute_latency : CALCULATE_LATENCY_LATER, needed_until : CALCULATE_LATENCY_LATER}))
}
Expand Down Expand Up @@ -421,7 +433,7 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
SubModuleOrWire::SubModule(self.submodules.alloc(SubModule { original_flat: original_wire, instance, wires : interface_real_wires, name : submodule.name.clone()}))
}
Instruction::Declaration(wire_decl) => {
let typ = self.concretize_type(&wire_decl.typ, wire_decl.typ_expr.get_span())?;
let typ = self.concretize_type(&wire_decl.typ_expr)?;
if wire_decl.identifier_type.is_generative() {
let initial_value = typ.get_initial_val(self.linker);
assert!(initial_value.is_of_type(&typ));
Expand Down Expand Up @@ -455,7 +467,28 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
}
}
Instruction::Wire(w) => {
let typ = self.concretize_type(&w.typ, w.span)?;
let typ = match &w.source {
&WireSource::WireRead(from) => {
self.concretize_type(&self.flattened.instructions[from].extract_wire_declaration().typ_expr)?
}
&WireSource::UnaryOp { op, right } => {
let right_typ = self.get_current_concrete_type(right);
typecheck_concrete_unary_operator(op, &right_typ, w.span, &self.linker.types, &self.errors)
}
&WireSource::BinaryOp { op, left, right } => {
let left_typ = self.get_current_concrete_type(left);
let right_typ = self.get_current_concrete_type(right);
typecheck_concrete_binary_operator(op, &left_typ, &right_typ, w.span, &self.linker.types, &self.errors)
}
&WireSource::ArrayAccess { arr, arr_idx, bracket_span : _ } => {
let arr_typ = self.get_current_concrete_type(arr);
let arr_idx_typ = self.get_current_concrete_type(arr_idx);
assert_eq!(arr_idx_typ, INT_CONCRETE_TYPE);
arr_typ.down_array().clone()
}
WireSource::Constant(v) => v.get_concrete_type_of_constant(),
&WireSource::NamedConstant(nc) => self.linker.constants[nc].get_concrete_type().clone(),
};
if w.is_compiletime {
let value_computed = self.compute_compile_time(&w.source)?;
assert!(value_computed.is_of_type(&typ));
Expand Down Expand Up @@ -533,6 +566,15 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
Some(())
}

fn get_current_concrete_type(&self, w: FlatID) -> ConcreteType {
match &self.generation_state[w] {
SubModuleOrWire::Wire(w_idx) => self.wires[*w_idx].typ.clone(),
SubModuleOrWire::CompileTimeValue(cv) => cv.get_concrete_type_of_constant(),
SubModuleOrWire::SubModule(_) => unreachable!("Cannot get concrete type of submodule"),
SubModuleOrWire::Unnasigned => unreachable!("Concrete type of Unassigned, should have been caught in abstract typecheck?"),
}
}

fn make_fanins(&self) -> (ListOfLists<FanInOut>, Vec<SpecifiedLatency>) {
let mut fanins : ListOfLists<FanInOut> = ListOfLists::new_with_groups_capacity(self.wires.len());
let mut initial_latencies = Vec::new();
Expand Down
14 changes: 11 additions & 3 deletions src/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
file_position::{FileText, Span},
flattening::Module,
parser::Documentation,
typing::Type,
typing::ConcreteType,
util::{const_str_position, const_str_position_in_tuples},
value::Value
};
Expand Down Expand Up @@ -94,7 +94,15 @@ pub trait Linkable {

#[derive(Debug)]
pub enum NamedConstant {
Builtin{name : &'static str, typ : Type, val : Value}
Builtin{name : &'static str, typ : ConcreteType, val : Value}
}

impl NamedConstant {
pub fn get_concrete_type(&self) -> &ConcreteType {
match self {
NamedConstant::Builtin { name : _, typ, val : _ } => typ
}
}
}

#[derive(Debug)]
Expand Down Expand Up @@ -193,7 +201,7 @@ impl Linker {
add_known_unique_name(&mut result, name.into(), NameElem::Type(id));
}
for (name, val) in BUILTIN_CONSTANTS {
let id = result.constants.alloc(NamedConstant::Builtin{name, typ : val.get_type_of_constant(), val});
let id = result.constants.alloc(NamedConstant::Builtin{name, typ : val.get_concrete_type_of_constant(), val});
add_known_unique_name(&mut result, name.into(), NameElem::Constant(id));
}

Expand Down
Loading

0 comments on commit 6ffa7fb

Please sign in to comment.