Import binops while importing types as well
This commit is contained in:
parent
58cc633f98
commit
0196fb53ed
@ -14,6 +14,6 @@ fn otus(param: &mut String) {
|
|||||||
fn main() -> u8 {
|
fn main() -> u8 {
|
||||||
let mut otus = from_str("hello");
|
let mut otus = from_str("hello");
|
||||||
otus(&mut otus);
|
otus(&mut otus);
|
||||||
print(otus);
|
print(otus + " beep");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -5,9 +5,7 @@
|
|||||||
use std::{fmt::Debug, marker::PhantomData};
|
use std::{fmt::Debug, marker::PhantomData};
|
||||||
|
|
||||||
use builder::{BlockValue, Builder, FunctionValue, InstructionValue, ModuleValue, TypeValue};
|
use builder::{BlockValue, Builder, FunctionValue, InstructionValue, ModuleValue, TypeValue};
|
||||||
use debug_information::{
|
use debug_information::{DebugFileData, DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue};
|
||||||
DebugFileData, DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue,
|
|
||||||
};
|
|
||||||
use fmt::PrintableModule;
|
use fmt::PrintableModule;
|
||||||
|
|
||||||
pub mod builder;
|
pub mod builder;
|
||||||
@ -66,13 +64,7 @@ pub struct Module<'ctx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> Module<'ctx> {
|
impl<'ctx> Module<'ctx> {
|
||||||
pub fn function(
|
pub fn function(&self, name: &str, ret: Type, params: Vec<Type>, flags: FunctionFlags) -> Function<'ctx> {
|
||||||
&self,
|
|
||||||
name: &str,
|
|
||||||
ret: Type,
|
|
||||||
params: Vec<Type>,
|
|
||||||
flags: FunctionFlags,
|
|
||||||
) -> Function<'ctx> {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
Function {
|
Function {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
@ -111,10 +103,7 @@ impl<'ctx> Module<'ctx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_debug_info(
|
pub fn create_debug_info(&mut self, file: DebugFileData) -> (DebugInformation, DebugProgramValue) {
|
||||||
&mut self,
|
|
||||||
file: DebugFileData,
|
|
||||||
) -> (DebugInformation, DebugProgramValue) {
|
|
||||||
let (debug_info, program_value) = DebugInformation::from_file(file);
|
let (debug_info, program_value) = DebugInformation::from_file(file);
|
||||||
self.debug_info = Some(debug_info.clone());
|
self.debug_info = Some(debug_info.clone());
|
||||||
(debug_info, program_value)
|
(debug_info, program_value)
|
||||||
@ -144,10 +133,17 @@ pub struct FunctionData {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Hash)]
|
#[derive(Debug, Clone, Copy, Hash)]
|
||||||
pub struct FunctionFlags {
|
pub struct FunctionFlags {
|
||||||
|
/// True in the destination module of the import, false in the source module.
|
||||||
pub is_extern: bool,
|
pub is_extern: bool,
|
||||||
|
/// Whether this function is the main function of the module, that should be
|
||||||
|
/// executed (and linked externally also).
|
||||||
pub is_main: bool,
|
pub is_main: bool,
|
||||||
|
/// Whether this function should be available externally always.
|
||||||
pub is_pub: bool,
|
pub is_pub: bool,
|
||||||
|
/// If this function is an imported function (either in the source or
|
||||||
|
/// destination module)
|
||||||
pub is_imported: bool,
|
pub is_imported: bool,
|
||||||
|
/// Whether this function should add "alwaysinline"-attribute.
|
||||||
pub inline: bool,
|
pub inline: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,11 +256,7 @@ impl Instr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'builder> Block<'builder> {
|
impl<'builder> Block<'builder> {
|
||||||
pub fn build_named<T: Into<String>>(
|
pub fn build_named<T: Into<String>>(&mut self, name: T, instruction: Instr) -> CompileResult<InstructionValue> {
|
||||||
&mut self,
|
|
||||||
name: T,
|
|
||||||
instruction: Instr,
|
|
||||||
) -> CompileResult<InstructionValue> {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
self.builder.add_instruction(
|
self.builder.add_instruction(
|
||||||
&self.value,
|
&self.value,
|
||||||
@ -295,15 +287,13 @@ impl<'builder> Block<'builder> {
|
|||||||
|
|
||||||
pub fn set_instr_location(&self, instruction: InstructionValue, location: DebugLocationValue) {
|
pub fn set_instr_location(&self, instruction: InstructionValue, location: DebugLocationValue) {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.builder
|
self.builder.add_instruction_location(&instruction, location);
|
||||||
.add_instruction_location(&instruction, location);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_instr_metadata(&self, instruction: InstructionValue, location: DebugMetadataValue) {
|
pub fn set_instr_metadata(&self, instruction: InstructionValue, location: DebugMetadataValue) {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.builder
|
self.builder.add_instruction_metadata(&instruction, location);
|
||||||
.add_instruction_metadata(&instruction, location);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -610,16 +600,10 @@ impl Type {
|
|||||||
| Type::U32
|
| Type::U32
|
||||||
| Type::U64
|
| Type::U64
|
||||||
| Type::U128 => TypeCategory::Integer,
|
| Type::U128 => TypeCategory::Integer,
|
||||||
Type::F16
|
Type::F16 | Type::F32B | Type::F32 | Type::F64 | Type::F80 | Type::F128 | Type::F128PPC => {
|
||||||
| Type::F32B
|
TypeCategory::Real
|
||||||
| Type::F32
|
|
||||||
| Type::F64
|
|
||||||
| Type::F80
|
|
||||||
| Type::F128
|
|
||||||
| Type::F128PPC => TypeCategory::Real,
|
|
||||||
Type::Bool | Type::Void | Type::CustomType(_) | Type::Array(_, _) | Type::Ptr(_) => {
|
|
||||||
TypeCategory::Other
|
|
||||||
}
|
}
|
||||||
|
Type::Bool | Type::Void | Type::CustomType(_) | Type::Array(_, _) | Type::Ptr(_) => TypeCategory::Other,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -630,23 +614,15 @@ impl Type {
|
|||||||
(I16, I32 | I64 | I128) => Some(Instr::SExt(value, other.clone())),
|
(I16, I32 | I64 | I128) => Some(Instr::SExt(value, other.clone())),
|
||||||
(I32, I64 | I128) => Some(Instr::SExt(value, other.clone())),
|
(I32, I64 | I128) => Some(Instr::SExt(value, other.clone())),
|
||||||
(I64, I128) => Some(Instr::SExt(value, other.clone())),
|
(I64, I128) => Some(Instr::SExt(value, other.clone())),
|
||||||
(I128 | U128, I64 | U64 | I32 | U32 | I16 | U16 | I8 | U8) => {
|
(I128 | U128, I64 | U64 | I32 | U32 | I16 | U16 | I8 | U8) => Some(Instr::Trunc(value, other.clone())),
|
||||||
Some(Instr::Trunc(value, other.clone()))
|
(I64 | U64, I32 | U32 | I16 | U16 | I8 | U8) => Some(Instr::Trunc(value, other.clone())),
|
||||||
}
|
|
||||||
(I64 | U64, I32 | U32 | I16 | U16 | I8 | U8) => {
|
|
||||||
Some(Instr::Trunc(value, other.clone()))
|
|
||||||
}
|
|
||||||
(I32 | U32, I16 | U16 | I8 | U8) => Some(Instr::Trunc(value, other.clone())),
|
(I32 | U32, I16 | U16 | I8 | U8) => Some(Instr::Trunc(value, other.clone())),
|
||||||
(I16 | U16, I8 | U8) => Some(Instr::Trunc(value, other.clone())),
|
(I16 | U16, I8 | U8) => Some(Instr::Trunc(value, other.clone())),
|
||||||
(U8 | I8, U8 | I8 | U16 | I16 | U32 | I32 | U64 | I64 | U128 | I128) => {
|
(U8 | I8, U8 | I8 | U16 | I16 | U32 | I32 | U64 | I64 | U128 | I128) => {
|
||||||
Some(Instr::ZExt(value, other.clone()))
|
Some(Instr::ZExt(value, other.clone()))
|
||||||
}
|
}
|
||||||
(U16 | I16, U16 | I16 | U32 | I32 | U64 | I64 | U128 | I128) => {
|
(U16 | I16, U16 | I16 | U32 | I32 | U64 | I64 | U128 | I128) => Some(Instr::ZExt(value, other.clone())),
|
||||||
Some(Instr::ZExt(value, other.clone()))
|
(U32 | I32, U32 | I32 | U64 | I64 | U128 | I128) => Some(Instr::ZExt(value, other.clone())),
|
||||||
}
|
|
||||||
(U32 | I32, U32 | I32 | U64 | I64 | U128 | I128) => {
|
|
||||||
Some(Instr::ZExt(value, other.clone()))
|
|
||||||
}
|
|
||||||
(U64 | I64, U64 | I64 | U128 | I128) => Some(Instr::ZExt(value, other.clone())),
|
(U64 | I64, U64 | I64 | U128 | I128) => Some(Instr::ZExt(value, other.clone())),
|
||||||
(U128 | I128, U128 | I128) => Some(Instr::ZExt(value, other.clone())),
|
(U128 | I128, U128 | I128) => Some(Instr::ZExt(value, other.clone())),
|
||||||
(U8 | U16 | U32 | U64 | U128, F16 | F32 | F32B | F64 | F80 | F128 | F128PPC) => {
|
(U8 | U16 | U32 | U64 | U128, F16 | F32 | F32B | F64 | F80 | F128 | F128PPC) => {
|
||||||
@ -667,15 +643,11 @@ impl Type {
|
|||||||
(Ptr(_), I128 | U128 | I64 | U64 | I32 | U32 | I16 | U16 | I8 | U8) => {
|
(Ptr(_), I128 | U128 | I64 | U64 | I32 | U32 | I16 | U16 | I8 | U8) => {
|
||||||
Some(Instr::PtrToInt(value, other.clone()))
|
Some(Instr::PtrToInt(value, other.clone()))
|
||||||
}
|
}
|
||||||
(F16, F32 | F32B | F64 | F80 | F128 | F128PPC) => {
|
(F16, F32 | F32B | F64 | F80 | F128 | F128PPC) => Some(Instr::FPExt(value, other.clone())),
|
||||||
Some(Instr::FPExt(value, other.clone()))
|
|
||||||
}
|
|
||||||
(F32 | F32B, F64 | F80 | F128 | F128PPC) => Some(Instr::FPExt(value, other.clone())),
|
(F32 | F32B, F64 | F80 | F128 | F128PPC) => Some(Instr::FPExt(value, other.clone())),
|
||||||
(F64, F80 | F128 | F128PPC) => Some(Instr::FPExt(value, other.clone())),
|
(F64, F80 | F128 | F128PPC) => Some(Instr::FPExt(value, other.clone())),
|
||||||
(F80, F128 | F128PPC) => Some(Instr::FPExt(value, other.clone())),
|
(F80, F128 | F128PPC) => Some(Instr::FPExt(value, other.clone())),
|
||||||
(F128PPC | F128, F80 | F64 | F32B | F32 | F16) => {
|
(F128PPC | F128, F80 | F64 | F32B | F32 | F16) => Some(Instr::FPTrunc(value, other.clone())),
|
||||||
Some(Instr::FPTrunc(value, other.clone()))
|
|
||||||
}
|
|
||||||
(F80, F64 | F32B | F32 | F16) => Some(Instr::FPTrunc(value, other.clone())),
|
(F80, F64 | F32B | F32 | F16) => Some(Instr::FPTrunc(value, other.clone())),
|
||||||
(F64, F32B | F32 | F16) => Some(Instr::FPTrunc(value, other.clone())),
|
(F64, F32B | F32 | F16) => Some(Instr::FPTrunc(value, other.clone())),
|
||||||
(F32B | F32, F16) => Some(Instr::FPTrunc(value, other.clone())),
|
(F32B | F32, F16) => Some(Instr::FPTrunc(value, other.clone())),
|
||||||
|
@ -4,6 +4,21 @@ extern fn malloc(size: u64) -> *u8;
|
|||||||
extern fn free(ptr: *u8);
|
extern fn free(ptr: *u8);
|
||||||
extern fn div(numerator: i32, denominator: i32) -> div_t;
|
extern fn div(numerator: i32, denominator: i32) -> div_t;
|
||||||
|
|
||||||
|
struct String {
|
||||||
|
inner: *char,
|
||||||
|
length: u64,
|
||||||
|
max_length: u64,
|
||||||
|
must_be_freed: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl binop (lhs: String) + (rhs: *char) -> String {
|
||||||
|
let mut new = lhs;
|
||||||
|
let added = from_str(rhs);
|
||||||
|
concat_strings(&mut new, added);
|
||||||
|
free_string(&added);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
struct div_t {
|
struct div_t {
|
||||||
quotient: i32,
|
quotient: i32,
|
||||||
remainder: i32,
|
remainder: i32,
|
||||||
@ -21,13 +36,6 @@ pub fn allocate(size: u64) -> *u8 {
|
|||||||
malloc(size)
|
malloc(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct String {
|
|
||||||
inner: *char,
|
|
||||||
length: u64,
|
|
||||||
max_length: u64,
|
|
||||||
must_be_freed: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_string() -> String {
|
pub fn new_string() -> String {
|
||||||
String {
|
String {
|
||||||
inner: allocate(0),
|
inner: allocate(0),
|
||||||
|
@ -117,6 +117,7 @@ impl ast::Module {
|
|||||||
block.2.as_meta(module_id),
|
block.2.as_meta(module_id),
|
||||||
),
|
),
|
||||||
meta: signature_range.as_meta(module_id),
|
meta: signature_range.as_meta(module_id),
|
||||||
|
exported: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ where
|
|||||||
return_type: ty.clone(),
|
return_type: ty.clone(),
|
||||||
fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleInstr(fun))),
|
fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleInstr(fun))),
|
||||||
meta: Default::default(),
|
meta: Default::default(),
|
||||||
|
exported: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,6 +64,7 @@ where
|
|||||||
return_type: TypeKind::Bool,
|
return_type: TypeKind::Bool,
|
||||||
fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicBooleanInstr(fun))),
|
fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicBooleanInstr(fun))),
|
||||||
meta: Default::default(),
|
meta: Default::default(),
|
||||||
|
exported: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ use scope::*;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
mir::{
|
mir::{
|
||||||
self, implement::TypeCategory, pass::ScopeBinopKey, CustomTypeKey, FunctionDefinitionKind, NamedVariableRef,
|
self, implement::TypeCategory, pass::BinopKey, CustomTypeKey, FunctionDefinitionKind, NamedVariableRef,
|
||||||
SourceModuleId, StructField, StructType, TypeDefinition, TypeDefinitionKind, TypeKind, WhileStatement,
|
SourceModuleId, StructField, StructType, TypeDefinition, TypeDefinitionKind, TypeKind, WhileStatement,
|
||||||
},
|
},
|
||||||
util::try_all,
|
util::try_all,
|
||||||
@ -214,8 +214,12 @@ impl mir::Module {
|
|||||||
|
|
||||||
let mut binops = HashMap::new();
|
let mut binops = HashMap::new();
|
||||||
for binop in &self.binop_defs {
|
for binop in &self.binop_defs {
|
||||||
|
let binop_fn_name = format!(
|
||||||
|
"binop.{}.{:?}.{}.{}",
|
||||||
|
binop.lhs.1, binop.op, binop.rhs.1, binop.return_type
|
||||||
|
);
|
||||||
binops.insert(
|
binops.insert(
|
||||||
ScopeBinopKey {
|
BinopKey {
|
||||||
params: (binop.lhs.1.clone(), binop.rhs.1.clone()),
|
params: (binop.lhs.1.clone(), binop.rhs.1.clone()),
|
||||||
operator: binop.op,
|
operator: binop.op,
|
||||||
},
|
},
|
||||||
@ -224,16 +228,14 @@ impl mir::Module {
|
|||||||
return_ty: binop.return_type.clone(),
|
return_ty: binop.return_type.clone(),
|
||||||
kind: match &binop.fn_kind {
|
kind: match &binop.fn_kind {
|
||||||
FunctionDefinitionKind::Local(block, metadata) => {
|
FunctionDefinitionKind::Local(block, metadata) => {
|
||||||
let binop_fn_name = format!(
|
|
||||||
"binop.{}.{:?}.{}.{}",
|
|
||||||
binop.lhs.1, binop.op, binop.rhs.1, binop.return_type
|
|
||||||
);
|
|
||||||
let ir_function = module.function(
|
let ir_function = module.function(
|
||||||
&binop_fn_name,
|
&binop_fn_name,
|
||||||
binop.return_type.get_type(&type_values),
|
binop.return_type.get_type(&type_values),
|
||||||
vec![binop.lhs.1.get_type(&type_values), binop.rhs.1.get_type(&type_values)],
|
vec![binop.lhs.1.get_type(&type_values), binop.rhs.1.get_type(&type_values)],
|
||||||
FunctionFlags {
|
FunctionFlags {
|
||||||
inline: true,
|
inline: true,
|
||||||
|
is_pub: binop.exported,
|
||||||
|
is_imported: binop.exported,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -289,7 +291,18 @@ impl mir::Module {
|
|||||||
|
|
||||||
StackBinopFunctionKind::UserGenerated(ir_function)
|
StackBinopFunctionKind::UserGenerated(ir_function)
|
||||||
}
|
}
|
||||||
FunctionDefinitionKind::Extern(_) => todo!(),
|
FunctionDefinitionKind::Extern(imported) => {
|
||||||
|
StackBinopFunctionKind::UserGenerated(module.function(
|
||||||
|
&binop_fn_name,
|
||||||
|
binop.return_type.get_type(&type_values),
|
||||||
|
vec![binop.lhs.1.get_type(&type_values), binop.rhs.1.get_type(&type_values)],
|
||||||
|
FunctionFlags {
|
||||||
|
is_extern: true,
|
||||||
|
is_imported: *imported,
|
||||||
|
..FunctionFlags::default()
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
FunctionDefinitionKind::Intrinsic(intrinsic_function) => {
|
FunctionDefinitionKind::Intrinsic(intrinsic_function) => {
|
||||||
StackBinopFunctionKind::Intrinsic(intrinsic_function)
|
StackBinopFunctionKind::Intrinsic(intrinsic_function)
|
||||||
}
|
}
|
||||||
@ -704,7 +717,7 @@ impl mir::Expression {
|
|||||||
let lhs = lhs_val.instr();
|
let lhs = lhs_val.instr();
|
||||||
let rhs = rhs_val.instr();
|
let rhs = rhs_val.instr();
|
||||||
|
|
||||||
let operation = scope.binops.get(&ScopeBinopKey {
|
let operation = scope.binops.get(&BinopKey {
|
||||||
params: (lhs_val.1.clone(), rhs_val.1.clone()),
|
params: (lhs_val.1.clone(), rhs_val.1.clone()),
|
||||||
operator: *binop,
|
operator: *binop,
|
||||||
});
|
});
|
||||||
|
@ -8,7 +8,7 @@ use reid_lib::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
lexer::FullToken,
|
lexer::FullToken,
|
||||||
mir::{pass::ScopeBinopKey, CustomTypeKey, SourceModuleId, TypeDefinition, TypeKind},
|
mir::{pass::BinopKey, CustomTypeKey, SourceModuleId, TypeDefinition, TypeKind},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{allocator::Allocator, ErrorKind, IntrinsicFunction, ModuleCodegen};
|
use super::{allocator::Allocator, ErrorKind, IntrinsicFunction, ModuleCodegen};
|
||||||
@ -24,7 +24,7 @@ pub struct Scope<'ctx, 'scope> {
|
|||||||
pub(super) types: &'scope HashMap<TypeValue, TypeDefinition>,
|
pub(super) types: &'scope HashMap<TypeValue, TypeDefinition>,
|
||||||
pub(super) type_values: &'scope HashMap<CustomTypeKey, TypeValue>,
|
pub(super) type_values: &'scope HashMap<CustomTypeKey, TypeValue>,
|
||||||
pub(super) functions: &'scope HashMap<String, Function<'ctx>>,
|
pub(super) functions: &'scope HashMap<String, Function<'ctx>>,
|
||||||
pub(super) binops: &'scope HashMap<ScopeBinopKey, StackBinopDefinition<'ctx>>,
|
pub(super) binops: &'scope HashMap<BinopKey, StackBinopDefinition<'ctx>>,
|
||||||
pub(super) stack_values: HashMap<String, StackValue>,
|
pub(super) stack_values: HashMap<String, StackValue>,
|
||||||
pub(super) debug: Option<Debug<'ctx>>,
|
pub(super) debug: Option<Debug<'ctx>>,
|
||||||
pub(super) allocator: Rc<RefCell<Allocator>>,
|
pub(super) allocator: Rc<RefCell<Allocator>>,
|
||||||
@ -150,15 +150,9 @@ impl<'ctx> StackBinopDefinition<'ctx> {
|
|||||||
StackBinopFunctionKind::UserGenerated(ir) => {
|
StackBinopFunctionKind::UserGenerated(ir) => {
|
||||||
let instr = scope
|
let instr = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::FunctionCall(
|
.build(Instr::FunctionCall(ir.value(), vec![lhs.instr(), rhs.instr()]))
|
||||||
ir.value(),
|
|
||||||
vec![lhs.instr(), rhs.instr()],
|
|
||||||
))
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Ok(StackValue(
|
Ok(StackValue(StackValueKind::Immutable(instr), self.return_ty.clone()))
|
||||||
StackValueKind::Immutable(instr),
|
|
||||||
self.return_ty.clone(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
StackBinopFunctionKind::Intrinsic(fun) => fun.codegen(scope, &[&lhs, &rhs]),
|
StackBinopFunctionKind::Intrinsic(fun) => fun.codegen(scope, &[&lhs, &rhs]),
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ pub fn perform_all_passes<'map>(
|
|||||||
for intrinsic in form_intrinsic_binops() {
|
for intrinsic in form_intrinsic_binops() {
|
||||||
binops
|
binops
|
||||||
.set(
|
.set(
|
||||||
mir::pass::ScopeBinopKey {
|
mir::pass::BinopKey {
|
||||||
params: (intrinsic.lhs.1.clone(), intrinsic.rhs.1.clone()),
|
params: (intrinsic.lhs.1.clone(), intrinsic.rhs.1.clone()),
|
||||||
operator: intrinsic.op,
|
operator: intrinsic.op,
|
||||||
},
|
},
|
||||||
|
@ -66,8 +66,14 @@ impl Display for BinopDefinition {
|
|||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"impl binop ({}: {:#}) {} ({}: {:#}) -> {:#} ",
|
"{}impl binop ({}: {:#}) {} ({}: {:#}) -> {:#} ",
|
||||||
self.lhs.0, self.lhs.1, self.op, self.rhs.0, self.rhs.1, self.return_type
|
if self.exported { "exported " } else { "" },
|
||||||
|
self.lhs.0,
|
||||||
|
self.lhs.1,
|
||||||
|
self.op,
|
||||||
|
self.rhs.0,
|
||||||
|
self.rhs.1,
|
||||||
|
self.return_type
|
||||||
)?;
|
)?;
|
||||||
Display::fmt(&self.fn_kind, f)
|
Display::fmt(&self.fn_kind, f)
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,10 @@ use crate::{
|
|||||||
codegen::scope,
|
codegen::scope,
|
||||||
compile_module,
|
compile_module,
|
||||||
error_raporting::{ErrorModules, ReidError},
|
error_raporting::{ErrorModules, ReidError},
|
||||||
mir::{CustomTypeKey, FunctionDefinitionKind, SourceModuleId, TypeDefinition, TypeKind},
|
mir::{
|
||||||
|
pass::BinopKey, BinopDefinition, CustomTypeKey, FunctionDefinitionKind, SourceModuleId, TypeDefinition,
|
||||||
|
TypeKind,
|
||||||
|
},
|
||||||
parse_module,
|
parse_module,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -110,6 +113,7 @@ impl<'map> Pass for LinkerPass<'map> {
|
|||||||
let mut modules_to_process: Vec<Rc<RefCell<_>>> = modules.values().cloned().collect();
|
let mut modules_to_process: Vec<Rc<RefCell<_>>> = modules.values().cloned().collect();
|
||||||
|
|
||||||
let mut already_imported_types = HashSet::<CustomTypeKey>::new();
|
let mut already_imported_types = HashSet::<CustomTypeKey>::new();
|
||||||
|
let mut already_imported_binops = HashSet::<BinopKey>::new();
|
||||||
|
|
||||||
while let Some(module) = modules_to_process.pop() {
|
while let Some(module) = modules_to_process.pop() {
|
||||||
let mut extern_types = HashMap::new();
|
let mut extern_types = HashMap::new();
|
||||||
@ -232,10 +236,39 @@ impl<'map> Pass for LinkerPass<'map> {
|
|||||||
kind: super::FunctionDefinitionKind::Extern(true),
|
kind: super::FunctionDefinitionKind::Extern(true),
|
||||||
});
|
});
|
||||||
} else if let Some(ty) = imported.typedefs.iter_mut().find(|f| f.name == *import_name) {
|
} else if let Some(ty) = imported.typedefs.iter_mut().find(|f| f.name == *import_name) {
|
||||||
dbg!("hello??");
|
|
||||||
let external_key = CustomTypeKey(ty.name.clone(), ty.source_module);
|
let external_key = CustomTypeKey(ty.name.clone(), ty.source_module);
|
||||||
|
let imported_ty = TypeKind::CustomType(external_key.clone());
|
||||||
imported_types.push((external_key, true));
|
imported_types.push((external_key, true));
|
||||||
dbg!(&imported_types);
|
|
||||||
|
for binop in &mut imported.binop_defs {
|
||||||
|
if binop.lhs.1 != imported_ty && binop.rhs.1 != imported_ty {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let binop_key = BinopKey {
|
||||||
|
params: (binop.lhs.1.clone(), binop.rhs.1.clone()),
|
||||||
|
operator: binop.op,
|
||||||
|
};
|
||||||
|
if already_imported_binops.contains(&binop_key) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
binop.exported = true;
|
||||||
|
already_imported_binops.insert(binop_key);
|
||||||
|
match &binop.fn_kind {
|
||||||
|
FunctionDefinitionKind::Local(block, metadata) => {
|
||||||
|
importer_module.binop_defs.push(BinopDefinition {
|
||||||
|
lhs: binop.lhs.clone(),
|
||||||
|
op: binop.op,
|
||||||
|
rhs: binop.rhs.clone(),
|
||||||
|
return_type: binop.return_type.clone(),
|
||||||
|
fn_kind: FunctionDefinitionKind::Extern(true),
|
||||||
|
meta: binop.meta.clone(),
|
||||||
|
exported: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
FunctionDefinitionKind::Extern(_) => {}
|
||||||
|
FunctionDefinitionKind::Intrinsic(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
state.ok::<_, Infallible>(
|
state.ok::<_, Infallible>(
|
||||||
Err(ErrorKind::ImportDoesNotExist(module_name.clone(), import_name.clone())),
|
Err(ErrorKind::ImportDoesNotExist(module_name.clone(), import_name.clone())),
|
||||||
|
@ -370,6 +370,8 @@ pub struct BinopDefinition {
|
|||||||
pub return_type: TypeKind,
|
pub return_type: TypeKind,
|
||||||
pub fn_kind: FunctionDefinitionKind,
|
pub fn_kind: FunctionDefinitionKind,
|
||||||
pub meta: Metadata,
|
pub meta: Metadata,
|
||||||
|
// Wether this binop definition has been imported into another module.
|
||||||
|
pub exported: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BinopDefinition {
|
impl BinopDefinition {
|
||||||
|
@ -117,7 +117,7 @@ impl<Key: std::hash::Hash + Eq, T: Clone + std::fmt::Debug> Storage<Key, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type BinopMap = Storage<ScopeBinopKey, ScopeBinopDef>;
|
pub type BinopMap = Storage<BinopKey, ScopeBinopDef>;
|
||||||
|
|
||||||
#[derive(Clone, Default, Debug)]
|
#[derive(Clone, Default, Debug)]
|
||||||
pub struct Scope<Data: Clone + Default> {
|
pub struct Scope<Data: Clone + Default> {
|
||||||
@ -182,7 +182,7 @@ pub struct ScopeVariable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq)]
|
#[derive(Clone, Debug, Eq)]
|
||||||
pub struct ScopeBinopKey {
|
pub struct BinopKey {
|
||||||
pub params: (TypeKind, TypeKind),
|
pub params: (TypeKind, TypeKind),
|
||||||
pub operator: BinaryOperator,
|
pub operator: BinaryOperator,
|
||||||
}
|
}
|
||||||
@ -194,7 +194,7 @@ pub enum CommutativeKind {
|
|||||||
Any,
|
Any,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for ScopeBinopKey {
|
impl PartialEq for BinopKey {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
if self.operator != other.operator {
|
if self.operator != other.operator {
|
||||||
return false;
|
return false;
|
||||||
@ -216,7 +216,7 @@ impl PartialEq for ScopeBinopKey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::hash::Hash for ScopeBinopKey {
|
impl std::hash::Hash for BinopKey {
|
||||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||||
if self.operator.is_commutative() {
|
if self.operator.is_commutative() {
|
||||||
let mut sorted = vec![&self.params.0, &self.params.1];
|
let mut sorted = vec![&self.params.0, &self.params.1];
|
||||||
@ -336,7 +336,7 @@ impl Context {
|
|||||||
scope
|
scope
|
||||||
.binops
|
.binops
|
||||||
.set(
|
.set(
|
||||||
ScopeBinopKey {
|
BinopKey {
|
||||||
params: (intrinsic.lhs.1.clone(), intrinsic.rhs.1.clone()),
|
params: (intrinsic.lhs.1.clone(), intrinsic.rhs.1.clone()),
|
||||||
operator: intrinsic.op,
|
operator: intrinsic.op,
|
||||||
},
|
},
|
||||||
@ -374,7 +374,7 @@ impl Module {
|
|||||||
scope
|
scope
|
||||||
.binops
|
.binops
|
||||||
.set(
|
.set(
|
||||||
ScopeBinopKey {
|
BinopKey {
|
||||||
params: (binop.lhs.1.clone(), binop.rhs.1.clone()),
|
params: (binop.lhs.1.clone(), binop.rhs.1.clone()),
|
||||||
operator: binop.op,
|
operator: binop.op,
|
||||||
},
|
},
|
||||||
|
@ -422,7 +422,7 @@ impl Expression {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
let binops = state.scope.binops.filter(&pass::ScopeBinopKey {
|
let binops = state.scope.binops.filter(&pass::BinopKey {
|
||||||
params: (lhs_type.clone(), rhs_type.clone()),
|
params: (lhs_type.clone(), rhs_type.clone()),
|
||||||
operator: *op,
|
operator: *op,
|
||||||
});
|
});
|
||||||
|
@ -20,7 +20,7 @@ use crate::{
|
|||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
super::{
|
super::{
|
||||||
pass::{Pass, PassResult, PassState, ScopeBinopKey},
|
pass::{BinopKey, Pass, PassResult, PassState},
|
||||||
TypeKind::*,
|
TypeKind::*,
|
||||||
VagueType::*,
|
VagueType::*,
|
||||||
},
|
},
|
||||||
@ -62,7 +62,7 @@ impl<'t> Pass for TypeInference<'t> {
|
|||||||
|
|
||||||
let mut seen_binops = HashSet::new();
|
let mut seen_binops = HashSet::new();
|
||||||
for binop in &module.binop_defs {
|
for binop in &module.binop_defs {
|
||||||
let binop_key = ScopeBinopKey {
|
let binop_key = BinopKey {
|
||||||
params: (binop.lhs.1.clone(), binop.rhs.1.clone()),
|
params: (binop.lhs.1.clone(), binop.rhs.1.clone()),
|
||||||
operator: binop.op,
|
operator: binop.op,
|
||||||
};
|
};
|
||||||
|
@ -10,7 +10,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
super::pass::{ScopeBinopDef, ScopeBinopKey, Storage},
|
super::pass::{BinopKey, ScopeBinopDef, Storage},
|
||||||
ErrorKind,
|
ErrorKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user