Skip to content

Commit

Permalink
Add builtin clog2, sizeof, assert
Browse files Browse the repository at this point in the history
This also includes refactors to the tree walking and hover system, to make it more generic for all globals.
  • Loading branch information
VonTum committed Jan 29, 2025
1 parent d7f1d1c commit f9de730
Show file tree
Hide file tree
Showing 22 changed files with 404 additions and 265 deletions.
14 changes: 1 addition & 13 deletions src/codegen/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,7 @@
use std::borrow::Cow;

use crate::{instantiation::RealWire, linker::get_builtin_type, TypeUUID};


pub fn get_type_name_size(id: TypeUUID) -> u64 {
if id == get_builtin_type("int") {
32 // TODO concrete int sizes
} else if id == get_builtin_type("bool") {
1
} else {
println!("TODO Named Structs Size");
1 // todo!() // Named structs are not implemented yet
}
}
use crate::instantiation::RealWire;

pub fn wire_name_with_latency(wire: &RealWire, absolute_latency: i64, use_latency: bool) -> Cow<str> {
assert!(wire.absolute_latency <= absolute_latency);
Expand Down
2 changes: 1 addition & 1 deletion src/codegen/system_verilog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ fn typ_to_declaration(mut typ: &ConcreteType, var_name: &str) -> String {
}
match typ {
ConcreteType::Named(id) => {
let sz = get_type_name_size(*id);
let sz = ConcreteType::sizeof_named(*id);
if sz == 1 {
format!("{array_string} {var_name}")
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/codegen/vhdl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fn typ_to_declaration(mut typ: &ConcreteType) -> String {
}
match typ {
ConcreteType::Named(id) => {
let sz = get_type_name_size(*id);
let sz = ConcreteType::sizeof_named(*id);
if sz == 1 {
format!("{array_string} std_logic")
} else {
Expand Down
9 changes: 8 additions & 1 deletion src/compiler_top.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::path::PathBuf;
use std::str::FromStr;

use crate::config::EarlyExitUpTo;
use crate::linker::{get_builtin_type, AFTER_INITIAL_PARSE_CP};
use crate::linker::{get_builtin_const, get_builtin_type, AFTER_INITIAL_PARSE_CP};
use crate::prelude::*;

use tree_sitter::Parser;
Expand Down Expand Up @@ -45,6 +45,13 @@ impl Linker {

assert_eq!(self.types[get_builtin_type("int")].link_info.name, "int");
assert_eq!(self.types[get_builtin_type("bool")].link_info.name, "bool");

assert_eq!(self.constants[get_builtin_const("true")].link_info.name, "true");
assert_eq!(self.constants[get_builtin_const("false")].link_info.name, "false");
assert_eq!(self.constants[get_builtin_const("__crash_compiler")].link_info.name, "__crash_compiler");
assert_eq!(self.constants[get_builtin_const("assert")].link_info.name, "assert");
assert_eq!(self.constants[get_builtin_const("sizeof")].link_info.name, "sizeof");
assert_eq!(self.constants[get_builtin_const("clog2")].link_info.name, "clog2");
}

pub fn add_all_files_in_directory<ExtraInfoManager : LinkerExtraFileInfoManager>(&mut self, directory : &PathBuf, info_mngr : &mut ExtraInfoManager) {
Expand Down
126 changes: 67 additions & 59 deletions src/dev_aid/lsp/hover_info.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::borrow::Cow;

use crate::alloc::ArenaAllocator;
use crate::prelude::*;
use crate::to_string::pretty_print_concrete_instance;

Expand All @@ -14,7 +15,7 @@ use crate::typing::{
template::{GenerativeParameterKind, ParameterKind, TypeParameterKind},
};

use super::tree_walk::{InModule, LocationInfo};
use super::tree_walk::{InGlobal, LocationInfo};

struct HoverCollector<'l> {
list: Vec<MarkedString>,
Expand Down Expand Up @@ -46,31 +47,35 @@ impl<'l> HoverCollector<'l> {
self.list.push(MarkedString::String(result_str));
}

fn gather_hover_infos(&mut self, md: &Module, id: FlatID, is_generative: bool) {
md.instantiations.for_each_instance(|_template_args, inst| {
if is_generative {
let value_str = match &inst.generation_state[id] {
SubModuleOrWire::SubModule(_) | SubModuleOrWire::Wire(_) => unreachable!(),
SubModuleOrWire::CompileTimeValue(v) => format!(" = {}", v),
SubModuleOrWire::Unnasigned => format!("never assigned to"),
};
self.monospace(value_str);
} else {
for (_id, wire) in &inst.wires {
if wire.original_instruction != id {
continue;
}
let typ_str = wire.typ.display(&self.linker.types);
let name_str = &wire.name;
let latency_str = if wire.absolute_latency != CALCULATE_LATENCY_LATER {
format!("{}", wire.absolute_latency)
} else {
"?".to_owned()
fn gather_hover_infos(&mut self, obj_id: GlobalUUID, id: FlatID, is_generative: bool) {
if let GlobalUUID::Module(md_id) = obj_id {
let md = &self.linker.modules[md_id];

md.instantiations.for_each_instance(|_template_args, inst| {
if is_generative {
let value_str = match &inst.generation_state[id] {
SubModuleOrWire::SubModule(_) | SubModuleOrWire::Wire(_) => unreachable!(),
SubModuleOrWire::CompileTimeValue(v) => format!(" = {}", v),
SubModuleOrWire::Unnasigned => format!("never assigned to"),
};
self.sus_code(format!("{typ_str} {name_str}'{latency_str}"));
self.monospace(value_str);
} else {
for (_id, wire) in &inst.wires {
if wire.original_instruction != id {
continue;
}
let typ_str = wire.typ.display(&self.linker.types);
let name_str = &wire.name;
let latency_str = if wire.absolute_latency != CALCULATE_LATENCY_LATER {
format!("{}", wire.absolute_latency)
} else {
"?".to_owned()
};
self.sus_code(format!("{typ_str} {name_str}'{latency_str}"));
}
}
}
});
});
}
}

fn gather_submodule_hover_infos(&mut self, md: &Module, submodule: &Module, id: FlatID) {
Expand All @@ -85,6 +90,14 @@ impl<'l> HoverCollector<'l> {
}
}

fn try_get_module(linker_modules: &ArenaAllocator<Module, ModuleUUIDMarker>, id: GlobalUUID) -> Option<&Module> {
if let GlobalUUID::Module(md_id) = id {
Some(&linker_modules[md_id])
} else {
None
}
}

pub fn hover(info: LocationInfo, linker: &Linker, file_data: &FileData) -> Vec<MarkedString> {
let mut hover = HoverCollector {
list: Vec::new(),
Expand All @@ -93,50 +106,47 @@ pub fn hover(info: LocationInfo, linker: &Linker, file_data: &FileData) -> Vec<M
};

match info {
LocationInfo::InModule(_md_id, md, decl_id, InModule::NamedLocal(decl)) => {
let mut details_vec: Vec<&str> = Vec::with_capacity(5);
let domain_str = if md.implicit_clk_domain {
if let DomainType::Physical(ph) = decl.typ.domain {
Some(DomainType::physical_to_string(ph, &md.domains))
} else {
None
}
} else {
None
};
LocationInfo::InGlobal(obj_id, link_info, decl_id, InGlobal::NamedLocal(decl)) => {
let mut details_vec: Vec<String> = Vec::with_capacity(5);

if let Some(ds) = &domain_str {
details_vec.push(ds);
if let Some(md) = try_get_module(&linker.modules, obj_id) {
if md.implicit_clk_domain {
if let DomainType::Physical(ph) = decl.typ.domain {
details_vec.push(DomainType::physical_to_string(ph, &md.domains));
}
}
}

match decl.decl_kind {
DeclarationKind::RegularPort {
is_input,
port_id: _,
} => details_vec.push(if is_input { "input" } else { "output" }),
} => details_vec.push(if is_input { "input" } else { "output" }.to_owned()),
DeclarationKind::NotPort | DeclarationKind::StructField { field_id:_ } => {}
DeclarationKind::GenerativeInput(_) => details_vec.push("param"),
DeclarationKind::GenerativeInput(_) => details_vec.push("param".to_owned()),
}

match decl.identifier_type {
IdentifierType::Local => {}
IdentifierType::State => details_vec.push("state"),
IdentifierType::Generative => details_vec.push("gen"),
IdentifierType::State => details_vec.push("state".to_owned()),
IdentifierType::Generative => details_vec.push("gen".to_owned()),
}

let typ_str = decl
.typ
.typ
.display(&linker.types, &md.link_info.template_parameters).to_string();
details_vec.push(&typ_str);
.display(&linker.types, &link_info.template_parameters).to_string();
details_vec.push(typ_str);

details_vec.push(&decl.name);
details_vec.push(decl.name.clone());

hover.documentation(&decl.documentation);
hover.sus_code(details_vec.join(" "));

hover.gather_hover_infos(md, decl_id, decl.identifier_type.is_generative());
hover.gather_hover_infos(obj_id, decl_id, decl.identifier_type.is_generative());
}
LocationInfo::InModule(_, md, id, InModule::NamedSubmodule(submod)) => {
LocationInfo::InGlobal(obj_id, _link_info, id, InGlobal::NamedSubmodule(submod)) => {
let md = &linker.modules[obj_id.unwrap_module()]; // Submodules can only exist within Modules
let submodule = &linker.modules[submod.module_ref.id];

// Declaration's documentation
Expand Down Expand Up @@ -165,32 +175,34 @@ pub fn hover(info: LocationInfo, linker: &Linker, file_data: &FileData) -> Vec<M
hover.documentation_link_info(&submodule.link_info);
hover.gather_submodule_hover_infos(md, submodule, id);
}
LocationInfo::InModule(_md_id, md, id, InModule::Temporary(wire)) => {
LocationInfo::InGlobal(obj_id, link_info, id, InGlobal::Temporary(wire)) => {
let mut details_vec: Vec<Cow<str>> = Vec::with_capacity(2);
match wire.typ.domain {
DomainType::Generative => details_vec.push(Cow::Borrowed("gen")),
DomainType::Physical(ph) => {
if md.implicit_clk_domain {
details_vec
.push(Cow::Owned(DomainType::physical_to_string(ph, &md.domains)))
if let Some(md) = try_get_module(&linker.modules, obj_id) {
if md.implicit_clk_domain {
details_vec
.push(Cow::Owned(DomainType::physical_to_string(ph, &md.domains)))
}
}
}
DomainType::Unknown(_) => unreachable!("Variables should have been eliminated already")
};
details_vec.push(Cow::Owned(
wire.typ
.typ
.display(&linker.types, &md.link_info.template_parameters).to_string(),
.display(&linker.types, &link_info.template_parameters).to_string(),
));
hover.sus_code(details_vec.join(" "));
hover.gather_hover_infos(md, id, wire.typ.domain.is_generative());
hover.gather_hover_infos(obj_id, id, wire.typ.domain.is_generative());
}
LocationInfo::Type(typ, link_info) => {
hover.sus_code(
typ.display(&linker.types, &link_info.template_parameters).to_string(),
);
}
LocationInfo::Parameter(in_obj, link_info, _template_id, template_arg) => {
LocationInfo::Parameter(obj_id, link_info, _template_id, template_arg) => {
match &template_arg.kind {
ParameterKind::Type(TypeParameterKind { }) => {
hover.monospace(format!("type {}", template_arg.name));
Expand All @@ -199,18 +211,14 @@ pub fn hover(info: LocationInfo, linker: &Linker, file_data: &FileData) -> Vec<M
decl_span: _,
declaration_instruction,
}) => {
let GlobalUUID::Module(md_id) = in_obj else {
todo!("Non-module template args")
};
let md = &linker.modules[md_id];
let decl = md.link_info.instructions[*declaration_instruction].unwrap_declaration();
let decl = link_info.instructions[*declaration_instruction].unwrap_declaration();
hover.sus_code(format!(
"param {} {}",
decl.typ_expr
.display(&linker.types, &link_info.template_parameters),
template_arg.name
));
hover.gather_hover_infos(md, *declaration_instruction, true);
hover.gather_hover_infos(obj_id, *declaration_instruction, true);
}
}
}
Expand Down
32 changes: 16 additions & 16 deletions src/dev_aid/lsp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ mod hover_info;
mod semantic_tokens;
mod tree_walk;

use crate::{compiler_top::LinkerExtraFileInfoManager, prelude::*};
use crate::{compiler_top::LinkerExtraFileInfoManager, linker::GlobalUUID, prelude::*};

use hover_info::hover;
use lsp_types::{notification::*, request::Request, *};
Expand All @@ -17,7 +17,7 @@ use crate::{
linker::FileData,
};

use tree_walk::{get_selected_object, InModule, LocationInfo};
use tree_walk::{get_selected_object, InGlobal, LocationInfo};

use self::tree_walk::RefersTo;

Expand Down Expand Up @@ -271,14 +271,14 @@ fn gather_references_in_file(
ref_locations
}

fn for_each_local_reference_in_module(
fn for_each_local_reference_in_global(
linker: &Linker,
md_id: ModuleUUID,
obj_id: GlobalUUID,
local: FlatID,
) -> Vec<Span> {
let mut ref_locations = Vec::new();
tree_walk::visit_all_in_module(linker, md_id, |span, info| {
if let LocationInfo::InModule(_, _, f_id, _) = info {
tree_walk::visit_all_in_module(linker, obj_id, |span, info| {
if let LocationInfo::InGlobal(_, _, f_id, _) = info {
if local == f_id {
ref_locations.push(span);
}
Expand All @@ -293,7 +293,7 @@ fn gather_all_references_in_one_file(linker: &Linker, file_id: FileUUID, pos: us
if refers_to.is_global() {
gather_references_in_file(&linker, &linker.files[file_id], refers_to)
} else if let Some(local) = refers_to.local {
for_each_local_reference_in_module(&linker, local.0, local.1)
for_each_local_reference_in_global(&linker, local.0, local.1)
} else {
Vec::new()
}
Expand Down Expand Up @@ -322,7 +322,7 @@ fn gather_all_references_across_all_files(
}
}
} else if let Some(local) = refers_to.local {
let found_refs = for_each_local_reference_in_module(&linker, local.0, local.1);
let found_refs = for_each_local_reference_in_global(&linker, local.0, local.1);
for r in &found_refs {
assert!(location.size() == r.size())
}
Expand Down Expand Up @@ -381,17 +381,17 @@ fn handle_request(
if let Some((_location, info)) = get_selected_object(linker, file_uuid, pos)
{
match info {
LocationInfo::InModule(_md_id, md, _decl_id, InModule::NamedLocal(decl)) => {
goto_definition_list.push((decl.name_span, md.link_info.file));
LocationInfo::InGlobal(_obj_id, link_info, _decl_id, InGlobal::NamedLocal(decl)) => {
goto_definition_list.push((decl.name_span, link_info.file));
}
LocationInfo::InModule(
_md_id,
md,
LocationInfo::InGlobal(
_obj_id,
link_info,
_decl_id,
InModule::NamedSubmodule(submod_decl),
InGlobal::NamedSubmodule(submod_decl),
) => goto_definition_list
.push((submod_decl.name.as_ref().unwrap().1, md.link_info.file)),
LocationInfo::InModule(_, _, _, InModule::Temporary(_)) => {}
.push((submod_decl.name.as_ref().unwrap().1, link_info.file)),
LocationInfo::InGlobal(_, _, _, InGlobal::Temporary(_)) => {}
LocationInfo::Type(_, _) => {}
LocationInfo::Parameter(_, link_info, _, template_arg) => {
goto_definition_list.push((template_arg.name_span, link_info.file))
Expand Down
8 changes: 4 additions & 4 deletions src/dev_aid/lsp/semantic_tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{

use crate::typing::{abstract_type::DomainType, template::ParameterKind};

use super::tree_walk::{self, InModule, LocationInfo};
use super::tree_walk::{self, InGlobal, LocationInfo};

const NUM_INTERFACE_DISTINGUISHERS: u32 = 5;
const TOKEN_TYPES: [SemanticTokenType; 8] = [
Expand Down Expand Up @@ -146,13 +146,13 @@ fn walk_name_color(file: &FileData, linker: &Linker) -> Vec<(Span, IDEIdentifier
result.push((
span,
match item {
LocationInfo::InModule(_md_id, _md, _, InModule::NamedLocal(decl)) => {
LocationInfo::InGlobal(_md_id, _md, _, InGlobal::NamedLocal(decl)) => {
IDEIdentifierType::from_identifier_typ(decl.identifier_type, decl.typ.domain)
}
LocationInfo::InModule(_md_id, _, _, InModule::NamedSubmodule(_)) => {
LocationInfo::InGlobal(_md_id, _, _, InGlobal::NamedSubmodule(_)) => {
IDEIdentifierType::Interface
}
LocationInfo::InModule(_md_id, _, _, InModule::Temporary(_)) => return,
LocationInfo::InGlobal(_md_id, _, _, InGlobal::Temporary(_)) => return,
LocationInfo::Type(_, _) => return,
LocationInfo::Parameter(_id, _link_info, _, template_arg) => {
match &template_arg.kind {
Expand Down
Loading

0 comments on commit f9de730

Please sign in to comment.