Skip to content

Commit

Permalink
WIP: better generics
Browse files Browse the repository at this point in the history
  • Loading branch information
yorickpeterse committed Aug 31, 2023
1 parent 37bc3f1 commit c7b52f9
Show file tree
Hide file tree
Showing 14 changed files with 1,354 additions and 145 deletions.
17 changes: 10 additions & 7 deletions compiler/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ use crate::config::{Config, SOURCE, SOURCE_EXT, TESTS};
use crate::hir;
use crate::linker::link;
use crate::llvm;
use crate::mir::passes as mir;
use crate::mir::printer::to_dot;
use crate::mir::{passes as mir, Mir};
use crate::mir::specialize::Specialize;
use crate::mir::Mir;
use crate::modules_parser::{ModulesParser, ParsedModule};
use crate::state::State;
use crate::type_check::define_types::{
Expand Down Expand Up @@ -131,12 +133,12 @@ impl Compiler {
}

let mut mir = Mir::new();
let state = &mut self.state;

mir::check_global_limits(&mut self.state)
.map_err(CompileError::Internal)?;
mir::check_global_limits(state).map_err(CompileError::Internal)?;

if mir::DefineConstants::run_all(&mut self.state, &mut mir, &modules)
&& mir::LowerToMir::run_all(&mut self.state, &mut mir, modules)
if mir::DefineConstants::run_all(state, &mut mir, &modules)
&& mir::LowerToMir::run_all(state, &mut mir, modules)
{
Ok(mir)
} else {
Expand Down Expand Up @@ -185,8 +187,9 @@ impl Compiler {
}

fn optimise_mir(&mut self, mir: &mut Mir) {
mir::ExpandDrop::run_all(&self.state.db, mir);
mir::ExpandReference::run_all(&self.state.db, mir);
Specialize::run_all(&mut self.state, mir);
mir::ExpandDrop::run_all(&self.state.db, mir); // TODO: remove in favour of specialization
mir::ExpandReference::run_all(&self.state.db, mir); // TODO: remove in favour of specialization
mir::clean_up_basic_blocks(mir);
}

Expand Down
8 changes: 4 additions & 4 deletions compiler/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ pub(crate) struct DefineVariant {
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub(crate) struct AssignInstanceLiteralField {
pub(crate) struct AssignClassLiteralField {
pub(crate) resolved_type: types::TypeRef,
pub(crate) field_id: Option<types::FieldId>,
pub(crate) field: Field,
Expand All @@ -349,7 +349,7 @@ pub(crate) struct ClassLiteral {
pub(crate) class_id: Option<types::ClassId>,
pub(crate) resolved_type: types::TypeRef,
pub(crate) class_name: Constant,
pub(crate) fields: Vec<AssignInstanceLiteralField>,
pub(crate) fields: Vec<AssignClassLiteralField>,
pub(crate) location: SourceLocation,
}

Expand Down Expand Up @@ -2782,7 +2782,7 @@ impl<'a> LowerToHir<'a> {
fields: node
.fields
.into_iter()
.map(|n| AssignInstanceLiteralField {
.map(|n| AssignClassLiteralField {
resolved_type: types::TypeRef::Unknown,
field_id: None,
field: self.field(n.field),
Expand Down Expand Up @@ -5881,7 +5881,7 @@ mod tests {
name: "A".to_string(),
location: cols(8, 8)
},
fields: vec![AssignInstanceLiteralField {
fields: vec![AssignClassLiteralField {
resolved_type: types::TypeRef::Unknown,
field_id: None,
field: Field {
Expand Down
15 changes: 8 additions & 7 deletions compiler/src/llvm/layouts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use inkwell::AddressSpace;
use std::cmp::max;
use std::collections::HashMap;
use types::{
ClassId, MethodId, MethodSource, BOOLEAN_ID, BYTE_ARRAY_ID, CALL_METHOD,
CHANNEL_ID, DROPPER_METHOD, FLOAT_ID, INT_ID, NIL_ID,
ClassId, MethodId, MethodSource, TraitId, BOOL_ID, BYTE_ARRAY_ID,
CALL_METHOD, CHANNEL_ID, DROPPER_METHOD, FLOAT_ID, INT_ID, NIL_ID,
};

/// The size of an object header.
Expand Down Expand Up @@ -180,12 +180,13 @@ impl<'ctx> Layouts<'ctx> {
//
// This information is defined first so we can update the `collision`
// flag when generating this information for method implementations.
for mir_trait in mir.traits.values() {
for method in mir_trait
.id
for idx in 0..db.number_of_traits() {
let id = TraitId(idx as _);

for method in id
.required_methods(db)
.into_iter()
.chain(mir_trait.id.default_methods(db))
.chain(id.default_methods(db))
{
let name = method.name(db);
let hash = method_hasher.hash(name);
Expand Down Expand Up @@ -249,7 +250,7 @@ impl<'ctx> Layouts<'ctx> {
header,
context.f64_type().into(),
),
BOOLEAN_ID | NIL_ID => {
BOOL_ID | NIL_ID => {
let typ = context.opaque_struct(&name);

typ.set_body(&[header.into()], false);
Expand Down
84 changes: 58 additions & 26 deletions compiler/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ use std::fmt;
use std::hash::{Hash, Hasher};
use std::rc::Rc;
use types::collections::IndexMap;
use types::{BuiltinFunction, Database};
use types::{BuiltinFunction, Database, TypeArguments};

/// The number of reductions to perform after calling a method.
const CALL_COST: u16 = 1;

pub(crate) mod passes;
pub(crate) mod pattern_matching;
pub(crate) mod printer;
pub(crate) mod specialize;

fn join(values: &[RegisterId]) -> String {
values.iter().map(|v| format!("r{}", v.0)).collect::<Vec<_>>().join(", ")
Expand All @@ -42,13 +43,21 @@ impl Registers {
&self.values[register.0 as usize]
}

pub(crate) fn get_mut(&mut self, register: RegisterId) -> &mut Register {
&mut self.values[register.0 as usize]
}

pub(crate) fn value_type(&self, register: RegisterId) -> types::TypeRef {
self.get(register).value_type
}

pub(crate) fn len(&self) -> usize {
self.values.len()
}

pub(crate) fn iter_mut(&mut self) -> impl Iterator<Item = &mut Register> {
self.values.iter_mut()
}
}

/// A directed control-flow graph.
Expand Down Expand Up @@ -409,12 +418,14 @@ impl Block {
register: RegisterId,
method: types::MethodId,
arguments: Vec<RegisterId>,
type_arguments: TypeArguments,
location: LocationId,
) {
self.instructions.push(Instruction::CallStatic(Box::new(CallStatic {
register,
method,
arguments,
type_arguments,
location,
})));
}
Expand All @@ -425,10 +436,18 @@ impl Block {
receiver: RegisterId,
method: types::MethodId,
arguments: Vec<RegisterId>,
type_arguments: TypeArguments,
location: LocationId,
) {
self.instructions.push(Instruction::CallInstance(Box::new(
CallInstance { register, receiver, method, arguments, location },
CallInstance {
register,
receiver,
method,
arguments,
type_arguments,
location,
},
)));
}

Expand All @@ -453,10 +472,18 @@ impl Block {
receiver: RegisterId,
method: types::MethodId,
arguments: Vec<RegisterId>,
type_arguments: TypeArguments,
location: LocationId,
) {
self.instructions.push(Instruction::CallDynamic(Box::new(
CallDynamic { register, receiver, method, arguments, location },
CallDynamic {
register,
receiver,
method,
arguments,
type_arguments,
location,
},
)));
}

Expand Down Expand Up @@ -500,12 +527,14 @@ impl Block {
receiver: RegisterId,
method: types::MethodId,
arguments: Vec<RegisterId>,
type_arguments: TypeArguments,
location: LocationId,
) {
self.instructions.push(Instruction::Send(Box::new(Send {
receiver,
method,
arguments,
type_arguments,
location,
})));
}
Expand Down Expand Up @@ -737,6 +766,7 @@ pub(crate) struct Switch {
pub(crate) location: LocationId,
}

// TODO: remove after implementing specialization
#[derive(Clone)]
pub(crate) struct SwitchKind {
pub(crate) register: RegisterId,
Expand Down Expand Up @@ -890,6 +920,7 @@ pub(crate) struct CallStatic {
pub(crate) register: RegisterId,
pub(crate) method: types::MethodId,
pub(crate) arguments: Vec<RegisterId>,
pub(crate) type_arguments: TypeArguments,
pub(crate) location: LocationId,
}

Expand All @@ -899,6 +930,7 @@ pub(crate) struct CallInstance {
pub(crate) receiver: RegisterId,
pub(crate) method: types::MethodId,
pub(crate) arguments: Vec<RegisterId>,
pub(crate) type_arguments: TypeArguments,
pub(crate) location: LocationId,
}

Expand All @@ -916,6 +948,7 @@ pub(crate) struct CallDynamic {
pub(crate) receiver: RegisterId,
pub(crate) method: types::MethodId,
pub(crate) arguments: Vec<RegisterId>,
pub(crate) type_arguments: TypeArguments,
pub(crate) location: LocationId,
}

Expand All @@ -940,6 +973,7 @@ pub(crate) struct Send {
pub(crate) receiver: RegisterId,
pub(crate) method: types::MethodId,
pub(crate) arguments: Vec<RegisterId>,
pub(crate) type_arguments: TypeArguments,
pub(crate) location: LocationId,
}

Expand Down Expand Up @@ -1216,15 +1250,31 @@ impl Instruction {
format!("return r{}", v.register.0)
}
Instruction::Allocate(ref v) => {
format!("r{} = allocate {}", v.register.0, v.class.name(db))
format!(
"r{} = allocate {}{}",
v.register.0,
v.class.name(db),
v.class
.get_specialization_id(db)
.map(|v| v.to_string())
.unwrap_or_else(String::new)
)
}
Instruction::Spawn(ref v) => {
format!("r{} = spawn {}", v.register.0, v.class.name(db))
}
Instruction::CallStatic(ref v) => {
let class = v
.method
.receiver(db)
.as_class(db)
.map(|v| v.name(db))
.expect("static methods must have a valid receiver");

format!(
"r{} = call_static {}({})",
"r{} = call_static {}.{}({})",
v.register.0,
class,
v.method.name(db),
join(&v.arguments)
)
Expand Down Expand Up @@ -1373,33 +1423,17 @@ impl Class {
}
}

pub(crate) struct Trait {
pub(crate) id: types::TraitId,
pub(crate) methods: Vec<types::MethodId>,
}

impl Trait {
pub(crate) fn new(id: types::TraitId) -> Self {
Self { id, methods: Vec::new() }
}

pub(crate) fn add_methods(&mut self, methods: &Vec<Method>) {
for method in methods {
self.methods.push(method.id);
}
}
}

#[derive(Clone)]
pub(crate) struct Module {
pub(crate) id: types::ModuleId,
pub(crate) classes: Vec<types::ClassId>,
pub(crate) constants: Vec<types::ConstantId>,
pub(crate) location: LocationId,
}

impl Module {
pub(crate) fn new(id: types::ModuleId) -> Self {
Self { id, classes: Vec::new(), constants: Vec::new() }
pub(crate) fn new(id: types::ModuleId, location: LocationId) -> Self {
Self { id, classes: Vec::new(), constants: Vec::new(), location }
}
}

Expand Down Expand Up @@ -1432,7 +1466,6 @@ pub(crate) struct Mir {
pub(crate) constants: HashMap<types::ConstantId, Constant>,
pub(crate) modules: IndexMap<types::ModuleId, Module>,
pub(crate) classes: HashMap<types::ClassId, Class>,
pub(crate) traits: HashMap<types::TraitId, Trait>,
pub(crate) methods: HashMap<types::MethodId, Method>,
locations: Vec<SourceLocation>,
}
Expand All @@ -1443,7 +1476,6 @@ impl Mir {
constants: HashMap::new(),
modules: IndexMap::new(),
classes: HashMap::new(),
traits: HashMap::new(),
methods: HashMap::new(),
locations: Vec::new(),
}
Expand Down
Loading

0 comments on commit c7b52f9

Please sign in to comment.