Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
emilyaherbert committed Jun 1, 2023
1 parent e7a226d commit 2e17cca
Show file tree
Hide file tree
Showing 13 changed files with 635 additions and 0 deletions.
7 changes: 7 additions & 0 deletions sway-core/src/monomorphize/collect/code_block.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use crate::{language::ty, monomorphize::priv_prelude::*};

pub(crate) fn gather_from_code_block(ctx: GatherContext, body: &ty::TyCodeBlock) {
body.contents
.iter()
.for_each(|node| gather_from_node(ctx, &node.content));
}
217 changes: 217 additions & 0 deletions sway-core/src/monomorphize/collect/collect_from.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
use crate::{monomorphize::priv_prelude::*, language::ty::*};

pub(crate) trait CollectFrom {
fn collect_from(&self, ctx: CollectContext);
}

impl CollectFrom for TyModule {
fn collect_from(&self, ctx: CollectContext) {
for (_, submod) in self.submodules_recursive() {
submod.module.collect_from(ctx);
}
for node in self.all_nodes.iter() {
node.content.collect_from(ctx);
}
}
}

impl CollectFrom for TyAstNodeContent {
fn collect_from(&self, ctx: CollectContext) {
use TyAstNodeContent::*;
match self {
Declaration(decl) => {
decl.collect_from(ctx);
}
Expression(exp) => {
exp.collect_from(ctx);
}
ImplicitReturnExpression(exp) => {
exp.collect_from(ctx);
}
SideEffect(_) => {}
}
}
}

impl CollectFrom for TyDecl {
fn collect_from(&self, ctx: CollectContext) {
use TyDecl::*;
match self {
VariableDecl(decl) => {
decl.body.collect_from(ctx);
}
ConstantDecl { .. } => todo!(),
FunctionDecl {
decl_id,
subst_list,
..
} => {
gather_from_fn_decl(ctx, decl_id, subst_list.inner());
}
TraitDecl {
name: _,
decl_id,
subst_list,
decl_span: _,
} => {
gather_from_trait_decl(ctx, decl_id, subst_list.inner());
}
StructDecl {
name: _,
decl_id,
subst_list,
decl_span: _,
} => {
gather_from_struct_decl(ctx, decl_id, subst_list.inner());
}
EnumDecl {
name: _,
decl_id,
subst_list,
decl_span: _,
} => {
gather_from_enum_decl(ctx, decl_id, subst_list.inner());
}
EnumVariantDecl { .. } => todo!(),
ImplTrait { .. } => todo!(),
AbiDecl { .. } => todo!(),
GenericTypeForFunctionScope { .. } => todo!(),
StorageDecl { .. } => todo!(),
ErrorRecovery(_) => {}
TypeAliasDecl { .. } => todo!(),
}
}
}

impl CollectFrom for TyFunctionDecl {
fn collect_from(&self, ctx: CollectContext) {
ctx.add_constraint(Constraint::mk_fn_decl(decl_id, subst_list));
let fn_decl = ctx.decl_engine.get_function(decl_id);
for param in fn_decl.parameters {
gather_from_ty(ctx, param.type_argument.type_id);
}
gather_from_ty(ctx, fn_decl.return_type.type_id);
gather_from_code_block(ctx, &fn_decl.body);
}
}

impl CollectFrom for TyStructDecl {
fn collect_from(&self, ctx: CollectContext) {
ctx.add_constraint(Constraint::mk_struct_decl(decl_id, subst_list));
let struct_decl = ctx.decl_engine.get_struct(decl_id);
for field in struct_decl.fields {
gather_from_ty(ctx, field.type_argument.type_id);
}
}
}

impl CollectFrom for TyEnumDecl {
fn collect_from(&self, ctx: CollectContext) {
ctx.add_constraint(Constraint::mk_enum_decl(decl_id, subst_list));
let enum_decl = ctx.decl_engine.get_enum(decl_id);
for variant in enum_decl.variants {
gather_from_ty(ctx, variant.type_argument.type_id);
}
}
}

impl CollectFrom for TyTraitDecl {
fn collect_from(&self, ctx: CollectContext) {
ctx.add_constraint(Constraint::mk_trait_decl(decl_id, subst_list));
let trait_decl = ctx.decl_engine.get_trait(decl_id);
todo!();
}
}

impl CollectFrom for TyExpression {
fn collect_from(&self, ctx: CollectContext) {
gather_from_ty(ctx, return_type);
self.expression.collect_from(ctx);
}
}

impl CollectFrom for TyExpressionVariant {
fn collect_from(&self, ctx: CollectContext) {
use TyExpressionVariant::*;
match exp {
FunctionApplication {
arguments,
contract_call_params,
call_path,
fn_ref,
..
} => {
arguments
.iter()
.for_each(|(_, arg)| {
arg.collect_from(ctx);
});
contract_call_params
.iter()
.for_each(|(_, arg)| {
arg.collect_from(ctx);
});
ctx.add_constraint(Constraint::mk_fn_call(call_path, arguments, fn_ref));
}
LazyOperator { lhs, rhs, .. } => {
lhs.collect_from(ctx);
rhs.collect_from(ctx);
}
VariableExpression { .. } => {
// NOTE: may need to do something here later
}
Tuple { fields } => {
fields.iter().for_each(|field| {
field.collect_from(ctx);
});
}
Array {
contents: _,
elem_type: _,
} => {
todo!();
// contents
// .iter()
// .for_each(|elem| gather_from_exp(ctx, elem));
}
ArrayIndex {
prefix: _,
index: _,
} => {
todo!();
// gather_from_exp(ctx, prefix);
// gather_from_exp(ctx, index);
}
StructExpression { .. } => todo!(),
CodeBlock(block) => {
gather_from_code_block(ctx, block);
}
IfExp { .. } => todo!(),
MatchExp { .. } => todo!(),
AsmExpression { .. } => todo!(),
StructFieldAccess { .. } => todo!(),
TupleElemAccess { prefix, .. } => {
prefix.collect_from(ctx);
}
EnumInstantiation { .. } => todo!(),
AbiCast { .. } => todo!(),
StorageAccess(_) => todo!(),
IntrinsicFunction(_) => todo!(),
AbiName(_) => todo!(),
EnumTag { exp } => {
exp.collect_from(ctx);
}
UnsafeDowncast { .. } => todo!(),
WhileLoop { .. } => todo!(),
Reassignment(_) => todo!(),
StorageReassignment(_) => todo!(),
Return(exp) => {
exp.collect_from(ctx);
}
Literal(_) => {}
Break => {}
Continue => {}
FunctionParameter => {}
}
}
}
54 changes: 54 additions & 0 deletions sway-core/src/monomorphize/collect/context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use hashbrown::{hash_map::RawEntryMut, HashMap};
use std::sync::RwLock;

use crate::{decl_engine::*, engine_threading::*, monomorphize::priv_prelude::*, TypeEngine};

/// Contextual state tracked and accumulated throughout collecting information
/// for monomorphization.
#[derive(Clone, Copy)]
pub(crate) struct CollectContext<'a> {
/// The type engine storing types.
pub(crate) type_engine: &'a TypeEngine,

/// The declaration engine holds declarations.
pub(crate) decl_engine: &'a DeclEngine,

/// The list of constraints.
/// NOTE: This only needs to be a [HashSet][hashbrown::HashSet], but there
/// isn't the right method implement on that data type for what we need, so
/// instead we use a dummy [HashMap][hashbrown::HashMap].
constraints: &'a RwLock<HashMap<Constraint, usize>>,
}

impl<'a> CollectContext<'a> {
/// Initialize a context.
pub(crate) fn new(
engines: Engines<'a>,
constraints: &'a RwLock<HashMap<Constraint, usize>>,
) -> CollectContext<'a> {
let (type_engine, decl_engine) = engines.unwrap();
Self {
type_engine,
decl_engine,
constraints,
}
}

pub(crate) fn add_constraint(&self, constraint: Constraint) {
let engines = Engines::new(self.type_engine, self.decl_engine);
let mut constraints = self.constraints.write().unwrap();
let hash_builder = constraints.hasher().clone();
let constraint_hash = make_hasher(&hash_builder, engines)(&constraint);
let raw_entry = constraints
.raw_entry_mut()
.from_hash(constraint_hash, |x| x.eq(&constraint, engines));
if let RawEntryMut::Vacant(v) = raw_entry {
v.insert_with_hasher(
constraint_hash,
constraint,
0,
make_hasher(&hash_builder, engines),
);
}
}
}
93 changes: 93 additions & 0 deletions sway-core/src/monomorphize/collect/declaration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
use crate::{decl_engine::DeclId, language::ty::*, monomorphize::priv_prelude::*, type_system::*};

pub(crate) fn gather_from_decl(ctx: GatherContext, decl: &TyDecl) {
use TyDecl::*;
match decl {
VariableDecl(decl) => {
gather_from_exp(ctx, &decl.body);
}
ConstantDecl { .. } => todo!(),
FunctionDecl {
decl_id,
subst_list,
..
} => {
gather_from_fn_decl(ctx, decl_id, subst_list.inner());
}
TraitDecl {
name: _,
decl_id,
subst_list,
decl_span: _,
} => {
gather_from_trait_decl(ctx, decl_id, subst_list.inner());
}
StructDecl {
name: _,
decl_id,
subst_list,
decl_span: _,
} => {
gather_from_struct_decl(ctx, decl_id, subst_list.inner());
}
EnumDecl {
name: _,
decl_id,
subst_list,
decl_span: _,
} => {
gather_from_enum_decl(ctx, decl_id, subst_list.inner());
}
EnumVariantDecl { .. } => todo!(),
ImplTrait { .. } => todo!(),
AbiDecl { .. } => todo!(),
GenericTypeForFunctionScope { .. } => todo!(),
StorageDecl { .. } => todo!(),
ErrorRecovery(_) => {}
TypeAliasDecl { .. } => todo!(),
}
}

fn gather_from_fn_decl(
ctx: GatherContext,
decl_id: &DeclId<TyFunctionDecl>,
subst_list: &SubstList,
) {
ctx.add_constraint(Constraint::mk_fn_decl(decl_id, subst_list));
let fn_decl = ctx.decl_engine.get_function(decl_id);
for param in fn_decl.parameters {
gather_from_ty(ctx, param.type_argument.type_id);
}
gather_from_ty(ctx, fn_decl.return_type.type_id);
gather_from_code_block(ctx, &fn_decl.body);
}

fn gather_from_trait_decl(
ctx: GatherContext,
decl_id: &DeclId<TyTraitDecl>,
subst_list: &SubstList,
) {
ctx.add_constraint(Constraint::mk_trait_decl(decl_id, subst_list));
let trait_decl = ctx.decl_engine.get_trait(decl_id);
todo!();
}

fn gather_from_struct_decl(
ctx: GatherContext,
decl_id: &DeclId<TyStructDecl>,
subst_list: &SubstList,
) {
ctx.add_constraint(Constraint::mk_struct_decl(decl_id, subst_list));
let struct_decl = ctx.decl_engine.get_struct(decl_id);
for field in struct_decl.fields {
gather_from_ty(ctx, field.type_argument.type_id);
}
}

fn gather_from_enum_decl(ctx: GatherContext, decl_id: &DeclId<TyEnumDecl>, subst_list: &SubstList) {
ctx.add_constraint(Constraint::mk_enum_decl(decl_id, subst_list));
let enum_decl = ctx.decl_engine.get_enum(decl_id);
for variant in enum_decl.variants {
gather_from_ty(ctx, variant.type_argument.type_id);
}
}
Loading

0 comments on commit 2e17cca

Please sign in to comment.