-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add module port names in initialization
- Loading branch information
Showing
8 changed files
with
233 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,137 @@ | ||
|
||
use sus_proc_macro::{field, kind}; | ||
|
||
|
||
use crate::{ | ||
errors::ErrorCollector, | ||
flattening::{FlattenedModule, Module}, | ||
instantiation::InstantiationList, | ||
linker::{FileBuilder, LinkInfo}, | ||
parser::Cursor | ||
arena_alloc::{FlatAlloc, UUIDMarker, UUIDRange, UUID}, file_position::{FileText, Span}, flattening::{FlattenedModule, Module}, instantiation::InstantiationList, linker::{FileBuilder, LinkInfo}, parser::Cursor | ||
}; | ||
|
||
use super::IdentifierType; | ||
|
||
|
||
|
||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
pub struct PortIDMarker; | ||
impl UUIDMarker for PortIDMarker {const DISPLAY_NAME : &'static str = "port_";} | ||
pub type PortID = UUID<PortIDMarker>; | ||
|
||
pub type PortIDRange = UUIDRange<PortIDMarker>; | ||
|
||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
pub struct InterfaceIDMarker; | ||
impl UUIDMarker for InterfaceIDMarker {const DISPLAY_NAME : &'static str = "port_";} | ||
pub type InterfaceID = UUID<InterfaceIDMarker>; | ||
|
||
|
||
#[derive(Debug)] | ||
pub struct Port { | ||
pub name : String, | ||
pub name_span : Span, | ||
pub decl_span : Span, | ||
pub id_typ : IdentifierType, | ||
pub interface : InterfaceID | ||
} | ||
|
||
#[derive(Debug)] | ||
pub struct Interface { | ||
pub func_call_inputs : PortIDRange, | ||
pub func_call_outputs : PortIDRange | ||
} | ||
|
||
|
||
#[derive(Debug)] | ||
pub struct ModulePorts { | ||
pub ports : FlatAlloc<Port, PortIDMarker>, | ||
pub interfaces : FlatAlloc<Interface, InterfaceIDMarker> | ||
} | ||
|
||
impl ModulePorts { | ||
/// Get a port by the given name. Returns None if it does not exist | ||
pub fn get_port_by_name(&self, name : &str) -> Option<PortID> { | ||
for (id, data) in &self.ports { | ||
if data.name == name { | ||
return Some(id) | ||
} | ||
} | ||
return None | ||
} | ||
|
||
/// This function is intended to retrieve a known port while walking the syntax tree. panics if the port doesn't exist | ||
pub fn get_port_by_decl_span(&self, span : Span) -> PortID { | ||
for (id, data) in &self.ports { | ||
if data.decl_span == span { | ||
return id | ||
} | ||
} | ||
unreachable!() | ||
} | ||
} | ||
|
||
pub fn gather_initial_file_data(builder : &mut FileBuilder) { | ||
let mut walker = Cursor::new_at_root(builder.tree, builder.file_text); | ||
walker.list(kind!("source_file"), |cursor| { | ||
let mut cursor = Cursor::new_at_root(builder.tree, builder.file_text); | ||
cursor.list_and_report_errors(kind!("source_file"), &builder.other_parsing_errors, |cursor| { | ||
let (kind, span) = cursor.kind_span(); | ||
assert!(kind == kind!("module")); | ||
let name_span = cursor.go_down_no_check(|cursor| cursor.field_span(field!("name"), kind!("identifier"))); | ||
let md = Module{ | ||
link_info: LinkInfo { | ||
documentation: cursor.extract_gathered_comments(), | ||
file: builder.file_id, | ||
name: builder.file_text[name_span].to_owned(), | ||
name_span, | ||
span | ||
match kind { | ||
kind!("module") => { | ||
let parsing_errors = builder.other_parsing_errors.new_for_same_file_inherit_did_error(); | ||
cursor.report_all_decendant_errors(&parsing_errors); | ||
cursor.go_down_no_check(|cursor| { | ||
let name_span = cursor.field_span(field!("name"), kind!("identifier")); | ||
|
||
let mut ports = FlatAlloc::new(); | ||
let mut interfaces = FlatAlloc::new(); | ||
|
||
let main_interface = interfaces.get_next_alloc_id(); | ||
|
||
let mut func_call_inputs = PortIDRange::empty(); | ||
let mut func_call_outputs = PortIDRange::empty(); | ||
|
||
if cursor.optional_field(field!("interface_ports")) { | ||
if cursor.optional_field(field!("inputs")) { | ||
func_call_inputs = gather_decl_names_in_list(IdentifierType::Input, main_interface, &mut ports, cursor, builder.file_text); | ||
} | ||
if cursor.optional_field(field!("outputs")) { | ||
func_call_outputs = gather_decl_names_in_list(IdentifierType::Output, main_interface, &mut ports, cursor, builder.file_text); | ||
} | ||
} | ||
|
||
interfaces.alloc(Interface{func_call_inputs, func_call_outputs}); | ||
|
||
let md = Module{ | ||
link_info: LinkInfo { | ||
documentation: cursor.extract_gathered_comments(), | ||
file: builder.file_id, | ||
name: builder.file_text[name_span].to_owned(), | ||
name_span, | ||
span | ||
}, | ||
flattened: FlattenedModule::empty(parsing_errors.new_for_same_file_inherit_did_error()), | ||
module_ports : ModulePorts{ | ||
ports, | ||
interfaces | ||
}, | ||
parsing_errors, | ||
instantiations: InstantiationList::new() | ||
}; | ||
|
||
builder.add_module(md); | ||
}); | ||
}, | ||
flattened: FlattenedModule::empty(ErrorCollector::new(builder.file_id, builder.file_text.len())), | ||
instantiations: InstantiationList::new() | ||
}; | ||
_other => cursor.could_not_match() | ||
} | ||
}); | ||
} | ||
|
||
builder.add_module(md); | ||
fn gather_decl_names_in_list(id_typ: IdentifierType, interface : InterfaceID, ports: &mut FlatAlloc<Port, PortIDMarker>, cursor: &mut Cursor, file_text : &FileText) -> PortIDRange { | ||
let list_start_at = ports.get_next_alloc_id(); | ||
cursor.list(kind!("declaration_list"), |cursor| { | ||
let decl_span = cursor.span(); | ||
cursor.go_down(kind!("declaration"), |cursor| { | ||
cursor.field(field!("type")); | ||
let name_span = cursor.field_span(field!("name"), kind!("identifier")); | ||
let name = file_text[name_span].to_owned(); | ||
ports.alloc(Port{name, name_span, decl_span, id_typ, interface}) | ||
}); | ||
}); | ||
ports.range_since(list_start_at) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.