Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
4fada0036c | |||
4f0ee72c83 | |||
deed96bbfd |
10
examples/a.reid
Normal file
10
examples/a.reid
Normal file
@ -0,0 +1,10 @@
|
||||
struct Foo {
|
||||
a: i32,
|
||||
b: i32,
|
||||
}
|
||||
|
||||
fn main() -> i32 {
|
||||
// ISSUE: The debugger says b is 1
|
||||
let foos = [Foo { a: 1, b: 2}];
|
||||
return 0;
|
||||
}
|
@ -4,5 +4,6 @@ import std::print;
|
||||
fn main() -> u8 {
|
||||
let bytes = include_bytes!("./macro_easy_file.txt");
|
||||
print(String::new() + bytes.length());
|
||||
return (bytes as *u8)[0];
|
||||
print(String::new() + (include_bytes!("./macro_easy_file.txt") as *u8)[1] as u64);
|
||||
return (include_bytes!("./macro_easy_file.txt") as *u8)[0];
|
||||
}
|
||||
|
@ -610,30 +610,9 @@ impl Builder {
|
||||
Instr::PtrToInt(instr, ty) => instr.cast_to(self, &ty).map(|_| ()),
|
||||
Instr::IntToPtr(instr, ty) => instr.cast_to(self, &ty).map(|_| ()),
|
||||
Instr::BitCast(..) => Ok(()),
|
||||
Instr::ShiftRightLogical(_, rhs) => {
|
||||
let rhs_ty = rhs.get_type(&self)?;
|
||||
if rhs_ty.category() == TypeCategory::UnsignedInteger {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ErrorKind::Null)
|
||||
}
|
||||
}
|
||||
Instr::ShiftRightArithmetic(_, rhs) => {
|
||||
let rhs_ty = rhs.get_type(&self)?;
|
||||
if rhs_ty.category() == TypeCategory::UnsignedInteger {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ErrorKind::Null)
|
||||
}
|
||||
}
|
||||
Instr::ShiftLeft(_, rhs) => {
|
||||
let rhs_ty = rhs.get_type(&self)?;
|
||||
if rhs_ty.category() == TypeCategory::UnsignedInteger {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ErrorKind::Null)
|
||||
}
|
||||
}
|
||||
Instr::ShiftRightLogical(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()),
|
||||
Instr::ShiftRightArithmetic(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()),
|
||||
Instr::ShiftLeft(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()),
|
||||
Instr::GetGlobal(_) => Ok(()),
|
||||
}
|
||||
}
|
||||
|
@ -540,7 +540,7 @@ impl DebugTypeHolder {
|
||||
field.pos.map(|p| p.line).unwrap_or(1),
|
||||
field.size_bits,
|
||||
0,
|
||||
1,
|
||||
field.offset,
|
||||
field.flags.as_llvm(),
|
||||
*debug.types.get(&field.ty).unwrap(),
|
||||
)
|
||||
|
@ -74,7 +74,7 @@ pub fn get_intrinsic_assoc_func(ty: &TypeKind, name: &str) -> Option<FunctionDef
|
||||
}],
|
||||
kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicConst(*len))),
|
||||
source: None,
|
||||
})
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -247,26 +247,17 @@ pub fn form_intrinsic_binops() -> Vec<BinopDefinition> {
|
||||
scope.block.build(Instr::XOr(lhs, rhs)).unwrap()
|
||||
}));
|
||||
if ty.signed() {
|
||||
intrinsics.push(complex_binop_def(
|
||||
BitshiftRight,
|
||||
&ty,
|
||||
&TypeKind::U64,
|
||||
|scope, lhs, rhs| scope.block.build(Instr::ShiftRightArithmetic(lhs, rhs)).unwrap(),
|
||||
));
|
||||
intrinsics.push(complex_binop_def(BitshiftRight, &ty, &ty, |scope, lhs, rhs| {
|
||||
scope.block.build(Instr::ShiftRightArithmetic(lhs, rhs)).unwrap()
|
||||
}));
|
||||
} else {
|
||||
intrinsics.push(complex_binop_def(
|
||||
BitshiftRight,
|
||||
&ty,
|
||||
&TypeKind::U64,
|
||||
|scope, lhs, rhs| scope.block.build(Instr::ShiftRightLogical(lhs, rhs)).unwrap(),
|
||||
));
|
||||
intrinsics.push(complex_binop_def(BitshiftRight, &ty, &ty, |scope, lhs, rhs| {
|
||||
scope.block.build(Instr::ShiftRightLogical(lhs, rhs)).unwrap()
|
||||
}));
|
||||
}
|
||||
intrinsics.push(complex_binop_def(
|
||||
BitshiftLeft,
|
||||
&ty,
|
||||
&TypeKind::U64,
|
||||
|scope, lhs, rhs| scope.block.build(Instr::ShiftLeft(lhs, rhs)).unwrap(),
|
||||
));
|
||||
intrinsics.push(complex_binop_def(BitshiftLeft, &ty, &ty, |scope, lhs, rhs| {
|
||||
scope.block.build(Instr::ShiftLeft(lhs, rhs)).unwrap()
|
||||
}));
|
||||
}
|
||||
for ty in INTEGERS.iter().chain(&[TypeKind::Bool, TypeKind::Char]) {
|
||||
intrinsics.push(boolean_binop_def(Cmp(CmpOperator::EQ), &ty, |scope, lhs, rhs| {
|
||||
@ -386,7 +377,9 @@ impl IntrinsicFunction for IntrinsicSizeOf {
|
||||
fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, _: &[StackValue]) -> Result<StackValue, ErrorKind> {
|
||||
let instr = scope
|
||||
.block
|
||||
.build(Instr::Constant(reid_lib::ConstValueKind::U64(self.0.size_of() / 8)))
|
||||
.build(Instr::Constant(reid_lib::ConstValueKind::U64(
|
||||
self.0.size_of(&scope.type_map) / 8,
|
||||
)))
|
||||
.unwrap();
|
||||
Ok(StackValue(StackValueKind::Literal(instr), self.0.clone()))
|
||||
}
|
||||
@ -404,7 +397,9 @@ impl IntrinsicFunction for IntrinsicMalloc {
|
||||
|
||||
let sizeof = scope
|
||||
.block
|
||||
.build(Instr::Constant(ConstValueKind::U64(self.0.size_of() / 8)))
|
||||
.build(Instr::Constant(ConstValueKind::U64(
|
||||
self.0.size_of(&scope.type_map) / 8,
|
||||
)))
|
||||
.unwrap();
|
||||
let bytes = scope.block.build(Instr::Mul(sizeof, amount.instr())).unwrap();
|
||||
let instr = scope.block.build(Instr::FunctionCall(function, vec![bytes])).unwrap();
|
||||
|
@ -144,6 +144,7 @@ impl mir::Module {
|
||||
let mut types = HashMap::new();
|
||||
let mut type_values = HashMap::new();
|
||||
let mut debug_types = HashMap::new();
|
||||
let mut type_map = HashMap::new();
|
||||
|
||||
macro_rules! insert_debug {
|
||||
($kind:expr) => {
|
||||
@ -153,8 +154,7 @@ impl mir::Module {
|
||||
&compile_unit,
|
||||
&debug,
|
||||
&debug_types,
|
||||
&type_values,
|
||||
&types,
|
||||
&type_map,
|
||||
self.module_id,
|
||||
&self.tokens,
|
||||
&modules,
|
||||
@ -182,6 +182,8 @@ impl mir::Module {
|
||||
|
||||
for typedef in typedefs {
|
||||
let type_key = CustomTypeKey(typedef.name.clone(), typedef.source_module);
|
||||
type_map.insert(type_key.clone(), typedef.clone());
|
||||
|
||||
let type_value = match &typedef.kind {
|
||||
TypeDefinitionKind::Struct(StructType(fields)) => {
|
||||
module.custom_type(CustomTypeKind::NamedStruct(NamedStruct(
|
||||
@ -198,6 +200,7 @@ impl mir::Module {
|
||||
};
|
||||
types.insert(type_value, typedef.clone());
|
||||
type_values.insert(type_key.clone(), type_value);
|
||||
|
||||
insert_debug!(&TypeKind::CustomType(type_key.clone()));
|
||||
}
|
||||
|
||||
@ -380,6 +383,7 @@ impl mir::Module {
|
||||
functions: &functions,
|
||||
types: &types,
|
||||
type_values: &type_values,
|
||||
type_map: &type_map,
|
||||
globals: &globals,
|
||||
stack_values: HashMap::new(),
|
||||
debug: Some(Debug {
|
||||
@ -457,6 +461,7 @@ impl mir::Module {
|
||||
functions: &functions,
|
||||
types: &types,
|
||||
type_values: &type_values,
|
||||
type_map: &type_map,
|
||||
stack_values: HashMap::new(),
|
||||
debug: Some(Debug {
|
||||
info: &debug,
|
||||
@ -518,6 +523,7 @@ impl mir::Module {
|
||||
functions: &functions,
|
||||
types: &types,
|
||||
type_values: &type_values,
|
||||
type_map: &type_map,
|
||||
stack_values: HashMap::new(),
|
||||
debug: Some(Debug {
|
||||
info: &debug,
|
||||
@ -1311,45 +1317,47 @@ impl mir::Expression {
|
||||
if val.1 == *type_kind {
|
||||
Some(val)
|
||||
} else {
|
||||
match (&val.1, type_kind) {
|
||||
(TypeKind::CodegenPtr(inner), TypeKind::UserPtr(ty2)) => match *inner.clone() {
|
||||
TypeKind::UserPtr(_) => Some(StackValue(
|
||||
val.0.derive(
|
||||
scope
|
||||
.block
|
||||
.build(Instr::BitCast(
|
||||
val.instr(),
|
||||
Type::Ptr(Box::new(type_kind.get_type(scope.type_values))),
|
||||
))
|
||||
.unwrap(),
|
||||
),
|
||||
TypeKind::CodegenPtr(Box::new(type_kind.clone())),
|
||||
)),
|
||||
TypeKind::Borrow(ty1, _) => match *ty1.clone() {
|
||||
TypeKind::Array(ty1, _) => {
|
||||
if ty1 == *ty2 {
|
||||
Some(StackValue(
|
||||
val.0.derive(
|
||||
scope
|
||||
.block
|
||||
.build(Instr::BitCast(
|
||||
val.instr(),
|
||||
Type::Ptr(Box::new(type_kind.get_type(scope.type_values))),
|
||||
))
|
||||
.unwrap(),
|
||||
),
|
||||
TypeKind::CodegenPtr(Box::new(type_kind.clone())),
|
||||
))
|
||||
} else {
|
||||
return Err(ErrorKind::Null);
|
||||
}
|
||||
let (ty, other) = if !state.should_load {
|
||||
let TypeKind::CodegenPtr(inner) = &val.1 else {
|
||||
panic!();
|
||||
};
|
||||
(*inner.clone(), TypeKind::CodegenPtr(Box::new(type_kind.clone())))
|
||||
} else {
|
||||
(val.1.clone(), type_kind.clone())
|
||||
};
|
||||
|
||||
dbg!(&ty, type_kind);
|
||||
|
||||
match (&ty, type_kind) {
|
||||
(TypeKind::UserPtr(_), TypeKind::UserPtr(_)) => Some(StackValue(
|
||||
val.0.derive(
|
||||
scope
|
||||
.block
|
||||
.build(Instr::BitCast(val.instr(), other.get_type(scope.type_values)))
|
||||
.unwrap(),
|
||||
),
|
||||
other.clone(),
|
||||
)),
|
||||
(TypeKind::Borrow(ty1, _), TypeKind::UserPtr(ty2)) => {
|
||||
if let TypeKind::Array(ty1, _) = ty1.as_ref() {
|
||||
if ty1 == ty2 {
|
||||
Some(StackValue(
|
||||
val.0.derive(
|
||||
scope
|
||||
.block
|
||||
.build(Instr::BitCast(val.instr(), other.get_type(scope.type_values)))
|
||||
.unwrap(),
|
||||
),
|
||||
other,
|
||||
))
|
||||
} else {
|
||||
return Err(ErrorKind::Null).unwrap();
|
||||
}
|
||||
_ => return Err(ErrorKind::Null),
|
||||
},
|
||||
_ => panic!(),
|
||||
},
|
||||
(TypeKind::UserPtr(_), TypeKind::UserPtr(_))
|
||||
| (TypeKind::Char, TypeKind::U8)
|
||||
} else {
|
||||
return Err(ErrorKind::Null).unwrap();
|
||||
}
|
||||
}
|
||||
(TypeKind::Char, TypeKind::U8)
|
||||
| (TypeKind::U8, TypeKind::Char)
|
||||
| (TypeKind::U8, TypeKind::I8) => Some(StackValue(
|
||||
val.0.derive(
|
||||
@ -1361,8 +1369,7 @@ impl mir::Expression {
|
||||
type_kind.clone(),
|
||||
)),
|
||||
_ => {
|
||||
let cast_instr = val
|
||||
.1
|
||||
let cast_instr = ty
|
||||
.get_type(scope.type_values)
|
||||
.cast_instruction(val.instr(), &type_kind.get_type(scope.type_values))
|
||||
.unwrap();
|
||||
@ -1378,11 +1385,30 @@ impl mir::Expression {
|
||||
mir::ExprKind::AssociatedFunctionCall(ty, call) => codegen_function_call(Some(ty), call, scope, state)?,
|
||||
mir::ExprKind::GlobalRef(global_name, ty) => {
|
||||
let global_value = scope.globals.get(global_name).unwrap();
|
||||
let a = Some(StackValue(
|
||||
StackValueKind::Literal(scope.block.build(Instr::GetGlobal(global_value.clone())).unwrap()),
|
||||
ty.clone(),
|
||||
));
|
||||
a
|
||||
|
||||
let value = scope.block.build(Instr::GetGlobal(global_value.clone())).unwrap();
|
||||
|
||||
if !state.should_load {
|
||||
let allocated = scope
|
||||
.block
|
||||
.build(Instr::Alloca(ty.get_type(scope.type_values)))
|
||||
.unwrap();
|
||||
|
||||
scope
|
||||
.block
|
||||
.build(Instr::Store(allocated, value))
|
||||
.unwrap()
|
||||
.maybe_location(&mut scope.block, location.clone());
|
||||
|
||||
let a = Some(StackValue(
|
||||
StackValueKind::Literal(allocated),
|
||||
TypeKind::CodegenPtr(Box::new(ty.clone())),
|
||||
));
|
||||
a
|
||||
} else {
|
||||
let a = Some(StackValue(StackValueKind::Literal(value), ty.clone()));
|
||||
a
|
||||
}
|
||||
}
|
||||
};
|
||||
if let Some(value) = &value {
|
||||
|
@ -26,6 +26,7 @@ pub struct Scope<'ctx, 'scope> {
|
||||
pub(super) block: Block<'ctx>,
|
||||
pub(super) types: &'scope HashMap<TypeValue, TypeDefinition>,
|
||||
pub(super) type_values: &'scope HashMap<CustomTypeKey, TypeValue>,
|
||||
pub(super) type_map: &'scope HashMap<CustomTypeKey, TypeDefinition>,
|
||||
pub(super) assoc_functions: &'scope HashMap<AssociatedFunctionKey, ScopeFunctionKind<'ctx>>,
|
||||
pub(super) functions: &'scope HashMap<String, ScopeFunctionKind<'ctx>>,
|
||||
pub(super) binops: &'scope HashMap<BinopKey, StackBinopDefinition<'ctx>>,
|
||||
@ -49,6 +50,7 @@ impl<'ctx, 'a> Scope<'ctx, 'a> {
|
||||
functions: self.functions,
|
||||
types: self.types,
|
||||
type_values: self.type_values,
|
||||
type_map: self.type_map,
|
||||
stack_values: self.stack_values.clone(),
|
||||
debug: self.debug.clone(),
|
||||
allocator: self.allocator.clone(),
|
||||
|
@ -109,8 +109,7 @@ impl TypeKind {
|
||||
&debug.scope,
|
||||
debug.info,
|
||||
debug.types,
|
||||
scope.type_values,
|
||||
scope.types,
|
||||
scope.type_map,
|
||||
scope.module_id,
|
||||
scope.tokens,
|
||||
scope.modules,
|
||||
@ -122,8 +121,7 @@ impl TypeKind {
|
||||
scope: &DebugScopeValue,
|
||||
debug_info: &DebugInformation,
|
||||
debug_types: &HashMap<TypeKind, DebugTypeValue>,
|
||||
type_values: &HashMap<CustomTypeKey, TypeValue>,
|
||||
types: &HashMap<TypeValue, TypeDefinition>,
|
||||
type_map: &HashMap<CustomTypeKey, TypeDefinition>,
|
||||
local_mod: SourceModuleId,
|
||||
tokens: &Vec<FullToken>,
|
||||
modules: &HashMap<SourceModuleId, ModuleCodegen>,
|
||||
@ -142,13 +140,12 @@ impl TypeKind {
|
||||
scope,
|
||||
debug_info,
|
||||
debug_types,
|
||||
type_values,
|
||||
types,
|
||||
type_map,
|
||||
local_mod,
|
||||
tokens,
|
||||
modules,
|
||||
),
|
||||
size_bits: self.size_of(),
|
||||
size_bits: self.size_of(type_map),
|
||||
})
|
||||
}
|
||||
TypeKind::Array(elem_ty, len) => {
|
||||
@ -156,21 +153,20 @@ impl TypeKind {
|
||||
scope,
|
||||
debug_info,
|
||||
debug_types,
|
||||
type_values,
|
||||
types,
|
||||
type_map,
|
||||
local_mod,
|
||||
tokens,
|
||||
modules,
|
||||
);
|
||||
DebugTypeData::Array(DebugArrayType {
|
||||
size_bits: self.size_of(),
|
||||
size_bits: self.size_of(type_map),
|
||||
align_bits: self.alignment(),
|
||||
element_type: elem_ty,
|
||||
length: *len,
|
||||
})
|
||||
}
|
||||
TypeKind::CustomType(key) => {
|
||||
let typedef = types.get(type_values.get(key).unwrap()).unwrap();
|
||||
let typedef = type_map.get(key).unwrap();
|
||||
match &typedef.kind {
|
||||
TypeDefinitionKind::Struct(struct_type) => {
|
||||
let mut fields = Vec::new();
|
||||
@ -186,21 +182,20 @@ impl TypeKind {
|
||||
name: field.0.clone(),
|
||||
scope: scope.clone(),
|
||||
pos: location.map(|l| l.pos),
|
||||
size_bits: field.1.size_of(),
|
||||
size_bits: field.1.size_of(type_map),
|
||||
offset: size_bits,
|
||||
flags: DwarfFlags,
|
||||
ty: field.1.get_debug_type_hard(
|
||||
scope,
|
||||
debug_info,
|
||||
debug_types,
|
||||
type_values,
|
||||
types,
|
||||
type_map,
|
||||
local_mod,
|
||||
tokens,
|
||||
modules,
|
||||
),
|
||||
});
|
||||
size_bits += field.1.size_of();
|
||||
size_bits += field.1.size_of(type_map);
|
||||
}
|
||||
{
|
||||
let location = if typedef.source_module != local_mod {
|
||||
@ -222,7 +217,7 @@ impl TypeKind {
|
||||
}
|
||||
_ => DebugTypeData::Basic(DebugBasicType {
|
||||
name,
|
||||
size_bits: self.size_of(),
|
||||
size_bits: self.size_of(type_map),
|
||||
encoding: match self {
|
||||
TypeKind::Bool => DwarfEncoding::Boolean,
|
||||
TypeKind::I8 => DwarfEncoding::SignedChar,
|
||||
|
@ -1,3 +1,5 @@
|
||||
use reid_lib::builder::TypeValue;
|
||||
|
||||
use crate::util::maybe;
|
||||
|
||||
use super::{typecheck::typerefs::TypeRefs, *};
|
||||
@ -57,7 +59,7 @@ impl TypeKind {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn size_of(&self) -> u64 {
|
||||
pub fn size_of(&self, map: &HashMap<CustomTypeKey, TypeDefinition>) -> u64 {
|
||||
match self {
|
||||
TypeKind::Bool => 1,
|
||||
TypeKind::I8 => 8,
|
||||
@ -72,8 +74,16 @@ impl TypeKind {
|
||||
TypeKind::U128 => 128,
|
||||
TypeKind::Void => 0,
|
||||
TypeKind::Char => 8,
|
||||
TypeKind::Array(type_kind, len) => type_kind.size_of() * (*len as u64),
|
||||
TypeKind::CustomType(..) => 32,
|
||||
TypeKind::Array(type_kind, len) => type_kind.size_of(map) * (*len as u64),
|
||||
TypeKind::CustomType(key) => match &map.get(key).unwrap().kind {
|
||||
TypeDefinitionKind::Struct(struct_type) => {
|
||||
let mut size = 0;
|
||||
for field in &struct_type.0 {
|
||||
size += field.1.size_of(map)
|
||||
}
|
||||
size
|
||||
}
|
||||
},
|
||||
TypeKind::CodegenPtr(_) => 64,
|
||||
TypeKind::Vague(_) => panic!("Tried to sizeof a vague type!"),
|
||||
TypeKind::Borrow(..) => 64,
|
||||
|
@ -118,10 +118,13 @@ impl mir::Expression {
|
||||
let mut globals = Vec::new();
|
||||
match &mut self.0 {
|
||||
mir::ExprKind::FunctionCall(function_call) => {
|
||||
for param in &mut function_call.parameters {
|
||||
globals.extend(param.gen_macros(data, state, map));
|
||||
}
|
||||
if function_call.is_macro {
|
||||
if let Some(existing_macro) = data.macros.get(&function_call.name) {
|
||||
let mut literals = Vec::new();
|
||||
for param in &function_call.parameters {
|
||||
for param in &mut function_call.parameters {
|
||||
match ¶m.0 {
|
||||
super::ExprKind::Literal(literal) => literals.push(literal.clone()),
|
||||
_ => state.note_errors(&vec![ErrorKind::InvalidMacroArgs], param.1),
|
||||
|
Loading…
Reference in New Issue
Block a user