Skip to content

Commit

Permalink
use original binding name with allocation for llvm
Browse files Browse the repository at this point in the history
  • Loading branch information
andogq committed Jul 30, 2024
1 parent df53368 commit 4d12ac5
Show file tree
Hide file tree
Showing 17 changed files with 134 additions and 44 deletions.
65 changes: 52 additions & 13 deletions src/compile_pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,40 @@ use crate::{
ty::Ty,
},
stage::{
codegen::ctx::LLVMCtx,
lower_ir::{FunctionBuilder as FunctionBuilderTrait, IRCtx},
parse::ParseCtx,
type_check::{FunctionSignature, TypeCheckCtx},
},
util::symbol_map::{interner_symbol_map::*, SymbolMap},
util::{
scope::Scope,
symbol_map::{interner_symbol_map::*, SymbolMap},
},
};

struct FunctionInfo {
signature: FunctionSignature,
scope: Option<Scope>,
ir: Option<ir::Function>,
}

pub struct CompilePass {
/// Backing symbol store for entire compile.
symbols: InternerSymbolMap,

function_signatures: IndexVec<FunctionIdx, FunctionSignature>,
function_symbols: HashMap<Symbol, FunctionIdx>,
/// All available functions within this pass
functions: IndexVec<FunctionIdx, FunctionInfo>,

ir_functions: HashMap<FunctionIdx, ir::Function>,
/// Mapping between interned symbol and a function identifier.
function_symbols: HashMap<Symbol, FunctionIdx>,
}

impl CompilePass {
pub fn new() -> Self {
Self {
symbols: InternerSymbolMap::new(),
function_signatures: IndexVec::new(),
functions: IndexVec::new(),
function_symbols: HashMap::new(),
ir_functions: HashMap::new(),
}
}
}
Expand Down Expand Up @@ -66,31 +77,39 @@ impl ParseCtx for CompilePass {}

impl TypeCheckCtx for CompilePass {
fn register_function(&mut self, symbol: Symbol, signature: FunctionSignature) -> FunctionIdx {
let idx = self.function_signatures.push(signature);
let idx = self.functions.push(FunctionInfo {
signature,
scope: None,
ir: None,
});
self.function_symbols.insert(symbol, idx);
idx
}

fn get_function(&self, idx: FunctionIdx) -> FunctionSignature {
self.function_signatures[idx].clone()
self.functions[idx].signature.clone()
}

fn lookup_function_symbol(&self, symbol: Symbol) -> Option<FunctionIdx> {
self.function_symbols.get(&symbol).cloned()
}

fn set_function_scope(&mut self, function: FunctionIdx, scope: Scope) {
self.functions[function].scope = Some(scope);
}
}

impl IRCtx for CompilePass {
type FunctionBuilder = FunctionBuilder;

fn register_function(&mut self, idx: FunctionIdx, function: ir::Function) {
self.ir_functions.insert(idx, function);
self.functions[idx].ir = Some(function);
}

fn all_functions(&self) -> Vec<(FunctionIdx, ir::Function)> {
self.ir_functions
.iter()
.map(|(idx, function)| (*idx, function.clone()))
self.functions
.iter_enumerated()
.filter_map(|(idx, function)| Some((idx, function.ir.as_ref()?.clone())))
.collect()
}
}
Expand Down Expand Up @@ -156,11 +175,31 @@ impl FunctionBuilderTrait for FunctionBuilder {
ctx.register_function(
self.idx,
ir::Function {
symbol: self.idx,
identifier: self.idx,
signature: self.signature,
basic_blocks: self.basic_blocks,
scope: self.scope.into_iter().map(|(symbol, _)| symbol).collect(),
},
)
}
}

impl LLVMCtx for CompilePass {
fn get_scoped_binding_name(&self, function: &FunctionIdx, binding: &ScopedBinding) -> String {
let (symbol, _) = self.functions[*function]
.scope
.as_ref()
.unwrap()
.get_binding(binding);
self.get(symbol)
}

fn get_scoped_binding_ty(&self, function: &FunctionIdx, binding: &ScopedBinding) -> Ty {
self.functions[*function]
.scope
.as_ref()
.unwrap()
.get_binding(binding)
.1
}
}
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{collections::HashMap, sync::Arc};
use std::collections::HashMap;

use inkwell::{
module::Module,
Expand Down
2 changes: 1 addition & 1 deletion src/repr/ir/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ index_vec::define_index_type! {

#[derive(Debug, Clone)]
pub struct Function {
pub symbol: FunctionIdx,
pub identifier: FunctionIdx,
pub signature: FunctionSignature,
pub basic_blocks: IndexVec<BasicBlockIdx, BasicBlock>,
pub scope: HashSet<ScopedBinding>,
Expand Down
15 changes: 15 additions & 0 deletions src/stage/codegen/ctx.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use crate::{
repr::{
identifier::{FunctionIdx, ScopedBinding},
ty::Ty,
},
util::symbol_map::{interner_symbol_map::Symbol, SymbolMap},
};

pub trait LLVMCtx: SymbolMap<Symbol = Symbol> {
/// Produce the original name for a scoped binding.
fn get_scoped_binding_name(&self, function: &FunctionIdx, binding: &ScopedBinding) -> String;

/// Produce the type for a scoped binding.
fn get_scoped_binding_ty(&self, function: &FunctionIdx, binding: &ScopedBinding) -> Ty;
}
24 changes: 12 additions & 12 deletions src/stage/codegen/llvm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@ use inkwell::{
IntPredicate,
};

use crate::{
repr::{
identifier::{FunctionIdx, ScopedBinding},
ir::{BasicBlockIdx, BinaryOp, ConstantValue, Function, Triple, TripleRef, UnaryOp, Value},
ty::Ty,
},
util::symbol_map::{interner_symbol_map::Symbol, SymbolMap},
use crate::repr::{
identifier::{FunctionIdx, ScopedBinding},
ir::{BasicBlockIdx, BinaryOp, ConstantValue, Function, Triple, TripleRef, UnaryOp, Value},
ty::Ty,
};

use super::ctx::LLVMCtx;

pub struct FunctionGenerator<'ctx, 'ink, Ctx> {
ctx: &'ctx mut Ctx,
llvm_ctx: &'ink Context,
Expand All @@ -37,7 +36,7 @@ pub struct FunctionGenerator<'ctx, 'ink, Ctx> {
blocks: HashMap<BasicBlockIdx, BasicBlock<'ink>>,
}

impl<'ctx, 'ink, Ctx: SymbolMap<Symbol = Symbol>> FunctionGenerator<'ctx, 'ink, Ctx> {
impl<'ctx, 'ink, Ctx: LLVMCtx> FunctionGenerator<'ctx, 'ink, Ctx> {
pub fn new(
ctx: &'ctx mut Ctx,
llvm_ctx: &'ink Context,
Expand Down Expand Up @@ -81,10 +80,11 @@ impl<'ctx, 'ink, Ctx: SymbolMap<Symbol = Symbol>> FunctionGenerator<'ctx, 'ink,
(
*binding,
self.alloca(
// TODO: Actually determine the type of this symbol
Ty::Int,
// TODO: Map between BindingIdx and string
"some symbol",
self.ctx
.get_scoped_binding_ty(&self.function.identifier, binding),
&self
.ctx
.get_scoped_binding_name(&self.function.identifier, binding),
),
)
})
Expand Down
1 change: 1 addition & 0 deletions src/stage/codegen/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod ctx;
pub mod llvm;
13 changes: 8 additions & 5 deletions src/stage/type_check/ctx/mod.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
mod scope;

use crate::{repr::identifier::FunctionIdx, util::symbol_map::interner_symbol_map::Symbol};
use crate::{
repr::identifier::FunctionIdx,
util::{scope::*, symbol_map::interner_symbol_map::Symbol},
};

use super::FunctionSignature;

pub use self::scope::*;

pub trait TypeCheckCtx {
/// Register a function's signature and associated symbol, to produce a unique identifier for the function.
fn register_function(&mut self, symbol: Symbol, signature: FunctionSignature) -> FunctionIdx;

/// Store the scope for a function
fn set_function_scope(&mut self, function: FunctionIdx, scope: Scope);

/// Get the signature associated with a function identifier.
fn get_function(&self, idx: FunctionIdx) -> FunctionSignature;

Expand All @@ -23,6 +25,7 @@ mockall::mock! {

impl TypeCheckCtx for TypeCheckCtx {
fn register_function(&mut self, symbol: Symbol, signature: FunctionSignature) -> FunctionIdx;
fn set_function_scope(&mut self, function: FunctionIdx, scope: Scope);
fn get_function(&self, idx: FunctionIdx) -> FunctionSignature;
fn lookup_function_symbol(&self, symbol: Symbol) -> Option<FunctionIdx>;
}
Expand Down
8 changes: 5 additions & 3 deletions src/stage/type_check/expression/block.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use ctx::{Scope, TypeCheckCtx};
use ctx::TypeCheckCtx;

use crate::util::scope::Scope;

use super::*;

Expand Down Expand Up @@ -59,8 +61,8 @@ mod test {

use crate::{
repr::{ast::untyped::*, ty::Ty},
stage::type_check::ctx::{MockTypeCheckCtx, Scope},
util::source::Span,
stage::type_check::ctx::MockTypeCheckCtx,
util::{scope::Scope, source::Span},
};

#[test]
Expand Down
2 changes: 2 additions & 0 deletions src/stage/type_check/expression/call.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::util::scope::Scope;

use super::*;

impl parse_ast::Call {
Expand Down
6 changes: 4 additions & 2 deletions src/stage/type_check/expression/ident.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::util::scope::Scope;

use super::*;

impl parse_ast::Ident {
Expand Down Expand Up @@ -27,8 +29,8 @@ mod test_ident {

use crate::{
repr::ast::untyped::Ident,
stage::type_check::ctx::{MockTypeCheckCtx, Scope},
util::source::Span,
stage::type_check::ctx::MockTypeCheckCtx,
util::{scope::Scope, source::Span},
};

use super::expression::Ty;
Expand Down
2 changes: 2 additions & 0 deletions src/stage/type_check/expression/if_else.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::util::scope::Scope;

use super::*;

impl parse_ast::If {
Expand Down
6 changes: 4 additions & 2 deletions src/stage/type_check/expression/infix.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::util::scope::Scope;

use super::*;

impl InfixOperation {
Expand Down Expand Up @@ -46,8 +48,8 @@ impl parse_ast::Infix {
mod test_infix {
use crate::{
repr::{ast::untyped::*, ty::Ty},
stage::type_check::ctx::{MockTypeCheckCtx, Scope},
util::source::Span,
stage::type_check::ctx::MockTypeCheckCtx,
util::{scope::Scope, source::Span},
};

#[test]
Expand Down
4 changes: 3 additions & 1 deletion src/stage/type_check/expression/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use ctx::{Scope, TypeCheckCtx};
use ctx::TypeCheckCtx;

use crate::util::scope::Scope;

use super::*;

Expand Down
8 changes: 7 additions & 1 deletion src/stage/type_check/function.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use ctx::{Scope, TypeCheckCtx};
use ctx::TypeCheckCtx;

use crate::util::scope::Scope;

use super::*;

Expand All @@ -18,8 +20,12 @@ impl parse_ast::Function {
.map(|(symbol, ty)| (scope.register(*symbol, *ty), *ty))
.collect();

// Type check the body, allowing it to use the function's scope
let body = self.body.ty_solve(ctx, &mut scope)?;

// Store the function's scope for future reference
ctx.set_function_scope(identifier, scope);

// If the body contains any return statements, they must match the annotated return statement
if let Some(return_ty) = body.ty_info.return_ty {
if self.return_ty != return_ty {
Expand Down
8 changes: 5 additions & 3 deletions src/stage/type_check/statement.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use ctx::{Scope, TypeCheckCtx};
use ctx::TypeCheckCtx;

use crate::util::scope::Scope;

use super::*;

Expand Down Expand Up @@ -97,8 +99,8 @@ mod test_statement {

use crate::{
repr::ast::untyped::*,
stage::type_check::ctx::{MockTypeCheckCtx, Scope},
util::{source::Span, symbol_map::interner_symbol_map::Symbol},
stage::type_check::ctx::MockTypeCheckCtx,
util::{scope::Scope, source::Span, symbol_map::interner_symbol_map::Symbol},
};

use super::Ty;
Expand Down
1 change: 1 addition & 0 deletions src/util/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod scope;
pub mod source;
pub mod symbol_map;
11 changes: 11 additions & 0 deletions src/stage/type_check/ctx/scope.rs → src/util/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ impl ScopePart {
}
}

impl Default for ScopePart {
fn default() -> Self {
Self::new()
}
}

pub struct Scope {
scopes: IndexVec<ScopeIdx, ScopePart>,
}
Expand Down Expand Up @@ -97,6 +103,11 @@ impl Scope {
.next_back()
}

/// Get the information for a binding.
pub fn get_binding(&self, binding: &ScopedBinding) -> (Symbol, Ty) {
self.scopes[binding.0].bindings[binding.1]
}

/// Find the currently activated scope identifier.
fn active_scope(&self) -> ScopeIdx {
self.scopes
Expand Down

0 comments on commit 4d12ac5

Please sign in to comment.