Skip to content

Commit

Permalink
Refactor all array accesses to be wire references
Browse files Browse the repository at this point in the history
  • Loading branch information
VonTum committed May 11, 2024
1 parent 42a3f84 commit 3e65179
Show file tree
Hide file tree
Showing 11 changed files with 541 additions and 412 deletions.
33 changes: 20 additions & 13 deletions src/codegen_fallback.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::ops::Deref;

use crate::{flattening::{Instruction, Module}, instantiation::{ConnectToPathElem, InstantiatedModule, RealWire, RealWireDataSource, WireID}, linker::{get_builtin_type, TypeUUID}, typing::ConcreteType};
use crate::{flattening::{Instruction, Module}, instantiation::{RealWirePathElem, InstantiatedModule, RealWire, RealWireDataSource, WireID}, linker::{get_builtin_type, TypeUUID}, typing::ConcreteType};

fn get_type_name_size(id : TypeUUID) -> u64 {
if id == get_builtin_type("int") {
Expand Down Expand Up @@ -60,16 +60,16 @@ impl<'g, 'out, Stream : std::fmt::Write> CodeGenerationContext<'g, 'out, Stream>
wire_name_with_latency(wire, requested_latency, self.use_latency)
}

fn write_path_to_string(&self, path : &[ConnectToPathElem], absolute_latency : i64) -> String {
fn write_path_to_string(&self, path : &[RealWirePathElem], absolute_latency : i64) -> String {
let mut result = String::new();
for path_elem in path {
result.push_str(&match path_elem {
ConnectToPathElem::MuxArrayWrite{idx_wire} => {
RealWirePathElem::MuxArrayWrite{span:_, idx_wire} => {
let idx_wire_name = self.wire_name(*idx_wire, absolute_latency);
format!("[{idx_wire_name}]")
}
ConnectToPathElem::ConstArrayWrite{idx} => {
format!("[{idx}]")
RealWirePathElem::ConstArrayWrite{span:_, idx} => {
format!("[{}]", idx.unwrap())
}
});
}
Expand Down Expand Up @@ -129,18 +129,26 @@ impl<'g, 'out, Stream : std::fmt::Write> CodeGenerationContext<'g, 'out, Stream>
write!(self.program_text, "{wire_or_reg}{type_str} {wire_name}")?;

match &w.source {
RealWireDataSource::Select { root, path } => {
write!(self.program_text, " = {}", self.wire_name(*root, w.absolute_latency))?;
for pe in path {
match pe {
RealWirePathElem::MuxArrayWrite { span:_, idx_wire } => {
write!(self.program_text, "[{}]", self.wire_name(*idx_wire, w.absolute_latency))?;
}
RealWirePathElem::ConstArrayWrite { span:_, idx } => {
write!(self.program_text, "[{}]", idx.unwrap())?;
}
}
}
writeln!(self.program_text, ";")?;
}
RealWireDataSource::UnaryOp { op, right } => {
writeln!(self.program_text, " = {}{};", op.op_text(), self.wire_name(*right, w.absolute_latency))?;
}
RealWireDataSource::BinaryOp { op, left, right } => {
writeln!(self.program_text, " = {} {} {};", self.wire_name(*left, w.absolute_latency), op.op_text(), self.wire_name(*right, w.absolute_latency))?;
}
RealWireDataSource::ArrayAccess { arr, arr_idx } => {
writeln!(self.program_text, " = {}[{}];", self.wire_name(*arr, w.absolute_latency), self.wire_name(*arr_idx, w.absolute_latency))?;
}
RealWireDataSource::ConstArrayAccess { arr, arr_idx } => {
writeln!(self.program_text, " = {}[{arr_idx}];", self.wire_name(*arr, w.absolute_latency))?;
}
RealWireDataSource::Constant { value } => {
writeln!(self.program_text, " = {};", value.to_string())?;
}
Expand Down Expand Up @@ -200,10 +208,9 @@ impl<'g, 'out, Stream : std::fmt::Write> CodeGenerationContext<'g, 'out, Stream>
}
writeln!(self.program_text, "end")?;
}
RealWireDataSource::Select{root : _, path : _} => {}
RealWireDataSource::UnaryOp{op : _, right : _} => {}
RealWireDataSource::BinaryOp{op : _, left : _, right : _} => {}
RealWireDataSource::ArrayAccess{arr : _, arr_idx : _} => {}
RealWireDataSource::ConstArrayAccess{arr : _, arr_idx : _} => {}
RealWireDataSource::Constant{value : _} => {}
}
}
Expand Down
165 changes: 93 additions & 72 deletions src/dev_aid/lsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
compiler_top::{add_file, recompile_all, update_file},
errors::{CompileError, ErrorCollector, ErrorLevel},
file_position::{FileText, LineCol, Span},
flattening::{WireReferenceRoot, FlatID, IdentifierType, Instruction, Module, WireInstance, WireSource},
flattening::{FlatID, IdentifierType, Instruction, Module, WireInstance, WireReference, WireReferenceRoot, WireSource},
instantiation::{SubModuleOrWire, CALCULATE_LATENCY_LATER},
linker::{FileData, FileUUID, FileUUIDMarker, Linker, NameElem},
typing::WrittenType,
Expand Down Expand Up @@ -268,20 +268,15 @@ enum LocationInfo<'linker> {
Global(NameElem)
}

struct LocationInfoBuilder<'linker> {
struct HoverContext<'linker> {
linker : &'linker Linker,
file : &'linker FileData,
position : usize,
best_instruction : Option<LocationInfo<'linker>>,
best_span : Span,
position : usize
}

impl<'linker> LocationInfoBuilder<'linker> {
fn new(token_idx : usize) -> Self {
Self{
best_instruction : None,
best_span : Span::MAX_POSSIBLE_SPAN,
position: token_idx
}
}
impl<'linker> HoverContext<'linker> {
fn update(&mut self, span : Span, info : LocationInfo<'linker>) {
if span.contains_pos(self.position) && span.size() <= self.best_span.size() {
//assert!(span.size() < self.best_span.size());
Expand All @@ -290,77 +285,103 @@ impl<'linker> LocationInfoBuilder<'linker> {
self.best_instruction = Some(info);
}
}
}

fn gather_info_wire_ref(&mut self, md : &'linker Module, wire_ref : &'linker WireReference) {
match &wire_ref.root {
WireReferenceRoot::LocalDecl(decl_id) => {
self.update(wire_ref.root_span, LocationInfo::WireRef(md, *decl_id));
}
WireReferenceRoot::NamedConstant(cst) => {
self.update(wire_ref.root_span, LocationInfo::Global(NameElem::Constant(*cst)))
}
WireReferenceRoot::SubModulePort(port) => {
if let Some(span) = port.port_name_span {
todo!("LSP for named ports");
}
}
}
}

fn get_info_about_source_location<'linker>(linker : &'linker Linker, position : usize, file : FileUUID) -> Option<(LocationInfo<'linker>, Span)> {
let mut location_builder = LocationInfoBuilder::new(position);

for global in &linker.files[file].associated_values {
match *global {
NameElem::Module(md_id) => {
let md = &linker.modules[md_id];
if md.link_info.span.contains_pos(position) {
location_builder.update(md.link_info.name_span, LocationInfo::Global(NameElem::Module(md_id)));
for (id, inst) in &md.instructions {
match inst {
Instruction::SubModule(sm) => {
location_builder.update(sm.module_name_span, LocationInfo::Global(NameElem::Module(sm.module_uuid)));
}
Instruction::Declaration(decl) => {
match decl.typ_expr.get_deepest_selected(position) {
Some(WrittenType::Named(span, name_id)) => {
location_builder.update(*span, LocationInfo::Global(NameElem::Type(*name_id)));
}
Some(typ) => {
location_builder.update(typ.get_span(), LocationInfo::Type(typ));
}
None => {}
}
if decl.declaration_itself_is_not_written_to && decl.name_span.contains_pos(position) {
location_builder.update(decl.name_span, LocationInfo::WireRef(md, id));
}
}
Instruction::Wire(wire) => {
let loc_info = if let WireSource::WireRead(decl_id) = &wire.source {
LocationInfo::WireRef(md, *decl_id)
} else {
LocationInfo::Temporary(md, id, wire)
};
location_builder.update(wire.span, loc_info);
}
Instruction::Write(write) => {
match write.to.root {
WireReferenceRoot::LocalDecl(decl_id) => {
location_builder.update(write.to.root_span, LocationInfo::WireRef(md, decl_id));
}
WireReferenceRoot::SubModulePort(port) => {
if let Some(span) = port.port_name_span {
todo!("LSP for named ports");
}
}
}
}
Instruction::IfStatement(_) | Instruction::ForStatement(_) => {}
};
fn gather_info_module(&mut self, md : &'linker Module) {
for (id, inst) in &md.instructions {
match inst {
Instruction::SubModule(sm) => {
self.update(sm.module_name_span, LocationInfo::Global(NameElem::Module(sm.module_uuid)));
}
Instruction::Declaration(decl) => {
match decl.typ_expr.get_deepest_selected(self.position) {
Some(WrittenType::Named(span, name_id)) => {
self.update(*span, LocationInfo::Global(NameElem::Type(*name_id)));
}
Some(typ) => {
self.update(typ.get_span(), LocationInfo::Type(typ));
}
None => {}
}
if decl.declaration_itself_is_not_written_to && decl.name_span.contains_pos(self.position) {
self.update(decl.name_span, LocationInfo::WireRef(md, id));
}
}
}
NameElem::Type(_) => {
todo!()
}
NameElem::Constant(_) => {
todo!()
Instruction::Wire(wire) => {
if let WireSource::WireRead(wire_ref) = &wire.source {
self.gather_info_wire_ref(md, wire_ref);
} else {
self.update(wire.span, LocationInfo::Temporary(md, id, wire));
};
}
Instruction::Write(write) => {
self.gather_info_wire_ref(md, &write.to);
}
Instruction::IfStatement(_) | Instruction::ForStatement(_) => {}
};
}
}

fn gather_info(&mut self) {
for global in &self.file.associated_values {
match *global {
NameElem::Module(md_id) => {
let md = &self.linker.modules[md_id];

if md.link_info.span.contains_pos(self.position) {
self.update(md.link_info.name_span, LocationInfo::Global(NameElem::Module(md_id)));
self.gather_info_module(md);
}
}
NameElem::Type(_) => {
todo!()
}
NameElem::Constant(_) => {
todo!()
}
}
}
}
if let Some(instr) = location_builder.best_instruction {
Some((instr, location_builder.best_span))
} else {
None

fn extract_result(self) -> Option<(LocationInfo<'linker>, Span)> {
if let Some(instr) = self.best_instruction {
Some((instr, self.best_span))
} else {
None
}
}
}

fn get_info_about_source_location<'linker>(linker : &'linker Linker, position : usize, file : FileUUID) -> Option<(LocationInfo<'linker>, Span)> {
let mut ctx = HoverContext {
linker,
position,
file : &linker.files[file],
best_instruction : None,
best_span : Span::MAX_POSSIBLE_SPAN
};

ctx.gather_info();

ctx.extract_result()
}


fn get_hover_info<'l>(file_cache : &'l LoadedFileCache, text_pos : &lsp_types::TextDocumentPositionParams) -> Option<(&'l FileData, LocationInfo<'l>, lsp_types::Range)> {
let uuid = file_cache.find_uri(&text_pos.text_document.uri).unwrap();

Expand Down
45 changes: 21 additions & 24 deletions src/dev_aid/syntax_highlighting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
compiler_top::{add_file, recompile_all},
errors::{CompileError, ErrorLevel},
file_position::Span,
flattening::{WireReferenceRoot, IdentifierType, Instruction, WireSource},
flattening::{IdentifierType, Instruction, Module, WireReference, WireReferenceRoot, WireSource},
linker::{FileUUID, FileUUIDMarker, Linker, NameElem}
};

Expand All @@ -24,6 +24,23 @@ pub struct SyntaxHighlightSettings {
pub show_tokens : bool
}

pub fn walk_name_color_wireref(module : &Module, wire_ref : &WireReference, result : &mut Vec<(IDEIdentifierType, Span)>) {
match &wire_ref.root {
WireReferenceRoot::LocalDecl(decl_id) => {
let decl = module.instructions[*decl_id].unwrap_wire_declaration();
result.push((IDEIdentifierType::Value(decl.identifier_type), wire_ref.root_span));
}
WireReferenceRoot::NamedConstant(_cst) => {
result.push((IDEIdentifierType::Constant, wire_ref.root_span));
}
WireReferenceRoot::SubModulePort(port) => {
if let Some(span) = port.port_name_span {
result.push((IDEIdentifierType::Value(port.port_identifier_typ), span))
}
}
}
}

pub fn walk_name_color(all_objects : &[NameElem], linker : &Linker) -> Vec<(IDEIdentifierType, Span)> {
let mut result : Vec<(IDEIdentifierType, Span)> = Vec::new();
for obj_uuid in all_objects {
Expand All @@ -34,22 +51,12 @@ pub fn walk_name_color(all_objects : &[NameElem], linker : &Linker) -> Vec<(IDEI
match item {
Instruction::Wire(w) => {
match &w.source {
&WireSource::WireRead(from_wire) => {
let decl = module.instructions[from_wire].unwrap_wire_declaration();
result.push((IDEIdentifierType::Value(decl.identifier_type), w.span));
WireSource::WireRead(from_wire) => {
walk_name_color_wireref(module, from_wire, &mut result);
}
WireSource::UnaryOp { op:_, right:_ } => {}
WireSource::BinaryOp { op:_, left:_, right:_ } => {}
WireSource::ArrayAccess { arr:_, arr_idx:_, bracket_span:_ } => {}
WireSource::Constant(_) => {}
WireSource::NamedConstant(_name) => {
result.push((IDEIdentifierType::Constant, w.span));
}
WireSource::PortRead(info) => {
if let Some(port_name_span) = &info.port_name_span {
result.push((IDEIdentifierType::Value(info.port_identifier_typ), *port_name_span))
}
}
}
}
Instruction::Declaration(decl) => {
Expand All @@ -59,17 +66,7 @@ pub fn walk_name_color(all_objects : &[NameElem], linker : &Linker) -> Vec<(IDEI
result.push((IDEIdentifierType::Value(decl.identifier_type), decl.name_span));
}
Instruction::Write(conn) => {
match conn.to.root {
WireReferenceRoot::LocalDecl(decl_id) => {
let decl = module.instructions[decl_id].unwrap_wire_declaration();
result.push((IDEIdentifierType::Value(decl.identifier_type), conn.to.root_span));
}
WireReferenceRoot::SubModulePort(port) => {
if let Some(span) = port.port_name_span {
todo!("Syntax highlight for named ports")
}
}
}
walk_name_color_wireref(module, &conn.to, &mut result);
}
Instruction::SubModule(sm) => {
result.push((IDEIdentifierType::Interface, sm.module_name_span));
Expand Down
1 change: 1 addition & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ impl ErrorCollector {
}

fn assert_span_good(&self, span : Span) {
span.debug();
let rng = span.into_range();
assert!(rng.end <= self.file_len); // Don't need to verify start, since Span already enforces start <= end
}
Expand Down
Loading

0 comments on commit 3e65179

Please sign in to comment.