From c661e48ba8222a6d0604126b5e062ec7a3fdedca Mon Sep 17 00:00:00 2001 From: Glyphack Date: Wed, 16 Oct 2024 19:04:41 +0200 Subject: [PATCH] Make interner global --- parser/src/intern.rs | 2 +- parser/src/parser/parser.rs | 16 ++++++++++++---- typechecker/src/checker.rs | 7 ++++--- typechecker/src/file.rs | 4 ---- typechecker/src/semantic_analyzer.rs | 23 ++++++++++++----------- typechecker/src/type_evaluator.rs | 6 +++--- 6 files changed, 32 insertions(+), 26 deletions(-) diff --git a/parser/src/intern.rs b/parser/src/intern.rs index bde2d904..48519257 100644 --- a/parser/src/intern.rs +++ b/parser/src/intern.rs @@ -2,7 +2,7 @@ use fxhash::FxHashMap; use serde::Serialize; #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize)] -pub struct StrId(u32); +pub struct StrId(pub u32); #[derive(Default, Debug, Clone)] pub struct Interner { diff --git a/parser/src/parser/parser.rs b/parser/src/parser/parser.rs index 8ba68187..d3fa8133 100644 --- a/parser/src/parser/parser.rs +++ b/parser/src/parser/parser.rs @@ -4,7 +4,7 @@ use core::panic; /// For example star expressions are defined slightly differently in python grammar and references. /// So there might be duplicates of both. Try to migrate the wrong names to how they are called in: /// https://docs.python.org/3/reference/grammar.html -use std::{sync::Arc, vec}; +use std::{cell::OnceCell, sync::Arc, vec}; use miette::Result; @@ -17,13 +17,21 @@ use crate::{ parser::{ast::*, extract_string_inside}, token::{Kind, Token}, }; +static mut INTERNER: OnceCell = OnceCell::new(); -#[derive(Debug, Clone)] +pub fn interner() -> &'static mut Interner { + unsafe { + INTERNER.get_or_init(Interner::default); + return INTERNER.get_mut().unwrap(); + } +} + +#[derive(Debug)] pub struct Parser<'a> { pub identifiers_start_offset: Vec<(u32, u32, String)>, pub source: &'a str, pub lexer: Lexer<'a>, - pub interner: Interner, + pub interner: &'a mut Interner, cur_token: Token, prev_token_end: u32, prev_nonwhitespace_token_end: u32, @@ -63,7 +71,7 @@ impl<'a> Parser<'a> { prev_nonwhitespace_token_end: prev_token_end, nested_expression_list, identifiers_start_offset: identifiers_offset, - interner: Interner::default(), + interner: interner(), } } diff --git a/typechecker/src/checker.rs b/typechecker/src/checker.rs index 0be449bb..d9d628e9 100644 --- a/typechecker/src/checker.rs +++ b/typechecker/src/checker.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use ast::{Expression, Statement}; use enderpy_python_parser as parser; use enderpy_python_parser::ast::{self, *}; +use enderpy_python_parser::parser::parser::interner; use super::{type_evaluator::TypeEvaluator, types::PythonType}; use crate::build::BuildManager; @@ -313,7 +314,7 @@ impl<'a> TraversalVisitor for TypeChecker<'a> { fn visit_function_def(&mut self, f: &Arc) { let file = &self.build_manager.files.get(&self.id).unwrap(); self.enter_scope(f.node.start); - let name = file.interner.lookup(f.name); + let name = interner().lookup(f.name); self.infer_name_type(name, f.node.start + 4, f.node.start + 4 + name.len() as u32); if let Some(ret_type) = &f.returns { self.visit_expr(ret_type); @@ -334,7 +335,7 @@ impl<'a> TraversalVisitor for TypeChecker<'a> { fn visit_async_function_def(&mut self, f: &Arc) { let file = &self.build_manager.files.get(&self.id).unwrap(); self.enter_scope(f.node.start); - let name = file.interner.lookup(f.name); + let name = interner().lookup(f.name); self.infer_name_type(name, f.node.start + 9, f.node.start + 9 + name.len() as u32); for stmt in &f.body { self.visit_stmt(stmt); @@ -344,7 +345,7 @@ impl<'a> TraversalVisitor for TypeChecker<'a> { fn visit_class_def(&mut self, c: &Arc) { let file = &self.build_manager.files.get(&self.id).unwrap(); - let name = file.interner.lookup(c.name); + let name = interner().lookup(c.name); self.infer_name_type(name, c.node.start + 6, c.node.start + 6 + name.len() as u32); self.enter_scope(c.node.start); diff --git a/typechecker/src/file.rs b/typechecker/src/file.rs index 7b8bc432..99a788ba 100755 --- a/typechecker/src/file.rs +++ b/typechecker/src/file.rs @@ -7,7 +7,6 @@ use std::sync::Arc; use crate::ast_visitor::TraversalVisitor; use enderpy_python_parser as parser; use enderpy_python_parser::ast::*; -use enderpy_python_parser::intern::Interner; use parser::{ast, get_row_col_position, parser::parser::Parser}; use std::sync::atomic::Ordering; @@ -33,7 +32,6 @@ pub struct EnderpyFile { pub source: String, pub line_starts: Vec, pub tree: ast::Module, - pub interner: Interner, } impl<'a> Eq for EnderpyFile {} @@ -74,7 +72,6 @@ impl<'a> EnderpyFile { } }; let line_starts = parser.lexer.line_starts.clone(); - let interner = parser.interner; let id = if path.ends_with("builtins.pyi") { symbol_table::Id(0) @@ -90,7 +87,6 @@ impl<'a> EnderpyFile { module, tree, path: Arc::new(path), - interner, } } pub fn module_name(&self) -> String { diff --git a/typechecker/src/semantic_analyzer.rs b/typechecker/src/semantic_analyzer.rs index 6541ce14..a6ad93d3 100644 --- a/typechecker/src/semantic_analyzer.rs +++ b/typechecker/src/semantic_analyzer.rs @@ -1,7 +1,8 @@ use std::sync::Arc; -use enderpy_python_parser as parser; use enderpy_python_parser::ast::Expression; +use enderpy_python_parser::parser::parser::interner; +use enderpy_python_parser::{self as parser}; use parser::ast::{self, GetNode, Name, Statement}; @@ -121,8 +122,8 @@ impl<'a> SemanticAnalyzer<'a> { self.symbol_table.current_scope().kind.as_function() { // TODO: some python usual names to be interned - if self.file.interner.lookup(function_def.name) == "__init__" - || self.file.interner.lookup(function_def.name) == "__new__" + if interner().lookup(function_def.name) == "__init__" + || interner().lookup(function_def.name) == "__new__" { true } else { @@ -510,7 +511,7 @@ impl<'a> TraversalVisitor for SemanticAnalyzer<'a> { } self.symbol_table.push_scope(SymbolTableScope::new( crate::symbol_table::SymbolTableType::Function(Arc::clone(f)), - self.file.interner.lookup(f.name).to_owned(), + interner().lookup(f.name).to_owned(), f.node.start, self.symbol_table.current_scope_id, )); @@ -558,7 +559,7 @@ impl<'a> TraversalVisitor for SemanticAnalyzer<'a> { }); let flags = SymbolFlags::empty(); self.create_symbol( - self.file.interner.lookup(f.name).to_owned(), + interner().lookup(f.name).to_owned(), function_declaration, flags, ); @@ -573,7 +574,7 @@ impl<'a> TraversalVisitor for SemanticAnalyzer<'a> { self.symbol_table.push_scope(SymbolTableScope::new( SymbolTableType::Function(Arc::new(f.to_function_def())), - self.file.interner.lookup(f.name).to_owned(), + interner().lookup(f.name).to_owned(), f.node.start, self.symbol_table.current_scope_id, )); @@ -620,7 +621,7 @@ impl<'a> TraversalVisitor for SemanticAnalyzer<'a> { }); let flags = SymbolFlags::empty(); self.create_symbol( - self.file.interner.lookup(f.name).to_string(), + interner().lookup(f.name).to_string(), function_declaration, flags, ); @@ -647,7 +648,7 @@ impl<'a> TraversalVisitor for SemanticAnalyzer<'a> { fn visit_class_def(&mut self, c: &Arc) { self.symbol_table.push_scope(SymbolTableScope::new( SymbolTableType::Class(c.clone()), - self.file.interner.lookup(c.name).to_owned(), + interner().lookup(c.name).to_owned(), c.node.start, self.symbol_table.current_scope_id, )); @@ -692,11 +693,11 @@ impl<'a> TraversalVisitor for SemanticAnalyzer<'a> { Arc::clone(c), class_declaration_path, class_body_scope_id, - self.file.interner.lookup(c.name), + interner().lookup(c.name), )); let flags = SymbolFlags::empty(); self.create_symbol( - self.file.interner.lookup(c.name).to_string(), + interner().lookup(c.name).to_string(), class_declaration, flags, ); @@ -879,7 +880,7 @@ pub fn get_member_access_info( } // e.g. "MyClass.x = 1" - if value_name == file.interner.lookup(enclosing_class.name) || is_class_member { + if value_name == interner().lookup(enclosing_class.name) || is_class_member { Some(false) } else { Some(true) diff --git a/typechecker/src/type_evaluator.rs b/typechecker/src/type_evaluator.rs index 392b88cd..5ee30c48 100755 --- a/typechecker/src/type_evaluator.rs +++ b/typechecker/src/type_evaluator.rs @@ -2,7 +2,7 @@ #![allow(unused_variables)] use core::panic; -use enderpy_python_parser::{self as parser}; +use enderpy_python_parser::{self as parser, parser::parser::interner}; use parser::ast; use parser::parser::parser::Parser; use std::{ @@ -1638,7 +1638,7 @@ impl<'a> TypeEvaluator<'a> { .get(&f.declaration_path.symbol_table_id) .unwrap(); PythonType::Callable(Box::new(CallableType::new( - file.interner.lookup(name).to_string(), + interner().lookup(name).to_string(), signature, return_type, false, @@ -1668,7 +1668,7 @@ impl<'a> TypeEvaluator<'a> { .get(&f.declaration_path.symbol_table_id) .unwrap(); PythonType::Callable(Box::new(CallableType::new( - file.interner.lookup(name).to_string(), + interner().lookup(name).to_string(), signature, PythonType::Coroutine(Box::new(types::CoroutineType { return_type,