From 20cba68cdea43facb347cb4870739db070ce74db Mon Sep 17 00:00:00 2001 From: Lukas Tenbrink Date: Fri, 19 Jul 2024 15:02:22 +0200 Subject: [PATCH] Use an ImperativeBuilder wide type factory, to support anonymous generics in the future. We also want to make use of the vm's capability to resolve types soon. --- src/resolver/function.rs | 17 ++++++++++------- src/resolver/global.rs | 2 +- src/resolver/imperative.rs | 18 +++++++++--------- src/resolver/imperative_builder.rs | 2 ++ src/resolver/interface.rs | 2 +- src/resolver/traits.rs | 2 +- src/resolver/type_factory.rs | 10 +++++----- 7 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/resolver/function.rs b/src/resolver/function.rs index 10d1a85..0edd64a 100644 --- a/src/resolver/function.rs +++ b/src/resolver/function.rs @@ -15,8 +15,17 @@ use crate::program::traits::{RequirementsAssumption, TraitConformance, TraitConf use crate::resolver::imperative::ImperativeResolver; use crate::resolver::imperative_builder::ImperativeBuilder; use crate::resolver::scopes; +use crate::resolver::type_factory::TypeFactory; pub fn resolve_function_body(head: &Rc, body: &ast::Expression, scope: &scopes::Scope, runtime: &mut Runtime) -> RResult> { + let mut builder = ImperativeBuilder { + runtime, + type_factory: TypeFactory::new(scope, &runtime.source), + types: Box::new(TypeForest::new()), + expression_tree: Box::new(ExpressionTree::new(Uuid::new_v4())), + locals_names: Default::default(), + }; + let mut scope = scope.subscope(); let granted_requirements = scope.trait_conformance.assume_granted( @@ -25,13 +34,6 @@ pub fn resolve_function_body(head: &Rc, body: &ast::Expression, sc add_conformances_to_scope(&mut scope, &granted_requirements)?; - let mut builder = ImperativeBuilder { - runtime, - types: Box::new(TypeForest::new()), - expression_tree: Box::new(ExpressionTree::new(Uuid::new_v4())), - locals_names: Default::default(), - }; - // Register parameters as variables. let mut parameter_variables = vec![]; for (parameter, internal_name) in zip_eq(head.interface.parameters.clone(), head.declared_internal_parameter_names.clone()) { @@ -67,6 +69,7 @@ pub fn resolve_anonymous_expression(interface: &Rc, body: &as // 2) We have no requirements let mut builder = ImperativeBuilder { runtime: &runtime, + type_factory: TypeFactory::new(scope, &runtime.source), types: Box::new(TypeForest::new()), expression_tree: Box::new(ExpressionTree::new(Uuid::new_v4())), locals_names: Default::default(), diff --git a/src/resolver/global.rs b/src/resolver/global.rs index 9c69d6f..6e371ba 100644 --- a/src/resolver/global.rs +++ b/src/resolver/global.rs @@ -123,7 +123,7 @@ impl <'a> GlobalResolver<'a> { ast::Statement::Conformance(syntax) => { pstatement.no_decorations()?; - let mut type_factory = TypeFactory::new(&self.global_variables, &mut self.runtime); + let mut type_factory = TypeFactory::new(&self.global_variables, &mut self.runtime.source); let self_type = type_factory.resolve_type(&syntax.declared_for, true)?; let declared_type = type_factory.resolve_type(&syntax.declared, false)?; let TypeUnit::Struct(declared) = &declared_type.unit else { diff --git a/src/resolver/imperative.rs b/src/resolver/imperative.rs index 355e000..bcf699f 100644 --- a/src/resolver/imperative.rs +++ b/src/resolver/imperative.rs @@ -55,6 +55,10 @@ impl <'a> ImperativeResolver<'a> { } } + if !self.builder.type_factory.requirements.is_empty() { + panic!() + } + Ok(()) } @@ -591,16 +595,12 @@ impl <'a> ImperativeResolver<'a> { } pub fn hint_type(&mut self, value: GenericAlias, type_declaration: &ast::Expression, scope: &scopes::Scope) -> RResult<()> { - let mut type_factory = TypeFactory::new(&scope, &self.builder.runtime); - - let type_declaration = type_factory.resolve_type(&type_declaration,true)?; - - for requirement in type_factory.requirements { - todo!("Implicit imperative requirements are not implemented yet") - } + let type_declaration = self.builder.type_factory.resolve_type(&type_declaration,true)?; - for (name, generic) in type_factory.generics.into_iter() { - panic!("Anonymous type hints are not supported yet") // need a mut scope + for (name, generic) in self.builder.type_factory.generics.iter() { + // need a mut scope + // also, we'd need to insert it into our types + panic!("Anonymous type hints are not supported yet") // scope.insert_singleton( // scopes::Environment::Global, // Reference::make_immutable_type(TypeProto::unit(generic.clone())), diff --git a/src/resolver/imperative_builder.rs b/src/resolver/imperative_builder.rs index 58dfeb9..a1352b8 100644 --- a/src/resolver/imperative_builder.rs +++ b/src/resolver/imperative_builder.rs @@ -11,10 +11,12 @@ use crate::program::functions::{FunctionBinding, FunctionOverload, FunctionTarge use crate::program::generics::TypeForest; use crate::program::types::TypeProto; use crate::resolver::scopes; +use crate::resolver::type_factory::TypeFactory; /// Note: This object should not know about the AST. pub struct ImperativeBuilder<'a> { pub runtime: &'a Runtime, + pub type_factory: TypeFactory<'a>, pub types: Box, pub expression_tree: Box, pub locals_names: HashMap, String>, diff --git a/src/resolver/interface.rs b/src/resolver/interface.rs index c83b8a0..df1fd49 100644 --- a/src/resolver/interface.rs +++ b/src/resolver/interface.rs @@ -17,7 +17,7 @@ use crate::resolver::type_factory::TypeFactory; use crate::util::position::Positioned; pub fn resolve_function_interface(interface: &ast::FunctionInterface, scope: &scopes::Scope, module: Option<&mut Module>, runtime: &Runtime, requirements: &HashSet>, generics: &HashSet>) -> RResult> { - let mut type_factory = TypeFactory::new(scope, runtime); + let mut type_factory = TypeFactory::new(scope, &runtime.source); let parsed = expressions::parse(&interface.expression, &scope.grammar)?; diff --git a/src/resolver/traits.rs b/src/resolver/traits.rs index 0d3c93e..5a02b65 100644 --- a/src/resolver/traits.rs +++ b/src/resolver/traits.rs @@ -54,7 +54,7 @@ impl <'a> TraitResolver<'a> { ); }; - let mut type_factory = TypeFactory::new(scope, &self.runtime); + let mut type_factory = TypeFactory::new(scope, &self.runtime.source); let variable_type = type_factory.resolve_type(type_declaration, true)?; diff --git a/src/resolver/type_factory.rs b/src/resolver/type_factory.rs index 30cb708..2b7f1b7 100644 --- a/src/resolver/type_factory.rs +++ b/src/resolver/type_factory.rs @@ -5,15 +5,15 @@ use itertools::Itertools; use crate::ast; use crate::error::{ErrInRange, RResult, RuntimeError}; -use crate::interpreter::runtime::Runtime; use crate::parser::expressions; use crate::program::functions::FunctionTargetType; use crate::program::traits::{Trait, TraitBinding}; use crate::program::types::{TypeProto, TypeUnit}; use crate::resolver::scopes; +use crate::source::Source; pub struct TypeFactory<'a> { - pub runtime: &'a Runtime, + pub source: &'a Source, pub scope: &'a scopes::Scope<'a>, pub generics: HashMap>, @@ -23,12 +23,12 @@ pub struct TypeFactory<'a> { // TODO Essentially this is a form of mini interpreter. // In the future it might be easier to rewrite it as such. impl <'a> TypeFactory<'a> { - pub fn new(scope: &'a scopes::Scope<'a>, runtime: &'a Runtime) -> TypeFactory<'a> { + pub fn new(scope: &'a scopes::Scope<'a>, source: &'a Source) -> TypeFactory<'a> { TypeFactory { scope, generics: HashMap::new(), requirements: HashSet::new(), - runtime, + source, } } @@ -38,7 +38,7 @@ impl <'a> TypeFactory<'a> { let function = overload.functions.iter().exactly_one() .map_err(|_| RuntimeError::error("Function overload cannot be resolved to a type.").to_array())?; - let trait_ = self.runtime.source.trait_references.get(function) + let trait_ = self.source.trait_references.get(function) .ok_or_else(|| RuntimeError::error(format!("Interpreted types aren't supported yet; please use an explicit type for now.\n{}", name).as_str()).to_array())?; return Ok(Rc::clone(trait_))