More stuff compiles
This commit is contained in:
+29
-12
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>,
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user