More stuff compiles

This commit is contained in:
Mia
2026-02-27 15:48:16 +01:00
parent 4b07d93ae3
commit 0b4f169c6f
20 changed files with 552 additions and 134 deletions
+1
View File
@@ -11,3 +11,4 @@ half = "2.7.1"
scc = "3.3.7"
leaf_allocators = { path = "../allocators" }
fxhash = "0.2.1"
+29 -12
View File
@@ -1,11 +1,12 @@
use crate::{
functions::Function,
types::derivations::{FuncT, TypeDerivations},
values::AnyConst,
values::Const,
};
use derive_more::Debug;
use fxhash::FxBuildHasher;
use leaf_allocators::SyncAllocator;
use scc::{HashMap, HashSet};
use scc::HashMap;
use std::{borrow::Cow, hash::Hash, sync::OnceLock};
#[derive(derive_more::Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -28,6 +29,7 @@ pub type Ctx<'l> = &'l Context<'l>;
pub struct Context<'l> {
pub(crate) alloc: &'l dyn SyncAllocator,
pub(crate) derivations: TypeDerivations<'l>,
strings: HashMap<&'l str, &'l str, FxBuildHasher>,
assemblies: HashMap<AssemblyIdentifier, &'l Assembly<'l>>,
}
@@ -49,6 +51,7 @@ impl<'l> Context<'l> {
pub fn new(alloc: &'l dyn SyncAllocator) -> &'l Self {
alloc.alloc(Self {
alloc,
strings: HashMap::default(),
derivations: TypeDerivations::new(alloc),
assemblies: Default::default(),
})
@@ -64,6 +67,15 @@ impl<'l> Context<'l> {
.entry_sync(ident.clone())
.or_insert_with(|| Assembly::new(self, ident))
}
pub fn intern_str(&'l self, str: &str) -> &'l str {
if let Some(value) = self.strings.get_sync(str) {
return (*value).into();
}
let str = self.alloc.alloc_str(str);
let _ = self.strings.insert_sync(str, str);
str
}
}
#[derive(Debug)]
@@ -71,12 +83,7 @@ pub struct Assembly<'l> {
#[debug(skip)]
ctx: &'l Context<'l>,
ident: AssemblyIdentifier,
#[debug("{:#?}", {
let mut c = vec![];
constants.iter_sync(|k| {c.push(*k); true});
c
})]
constants: HashSet<AnyConst<'l>>,
functions: boxcar::Vec<&'l Function<'l>>,
}
impl Eq for Assembly<'_> {}
@@ -98,7 +105,7 @@ impl<'l> Assembly<'l> {
let assembly = ctx.alloc.alloc(Self {
ctx,
ident,
constants: HashSet::new(),
functions: boxcar::vec![],
});
assembly
}
@@ -114,9 +121,19 @@ impl<'l> Assembly<'l> {
body: OnceLock::new(),
declaring_assembly: self,
});
self.constants
.insert_sync(AnyConst::Function(func))
.unwrap();
self.functions.push(func);
func
}
pub fn find_function(
&'l self,
filter: impl Fn(&'l Function<'l>) -> bool,
) -> Option<&'l Function<'l>> {
for (_, func) in self.functions.iter() {
if filter(func) {
return Some(func);
}
}
None
}
}
+38 -6
View File
@@ -59,7 +59,8 @@ impl<'l> Instruction<'l> {
pub fn value_flags(&self) -> ValueFlags {
match self.variant {
_ => todo!(),
InstructionVariant::StackAlloc(_) => ValueFlags::LValue,
_ => ValueFlags::empty(),
}
}
@@ -73,8 +74,11 @@ impl<'l> Instruction<'l> {
_ => unreachable!(),
},
InstructionVariant::IAdd(a, _) => a.ty(),
InstructionVariant::IMul(a, _) => a.ty(),
InstructionVariant::FAdd(a, _) => a.ty(),
InstructionVariant::FMul(a, _) => a.ty(),
InstructionVariant::ICmp(_, _, _) => Type::Bool,
InstructionVariant::Call(f, _) => f.ty.ret_t,
_ => todo!("{self:?}"),
}
}
@@ -98,7 +102,9 @@ pub enum InstructionVariant<'l> {
Store(Value<'l>, Value<'l>),
IAdd(Value<'l>, Value<'l>),
IMul(Value<'l>, Value<'l>),
FAdd(Value<'l>, Value<'l>),
FMul(Value<'l>, Value<'l>),
ICmp(Value<'l>, Value<'l>, Cmp),
FCmp(Value<'l>, Value<'l>, Cmp),
@@ -132,11 +138,17 @@ impl std::fmt::Debug for InstructionVariant<'_> {
Self::Load(v) => write!(f, "load {v}"),
Self::Store(t, v) => write!(f, "store {t}, {v}"),
Self::IAdd(a, b) => write!(f, "iadd {a}, {b}"),
Self::IMul(a, b) => write!(f, "imul {a}, {b}"),
Self::FAdd(a, b) => write!(f, "fadd {a}, {b}"),
Self::FMul(a, b) => write!(f, "fmul {a}, {b}"),
Self::ICmp(a, b, c) => write!(f, "icmp {c:?} {a}, {b}"),
Self::FCmp(a, b, c) => write!(f, "fcmp {c:?} {a}, {b}"),
Self::Call(func, args) => {
write!(f, "call {:#?}(", *func as *const Function)?;
write!(
f,
"call {}(",
func.name.get().unwrap_or(&"<anonymous function>".into())
)?;
let mut separator = "";
for arg in args {
write!(f, "{separator}{arg}")?;
@@ -252,6 +264,22 @@ impl<'l> BlockBuilder<'l> {
}
}
pub fn mul(&mut self, a: Value<'l>, b: Value<'l>) -> BlockBuilderResult<'l, Value<'l>> {
let [a_ty, b_ty] = [a.ty(), b.ty()];
match (a_ty, b_ty) {
(Type::Int(a_ty), Type::Int(b_ty)) if a_ty == b_ty => {
let inst = self.push_instruction(InstructionVariant::IMul(a, b))?;
Ok(inst.into())
}
(Type::Float(a_ty), Type::Float(b_ty)) if a_ty == b_ty => {
let inst = self.push_instruction(InstructionVariant::FMul(a, b))?;
Ok(inst.into())
}
_ => Err(format!("Cannot add values of type `{a_ty}` and `b_ty`.").into()),
}
}
pub fn cmp(
&mut self,
a: Value<'l>,
@@ -358,7 +386,7 @@ impl<'l> BlockBuilder<'l> {
pub fn build(self) -> BlockBuilderResult<'l, &'l Block<'l>> {
if !self.has_termination() {
return Err(format!("Block #{} has not termination.", self.block.id).into());
return Err(format!("Block #{} has no termination.", self.block.id).into());
}
self.block.instructions.set(self.instructions).unwrap();
Ok(self.block)
@@ -398,15 +426,15 @@ impl<'l> FunctionBodyBuilder<'l> {
builder
}
pub fn current_block(&self) -> &'l Block<'l> {
self.blocks[self.current_block].block
pub fn current_block(&self) -> &BlockBuilder<'l> {
&self.blocks[self.current_block]
}
pub fn set_current_block(&mut self, block: &'l Block<'l>) -> Option<&'l Block<'l>> {
match std::ptr::eq(block.func, self.func) {
false => None,
true => {
let current = self.current_block();
let current = &self.blocks[self.current_block].block;
self.current_block = block.id as usize;
Some(current)
}
@@ -466,6 +494,10 @@ impl<'l> FunctionBodyBuilder<'l> {
self.current_builder().add(a, b)
}
pub fn mul(&mut self, a: Value<'l>, b: Value<'l>) -> BlockBuilderResult<'l, Value<'l>> {
self.current_builder().mul(a, b)
}
pub fn cmp(
&mut self,
a: Value<'l>,
+1
View File
@@ -62,6 +62,7 @@ impl FmtDebug for Function<'_> {
f.debug_struct("Function")
.field("ty", &format_args!("{}", self.ty))
.field("name", &self.name.get())
.field("body", body)
.finish_non_exhaustive()
}
+15 -1
View File
@@ -1,4 +1,4 @@
use crate::{functions::Function, types::Type};
use crate::{functions::Function, types::Type, values::ValueFlags};
use derive_more::{Debug, *};
use half::f16;
use std::hash::Hash;
@@ -9,13 +9,17 @@ pub enum Int {
I16(i16),
I32(i32),
I64(i64),
#[from]
I128(i128),
ISize(i128),
U8(u8),
U16(u16),
U32(u32),
U64(u64),
#[from]
U128(u128),
USize(u128),
}
#[derive(Debug, Display, Clone, Copy, From, TryInto, PartialEq)]
@@ -90,15 +94,25 @@ impl<'l> AnyConst<'l> {
Self::Int(Int::I32(_)) => Type::I32,
Self::Int(Int::I64(_)) => Type::I64,
Self::Int(Int::I128(_)) => Type::I128,
Self::Int(Int::ISize(_)) => Type::ISIZE,
Self::Int(Int::U8(_)) => Type::U8,
Self::Int(Int::U16(_)) => Type::U16,
Self::Int(Int::U32(_)) => Type::U32,
Self::Int(Int::U64(_)) => Type::U64,
Self::Int(Int::U128(_)) => Type::U128,
Self::Int(Int::USize(_)) => Type::USIZE,
Self::Float(Float::F16(_)) => Type::F16,
Self::Float(Float::F32(_)) => Type::F32,
Self::Float(Float::F64(_)) => Type::F64,
_ => todo!("{self:?}"),
}
}
pub fn flags(&self) -> super::ValueFlags {
match self {
AnyConst::Function(function) => ValueFlags::Function,
AnyConst::Type(_) => ValueFlags::Type,
_ => ValueFlags::Const,
}
}
}
+21 -1
View File
@@ -1,4 +1,7 @@
use crate::{functions::ir::Instruction, types::Type};
use crate::{
functions::{Function, ir::Instruction},
types::Type,
};
use bitflags::bitflags;
use derive_more::{Debug, Display, *};
use std::hash::Hash;
@@ -11,6 +14,7 @@ bitflags! {
pub struct ValueFlags: u16 {
const Mutable = 0b00000000_00000001;
const Volatile = 0b00000000_00000010;
const LValue = 0b00000000_00000100;
const Const = 0b00000001_00000000;
const ConstOnly = 0b00000011_00000000;
const Type = 0b00000111_00000000;
@@ -20,10 +24,15 @@ bitflags! {
#[derive(Debug, Display, Clone, Copy, From, TryInto, PartialEq, Eq, Hash)]
pub enum Value<'l> {
Uninit,
#[display("{_0}")]
Constant(AnyConst<'l>),
#[display("{_0}")]
Instruction(&'l Instruction<'l>),
#[debug("${_0}")]
#[display("${_0}")]
Parameter(usize, &'l Function<'l>),
}
impl From<Int> for Value<'_> {
@@ -37,6 +46,17 @@ impl<'l> Value<'l> {
match self {
Value::Constant(v) => v.ty(),
Value::Instruction(v) => v.value_ty(),
Value::Parameter(i, f) => f.ty.par_t[*i],
Value::Uninit => unreachable!(),
}
}
pub fn flags(&self) -> ValueFlags {
match self {
Value::Instruction(instruction) => instruction.value_flags(),
Value::Parameter(_, _) => ValueFlags::empty(),
Value::Constant(c) => c.flags(),
_ => todo!("{self:?}"),
}
}
}