Skip to content

Commit

Permalink
re-arrange compiler
Browse files Browse the repository at this point in the history
  • Loading branch information
andogq committed Aug 18, 2024
1 parent f922be0 commit 90681d9
Show file tree
Hide file tree
Showing 13 changed files with 195 additions and 222 deletions.
27 changes: 13 additions & 14 deletions src/codegen/llvm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,17 @@ impl<'compiler, 'ink> Module<'compiler, 'ink> {

// TODO: Declare all functions in the compiler
let functions = compiler
.function_manager
.functions()
.functions
.iter()
.map(|(idx, registration)| {
module.add_function(
// Pull out the name of the function
compiler
.symbols
.resolve(
compiler
.function_manager
.get_function_symbol(idx)
.functions
.symbol_for(idx)
.expect("registered function must have symbol"),
)
.unwrap(),
Expand Down Expand Up @@ -138,7 +138,6 @@ pub struct FunctionGenerator<'module, 'compiler, 'ink> {
impl<'module, 'compiler, 'ink> FunctionGenerator<'module, 'compiler, 'ink> {
pub fn new(
module: &'module Module<'compiler, 'ink>,
// NOTE: Pre-generate function value, so that a function map can be supplied even if other functions aren't generated
llvm_function: FunctionValue<'ink>,
function: &'module Function,
) -> Self {
Expand Down Expand Up @@ -169,7 +168,8 @@ impl<'module, 'compiler, 'ink> FunctionGenerator<'module, 'compiler, 'ink> {
let registration = self
.module
.compiler
.get_function(self.function.identifier)
.functions
.get(self.function.identifier)
.unwrap();

// Create stack allocations for all of the variables in scope
Expand All @@ -182,10 +182,7 @@ impl<'module, 'compiler, 'ink> FunctionGenerator<'module, 'compiler, 'ink> {

(
*binding,
self.alloca(
ty,
self.module.compiler.get_interned_string(symbol).unwrap(),
),
self.alloca(ty, self.module.compiler.symbols.resolve(symbol).unwrap()),
)
})
.collect::<HashMap<_, _>>();
Expand Down Expand Up @@ -318,8 +315,9 @@ impl<'module, 'compiler, 'ink> FunctionGenerator<'module, 'compiler, 'ink> {
"{}_result",
self.module
.compiler
.get_function_symbol(*function)
.and_then(|symbol| self.module.compiler.get_interned_string(symbol))
.functions
.symbol_for(*function)
.and_then(|symbol| self.module.compiler.symbols.resolve(symbol))
.unwrap()
),
)
Expand Down Expand Up @@ -350,13 +348,14 @@ impl<'module, 'compiler, 'ink> FunctionGenerator<'module, 'compiler, 'ink> {
let (symbol, _) = self
.module
.compiler
.get_function(self.function.identifier)
.functions
.get(self.function.identifier)
.unwrap()
.get_binding(*binding)
.unwrap();

let ptr = self.bindings.get(binding).expect("symbol must be defined");
let name = self.module.compiler.get_interned_string(symbol).unwrap();
let name = self.module.compiler.symbols.resolve(symbol).unwrap();

self.builder
.build_load(self.module.llvm_ctx.i64_type(), *ptr, name)
Expand Down
193 changes: 0 additions & 193 deletions src/compiler.rs

This file was deleted.

107 changes: 107 additions & 0 deletions src/compiler/function_manager.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
use std::collections::HashMap;

use index_vec::IndexVec;

use crate::{
repr::{
identifier::{FunctionIdx, ScopedBinding},
ty::Ty,
},
stage::type_check::FunctionSignature,
};

use super::Symbol;

/// Handles all of the bindings and information for functions.
#[derive(Default, Debug, Clone)]
pub struct FunctionManager {
/// Function registrations, stored against a unique index.
registrations: IndexVec<FunctionIdx, FunctionRegistration>,

/// Map to resolve a function's symbol into it's index.
symbols: HashMap<Symbol, FunctionIdx>,
}

impl FunctionManager {
/// Register a new function signature against a signature, producing a new index for it.
pub fn register(&mut self, symbol: Symbol, signature: FunctionSignature) -> FunctionIdx {
let idx = self
.registrations
.push(FunctionRegistration::new(signature));

assert!(
!self.symbols.contains_key(&symbol),
"cannot register function with symbol that's already been registered"
);
self.symbols.insert(symbol, idx);

idx
}

/// Attempt to get the index associated with a symbol.
pub fn get_idx(&self, symbol: Symbol) -> Option<FunctionIdx> {
self.symbols.get(&symbol).cloned()
}

/// Get the registration associated with a [`FunctionIdx`].
pub fn get(&self, idx: FunctionIdx) -> Option<&FunctionRegistration> {
self.registrations.get(idx)
}

/// Get the mutable registration associated with a [`FunctionIdx`].
pub fn get_mut(&mut self, idx: FunctionIdx) -> Option<&mut FunctionRegistration> {
self.registrations.get_mut(idx)
}

/// Retrieve the original symbol for a function.
pub fn symbol_for(&self, idx: FunctionIdx) -> Option<Symbol> {
self.symbols
.iter()
.find(|(_, test_idx)| idx == **test_idx)
.map(|(symbol, _)| *symbol)
}

/// Produce an iterator of all function registrations.
pub fn iter(&self) -> impl Iterator<Item = (FunctionIdx, &FunctionRegistration)> {
self.registrations.iter_enumerated()
}
}

/// compile process, including the signature, type information, and other representations.
#[derive(Debug, Clone)]
pub struct FunctionRegistration {
/// Signature of the function.
signature: FunctionSignature,

/// Information for every binding within the function, containing symbol and type information.
bindings: HashMap<ScopedBinding, (Symbol, Ty)>,
}

impl FunctionRegistration {
/// Create a new function registration with the provided signature.
fn new(signature: FunctionSignature) -> Self {
Self {
signature,
bindings: HashMap::new(),
}
}

/// Register a new binding and its information to this function.
pub fn register_binding(&mut self, scoped_binding: ScopedBinding, symbol: Symbol, ty: Ty) {
assert!(
!self.bindings.contains_key(&scoped_binding),
"cannot register binding that's already been registered"
);

self.bindings.insert(scoped_binding, (symbol, ty));
}

pub fn get_binding(&self, scoped_binding: ScopedBinding) -> Option<(Symbol, Ty)> {
self.bindings.get(&scoped_binding).cloned()
}

/// Get a reference to the signature.
pub fn get_signature(&self) -> &FunctionSignature {
&self.signature
}
}
Loading

0 comments on commit 90681d9

Please sign in to comment.