Skip to content

Commit

Permalink
Split instantiation into execution and typechecking
Browse files Browse the repository at this point in the history
  • Loading branch information
VonTum committed May 17, 2024
1 parent 62018e1 commit 203de11
Show file tree
Hide file tree
Showing 14 changed files with 603 additions and 461 deletions.
41 changes: 25 additions & 16 deletions src/arena_alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,10 @@ impl<T, IndexMarker : UUIDMarker> ArenaAllocator<T, IndexMarker> {
self.data.clear();
self.free_slots.clear();
}
pub fn iter<'a>(&'a self) -> ArenaIterator<'a, T, IndexMarker> {
pub fn iter<'a>(&'a self) -> FlatOptionIterator<'a, T, IndexMarker> {
self.into_iter()
}
pub fn iter_mut<'a>(&'a mut self) -> ArenaIteratorMut<'a, T, IndexMarker> {
pub fn iter_mut<'a>(&'a mut self) -> FlatOptionIteratorMut<'a, T, IndexMarker> {
self.into_iter()
}
}
Expand All @@ -197,12 +197,12 @@ impl<T, IndexMarker : UUIDMarker> IndexMut<UUID<IndexMarker>> for ArenaAllocator
}
}

pub struct ArenaIterator<'a, T, IndexMarker> {
pub struct FlatOptionIterator<'a, T, IndexMarker> {
it: Enumerate<std::slice::Iter<'a, Option<T>>>,
_ph : PhantomData<IndexMarker>
}

impl<'a, T, IndexMarker : UUIDMarker> Iterator for ArenaIterator<'a, T, IndexMarker> {
impl<'a, T, IndexMarker : UUIDMarker> Iterator for FlatOptionIterator<'a, T, IndexMarker> {
type Item = (UUID<IndexMarker>, &'a T);

fn next(&mut self) -> Option<Self::Item> {
Expand All @@ -220,12 +220,12 @@ impl<'a, T, IndexMarker : UUIDMarker> Iterator for ArenaIterator<'a, T, IndexMar
}
}

pub struct ArenaIteratorMut<'a, T, IndexMarker> {
pub struct FlatOptionIteratorMut<'a, T, IndexMarker> {
it: Enumerate<std::slice::IterMut<'a, Option<T>>>,
_ph : PhantomData<IndexMarker>
}

impl<'a, T, IndexMarker : UUIDMarker> Iterator for ArenaIteratorMut<'a, T, IndexMarker> {
impl<'a, T, IndexMarker : UUIDMarker> Iterator for FlatOptionIteratorMut<'a, T, IndexMarker> {
type Item = (UUID<IndexMarker>, &'a mut T);

fn next(&mut self) -> Option<Self::Item> {
Expand All @@ -246,20 +246,20 @@ impl<'a, T, IndexMarker : UUIDMarker> Iterator for ArenaIteratorMut<'a, T, Index
impl<'a, T, IndexMarker : UUIDMarker> IntoIterator for &'a ArenaAllocator<T, IndexMarker> {
type Item = (UUID<IndexMarker>, &'a T);

type IntoIter = ArenaIterator<'a, T, IndexMarker>;
type IntoIter = FlatOptionIterator<'a, T, IndexMarker>;

fn into_iter(self) -> Self::IntoIter {
ArenaIterator{it : self.data.iter().enumerate(), _ph : PhantomData}
FlatOptionIterator{it : self.data.iter().enumerate(), _ph : PhantomData}
}
}

impl<'a, T, IndexMarker : UUIDMarker> IntoIterator for &'a mut ArenaAllocator<T, IndexMarker> {
type Item = (UUID<IndexMarker>, &'a mut T);

type IntoIter = ArenaIteratorMut<'a, T, IndexMarker>;
type IntoIter = FlatOptionIteratorMut<'a, T, IndexMarker>;

fn into_iter(self) -> Self::IntoIter {
ArenaIteratorMut{it : self.data.iter_mut().enumerate(), _ph : PhantomData}
FlatOptionIteratorMut{it : self.data.iter_mut().enumerate(), _ph : PhantomData}
}
}

Expand All @@ -282,10 +282,10 @@ impl<T, IndexMarker : UUIDMarker> ArenaVector<T, IndexMarker> {
pub fn remove(&mut self, UUID(uuid, _) : UUID<IndexMarker>) {
self.data[uuid] = None;
}
pub fn iter<'a>(&'a self) -> ArenaIterator<'a, T, IndexMarker> {
pub fn iter<'a>(&'a self) -> FlatOptionIterator<'a, T, IndexMarker> {
self.into_iter()
}
pub fn iter_mut<'a>(&'a mut self) -> ArenaIteratorMut<'a, T, IndexMarker> {
pub fn iter_mut<'a>(&'a mut self) -> FlatOptionIteratorMut<'a, T, IndexMarker> {
self.into_iter()
}
}
Expand All @@ -307,20 +307,20 @@ impl<T, IndexMarker : UUIDMarker> IndexMut<UUID<IndexMarker>> for ArenaVector<T,
impl<'a, T, IndexMarker : UUIDMarker> IntoIterator for &'a ArenaVector<T, IndexMarker> {
type Item = (UUID<IndexMarker>, &'a T);

type IntoIter = ArenaIterator<'a, T, IndexMarker>;
type IntoIter = FlatOptionIterator<'a, T, IndexMarker>;

fn into_iter(self) -> Self::IntoIter {
ArenaIterator{it : self.data.iter().enumerate(), _ph : PhantomData}
FlatOptionIterator{it : self.data.iter().enumerate(), _ph : PhantomData}
}
}

impl<'a, T, IndexMarker : UUIDMarker> IntoIterator for &'a mut ArenaVector<T, IndexMarker> {
type Item = (UUID<IndexMarker>, &'a mut T);

type IntoIter = ArenaIteratorMut<'a, T, IndexMarker>;
type IntoIter = FlatOptionIteratorMut<'a, T, IndexMarker>;

fn into_iter(self) -> Self::IntoIter {
ArenaIteratorMut{it : self.data.iter_mut().enumerate(), _ph : PhantomData}
FlatOptionIteratorMut{it : self.data.iter_mut().enumerate(), _ph : PhantomData}
}
}

Expand Down Expand Up @@ -478,6 +478,15 @@ impl<T, IndexMarker : UUIDMarker> FlatAlloc<T, IndexMarker> {
}
}

impl<T, IndexMarker : UUIDMarker> FlatAlloc<Option<T>, IndexMarker> {
pub fn iter_valids<'a>(&'a self) -> FlatOptionIterator<'a, T, IndexMarker> {
FlatOptionIterator{ it: self.data.iter().enumerate(), _ph: PhantomData }
}
pub fn iter_valids_mut<'a>(&'a mut self) -> FlatOptionIteratorMut<'a, T, IndexMarker> {
FlatOptionIteratorMut{ it: self.data.iter_mut().enumerate(), _ph: PhantomData }
}
}

impl<T, IndexMarker : UUIDMarker> Index<UUID<IndexMarker>> for FlatAlloc<T, IndexMarker> {
type Output = T;

Expand Down
24 changes: 10 additions & 14 deletions src/codegen_fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,22 @@ fn get_type_name_size(id : TypeUUID) -> u64 {
}
}

fn arr_str(sz : u64) -> String {
format!("[{}:0]", sz - 1)
}

fn typ_to_verilog_array(typ : &ConcreteType) -> String {
match typ {
ConcreteType::Named(id) => {
let sz = get_type_name_size(*id);
if sz == 1 {
String::new()
} else {
arr_str(sz)
format!("[{}:0]", sz - 1)
}
}
ConcreteType::Array(arr) => {
let (sub_typ, size) = arr.deref();
typ_to_verilog_array(sub_typ) + &arr_str(size.unwrap())
let sz = size.unwrap_value().unwrap_integer();
typ_to_verilog_array(sub_typ) + &format!("[{}:0]", sz - 1)
}
ConcreteType::Unknown | ConcreteType::Error => unreachable!()
&ConcreteType::Value(_) | ConcreteType::Unknown | ConcreteType::Error => unreachable!()
}
}

Expand Down Expand Up @@ -70,7 +67,7 @@ impl<'g, 'out, Stream : std::fmt::Write> CodeGenerationContext<'g, 'out, Stream>
format!("[{idx_wire_name}]")
}
RealWirePathElem::ConstArrayWrite{span:_, idx} => {
format!("[{}]", idx.unwrap())
format!("[{}]", idx)
}
});
}
Expand All @@ -96,15 +93,15 @@ impl<'g, 'out, Stream : std::fmt::Write> CodeGenerationContext<'g, 'out, Stream>
// First output the interface of the module
writeln!(self.program_text, "module {}(", self.md.link_info.name)?;
writeln!(self.program_text, "\tinput clk,")?;
for (_id, port) in self.instance.interface_ports.iter() {
for (_id, port) in self.instance.interface_ports.iter_valids() {
let port_wire = &self.instance.wires[port.wire];
let input_or_output = if port.is_input {"input"} else {"output /*mux_wire*/ reg"};
let wire_typ = typ_to_verilog_array(&port_wire.typ);
let wire_name = wire_name_self_latency(port_wire, self.use_latency);
writeln!(self.program_text, "\t{input_or_output}{wire_typ} {wire_name},")?;
}
writeln!(self.program_text, ");\n")?;
for (_id, port) in self.instance.interface_ports.iter() {
for (_id, port) in self.instance.interface_ports.iter_valids() {
let port_wire = &self.instance.wires[port.wire];
self.add_latency_registers(port_wire)?;
}
Expand Down Expand Up @@ -138,7 +135,7 @@ impl<'g, 'out, Stream : std::fmt::Write> CodeGenerationContext<'g, 'out, Stream>
write!(self.program_text, "[{}]", self.wire_name(*idx_wire, w.absolute_latency))?;
}
RealWirePathElem::ConstArrayWrite { span:_, idx } => {
write!(self.program_text, "[{}]", idx.unwrap())?;
write!(self.program_text, "[{}]", idx)?;
}
}
}
Expand Down Expand Up @@ -175,10 +172,9 @@ impl<'g, 'out, Stream : std::fmt::Write> CodeGenerationContext<'g, 'out, Stream>
let sm_name = &sm.name;
writeln!(self.program_text, "{sm_instance_name} {sm_name}(")?;
writeln!(self.program_text, "\t.clk(clk),")?;
for (port_id, port) in &sm.port_map {
let iport = &sm.instance.interface_ports[port_id];
for (port_id, iport) in sm.instance.interface_ports.iter_valids() {
let port_name = wire_name_self_latency(&sm.instance.wires[iport.wire], self.use_latency);
let wire_name = wire_name_self_latency(&self.instance.wires[*port], self.use_latency);
let wire_name = wire_name_self_latency(&self.instance.wires[sm.port_map[port_id]], self.use_latency);
writeln!(self.program_text, "\t.{port_name}({wire_name}),")?;
}
writeln!(self.program_text, ");")?;
Expand Down
12 changes: 7 additions & 5 deletions src/compiler_top.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::rc::Rc;
use tree_sitter::Parser;

use crate::{
config::config, debug::SpanDebugger, errors::ErrorStore, file_position::FileText, flattening::{flatten_all_modules, gather_initial_file_data, typecheck_all_modules, Module}, instantiation::InstantiatedModule, linker::{FileData, FileUUID, Linker, ModuleUUID}
config::config, debug::SpanDebugger, errors::ErrorStore, file_position::FileText, flattening::{flatten_all_modules, gather_initial_file_data, typecheck_all_modules, Module}, instantiation::InstantiatedModule, linker::{FileData, FileUUID, Linker}
};

pub fn add_file(text : String, linker : &mut Linker) -> FileUUID {
Expand Down Expand Up @@ -67,16 +67,18 @@ pub fn recompile_all(linker : &mut Linker) {

// Make an initial instantiation of all modules
// Won't be possible once we have template modules
for (id, _md) in &linker.modules {
for (_id, md) in &linker.modules {
//md.print_flattened_module();
// Already instantiate any modules without parameters
// Currently this is all modules
let _inst = instantiate(&linker, id);
let span_debug = format!("instantiating {}", &md.link_info.name);
let mut span_debugger = SpanDebugger::new(&span_debug, &linker.files[md.link_info.file].file_text);
let _inst = instantiate(&linker, md);
span_debugger.defuse();
}
}

pub fn instantiate(linker : &Linker, module_id : ModuleUUID) -> Option<Rc<InstantiatedModule>> {
let md = &linker.modules[module_id];
pub fn instantiate(linker : &Linker, md : &Module) -> Option<Rc<InstantiatedModule>> {
println!("Instantiating {}", md.link_info.name);

md.instantiations.instantiate(&md.link_info.name, md, linker)
Expand Down
31 changes: 30 additions & 1 deletion src/dev_aid/ariadne_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use std::{ops::Range, path::PathBuf};

use crate::{
arena_alloc::ArenaVector, compiler_top::{add_file, recompile_all}, config::config, errors::{CompileError, ErrorLevel}, linker::{FileUUID, FileUUIDMarker, Linker}
arena_alloc::ArenaVector, compiler_top::{add_file, recompile_all}, config::config, errors::{CompileError, ErrorLevel}, linker::{FileUUID, FileUUIDMarker, Linker},
};

use ariadne::*;
Expand Down Expand Up @@ -118,3 +118,32 @@ pub fn pretty_print_spans_in_reverse_order(file_text : String, spans : Vec<Range
}
}

pub fn pretty_print_many_spans(file_text : String, spans : &[(String, Range<usize>)]) {
let text_len = file_text.len();
let mut source = Source::from(file_text);

let config =
Config::default()
.with_index_type(IndexType::Byte)
.with_color(!config().use_lsp); // Disable color because LSP output doesn't support it

if spans.len() == 0 {return}

let mut report: ReportBuilder<'_, Range<usize>> = Report::build(ReportKind::Advice, (), spans[0].1.start).with_config(config);

for (text, span) in spans.into_iter().rev() {
// If span not in file, just don't print it. This happens.
if span.end > text_len {
println!("Span({}, {}) certainly does not correspond to this file. ", span.start, span.end);
return;
}

report = report.with_label(
Label::new(span.clone())
.with_message(text)
.with_color(Color::Blue)
);
}
report.finish().print(&mut source).unwrap();
}

40 changes: 25 additions & 15 deletions src/flattening/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub use initialization::gather_initial_file_data;
pub use typechecking::typecheck_all_modules;

use crate::{
arena_alloc::{FlatAlloc, UUIDMarker, UUIDRange, UUID}, errors::ErrorCollector, file_position::{BracketSpan, FileText, Span}, instantiation::InstantiationList, linker::{ConstantUUID, LinkInfo, ModuleUUID}, parser::Documentation, typing::{AbstractType, WrittenType}, value::Value
arena_alloc::{FlatAlloc, UUIDMarker, UUIDRange, UUID}, errors::ErrorCollector, file_position::{BracketSpan, FileText, Span}, instantiation::InstantiationList, linker::{ConstantUUID, LinkInfo, ModuleUUID}, parser::Documentation, pretty_print_many_spans, typing::{AbstractType, WrittenType}, value::Value
};


Expand Down Expand Up @@ -107,10 +107,14 @@ impl Module {
for (port_id, port) in &self.module_ports.ports {
println!(" {} -> {:?}", self.make_port_info_string(port_id, file_text), port);
}
println!("Instantiations:");
println!("Instructions:");
let mut spans_print = Vec::new();
for (id, inst) in &self.instructions {
println!(" {:?}: {:?}", id, inst);
println!(" {id:?}: {inst:?}");
let span = self.get_instruction_span(id);
spans_print.push((format!("{id:?}"), span.into_range()));
}
pretty_print_many_spans(file_text.file_text.clone(), &spans_print);
}

/// Get a port by the given name. Reports non existing ports errors
Expand All @@ -126,6 +130,17 @@ impl Module {
.info_obj(self);
return None
}

pub fn get_instruction_span(&self, instr_id : FlatID) -> Span {
match &self.instructions[instr_id] {
Instruction::SubModule(sm) => sm.module_name_span,
Instruction::Declaration(decl) => decl.get_span(),
Instruction::Wire(w) => w.span,
Instruction::Write(conn) => conn.to.span,
Instruction::IfStatement(if_stmt) => self.get_instruction_span(if_stmt.condition),
Instruction::ForStatement(for_stmt) => self.get_instruction_span(for_stmt.loop_var_decl),
}
}
}


Expand Down Expand Up @@ -386,12 +401,17 @@ impl WireSource {
/// Enumerates all instructions that this instruction depends on. This includes (maybe compiletime) wires, and submodules.
pub fn for_each_dependency<F : FnMut(FlatID)>(&self, mut func : F) {
match self {
WireSource::WireRef(from_wire) => {
match &from_wire.root {
WireSource::WireRef(wire_ref) => {
match &wire_ref.root {
WireReferenceRoot::LocalDecl(decl_id, _) => func(*decl_id),
WireReferenceRoot::NamedConstant(_, _) => {}
WireReferenceRoot::SubModulePort(submod_port) => func(submod_port.submodule_flat),
}
for p in &wire_ref.path {
match p {
WireReferencePathElement::ArrayIdx { idx, bracket_span:_ } => func(*idx),
}
}
}
&WireSource::UnaryOp { op:_, right } => {func(right)}
&WireSource::BinaryOp { op:_, left, right } => {func(left); func(right)},
Expand Down Expand Up @@ -502,16 +522,6 @@ impl Instruction {
}
}
}

pub fn get_location_of_module_part(&self) -> Option<Span> {
Some(match self {
Instruction::SubModule(sm) => sm.module_name_span,
Instruction::Declaration(decl) => decl.name_span,
Instruction::Wire(w) => w.span,
Instruction::Write(conn) => conn.to.span,
Instruction::IfStatement(_) | Instruction::ForStatement(_) => return None
})
}
}


Expand Down
3 changes: 2 additions & 1 deletion src/flattening/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,9 @@ impl<'l, 'errs> FlatteningContext<'l, 'errs> {
}

fn flatten_array_bracket(&mut self, cursor : &mut Cursor) -> (FlatID, BracketSpan) {
let bracket_span = BracketSpan::from_outer(cursor.span());
cursor.go_down_content(kind!("array_bracket_expression"),
|cursor| (self.flatten_expr(cursor), BracketSpan::from_outer(cursor.span()))
|cursor| (self.flatten_expr(cursor), bracket_span)
)
}

Expand Down
Loading

0 comments on commit 203de11

Please sign in to comment.