From cda089c1bcd18a53396bcbe95da7a7e4be1bf20f Mon Sep 17 00:00:00 2001 From: DasLixou Date: Sun, 12 May 2024 19:57:51 +0200 Subject: [PATCH] Retrieve basic arch --- ohdlc/src/ir/registries.rs | 7 +- ohdlc/src/ir/stages/architectures/mod.rs | 87 ++++++++++++++++++++++++ ohdlc/src/ir/stages/mod.rs | 2 + ohdlc/src/ir/stages/refine/mod.rs | 1 + ohdlc/src/ir/stages/rough/mod.rs | 9 ++- ohdlc/src/ir/stages/rough/registries.rs | 3 + ohdlc/src/main.rs | 20 +++++- ohdlc/tests/basic.rs | 20 +++++- 8 files changed, 141 insertions(+), 8 deletions(-) create mode 100644 ohdlc/src/ir/stages/architectures/mod.rs diff --git a/ohdlc/src/ir/registries.rs b/ohdlc/src/ir/registries.rs index d4590e3..055bf7b 100644 --- a/ohdlc/src/ir/registries.rs +++ b/ohdlc/src/ir/registries.rs @@ -4,13 +4,14 @@ use super::{ modules::{Module, ModuleId}, stages::{ refine::registries::{Entity, Type}, - rough::registries::{RoughEntity, RoughType}, + rough::registries::{RoughArch, RoughEntity, RoughType}, }, }; pub type ModuleRegistry = SimpleSurotto; pub type RoughTypeRegistry<'ast> = SimpleSurotto>; pub type RoughEntityRegistry<'ast> = SimpleSurotto>; +pub type RoughArchRegistry<'ast> = SimpleSurotto>; pub type RefinedTypeRegistry<'ir> = SimpleSurotto>; pub type RefinedEntityRegistry<'ir> = SimpleSurotto>; @@ -21,3 +22,7 @@ simple_key!( simple_key!( pub struct EntityId; ); + +simple_key!( + pub struct ArchId; +); diff --git a/ohdlc/src/ir/stages/architectures/mod.rs b/ohdlc/src/ir/stages/architectures/mod.rs new file mode 100644 index 0000000..02b0384 --- /dev/null +++ b/ohdlc/src/ir/stages/architectures/mod.rs @@ -0,0 +1,87 @@ +use bumpalo::Bump; + +use crate::{ + ast, + ir::{ + import_bucket::LookupStrategy, + name_lookup::{PostFlattenNameLookup, Resolved, ScopeId}, + registries::{ArchId, EntityId, ModuleRegistry, RoughArchRegistry}, + }, + message::Message, + MESSAGES, +}; + +use super::rough::registries::RoughArch; + +pub struct ArchitectureStage<'ir, 'b, 'ast> { + pub arena: &'ir Bump, + pub name_lookup: &'b PostFlattenNameLookup, + pub module_reg: &'b ModuleRegistry, + pub arch_reg: &'b RoughArchRegistry<'ast>, +} + +impl<'ir, 'ast> ArchitectureStage<'ir, '_, 'ast> { + pub fn lower(self) { + for (id, arch) in self.arch_reg.iter() { + self.lower_arch(id, arch) + } + } + + fn lower_arch(&self, id: ArchId, arch: &RoughArch<'ast>) { + let ty = self.lookup_entity(arch.0, &arch.1.ty); + println!("Implementing arch '{}' for {:?}", arch.1.name.0.get(), ty); + } + + // TODO: similar to one in `architectures`, fix duplicate pls + fn lookup_entity(&self, scope: ScopeId, ty: &ast::Type) -> Option { + let mut lookup_scope = match ty.path.0 .1 { + ast::PathStart::Root => self.name_lookup.root, + ast::PathStart::Local => scope, + }; + + let mut path = ty.path.0 .0.iter().peekable(); + let mut is_start = true; + while let Some(segment) = path.next() { + let is_terminal = path.peek().is_none(); + let segment = segment.0; + + let lookup = self.name_lookup.lookup( + lookup_scope, + &segment, + if is_start { + LookupStrategy::Indirect + } else { + LookupStrategy::Direct + }, + ); + match (is_terminal, lookup) { + (false, Some(Resolved::Entity(_))) => { + MESSAGES.report(Message::use_continues_after_type(segment.1)); + return None; + } + (false, Some(Resolved::Module(m))) => { + lookup_scope = self.module_reg[*m].scope; + } + + (true, Some(Resolved::Entity(t))) => return Some(*t), + (true, Some(Resolved::Module(_))) => { + MESSAGES.report(Message::wrong_path_end(segment, "Entity", "Module")); + return None; + } + + (_, Some(Resolved::Type(_))) => { + // TODO: better error, this can also appear at non-end position + MESSAGES.report(Message::wrong_path_end(segment, "Entity", "Type")) + } + (_, None) => { + MESSAGES.report(Message::could_not_resolve(segment)); + return None; + } + } + + is_start = false; + } + + return None; + } +} diff --git a/ohdlc/src/ir/stages/mod.rs b/ohdlc/src/ir/stages/mod.rs index 574f7b6..5f9dc0c 100644 --- a/ohdlc/src/ir/stages/mod.rs +++ b/ohdlc/src/ir/stages/mod.rs @@ -3,3 +3,5 @@ pub mod rough; pub mod flatten_lookup; pub mod refine; + +pub mod architectures; diff --git a/ohdlc/src/ir/stages/refine/mod.rs b/ohdlc/src/ir/stages/refine/mod.rs index c279b35..5e7a3e9 100644 --- a/ohdlc/src/ir/stages/refine/mod.rs +++ b/ohdlc/src/ir/stages/refine/mod.rs @@ -82,6 +82,7 @@ impl<'ir, 'ast> RefineStage<'ir, '_> { }) } + // TODO: equal to one in `architectures`, fix duplicate pls fn lookup_type(&self, scope: ScopeId, ty: &ast::Type) -> Option { let mut lookup_scope = match ty.path.0 .1 { ast::PathStart::Root => self.name_lookup.root, diff --git a/ohdlc/src/ir/stages/rough/mod.rs b/ohdlc/src/ir/stages/rough/mod.rs index 92a31c1..85a2cf4 100644 --- a/ohdlc/src/ir/stages/rough/mod.rs +++ b/ohdlc/src/ir/stages/rough/mod.rs @@ -6,13 +6,13 @@ use crate::{ import_bucket::{Import, ImportBucket, LookupStrategy}, modules::Module, name_lookup::{PreFlattenNameLookup, Resolvable, Resolved, ScopeId}, - registries::{ModuleRegistry, RoughEntityRegistry, RoughTypeRegistry}, + registries::{ModuleRegistry, RoughArchRegistry, RoughEntityRegistry, RoughTypeRegistry}, }, span::Spanned, symbol::Ident, }; -use self::registries::{RoughEntity, RoughType}; +use self::registries::{RoughArch, RoughEntity, RoughType}; pub mod registries; @@ -23,6 +23,7 @@ pub struct RoughStage<'ir, 'b, 'ast> { pub module_reg: &'b mut ModuleRegistry, pub type_reg: &'b mut RoughTypeRegistry<'ast>, pub entity_reg: &'b mut RoughEntityRegistry<'ast>, + pub arch_reg: &'b mut RoughArchRegistry<'ast>, pub root: &'ast [Spanned>], } @@ -40,7 +41,9 @@ impl<'ir, 'ast> RoughStage<'ir, '_, 'ast> { ast::Item::Entity(e) => self.introduce_entity(scope, e.name, RoughEntity(scope, e)), ast::Item::Record(r) => self.introduce_type(scope, r.name, RoughType::Record(scope, r)), ast::Item::Enum(e) => self.introduce_type(scope, e.name, RoughType::Enum(e)), - ast::Item::Arch(_) => {} + ast::Item::Arch(a) => { + self.arch_reg.insert(RoughArch(scope, a)); + } } } diff --git a/ohdlc/src/ir/stages/rough/registries.rs b/ohdlc/src/ir/stages/rough/registries.rs index 5155741..fec0dff 100644 --- a/ohdlc/src/ir/stages/rough/registries.rs +++ b/ohdlc/src/ir/stages/rough/registries.rs @@ -8,3 +8,6 @@ pub enum RoughType<'ast> { #[derive(Debug)] pub struct RoughEntity<'ast>(pub ScopeId, pub &'ast ast::Entity); + +#[derive(Debug)] +pub struct RoughArch<'ast>(pub ScopeId, pub &'ast ast::Arch<'ast>); diff --git a/ohdlc/src/main.rs b/ohdlc/src/main.rs index 3f2bf07..4d081b2 100644 --- a/ohdlc/src/main.rs +++ b/ohdlc/src/main.rs @@ -7,8 +7,11 @@ use ohdlc::{ ir::{ import_bucket::ImportBucket, name_lookup::NameLookup, - registries::{ModuleRegistry, RoughEntityRegistry, RoughTypeRegistry}, - stages::{flatten_lookup::FlattenLookupStage, refine::RefineStage, rough::RoughStage}, + registries::{ModuleRegistry, RoughArchRegistry, RoughEntityRegistry, RoughTypeRegistry}, + stages::{ + architectures::ArchitectureStage, flatten_lookup::FlattenLookupStage, + refine::RefineStage, rough::RoughStage, + }, }, lexer::Lexer, parser::Parser, @@ -44,6 +47,7 @@ fn main() -> Result<(), ()> { let mut module_reg = ModuleRegistry::default(); let mut type_reg = RoughTypeRegistry::default(); let mut entity_reg = RoughEntityRegistry::default(); + let mut arch_reg = RoughArchRegistry::default(); let mut name_lookup = NameLookup::new(); let mut import_bucket = ImportBucket::new(); @@ -55,6 +59,7 @@ fn main() -> Result<(), ()> { module_reg: &mut module_reg, type_reg: &mut type_reg, entity_reg: &mut entity_reg, + arch_reg: &mut arch_reg, root: &root, }; rough.lower(); @@ -93,6 +98,17 @@ fn main() -> Result<(), ()> { println!("{type_reg:#?}"); println!("{entity_reg:#?}"); + { + let architectures = ArchitectureStage { + arena: &ir_arena, + name_lookup: &name_lookup, + module_reg: &module_reg, + arch_reg: &arch_reg, + }; + architectures.lower(); + report_messages(&source); + }; + Ok(()) } diff --git a/ohdlc/tests/basic.rs b/ohdlc/tests/basic.rs index 1850cb3..dec31d8 100644 --- a/ohdlc/tests/basic.rs +++ b/ohdlc/tests/basic.rs @@ -5,8 +5,11 @@ use ohdlc::{ ir::{ import_bucket::ImportBucket, name_lookup::NameLookup, - registries::{ModuleRegistry, RoughEntityRegistry, RoughTypeRegistry}, - stages::{flatten_lookup::FlattenLookupStage, refine::RefineStage, rough::RoughStage}, + registries::{ModuleRegistry, RoughArchRegistry, RoughEntityRegistry, RoughTypeRegistry}, + stages::{ + architectures::ArchitectureStage, flatten_lookup::FlattenLookupStage, + refine::RefineStage, rough::RoughStage, + }, }, lexer::Lexer, parser::Parser, @@ -45,6 +48,7 @@ fn main() { let mut module_reg = ModuleRegistry::default(); let mut type_reg = RoughTypeRegistry::default(); let mut entity_reg = RoughEntityRegistry::default(); + let mut arch_reg = RoughArchRegistry::default(); let mut name_lookup = NameLookup::new(); let mut import_bucket = ImportBucket::new(); @@ -56,6 +60,7 @@ fn main() { module_reg: &mut module_reg, type_reg: &mut type_reg, entity_reg: &mut entity_reg, + arch_reg: &mut arch_reg, root: &root, }; rough.lower(); @@ -93,6 +98,17 @@ fn main() { assert_debug_snapshot!(type_reg); assert_debug_snapshot!(entity_reg); + + { + let architectures = ArchitectureStage { + arena: &ir_arena, + name_lookup: &name_lookup, + module_reg: &module_reg, + arch_reg: &arch_reg, + }; + architectures.lower(); + report_messages(&source); + }; } fn report_messages(source: &Source<'_>) {