diff --git a/Cargo.toml b/Cargo.toml index 8a7e7a2..b75c290 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,3 +54,12 @@ lsp = ["lsp-server", "lsp-types", "serde_json", "serde"] [profile.release] debug = true + +[profile.smol] +debug = false +strip = true +opt-level = 'z' +codegen-units = 1 +lto = true +panic = 'abort' +inherits = "release" diff --git a/bitSerialMatrixMultiply.sus b/bitSerialMatrixMultiply.sus index 152ad92..39ff503 100644 --- a/bitSerialMatrixMultiply.sus +++ b/bitSerialMatrixMultiply.sus @@ -101,12 +101,10 @@ module BitSerialMatrixMultiplyState { for int Y in 0..HEIGHT { BitSerialRow:: row - if feed { - result_vector[Y] = result_vector[Y] * 2 + row(vector_bits) - } - if start { result_vector[Y] = 0 + } else if feed { + result_vector[Y] = result_vector[Y] * 2 + row(vector_bits) } } } diff --git a/philosophy/images/bitSerialMatMul.drawio.png b/philosophy/images/bitSerialMatMul.drawio.png index 1660427..f19a13f 100644 Binary files a/philosophy/images/bitSerialMatMul.drawio.png and b/philosophy/images/bitSerialMatMul.drawio.png differ diff --git a/philosophy/images/bitSerialRow.drawio.png b/philosophy/images/bitSerialRow.drawio.png index 7660c3f..6aafd1c 100644 Binary files a/philosophy/images/bitSerialRow.drawio.png and b/philosophy/images/bitSerialRow.drawio.png differ diff --git a/src/dev_aid/lsp/tree_walk.rs b/src/dev_aid/lsp/tree_walk.rs index 2b9a502..afed94a 100644 --- a/src/dev_aid/lsp/tree_walk.rs +++ b/src/dev_aid/lsp/tree_walk.rs @@ -441,7 +441,7 @@ impl<'linker, Visitor: FnMut(Span, LocationInfo<'linker>), Pruner: Fn(Span) -> b self.walk_module(md_id); } NameElem::Type(_) => { - todo!() + println!("TODO: tree_walk::walk_file of NameElem::Type") } NameElem::Constant(_) => { todo!() diff --git a/src/flattening/flatten.rs b/src/flattening/flatten.rs index 110d109..dd76fb0 100644 --- a/src/flattening/flatten.rs +++ b/src/flattening/flatten.rs @@ -1580,11 +1580,17 @@ pub fn flatten_all_modules(linker: &mut Linker) { // Skip because we know this from initialization. cursor.field(field!("object_type")); - let Some(NameElem::Module(module_uuid)) = associated_value_iter.next() else { - unreachable!() - }; - - flatten(linker_ptr, *module_uuid, cursor); + match associated_value_iter.next().expect("Iterator cannot be exhausted") { + NameElem::Module(module_uuid) => { + flatten(linker_ptr, *module_uuid, cursor); + } + NameElem::Type(type_uuid) => { + println!("TODO Type flattening") + } + NameElem::Constant(const_uuid) => { + println!("TODO Constant flattening") + } + } }); }); span_debugger.defuse(); diff --git a/src/flattening/initialization.rs b/src/flattening/initialization.rs index ca11735..ed11d77 100644 --- a/src/flattening/initialization.rs +++ b/src/flattening/initialization.rs @@ -14,16 +14,22 @@ use crate::typing::template::{ use super::parser::Cursor; use super::*; -struct ModuleInitializationContext<'linker> { +struct InitializationContext<'linker> { + template_inputs: TemplateInputs, + + // module-only stuff ports: FlatAlloc, interfaces: FlatAlloc, domains: FlatAlloc, - template_inputs: TemplateInputs, + + // struct-only stuff + fields: FlatAlloc, + file_text: &'linker FileText, } -impl<'linker> ModuleInitializationContext<'linker> { - fn gather_initial_module(&mut self, cursor: &mut Cursor) -> (Span, String) { +impl<'linker> InitializationContext<'linker> { + fn gather_initial_global_object(&mut self, cursor: &mut Cursor) -> (Span, String) { let name_span = cursor.field_span(field!("name"), kind!("identifier")); let name = self.file_text[name_span].to_owned(); self.domains.alloc(name.clone()); @@ -184,10 +190,8 @@ impl<'linker> ModuleInitializationContext<'linker> { } fn finish_gather_decl(&mut self, is_input: Option, whole_decl_span: Span, cursor: &mut Cursor) { - if is_input.is_none() {return}; // TODO early return now - // If generative input it's a template arg - let is_gen = if cursor.optional_field(field!("declaration_modifiers")) { + let is_generative = if cursor.optional_field(field!("declaration_modifiers")) { cursor.kind() == kw!("gen") } else { false @@ -198,17 +202,19 @@ impl<'linker> ModuleInitializationContext<'linker> { let decl_span = Span::new_overarching(type_span, whole_decl_span.empty_span_at_end()); let name_span = cursor.field_span(field!("name"), kind!("identifier")); let name = self.file_text[name_span].to_owned(); - if is_gen { - self.template_inputs.alloc(TemplateInput { - name, - name_span, - kind: TemplateInputKind::Generative(GenerativeTemplateInputKind { - decl_span, - declaration_instruction: FlatID::PLACEHOLDER, - }), - }); - } else { - if let Some(is_input) = is_input { + + match (is_generative, is_input) { + (true, Some(true)) => { + self.template_inputs.alloc(TemplateInput { + name, + name_span, + kind: TemplateInputKind::Generative(GenerativeTemplateInputKind { + decl_span, + declaration_instruction: FlatID::PLACEHOLDER, + }), + }); + } + (false, Some(is_input)) => { self.ports.alloc(Port { name, name_span, @@ -218,6 +224,15 @@ impl<'linker> ModuleInitializationContext<'linker> { declaration_instruction: FlatID::PLACEHOLDER, }); } + (false, None) => { + self.fields.alloc(StructField{ + name: name.clone(), + name_span, + decl_span, + declaration_instruction: FlatID::PLACEHOLDER + }); + } + _other => {} } } } @@ -231,73 +246,87 @@ pub fn gather_initial_file_data(mut builder: FileBuilder) { let parsing_errors = ErrorCollector::new_empty(builder.file_id, builder.files); cursor.report_all_decendant_errors(&parsing_errors); + let span = cursor.span(); cursor.go_down(kind!("global_object"), |cursor| { - let span = cursor.span(); - let extern_kw = cursor.optional_field(field!("extern_marker")).then(|| cursor.kind()); - cursor.field(field!("object_type")); - let global_obj_kind = match cursor.kind() { - kw!("module") => { - GlobalObjectKind::Module - } - kw!("function") => { - GlobalObjectKind::Functions - } - kw!("struct") => { - GlobalObjectKind::Struct - } - _other => cursor.could_not_match() - }; - - initialize_module(&mut builder, extern_kw, parsing_errors, span, cursor); + initialize_global_object(&mut builder, parsing_errors, span, cursor); }); }, ); } -fn initialize_module(builder: &mut FileBuilder, extern_kw : Option, parsing_errors: ErrorCollector, span: Span, cursor: &mut Cursor) { - let mut ctx = ModuleInitializationContext { +fn initialize_global_object(builder: &mut FileBuilder, parsing_errors: ErrorCollector, span: Span, cursor: &mut Cursor) { + let is_extern = match cursor.optional_field(field!("extern_marker")).then(|| cursor.kind()) { + None => IsExtern::Normal, + Some(kw!("extern")) => IsExtern::Extern, + Some(kw!("__builtin__")) => IsExtern::Builtin, + Some(_) => cursor.could_not_match() + }; + + cursor.field(field!("object_type")); + let global_obj_kind = match cursor.kind() { + kw!("module") => { + GlobalObjectKind::Module + } + kw!("function") => { + GlobalObjectKind::Function + } + kw!("struct") => { + GlobalObjectKind::Struct + } + _other => cursor.could_not_match() + }; + + let mut ctx = InitializationContext { ports: FlatAlloc::new(), interfaces: FlatAlloc::new(), domains: FlatAlloc::new(), template_inputs: FlatAlloc::new(), + fields: FlatAlloc::new(), file_text: &builder.file_data.file_text, }; - let (name_span, name) = ctx.gather_initial_module(cursor); + let (name_span, name) = ctx.gather_initial_global_object(cursor); let resolved_globals = ResolvedGlobals::empty(); let errors = parsing_errors.into_storage(); let after_initial_parse_cp = CheckPoint::checkpoint(&errors, &resolved_globals); - let is_extern = match extern_kw { - None => IsExtern::Normal, - Some(kw!("extern")) => IsExtern::Extern, - Some(kw!("__builtin__")) => IsExtern::Builtin, - Some(_) => cursor.could_not_match() + let link_info = LinkInfo { + documentation: cursor.extract_gathered_comments(), + file: builder.file_id, + name, + name_span, + span, + errors, + is_extern, + resolved_globals, + template_arguments: ctx.template_inputs, + after_initial_parse_cp, + after_flatten_cp: None, }; - let md = Module { - link_info: LinkInfo { - documentation: cursor.extract_gathered_comments(), - file: builder.file_id, - name, - name_span, - span, - errors, - is_extern, - resolved_globals, - template_arguments: ctx.template_inputs, - after_initial_parse_cp, - after_flatten_cp: None, - }, - instructions: FlatAlloc::new(), - ports: ctx.ports, - domain_names: ctx.domains, - domains: FlatAlloc::new(), - interfaces: ctx.interfaces, - instantiations: InstantiationList::new(), - }; + match global_obj_kind { + GlobalObjectKind::Module | GlobalObjectKind::Function => { + let md = Module { + link_info, + instructions: FlatAlloc::new(), + ports: ctx.ports, + domain_names: ctx.domains, + domains: FlatAlloc::new(), + interfaces: ctx.interfaces, + instantiations: InstantiationList::new(), + }; + + builder.add_module(md); + } + GlobalObjectKind::Struct => { + let typ = StructType { + link_info, + fields: ctx.fields + }; - builder.add_module(md); + builder.add_type(typ); + } + } } diff --git a/src/flattening/mod.rs b/src/flattening/mod.rs index 9276193..1334bb7 100644 --- a/src/flattening/mod.rs +++ b/src/flattening/mod.rs @@ -24,7 +24,7 @@ use crate::typing::{ #[derive(Debug)] pub enum GlobalObjectKind { Module, - Functions, + Function, Struct } @@ -133,6 +133,27 @@ impl Module { } } +#[derive(Debug)] +pub struct StructType { + /// Created in Stage 1: Initialization + pub link_info : LinkInfo, + + /// Created in Stage 1: Initialization + /// + /// [StructField::declaration_instruction] are set in Stage 2: Flattening + fields: FlatAlloc, +} + +#[derive(Debug)] +pub struct StructField { + pub name: String, + pub name_span: Span, + pub decl_span: Span, + /// This is only set after flattening is done. Initially just [UUID::PLACEHOLDER] + pub declaration_instruction: FlatID, +} + + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum PortOrInterface { Port(PortID), diff --git a/src/linker/mod.rs b/src/linker/mod.rs index 6c2f19d..b6c6155 100644 --- a/src/linker/mod.rs +++ b/src/linker/mod.rs @@ -21,6 +21,8 @@ use crate::{ use crate::errors::{CompileError, ErrorInfo, ErrorLevel, ErrorStore}; +use crate::flattening::StructType; + use crate::typing::{ abstract_type::{DomainType, FullType}, concrete_type::ConcreteType, @@ -151,6 +153,7 @@ impl NamedConstant { #[derive(Debug)] pub enum NamedType { Builtin(&'static str), + Struct(StructType) } impl Linkable for NamedConstant { @@ -174,21 +177,37 @@ impl Linkable for NamedConstant { } impl Linkable for NamedType { - fn get_name(&self) -> &'static str { + fn get_name(&self) -> &str { match self { NamedType::Builtin(name) => name, + NamedType::Struct(s) => &s.link_info.name } } fn get_linking_error_location(&self) -> LinkingErrorLocation { - LinkingErrorLocation { - named_type: "Builtin Type", - full_name: self.get_full_name(), - location: None, + + match self { + NamedType::Builtin(_) => { + LinkingErrorLocation { + named_type: "Builtin Type", + full_name: self.get_full_name(), + location: None, + } + } + NamedType::Struct(typ) => { + LinkingErrorLocation { + named_type: "Struct", + full_name: typ.link_info.get_full_name(), + location: Some((typ.link_info.name_span, typ.link_info.file)), + } + } } } fn get_link_info(&self) -> Option<&LinkInfo> { match self { NamedType::Builtin(_) => None, + NamedType::Struct(typ) => { + Some(&typ.link_info) + } } } } @@ -501,4 +520,11 @@ impl<'linker> FileBuilder<'linker> { self.associated_values.push(new_module_uuid); self.add_name(module_name, new_module_uuid); } + + pub fn add_type(&mut self, typ: StructType) { + let type_name = typ.link_info.name.clone(); + let new_type_uuid = NameElem::Type(self.types.alloc(NamedType::Struct(typ))); + self.associated_values.push(new_type_uuid); + self.add_name(type_name, new_type_uuid); + } } diff --git a/src/prelude.rs b/src/prelude.rs index 36a3ae1..666ad11 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -69,6 +69,13 @@ impl UUIDMarker for DomainIDMarker { /// Interfaces are also indexed using DomainIDs. But in general, these refer to (clock/latency counting) domains pub type DomainID = UUID; +pub struct FieldIDMarker; +impl UUIDMarker for FieldIDMarker { + const DISPLAY_NAME: &'static str = "field_"; +} +pub type FieldID = UUID; + + pub struct TemplateIDMarker; impl UUIDMarker for TemplateIDMarker { const DISPLAY_NAME: &'static str = "template_arg_"; diff --git a/tinyTestFile.sus b/tinyTestFile.sus index b4b055f..8a9935f 100644 --- a/tinyTestFile.sus +++ b/tinyTestFile.sus @@ -4,3 +4,20 @@ extern module TestExtern { output int in_b'5 } + +struct Matrix { + input gen int WIDTH + input gen int HEIGHT + + T[WIDTH][HEIGHT] data +} + +struct float {} + +module ModUsingFloat { + input float beep + + output float boop + + boop = beep +}