Skip to content

Commit

Permalink
Add basic named ports and a bunch of debugging help
Browse files Browse the repository at this point in the history
  • Loading branch information
VonTum committed May 12, 2024
1 parent f7539b0 commit 4909bce
Show file tree
Hide file tree
Showing 15 changed files with 386 additions and 270 deletions.
14 changes: 14 additions & 0 deletions multiply_add.sus
Original file line number Diff line number Diff line change
Expand Up @@ -683,4 +683,18 @@ module monotonize_down : bool[16] mbf -> bool[16] mtDown {
}


module submodule_named_ports : int port_a, int port_b -> int port_c {
port_c = port_a + port_b
}

module use_submodule_named_ports : int i -> int o {
submodule_named_ports sm

o = sm(i, i)

sm.port_a = i

sm.port_b = i

o = sm.port_c
}
8 changes: 7 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::rc::Rc;
use tree_sitter::Parser;

use crate::{
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, ModuleUUID}
};

pub fn add_file(text : String, linker : &mut Linker) -> FileUUID {
Expand Down Expand Up @@ -59,6 +59,12 @@ pub fn recompile_all(linker : &mut Linker) {
flatten_all_modules(linker);
typecheck_all_modules(linker);

if config().debug_flattened {
for (_, md) in &linker.modules {
md.print_flattened_module(&linker.files[md.link_info.file].file_text);
}
}

// Make an initial instantiation of all modules
// Won't be possible once we have template modules
for (id, _md) in &linker.modules {
Expand Down
85 changes: 85 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use std::{cell::UnsafeCell, env, path::PathBuf};


pub struct ConfigStruct {
pub use_lsp : bool,
pub lsp_debug_mode : bool,
pub lsp_port : u16,
pub codegen : bool,
pub debug_flattened : bool
}

pub fn config() -> &'static ConfigStruct {
unsafe {
&*CONFIG.cf.get()
}
}

pub fn parse_args() -> Vec<PathBuf> {
let mut args = env::args();

let _executable_path = args.next();

let config = unsafe{&mut *CONFIG.cf.get()};

let mut file_paths : Vec<PathBuf> = Vec::new();

while let Some(arg) = args.next() {
if arg.starts_with("-") {
if let Some((name, value)) = arg.split_once("=") {
match name {
"--socket" => {
config.lsp_port = u16::from_str_radix(value, 10).unwrap();
}
other => panic!("Unknown option {other}"),
}
} else {
match arg.as_str() {
"--lsp" => {
config.use_lsp = true;
}
"--lsp-debug" => {
config.lsp_debug_mode = true;
}
"--codegen" => {
config.codegen = true;
}
"--debug" => {
config.debug_flattened = true;
}
other => {
panic!("Unknown option {other}");
}
}
}
} else {
file_paths.push(PathBuf::from(arg));
}
}

// For debugging
if file_paths.len() == 0 {
// Quick debugging
//file_paths.push(PathBuf::from("resetNormalizer.sus"));
//file_paths.push(PathBuf::from("multiply_add.sus"));
file_paths.push(PathBuf::from("tinyTestFile.sus"));
config.codegen = true;
//codegen = Some("first_bit_idx_6".to_owned());
}

file_paths
}

struct ConfigStructWrapper {
cf : UnsafeCell<ConfigStruct>
}

unsafe impl Sync for ConfigStructWrapper {}

static CONFIG : ConfigStructWrapper = ConfigStructWrapper{cf: UnsafeCell::new(ConfigStruct{
use_lsp : false,
lsp_port : 25000,
lsp_debug_mode : false,
debug_flattened : false,
codegen : false
})};
95 changes: 55 additions & 40 deletions src/dev_aid/lsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,7 @@ use lsp_server::{Connection, Message, Response};
use lsp_types::notification::Notification;

use crate::{
arena_alloc::ArenaVector,
compiler_top::{add_file, recompile_all, update_file},
errors::{CompileError, ErrorLevel},
file_position::{FileText, LineCol, Span},
flattening::{FlatID, IdentifierType, Instruction, Module, WireInstance, WireReference, WireReferenceRoot, WireSource},
instantiation::{SubModuleOrWire, CALCULATE_LATENCY_LATER},
linker::{FileData, FileUUID, FileUUIDMarker, Linker, NameElem},
typing::WrittenType,
walk_name_color
arena_alloc::ArenaVector, compiler_top::{add_file, recompile_all, update_file}, config::config, errors::{CompileError, ErrorLevel}, file_position::{FileText, LineCol, Span, SpanFile}, flattening::{FlatID, IdentifierType, Instruction, Module, PortID, WireInstance, WireReference, WireReferenceRoot, WireSource}, instantiation::{SubModuleOrWire, CALCULATE_LATENCY_LATER}, linker::{FileData, FileUUID, FileUUIDMarker, Linker, ModuleUUID, NameElem}, typing::WrittenType, walk_name_color
};

use super::syntax_highlighting::IDEIdentifierType;
Expand Down Expand Up @@ -56,16 +48,16 @@ impl LoadedFileCache {
}
}

pub fn lsp_main(port : u16, debug : bool) -> Result<(), Box<dyn Error + Sync + Send>> {
pub fn lsp_main() -> Result<(), Box<dyn Error + Sync + Send>> {
std::env::set_var("RUST_BACKTRACE", "1"); // Enable backtrace because I can't set it in Env vars

println!("starting LSP server");

// Create the transport. Includes the stdio (stdin and stdout) versions but this could
// also be implemented to use sockets or HTTP.
//let (connection, io_threads) = Connection::listen(SocketAddr::from(([127,0,0,1], 25000)))?;
println!("Connecting on port {}...", port);
let (connection, io_threads) = Connection::connect(SocketAddr::from(([127,0,0,1], port)))?;
println!("Connecting on port {}...", config().lsp_port);
let (connection, io_threads) = Connection::connect(SocketAddr::from(([127,0,0,1], config().lsp_port)))?;
println!("connection established");

// Run the server and wait for the two threads to end (typically by trigger LSP Exit event).
Expand Down Expand Up @@ -120,7 +112,7 @@ pub fn lsp_main(port : u16, debug : bool) -> Result<(), Box<dyn Error + Sync + S
})
.unwrap();
let initialization_params = connection.initialize(server_capabilities)?;
main_loop(connection, initialization_params, debug)?;
main_loop(connection, initialization_params)?;
io_threads.join()?;

// Shut down gracefully.
Expand Down Expand Up @@ -242,7 +234,8 @@ enum LocationInfo<'linker> {
WireRef(&'linker Module, FlatID),
Temporary(&'linker Module, FlatID, &'linker WireInstance),
Type(&'linker WrittenType),
Global(NameElem)
Global(NameElem),
Port(PortID, ModuleUUID)
}

struct HoverContext<'linker> {
Expand All @@ -265,15 +258,17 @@ impl<'linker> HoverContext<'linker> {

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::LocalDecl(decl_id, span) => {
self.update(*span, LocationInfo::WireRef(md, *decl_id));
}
WireReferenceRoot::NamedConstant(cst) => {
self.update(wire_ref.root_span, LocationInfo::Global(NameElem::Constant(*cst)))
WireReferenceRoot::NamedConstant(cst, span) => {
self.update(*span, LocationInfo::Global(NameElem::Constant(*cst)))
}
WireReferenceRoot::SubModulePort(port) => {
self.update(port.submodule_name_span, LocationInfo::WireRef(md, port.submodule_flat));
if let Some(span) = port.port_name_span {
todo!("LSP for named ports");
span.debug();
self.update(span, LocationInfo::Port(port.port, md.instructions[port.submodule_flat].unwrap_submodule().module_uuid))
}
}
}
Expand Down Expand Up @@ -470,7 +465,7 @@ fn gather_completions(linker : &Linker, file_id : FileUUID, position : usize) ->
result
}

fn handle_request(method : &str, params : serde_json::Value, file_cache : &mut LoadedFileCache, debug : bool) -> Result<serde_json::Value, serde_json::Error> {
fn handle_request(method : &str, params : serde_json::Value, file_cache : &mut LoadedFileCache) -> Result<serde_json::Value, serde_json::Error> {
match method {
request::HoverRequest::METHOD => {
let params : HoverParams = serde_json::from_value(params).expect("JSON Encoding Error while parsing params");
Expand All @@ -479,7 +474,7 @@ fn handle_request(method : &str, params : serde_json::Value, file_cache : &mut L
file_cache.ensure_contains_file(&params.text_document_position_params.text_document.uri);
serde_json::to_value(&if let Some((file_data, info, range)) = get_hover_info(&file_cache, &params.text_document_position_params) {
let mut hover_list : Vec<MarkedString> = Vec::new();
if debug {
if config().lsp_debug_mode {
hover_list.push(MarkedString::String(format!("{info:?}")))
} else {
match info {
Expand Down Expand Up @@ -508,7 +503,19 @@ fn handle_request(method : &str, params : serde_json::Value, file_cache : &mut L
if let Some(link_info) = file_cache.linker.get_link_info(global) {
hover_list.push(MarkedString::String(link_info.documentation.to_string(&file_data.file_text)));
}
hover_list.push(MarkedString::String(file_cache.linker.get_full_name(global)));
hover_list.push(MarkedString::String(format!(" {}", file_cache.linker.get_full_name(global))));
match global {
NameElem::Module(md_uuid) => {
let md = &file_cache.linker.modules[md_uuid];
hover_list.push(MarkedString::String(md.make_all_ports_info_string(&file_cache.linker.files[md.link_info.file].file_text)));
}
NameElem::Type(_) => todo!(),
NameElem::Constant(_) => todo!(),
}
}
LocationInfo::Port(port, md_uuid) => {
let md = &file_cache.linker.modules[md_uuid];
hover_list.push(MarkedString::String(md.make_port_info_string(port, &file_cache.linker.files[md.link_info.file].file_text)));
}
};
}
Expand All @@ -522,32 +529,40 @@ fn handle_request(method : &str, params : serde_json::Value, file_cache : &mut L
println!("GotoDefinition");

file_cache.ensure_contains_file(&params.text_document_position_params.text_document.uri);
serde_json::to_value(&if let Some((_file_data, info, _range)) = get_hover_info(&file_cache, &params.text_document_position_params) {

let mut goto_definition_list : Vec<SpanFile> = Vec::new();

if let Some((_file_data, info, _range)) = get_hover_info(&file_cache, &params.text_document_position_params) {
match info {
LocationInfo::WireRef(md, decl_id) => {
let uri = file_cache.uris[md.link_info.file].clone();
let decl = md.instructions[decl_id].unwrap_wire_declaration();
let range = to_position_range(file_cache.linker.files[md.link_info.file].file_text.get_span_linecol_range(decl.name_span));
GotoDefinitionResponse::Scalar(Location{uri, range})
}
LocationInfo::Temporary(_, _, _) => {
GotoDefinitionResponse::Array(Vec::new())
}
LocationInfo::Type(_) => {
GotoDefinitionResponse::Array(Vec::new())
goto_definition_list.push((decl.name_span, md.link_info.file));
}
LocationInfo::Temporary(_, _, _) => {}
LocationInfo::Type(_) => {}
LocationInfo::Global(id) => {
if let Some(link_info) = file_cache.linker.get_link_info(id) {
let uri = file_cache.uris[link_info.file].clone();
let range = to_position_range(file_cache.linker.files[link_info.file].file_text.get_span_linecol_range(link_info.name_span));
GotoDefinitionResponse::Scalar(Location{uri, range})
} else {
GotoDefinitionResponse::Array(Vec::new())
goto_definition_list.push((link_info.name_span, link_info.file));
}
}
LocationInfo::Port(port_id, md_uuid) => {
let md = &file_cache.linker.modules[md_uuid];
let port = &md.module_ports.ports[port_id];
goto_definition_list.push((port.name_span, md.link_info.file));
}
}
}

let cvt = |(span, file)| {
let uri = file_cache.uris[file].clone();
let range = to_position_range(file_cache.linker.files[file].file_text.get_span_linecol_range(span));
Location{uri, range}
};

serde_json::to_value(&if goto_definition_list.len() == 1 {
GotoDefinitionResponse::Scalar(cvt(goto_definition_list[0]))
} else {
GotoDefinitionResponse::Array(Vec::new())
GotoDefinitionResponse::Array(goto_definition_list.into_iter().map(cvt).collect())
})
}
request::SemanticTokensFullRequest::METHOD => {
Expand Down Expand Up @@ -616,7 +631,7 @@ fn handle_notification(connection: &Connection, notification : lsp_server::Notif
Ok(())
}

fn main_loop(connection: Connection, initialize_params: serde_json::Value, debug : bool) -> Result<(), Box<dyn Error + Sync + Send>> {
fn main_loop(connection: Connection, initialize_params: serde_json::Value) -> Result<(), Box<dyn Error + Sync + Send>> {
let initialize_params: InitializeParams = serde_json::from_value(initialize_params).unwrap();

let mut file_cache = initialize_all_files(&initialize_params);
Expand All @@ -632,7 +647,7 @@ fn main_loop(connection: Connection, initialize_params: serde_json::Value, debug
return Ok(());
}

let response_value = handle_request(&req.method, req.params, &mut file_cache, debug);
let response_value = handle_request(&req.method, req.params, &mut file_cache);

let result = response_value.unwrap();
let response = Response{id : req.id, result: Some(result), error: None};
Expand Down
21 changes: 6 additions & 15 deletions src/dev_aid/syntax_highlighting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@
use std::{ops::Range, path::PathBuf};

use crate::{
arena_alloc::ArenaVector,
compiler_top::{add_file, recompile_all},
errors::{CompileError, ErrorLevel},
file_position::Span,
flattening::{IdentifierType, Instruction, Module, WireReference, WireReferenceRoot, WireSource},
linker::{FileUUID, FileUUIDMarker, Linker, NameElem}
arena_alloc::ArenaVector, compiler_top::{add_file, recompile_all}, config::config, errors::{CompileError, ErrorLevel}, file_position::Span, flattening::{IdentifierType, Instruction, Module, WireReference, WireReferenceRoot, WireSource}, linker::{FileUUID, FileUUIDMarker, Linker, NameElem}
};

use ariadne::*;
Expand All @@ -20,18 +15,14 @@ pub enum IDEIdentifierType {
Constant
}

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) => {
WireReferenceRoot::LocalDecl(decl_id, span) => {
let decl = module.instructions[*decl_id].unwrap_wire_declaration();
result.push((IDEIdentifierType::Value(decl.identifier_type), wire_ref.root_span));
result.push((IDEIdentifierType::Value(decl.identifier_type), *span));
}
WireReferenceRoot::NamedConstant(_cst) => {
result.push((IDEIdentifierType::Constant, wire_ref.root_span));
WireReferenceRoot::NamedConstant(_cst, span) => {
result.push((IDEIdentifierType::Constant, *span));
}
WireReferenceRoot::SubModulePort(port) => {
if let Some(span) = port.port_name_span {
Expand Down Expand Up @@ -181,7 +172,7 @@ pub fn pretty_print_spans_in_reverse_order(file_text : String, spans : Vec<Range
let config =
Config::default()
.with_index_type(IndexType::Byte)
.with_color(false); // Disable color because LSP output doesn't support it
.with_color(!config().use_lsp); // Disable color because LSP output doesn't support it

let mut report: ReportBuilder<'_, Range<usize>> = Report::build(ReportKind::Advice, (), span.start).with_config(config);
report = report
Expand Down
Loading

0 comments on commit 4909bce

Please sign in to comment.