diff --git a/src/arena_alloc.rs b/src/arena_alloc.rs index 34bb16e..0e791ba 100644 --- a/src/arena_alloc.rs +++ b/src/arena_alloc.rs @@ -356,8 +356,10 @@ impl FlatAlloc { pub fn new() -> Self { Self{data : Vec::new(), _ph : PhantomData} } - pub fn alloc(&mut self, UUID(uuid, _) : UUID, value : T) { - self.data[uuid] = value; + pub fn alloc(&mut self, value : T) -> UUID { + let uuid = self.data.len(); + self.data.push(value); + UUID(uuid, PhantomData) } pub fn iter<'a>(&'a self) -> FlatAllocIter<'a, T, IndexMarker> { self.into_iter() @@ -383,10 +385,6 @@ impl IndexMut> for FlatAlloc(tup : (usize, T)) -> (UUID, T) { - (UUID(tup.0, PhantomData), tup.1) -} - #[derive(Debug)] pub struct FlatAllocIter<'a, T, IndexMarker : UUIDMarker> { iter : Enumerate>, diff --git a/src/ast.rs b/src/ast.rs index 857045b..300727f 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -1,7 +1,7 @@ use num::bigint::BigUint; -use crate::{tokenizer::{TokenTypeIdx, get_token_type_name}, linker::{NamedUUID, FileUUID}, flattening::{FlattenedModule, FlattenedInterface}, arena_alloc::{ListAllocator, UUIDMarker, UUID}, instantiation::InstantiationList}; +use crate::{tokenizer::{TokenTypeIdx, get_token_type_name}, linker::{NamedUUID, FileUUID}, flattening::{FlattenedModule, FlattenedInterface}, arena_alloc::{UUIDMarker, UUID, FlatAlloc}, instantiation::InstantiationList}; use core::ops::Range; use std::fmt::Display; @@ -66,6 +66,7 @@ pub type SpanTypeExpression = (TypeExpression, Span); #[derive(Debug,Clone)] pub struct SignalDeclaration { pub span : Span, + pub name_token : usize, pub typ : SpanTypeExpression, pub name : Box, // File position pub identifier_type : IdentifierType @@ -148,7 +149,7 @@ pub struct LinkInfo { pub struct Module { pub link_info : LinkInfo, - pub declarations : ListAllocator, + pub declarations : FlatAlloc, pub code : CodeBlock, pub interface : FlattenedInterface, @@ -193,7 +194,7 @@ impl IterIdentifiers for SpanExpression { } } Expression::Array(b) => { - let (array, idx, bracket_span) = &**b; + let (array, idx, _bracket_span) = &**b; array.for_each_value(func); idx.for_each_value(func); } @@ -210,7 +211,7 @@ impl IterIdentifiers for SpanAssignableExpression { func(LocalOrGlobal::Local(*id), span.0); } AssignableExpression::ArrayIndex(b) => { - let (array, idx, bracket_span) = &**b; + let (array, idx, _bracket_span) = &**b; array.for_each_value(func); idx.for_each_value(func); } diff --git a/src/dev_aid/syntax_highlighting.rs b/src/dev_aid/syntax_highlighting.rs index 3aa78af..c6ae696 100644 --- a/src/dev_aid/syntax_highlighting.rs +++ b/src/dev_aid/syntax_highlighting.rs @@ -35,6 +35,10 @@ pub struct IDEToken { pub typ : IDETokenType } +pub struct SyntaxHighlightSettings { + pub show_tokens : bool +} + fn pretty_print_chunk_with_whitespace(whitespace_start : usize, file_text : &str, text_span : Range, st : Style) { let whitespace_text = &file_text[whitespace_start..text_span.start]; @@ -206,7 +210,7 @@ fn generate_character_offsets(file_text : &str, tokens : &[Token]) -> Vec) { +pub fn syntax_highlight_file(file_paths : Vec, settings : &SyntaxHighlightSettings) { let mut prelinker : PreLinker = PreLinker::new(); let mut paths_arena = ArenaVector::new(); for file_path in file_paths { @@ -234,7 +238,9 @@ pub fn syntax_highlight_file(file_paths : Vec) { linker.flatten_all_modules(); for (file_uuid, f) in &linker.files { - //print_tokens(&f.file_text, &f.tokens); + if settings.show_tokens { + print_tokens(&f.file_text, &f.tokens); + } let ide_tokens = create_token_ide_info(f, &linker.links); pretty_print(&f.file_text, &f.tokens, &ide_tokens); diff --git a/src/flattening.rs b/src/flattening.rs index 8f395da..c482da0 100644 --- a/src/flattening.rs +++ b/src/flattening.rs @@ -1,7 +1,7 @@ use std::{ops::{Deref, Range}, iter::zip}; use crate::{ - ast::{Span, Value, Module, Expression, SpanExpression, LocalOrGlobal, Operator, AssignableExpression, SpanAssignableExpression, Statement, CodeBlock, IdentifierType, GlobalReference, TypeExpression, DeclIDMarker}, + ast::{Span, Value, Module, Expression, SpanExpression, LocalOrGlobal, Operator, AssignableExpression, SpanAssignableExpression, Statement, CodeBlock, IdentifierType, GlobalReference, TypeExpression, DeclIDMarker, DeclID}, linker::{Linker, Named, Linkable, get_builtin_uuid, FileUUID, NamedUUID}, errors::{ErrorCollector, error_info}, arena_alloc::{ListAllocator, UUID, UUIDMarker, FlatAlloc}, tokenizer::kw, typing::{Type, typecheck_unary_operator, get_binary_operator_types, typecheck, typecheck_is_array_indexer}, block_vector::BlockVec }; @@ -35,10 +35,16 @@ impl ConnectionWrite { } } +#[derive(Debug)] +pub struct InterfacePort { + pub is_input : bool, + pub id : UID +} + #[derive(Debug)] pub enum Instantiation { - SubModule{module_uuid : NamedUUID, typ_span : Span, interface_wires : Vec}, - PlainWire{read_only : bool, typ : Type, typ_span : Span}, + SubModule{module_uuid : NamedUUID, typ_span : Span, interface_wires : Vec>}, + PlainWire{read_only : bool, typ : Type, decl_id : Option}, UnaryOp{typ : Type, op : Operator, right : SpanFlatID}, BinaryOp{typ : Type, op : Operator, left : SpanFlatID, right : SpanFlatID}, ArrayAccess{typ : Type, arr : SpanFlatID, arr_idx : SpanFlatID}, @@ -50,7 +56,7 @@ impl Instantiation { pub fn get_type(&self) -> &Type { match self { Instantiation::SubModule{module_uuid : _, typ_span : _, interface_wires : _} => panic!("This is not a struct!"), - Instantiation::PlainWire{read_only: _, typ, typ_span : _} => typ, + Instantiation::PlainWire{read_only: _, typ, decl_id : _} => typ, Instantiation::UnaryOp{typ, op : _, right : _} => typ, Instantiation::BinaryOp{typ, op : _, left : _, right : _} => typ, Instantiation::ArrayAccess{typ, arr : _, arr_idx : _} => typ, @@ -58,6 +64,24 @@ impl Instantiation { Instantiation::Error => panic!("This was not properly resolved!") } } + + pub fn iter_sources ()>(&self, mut f : F) { + match self { + Instantiation::SubModule { module_uuid, typ_span, interface_wires } => { + for port in interface_wires { + if port.is_input { + f(port.id); + } + } + } + Instantiation::PlainWire { read_only, typ, decl_id } => {} + Instantiation::UnaryOp { typ, op, right } => {f(right.0);} + Instantiation::BinaryOp { typ, op, left, right } => {f(left.0); f(right.0);} + Instantiation::ArrayAccess { typ, arr, arr_idx } => {f(arr.0); f(arr_idx.0)} + Instantiation::Constant { typ, value } => {} + Instantiation::Error => {} + } + } } #[derive(Debug)] @@ -119,12 +143,12 @@ impl<'l, 'm, 'fl> FlatteningContext<'l, 'm, 'fl> { } fn alloc_module_interface(&self, module : &Module, module_uuid : NamedUUID, typ_span : Span) -> Instantiation { let interface_wires = module.interface.interface_wires.iter().map(|port| { - self.instantiations.alloc(Instantiation::PlainWire { read_only : !port.is_input, typ: port.typ.clone(), typ_span }) + InterfacePort{is_input : port.is_input, id : self.instantiations.alloc(Instantiation::PlainWire { read_only : !port.is_input, typ: port.typ.clone(), decl_id : None })} }).collect(); Instantiation::SubModule{module_uuid, typ_span, interface_wires} } - fn desugar_func_call(&self, func_and_args : &[SpanExpression], closing_bracket_pos : usize, condition : FlatID) -> Option<(&Module, &[FlatID])> { + fn desugar_func_call(&self, func_and_args : &[SpanExpression], closing_bracket_pos : usize, condition : FlatID) -> Option<(&Module, &[InterfacePort])> { let (name_expr, name_expr_span) = &func_and_args[0]; // Function name is always there let func_instantiation_id = match name_expr { Expression::Named(LocalOrGlobal::Local(l)) => { @@ -133,7 +157,7 @@ impl<'l, 'm, 'fl> FlatteningContext<'l, 'm, 'fl> { Expression::Named(LocalOrGlobal::Global(g)) => { let module_ref = self.module.link_info.global_references[*g]; - let dependency = self.linker.get_module(module_ref, &self.errors)?; + let dependency = self.linker.try_get_module(module_ref, &self.errors)?; let new_module_interface = self.alloc_module_interface(dependency, module_ref.1, *name_expr_span); self.instantiations.alloc(new_module_interface) } @@ -170,8 +194,8 @@ impl<'l, 'm, 'fl> FlatteningContext<'l, 'm, 'fl> { if self.typecheck(arg_read_side, &md.interface.interface_wires[field].typ, "submodule output") == None { continue; } - let func_input_wire = interface_wires[field]; - self.create_connection(Connection { num_regs: 0, from: arg_read_side, to: ConnectionWrite::simple(func_input_wire, *name_expr_span), condition }); + let func_input_port = &interface_wires[field]; + self.create_connection(Connection { num_regs: 0, from: arg_read_side, to: ConnectionWrite::simple(func_input_port.id, *name_expr_span), condition }); } } @@ -185,7 +209,7 @@ impl<'l, 'm, 'fl> FlatteningContext<'l, 'm, 'fl> { } Expression::Named(LocalOrGlobal::Global(g)) => { let r = self.module.link_info.global_references[*g]; - let cst = self.linker.get_constant(r, &self.errors)?; + let cst = self.linker.try_get_constant(r, &self.errors)?; self.instantiations.alloc(Instantiation::Constant{typ : cst.get_type(), value : cst}) } Expression::Constant(cst) => { @@ -227,7 +251,7 @@ impl<'l, 'm, 'fl> FlatteningContext<'l, 'm, 'fl> { return None; } - outputs[0] + outputs[0].id } }; Some((single_connection_side, *expr_span)) @@ -236,10 +260,10 @@ impl<'l, 'm, 'fl> FlatteningContext<'l, 'm, 'fl> { Some(match expr { AssignableExpression::Named{local_idx} => { let root = self.decl_to_flat_map[*local_idx]; - if let Instantiation::PlainWire { read_only : false, typ : _, typ_span : _ } = &self.instantiations[root] { + if let Instantiation::PlainWire { read_only : false, typ : _, decl_id } = &self.instantiations[root] { ConnectionWrite{root, path : Vec::new(), span : *span} } else { - let decl_info = error_info(*span, self.errors.file, "Declared here"); + let decl_info = error_info(self.module.declarations[*local_idx].span, self.errors.file, "Declared here"); self.errors.error_with_info(*span, "Cannot Assign to Read-Only value", vec![decl_info]); return None } @@ -274,7 +298,6 @@ impl<'l, 'm, 'fl> FlatteningContext<'l, 'm, 'fl> { let decl = &self.module.declarations[*decl_id]; let Some(typ) = self.map_to_type(&decl.typ.0, &self.module.link_info.global_references) else {continue;}; - let typ_copy = typ.clone(); let typ_span = decl.typ.1; let decl_typ_root_reference = typ.get_root(); @@ -295,7 +318,7 @@ impl<'l, 'm, 'fl> FlatteningContext<'l, 'm, 'fl> { } } Named::Type(_) => { - Instantiation::PlainWire{read_only : decl.identifier_type == IdentifierType::Input, typ, typ_span} + Instantiation::PlainWire{read_only : decl.identifier_type == IdentifierType::Input, typ, decl_id : Some(*decl_id)} } } }; @@ -334,7 +357,7 @@ impl<'l, 'm, 'fl> FlatteningContext<'l, 'm, 'fl> { for (field, to_i) in zip(outputs, to) { let Some(write_side) = self.flatten_assignable_expr(&to_i.expr, condition) else {return;}; - self.create_connection(Connection{num_regs : to_i.num_regs, from: (*field, func_name_span), to: write_side, condition}); + self.create_connection(Connection{num_regs : to_i.num_regs, from: (field.id, func_name_span), to: write_side, condition}); } }, Statement::Assign{to, expr : non_func_expr, eq_sign_position : _} => { @@ -358,11 +381,11 @@ impl<'l, 'm, 'fl> FlatteningContext<'l, 'm, 'fl> { #[derive(Debug)] pub struct FlattenedInterfacePort { - wire_id : FlatID, - is_input : bool, - typ : Type, - port_name : Box, - span : Span + pub wire_id : FlatID, + pub is_input : bool, + pub typ : Type, + pub port_name : Box, + pub span : Span } #[derive(Debug, Default)] @@ -430,7 +453,7 @@ impl FlattenedModule { module, }; - for (id, decl) in &module.declarations { + for (decl_id, decl) in &module.declarations { let is_input = match decl.identifier_type { IdentifierType::Input => true, IdentifierType::Output => false, @@ -438,13 +461,13 @@ impl FlattenedModule { }; let (wire_id, typ) = if let Some(typ) = context.map_to_type(&decl.typ.0, &module.link_info.global_references) { - let wire_id = self.instantiations.alloc(Instantiation::PlainWire { read_only: is_input, typ : typ.clone(), typ_span: decl.typ.1 }); + let wire_id = self.instantiations.alloc(Instantiation::PlainWire { read_only: is_input, typ : typ.clone(), decl_id : Some(decl_id)}); (wire_id, typ) } else { (UUID::INVALID, Type::Named(UUID::INVALID)) }; interface.interface_wires.push(FlattenedInterfacePort { wire_id, is_input, typ, port_name: decl.name.clone(), span: decl.span }); - context.decl_to_flat_map[id] = wire_id; + context.decl_to_flat_map[decl_id] = wire_id; } (interface, context.decl_to_flat_map) @@ -467,4 +490,48 @@ impl FlattenedModule { }; context.flatten_code(&module.code, FlatID::INVALID); } + + pub fn find_unused_variables(&self, md : &Module) { + // Setup Wire Fanouts List for faster processing + let mut wire_fanouts : FlatAlloc, FlatIDMarker> = self.instantiations.iter().map(|_| Vec::new()).collect(); + + for (id, w) in &self.instantiations { + w.iter_sources(|s_id| { + wire_fanouts[s_id].push(id); + }); + } + + for conn in &self.connections { + wire_fanouts[conn.from.0].push(conn.to.root); + } + + let mut is_instance_used_map : FlatAlloc = self.instantiations.iter().map(|_| false).collect(); + + let mut wire_to_explore_queue : Vec = Vec::new(); + + for port in &md.interface.interface_wires { + if !port.is_input { + is_instance_used_map[port.wire_id] = true; + wire_to_explore_queue.push(port.wire_id); + } + } + + while let Some(item) = wire_to_explore_queue.pop() { + for to in &wire_fanouts[item] { + if !is_instance_used_map[*to] { + is_instance_used_map[*to] = true; + wire_to_explore_queue.push(*to); + } + } + } + + // Now produce warnings from the unused list + for (id, inst) in &self.instantiations { + if !is_instance_used_map[id] { + if let Instantiation::PlainWire { read_only : _, typ : _, decl_id : Some(decl_id) } = inst { + self.errors.warn_basic(Span::from(md.declarations[*decl_id].name_token), "Unused variable"); + } + } + } + } } diff --git a/src/instantiation.rs b/src/instantiation.rs index e75025b..0872212 100644 --- a/src/instantiation.rs +++ b/src/instantiation.rs @@ -1,6 +1,6 @@ -use std::{rc::Rc, ops::Deref, cell::RefCell}; +use std::{rc::Rc, ops::Deref, cell::RefCell, iter::zip}; -use crate::{arena_alloc::{UUID, ListAllocator, UUIDMarker}, ast::{Value, Operator}, typing::{ConcreteType, Type}, flattening::{FlatID, FieldID, Instantiation, FlattenedModule, FlatIDMarker, ConnectionWrite, ConnectionWritePathElement}, errors::{ErrorCollector, error_info}, linker::{Linker, get_builtin_uuid}}; +use crate::{arena_alloc::{UUID, UUIDMarker, FlatAlloc}, ast::{Value, Operator, Module}, typing::{ConcreteType, Type}, flattening::{FlatID, Instantiation, FlatIDMarker, ConnectionWrite, ConnectionWritePathElement, InterfacePort}, errors::ErrorCollector, linker::{Linker, get_builtin_uuid, NamedUUID}}; @@ -77,18 +77,20 @@ pub struct RealWire { #[derive(Debug)] pub struct SubModuleInstance { + module_uuid : NamedUUID, instance : Rc, - interface_wires : Vec + interface_wires : Vec> } #[derive(Debug)] pub struct InstantiatedModule { pub interface : Vec, - pub wires : ListAllocator, - pub submodules : ListAllocator, + pub wires : FlatAlloc, + pub submodules : FlatAlloc, pub errors : ErrorCollector } +#[derive(Clone,Copy)] enum SubModuleOrWire { SubModule(SubModuleID), Wire(WireID), @@ -107,19 +109,19 @@ impl SubModuleOrWire { } struct InstantiationContext<'fl, 'l> { - instance_map : ListAllocator, - wires : ListAllocator, - submodules : ListAllocator, + instance_map : FlatAlloc, + wires : FlatAlloc, + submodules : FlatAlloc, interface : Vec, errors : ErrorCollector, - flattened : &'fl FlattenedModule, + module : &'fl Module, linker : &'l Linker, } impl<'fl, 'l> InstantiationContext<'fl, 'l> { fn compute_constant(&self, wire : FlatID) -> Value { - let Instantiation::Constant { typ, value } = &self.flattened.instantiations[wire] else {todo!()}; + let Instantiation::Constant { typ, value } = &self.module.flattened.instantiations[wire] else {todo!()}; value.clone() } fn concretize_type(&self, typ : &Type) -> ConcreteType { @@ -166,13 +168,15 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> { sources.push(Connect{from, path : new_path}) } fn instantiate_flattened_module(&mut self) { - for (original_wire, inst) in &self.flattened.instantiations { + for (original_wire, inst) in &self.module.flattened.instantiations { let instance_to_add : SubModuleOrWire = match inst { - Instantiation::SubModule{module_uuid: name, typ_span, interface_wires} => { - let interface_real_wires = interface_wires.iter().map(|w| self.instance_map[*w].extract_wire()).collect(); - SubModuleOrWire::SubModule(self.submodules.alloc(SubModuleInstance{instance : self.linker.instantiate(*name), interface_wires : interface_real_wires})) + Instantiation::SubModule{module_uuid, typ_span, interface_wires} => { + let interface_real_wires = interface_wires.iter().map(|port| { + InterfacePort { is_input: port.is_input, id: self.instance_map[port.id].extract_wire()} + }).collect(); + SubModuleOrWire::SubModule(self.submodules.alloc(SubModuleInstance{module_uuid : *module_uuid, instance : self.linker.instantiate(*module_uuid), interface_wires : interface_real_wires})) }, - Instantiation::PlainWire{read_only, typ, typ_span} => { + Instantiation::PlainWire{read_only, typ, decl_id} => { let source = if *read_only { RealWireDataSource::ReadOnly } else { @@ -196,7 +200,7 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> { }; self.instance_map[original_wire] = instance_to_add; } - for conn in &self.flattened.connections { + for conn in &self.module.flattened.connections { let condition = if conn.condition != UUID::INVALID { self.instance_map[conn.condition].extract_wire() } else { @@ -225,19 +229,19 @@ impl InstantiationList { Self{cache : RefCell::new(Vec::new())} } - pub fn instantiate(&self, flattened : &FlattenedModule, linker : &Linker) -> Rc { + pub fn instantiate(&self, module : &Module, linker : &Linker) -> Rc { let mut cache_borrow = self.cache.borrow_mut(); // Temporary, no template arguments yet if cache_borrow.is_empty() { let mut context = InstantiationContext{ - instance_map : flattened.instantiations.iter().map(|(_, _)| SubModuleOrWire::Unnasigned).collect(), - wires : ListAllocator::new(), - submodules : ListAllocator::new(), + instance_map : module.flattened.instantiations.iter().map(|(_, _)| SubModuleOrWire::Unnasigned).collect(), + wires : FlatAlloc::new(), + submodules : FlatAlloc::new(), interface : Vec::new(), - flattened : flattened, + module : module, linker : linker, - errors : ErrorCollector::new(flattened.errors.file) + errors : ErrorCollector::new(module.flattened.errors.file) }; context.instantiate_flattened_module(); @@ -256,3 +260,5 @@ impl InstantiationList { } } } + + diff --git a/src/linker.rs b/src/linker.rs index 33d09f2..4a26cbd 100644 --- a/src/linker.rs +++ b/src/linker.rs @@ -447,7 +447,12 @@ impl Linker { self.add_reserved_file(file, parse_result, parsing_errors); } - pub fn get_constant(&self, GlobalReference(identifier_span, uuid) : GlobalReference, errors : &ErrorCollector) -> Option { + pub fn get_module(&self, uuid : NamedUUID) -> &Module { + let Named::Module(md) = &self.links.globals[uuid] else {unreachable!()}; + md + } + + pub fn try_get_constant(&self, GlobalReference(identifier_span, uuid) : GlobalReference, errors : &ErrorCollector) -> Option { if uuid == UUID::INVALID { return None; // Error reporting already handled by linking } @@ -470,7 +475,7 @@ impl Linker { } } - pub fn get_module(&self, GlobalReference(identifier_span, uuid) : GlobalReference, errors : &ErrorCollector) -> Option<&Module> { + pub fn try_get_module(&self, GlobalReference(identifier_span, uuid) : GlobalReference, errors : &ErrorCollector) -> Option<&Module> { if uuid == UUID::INVALID { return None; // Error reporting already handled by linking } @@ -523,6 +528,7 @@ impl Linker { // Do check for linking errors when generating code, as this could cause the compiler to error if !md.link_info.is_fully_linked {continue;} md.flattened.flatten(md, &self, decl_to_flat_map); + md.flattened.find_unused_variables(md); println!("[[{}]]:", md.link_info.name); println!("\tInstantiations:"); @@ -541,6 +547,6 @@ impl Linker { let Named::Module(md) = &self.links.globals[module_id] else {panic!("{module_id:?} is not a Module!")}; println!("Instantiating {}", md.link_info.name); - md.instantiations.instantiate(&md.flattened, self) + md.instantiations.instantiate(&md, self) } } diff --git a/src/main.rs b/src/main.rs index af3e991..0947e1e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,14 +30,21 @@ fn main() -> Result<(), Box> { let mut file_paths : Vec = Vec::new(); let mut is_lsp = false; let mut codegen = true; + let mut settings = SyntaxHighlightSettings{ + show_tokens : false + }; + for arg in args { match arg.as_str() { "--lsp" => { is_lsp = true; - }, + } "--codegen" => { codegen = true; } + "--tokens" => { + settings.show_tokens = true; + } other => { file_paths.push(PathBuf::from(other)); } @@ -58,8 +65,7 @@ fn main() -> Result<(), Box> { //file_paths.push(PathBuf::from("resetNormalizer.sus")); file_paths.push(PathBuf::from("multiply_add.sus")); } - syntax_highlight_file(file_paths); + syntax_highlight_file(file_paths, &settings); Ok(()) } - diff --git a/src/parser.rs b/src/parser.rs index 63e62af..d53775d 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,7 +1,7 @@ use num::bigint::BigUint; -use crate::{tokenizer::*, errors::*, ast::*, linker::{FileUUID, NamedUUID}, flattening::{FlattenedModule, FlattenedInterface}, arena_alloc::ListAllocator, instantiation::InstantiationList}; +use crate::{tokenizer::*, errors::*, ast::*, linker::{FileUUID, NamedUUID}, flattening::{FlattenedModule, FlattenedInterface}, arena_alloc::FlatAlloc, instantiation::InstantiationList}; use std::{iter::Peekable, str::FromStr, ops::Range}; use core::slice::Iter; @@ -314,9 +314,9 @@ impl<'g, 'file> ASTParserContext<'g, 'file> { } } - fn add_declaration(&mut self, type_expr : SpanTypeExpression, name : TokenContent, identifier_type : IdentifierType, declarations : &mut ListAllocator, scope : &mut LocalVariableContext<'_, 'file>) -> DeclID { + fn add_declaration(&mut self, type_expr : SpanTypeExpression, name : TokenContent, identifier_type : IdentifierType, declarations : &mut FlatAlloc, scope : &mut LocalVariableContext<'_, 'file>) -> DeclID { let span = Span(type_expr.1.0, name.position); - let decl = SignalDeclaration{typ : type_expr, span, name : self.file_text[name.text.clone()].into(), identifier_type}; + let decl = SignalDeclaration{typ : type_expr, span, name_token : name.position, name : self.file_text[name.text.clone()].into(), identifier_type}; let decl_id = declarations.alloc(decl); if let Err(conflict) = scope.add_declaration(&self.file_text[name.text.clone()], decl_id) { self.errors.error_with_info(span, format!("This name was already declared previously"), vec![ @@ -430,7 +430,7 @@ impl<'g, 'file> ASTParserContext<'g, 'file> { } } - fn parse_signal_declaration(&mut self, token_stream : &mut TokenStream, identifier_type : IdentifierType, declarations : &mut ListAllocator, scope : &mut LocalVariableContext<'_, 'file>) -> Option<()> { + fn parse_signal_declaration(&mut self, token_stream : &mut TokenStream, identifier_type : IdentifierType, declarations : &mut FlatAlloc, scope : &mut LocalVariableContext<'_, 'file>) -> Option<()> { let sig_type = self.try_parse_type(token_stream, scope)?; let name = self.eat_identifier(token_stream, "signal declaration")?; self.add_declaration(sig_type, name, identifier_type, declarations, scope); @@ -450,7 +450,7 @@ impl<'g, 'file> ASTParserContext<'g, 'file> { Some(cur_type) } - fn try_parse_declaration(&mut self, token_stream : &mut TokenStream, declarations : &mut ListAllocator, scope : &mut LocalVariableContext<'_, 'file>) -> Option<(DeclID, Span)> { + fn try_parse_declaration(&mut self, token_stream : &mut TokenStream, declarations : &mut FlatAlloc, scope : &mut LocalVariableContext<'_, 'file>) -> Option<(DeclID, Span)> { let identifier_type = if token_stream.eat_is_plain(kw("state")).is_some() { IdentifierType::State } else { @@ -463,7 +463,7 @@ impl<'g, 'file> ASTParserContext<'g, 'file> { Some((local_idx, Span::from(name_token.position))) } - fn parse_bundle(&mut self, token_stream : &mut TokenStream, identifier_type : IdentifierType, declarations : &mut ListAllocator, scope : &mut LocalVariableContext<'_, 'file>) { + fn parse_bundle(&mut self, token_stream : &mut TokenStream, identifier_type : IdentifierType, declarations : &mut FlatAlloc, scope : &mut LocalVariableContext<'_, 'file>) { while token_stream.peek_is_plain(TOKEN_IDENTIFIER) { if let Some(_) = self.parse_signal_declaration(token_stream, identifier_type, declarations, scope) { @@ -478,7 +478,7 @@ impl<'g, 'file> ASTParserContext<'g, 'file> { } } - fn parse_interface(&mut self, token_stream : &mut TokenStream, declarations : &mut ListAllocator, scope : &mut LocalVariableContext<'_, 'file>) { + fn parse_interface(&mut self, token_stream : &mut TokenStream, declarations : &mut FlatAlloc, scope : &mut LocalVariableContext<'_, 'file>) { self.parse_bundle(token_stream, IdentifierType::Input, declarations, scope); if token_stream.eat_is_plain(kw("->")).is_some() { @@ -486,7 +486,7 @@ impl<'g, 'file> ASTParserContext<'g, 'file> { } } - fn parse_statement(&mut self, token_stream : &mut TokenStream, declarations : &mut ListAllocator, scope : &mut LocalVariableContext<'_, 'file>, code_block : &mut CodeBlock) -> Option<()> { + fn parse_statement(&mut self, token_stream : &mut TokenStream, declarations : &mut FlatAlloc, scope : &mut LocalVariableContext<'_, 'file>, code_block : &mut CodeBlock) -> Option<()> { let start_at = if let Some(peek) = token_stream.peek() { peek.get_span().0 } else { @@ -613,7 +613,7 @@ impl<'g, 'file> ASTParserContext<'g, 'file> { return None; } } - fn parse_if_statement(&mut self, token_stream : &mut TokenStream, if_token : &TokenContent, declarations : &mut ListAllocator, scope : &LocalVariableContext<'_, 'file>) -> Option<(Statement, Span)> { + fn parse_if_statement(&mut self, token_stream : &mut TokenStream, if_token : &TokenContent, declarations : &mut FlatAlloc, scope : &LocalVariableContext<'_, 'file>) -> Option<(Statement, Span)> { let condition = self.parse_expression(token_stream, &scope)?; let (then_block, then_block_span) = self.eat_block(token_stream, kw("{"), "Then block of if statement")?; @@ -637,7 +637,7 @@ impl<'g, 'file> ASTParserContext<'g, 'file> { Some((Statement::If{condition, then: then_content, els: else_content }, Span(if_token.position, span_end))) } - fn parse_code_block(&mut self, block_tokens : &[TokenTreeNode], span : Span, declarations : &mut ListAllocator, outer_scope : &LocalVariableContext<'_, 'file>) -> CodeBlock { + fn parse_code_block(&mut self, block_tokens : &[TokenTreeNode], span : Span, declarations : &mut FlatAlloc, outer_scope : &LocalVariableContext<'_, 'file>) -> CodeBlock { let mut token_stream = TokenStream::new(block_tokens, span.0, span.1); let mut code_block = CodeBlock{statements : Vec::new()}; @@ -680,7 +680,7 @@ impl<'g, 'file> ASTParserContext<'g, 'file> { let name = self.eat_identifier(token_stream, "module")?; self.eat_plain(token_stream, kw(":"), "module")?; - let mut declarations = ListAllocator::new(); + let mut declarations = FlatAlloc::new(); let mut scope = LocalVariableContext::new_initial(); self.parse_interface(token_stream, &mut declarations, &mut scope);