Skip to content

Commit

Permalink
Use an ImperativeBuilder wide type factory, to support anonymous gene…
Browse files Browse the repository at this point in the history
…rics in the future. We also want to make use of the vm's capability to resolve types soon.
  • Loading branch information
Ivorforce committed Jul 19, 2024
1 parent 73cdb6e commit 20cba68
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 24 deletions.
17 changes: 10 additions & 7 deletions src/resolver/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<FunctionHead>, body: &ast::Expression, scope: &scopes::Scope, runtime: &mut Runtime) -> RResult<Box<FunctionImplementation>> {
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(
Expand All @@ -25,13 +34,6 @@ pub fn resolve_function_body(head: &Rc<FunctionHead>, 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()) {
Expand Down Expand Up @@ -67,6 +69,7 @@ pub fn resolve_anonymous_expression(interface: &Rc<FunctionInterface>, 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(),
Expand Down
2 changes: 1 addition & 1 deletion src/resolver/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
18 changes: 9 additions & 9 deletions src/resolver/imperative.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ impl <'a> ImperativeResolver<'a> {
}
}

if !self.builder.type_factory.requirements.is_empty() {
panic!()
}

Ok(())
}

Expand Down Expand Up @@ -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())),
Expand Down
2 changes: 2 additions & 0 deletions src/resolver/imperative_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<TypeForest>,
pub expression_tree: Box<ExpressionTree>,
pub locals_names: HashMap<Rc<ObjectReference>, String>,
Expand Down
2 changes: 1 addition & 1 deletion src/resolver/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Rc<TraitBinding>>, generics: &HashSet<Rc<Trait>>) -> RResult<Rc<FunctionHead>> {
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)?;

Expand Down
2 changes: 1 addition & 1 deletion src/resolver/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?;

Expand Down
10 changes: 5 additions & 5 deletions src/resolver/type_factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, Rc<Trait>>,
Expand All @@ -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,
}
}

Expand All @@ -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_))
Expand Down

0 comments on commit 20cba68

Please sign in to comment.