mirror of
https://github.com/edg-l/edlang.git
synced 2024-11-23 08:28:24 +00:00
array codegen
This commit is contained in:
parent
82fbd609c1
commit
a6d4bee05a
|
@ -31,7 +31,7 @@ enum Commands {
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
name: Option<String>,
|
name: Option<String>,
|
||||||
|
|
||||||
/// Use a binary (application) template [default]
|
/// Use a binary (application) template \[default\]
|
||||||
#[arg(long, group = "binary", default_value_t = true)]
|
#[arg(long, group = "binary", default_value_t = true)]
|
||||||
bin: bool,
|
bin: bool,
|
||||||
|
|
||||||
|
|
|
@ -48,13 +48,20 @@ pub struct Ident {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
// T: A + B
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct Type {
|
pub enum Type {
|
||||||
pub name: Ident,
|
Basic {
|
||||||
pub generics: Vec<Type>,
|
name: Ident,
|
||||||
pub qualifiers: Vec<TypeQualifier>,
|
generics: Vec<Type>,
|
||||||
pub span: Span,
|
qualifiers: Vec<TypeQualifier>,
|
||||||
|
span: Span,
|
||||||
|
},
|
||||||
|
Array {
|
||||||
|
of: Box<Self>,
|
||||||
|
size: Option<u32>,
|
||||||
|
qualifiers: Vec<TypeQualifier>,
|
||||||
|
span: Span,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
@ -184,6 +191,7 @@ pub enum Expression {
|
||||||
Value(ValueExpr),
|
Value(ValueExpr),
|
||||||
FnCall(FnCallExpr),
|
FnCall(FnCallExpr),
|
||||||
StructInit(StructInitExpr),
|
StructInit(StructInitExpr),
|
||||||
|
ArrayInit(ArrayInitExpr),
|
||||||
Unary(UnaryOp, Box<Self>),
|
Unary(UnaryOp, Box<Self>),
|
||||||
Binary(Box<Self>, BinaryOp, Box<Self>),
|
Binary(Box<Self>, BinaryOp, Box<Self>),
|
||||||
Deref(Box<Self>, Span),
|
Deref(Box<Self>, Span),
|
||||||
|
@ -209,11 +217,18 @@ pub struct StructInitField {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct StructInitExpr {
|
pub struct StructInitExpr {
|
||||||
pub name: Type,
|
pub name: Ident,
|
||||||
|
pub generics: Vec<Type>,
|
||||||
pub fields: BTreeMap<Ident, StructInitField>,
|
pub fields: BTreeMap<Ident, StructInitField>,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct ArrayInitExpr {
|
||||||
|
pub data: Vec<Expression>,
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct FnCallExpr {
|
pub struct FnCallExpr {
|
||||||
pub name: Ident,
|
pub name: Ident,
|
||||||
|
|
|
@ -21,7 +21,7 @@ use inkwell::{
|
||||||
values::{BasicValue, BasicValueEnum, PointerValue},
|
values::{BasicValue, BasicValueEnum, PointerValue},
|
||||||
AddressSpace,
|
AddressSpace,
|
||||||
};
|
};
|
||||||
use ir::{LocalKind, ModuleBody, ProgramBody, TypeInfo, ValueTree};
|
use ir::{LocalKind, ModuleBody, Place, ProgramBody, TypeInfo, ValueTree};
|
||||||
use llvm_sys::debuginfo::LLVMDIFlagPublic;
|
use llvm_sys::debuginfo::LLVMDIFlagPublic;
|
||||||
use tracing::{info, trace};
|
use tracing::{info, trace};
|
||||||
|
|
||||||
|
@ -160,7 +160,11 @@ pub fn compile(session: &Session, program: &ProgramBody) -> Result<PathBuf, Box<
|
||||||
compile_module(&mut module_ctx, *module_id);
|
compile_module(&mut module_ctx, *module_id);
|
||||||
|
|
||||||
module_ctx.di_builder.finalize();
|
module_ctx.di_builder.finalize();
|
||||||
module_ctx.module.verify()?;
|
|
||||||
|
if let Err(e) = module_ctx.module.verify() {
|
||||||
|
eprintln!("{}", e.to_str()?);
|
||||||
|
Err(e)?;
|
||||||
|
}
|
||||||
|
|
||||||
// todo link modules together
|
// todo link modules together
|
||||||
llvm_modules.push_back(module_ctx.module);
|
llvm_modules.push_back(module_ctx.module);
|
||||||
|
@ -458,7 +462,44 @@ fn compile_fn(ctx: &ModuleCompileCtx, fn_id: DefId) -> Result<(), BuilderError>
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ir::PlaceElem::Index { .. } => todo!(),
|
ir::PlaceElem::Index { local } => {
|
||||||
|
let value = compile_load_place(
|
||||||
|
ctx,
|
||||||
|
fn_id,
|
||||||
|
&locals,
|
||||||
|
&Place {
|
||||||
|
local: *local,
|
||||||
|
projection: Default::default(),
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
ptr = unsafe {
|
||||||
|
ctx.builder.build_in_bounds_gep(
|
||||||
|
ptr.get_type(),
|
||||||
|
ptr,
|
||||||
|
&[
|
||||||
|
ctx.ctx.context.i32_type().const_int(0, false),
|
||||||
|
value.0.into_int_value(),
|
||||||
|
],
|
||||||
|
"constindex",
|
||||||
|
)?
|
||||||
|
};
|
||||||
|
}
|
||||||
|
ir::PlaceElem::ConstIndex { index } => {
|
||||||
|
ptr = unsafe {
|
||||||
|
ctx.builder.build_in_bounds_gep(
|
||||||
|
ptr.get_type(),
|
||||||
|
ptr,
|
||||||
|
&[ctx
|
||||||
|
.ctx
|
||||||
|
.context
|
||||||
|
.i32_type()
|
||||||
|
.const_int((*index) as u64, false)],
|
||||||
|
"constindex",
|
||||||
|
)?
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1034,6 +1075,7 @@ fn compile_rvalue<'ctx>(
|
||||||
}
|
}
|
||||||
ir::PlaceElem::Field { .. } => todo!(),
|
ir::PlaceElem::Field { .. } => todo!(),
|
||||||
ir::PlaceElem::Index { .. } => todo!(),
|
ir::PlaceElem::Index { .. } => todo!(),
|
||||||
|
ir::PlaceElem::ConstIndex { .. } => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1224,6 +1266,7 @@ fn compile_load_place<'ctx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ir::PlaceElem::Index { .. } => todo!(),
|
ir::PlaceElem::Index { .. } => todo!(),
|
||||||
|
ir::PlaceElem::ConstIndex { .. } => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1351,7 +1394,7 @@ fn compile_basic_type<'ctx>(
|
||||||
match &ty.kind {
|
match &ty.kind {
|
||||||
ir::TypeKind::Unit => todo!(),
|
ir::TypeKind::Unit => todo!(),
|
||||||
ir::TypeKind::Bool => ctx.ctx.context.bool_type().as_basic_type_enum(),
|
ir::TypeKind::Bool => ctx.ctx.context.bool_type().as_basic_type_enum(),
|
||||||
ir::TypeKind::Char => ctx.ctx.context.i32_type().as_basic_type_enum(),
|
ir::TypeKind::Char => ctx.ctx.context.i8_type().as_basic_type_enum(),
|
||||||
ir::TypeKind::Int(ty) => match ty {
|
ir::TypeKind::Int(ty) => match ty {
|
||||||
ir::IntTy::I128 => ctx.ctx.context.i128_type().as_basic_type_enum(),
|
ir::IntTy::I128 => ctx.ctx.context.i128_type().as_basic_type_enum(),
|
||||||
ir::IntTy::I64 => ctx.ctx.context.i64_type().as_basic_type_enum(),
|
ir::IntTy::I64 => ctx.ctx.context.i64_type().as_basic_type_enum(),
|
||||||
|
@ -1437,6 +1480,26 @@ fn compile_basic_type<'ctx>(
|
||||||
.struct_type(&fields, false)
|
.struct_type(&fields, false)
|
||||||
.as_basic_type_enum()
|
.as_basic_type_enum()
|
||||||
}
|
}
|
||||||
|
ir::TypeKind::Slice(inner, size) => {
|
||||||
|
let inner = compile_basic_type(ctx, inner);
|
||||||
|
if let Some(size) = size {
|
||||||
|
inner.array_type(*size).as_basic_type_enum()
|
||||||
|
} else {
|
||||||
|
ctx.ctx
|
||||||
|
.context
|
||||||
|
.struct_type(
|
||||||
|
&[
|
||||||
|
ctx.ctx
|
||||||
|
.context
|
||||||
|
.ptr_type(AddressSpace::default())
|
||||||
|
.as_basic_type_enum(),
|
||||||
|
ctx.ctx.context.i64_type().as_basic_type_enum(),
|
||||||
|
],
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.as_basic_type_enum()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1631,5 +1694,52 @@ fn compile_debug_type<'ctx>(ctx: &ModuleCompileCtx<'ctx, '_>, ty: &ir::TypeInfo)
|
||||||
)
|
)
|
||||||
.as_type()
|
.as_type()
|
||||||
}
|
}
|
||||||
|
ir::TypeKind::Slice(inner, size) => {
|
||||||
|
let real_ty = compile_basic_type(ctx, ty);
|
||||||
|
let inner_type = compile_debug_type(ctx, inner);
|
||||||
|
|
||||||
|
if let Some(size) = size {
|
||||||
|
ctx.di_builder
|
||||||
|
.create_array_type(
|
||||||
|
inner_type,
|
||||||
|
ctx.target_data.get_abi_size(&real_ty),
|
||||||
|
ctx.target_data.get_abi_alignment(&real_ty),
|
||||||
|
#[allow(clippy::single_range_in_vec_init)] // false positive
|
||||||
|
&[0..((*size) as i64)],
|
||||||
|
)
|
||||||
|
.as_type()
|
||||||
|
} else {
|
||||||
|
ctx.di_builder
|
||||||
|
.create_struct_type(
|
||||||
|
ctx.di_namespace,
|
||||||
|
"str",
|
||||||
|
ctx.di_unit.get_file(),
|
||||||
|
0,
|
||||||
|
ctx.target_data.get_bit_size(&real_ty),
|
||||||
|
ctx.target_data.get_abi_alignment(&real_ty),
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
&[
|
||||||
|
ctx.di_builder
|
||||||
|
.create_pointer_type(
|
||||||
|
name,
|
||||||
|
inner_type,
|
||||||
|
(ctx.target_data.get_pointer_byte_size(None) * 8).into(),
|
||||||
|
ctx.target_data.get_pointer_byte_size(None),
|
||||||
|
AddressSpace::default(),
|
||||||
|
)
|
||||||
|
.as_type(),
|
||||||
|
ctx.di_builder
|
||||||
|
.create_basic_type(name, 64, 0x7, LLVMDIFlagPublic)
|
||||||
|
.unwrap()
|
||||||
|
.as_type(),
|
||||||
|
],
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
"str",
|
||||||
|
)
|
||||||
|
.as_type()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,6 @@ pub fn link_binary(objects: &[PathBuf], output_filename: &Path) -> std::io::Resu
|
||||||
let mut args = vec![
|
let mut args = vec![
|
||||||
"-L/usr/local/lib",
|
"-L/usr/local/lib",
|
||||||
"-L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib",
|
"-L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib",
|
||||||
&input_path.display().to_string(),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
args.extend(objects.iter().map(|x| x.as_str()));
|
args.extend(objects.iter().map(|x| x.as_str()));
|
||||||
|
|
|
@ -262,6 +262,7 @@ pub enum TypeKind {
|
||||||
Ref(bool, Box<TypeInfo>),
|
Ref(bool, Box<TypeInfo>),
|
||||||
// name for print purposes
|
// name for print purposes
|
||||||
Struct(DefId, String), // todo, add generics
|
Struct(DefId, String), // todo, add generics
|
||||||
|
Slice(Box<TypeInfo>, Option<u32>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeKind {
|
impl TypeKind {
|
||||||
|
@ -308,6 +309,7 @@ impl TypeKind {
|
||||||
TypeKind::Ref(_, inner) => inner.kind.get_falsy_value(),
|
TypeKind::Ref(_, inner) => inner.kind.get_falsy_value(),
|
||||||
TypeKind::Struct(_, _name) => todo!(),
|
TypeKind::Struct(_, _name) => todo!(),
|
||||||
TypeKind::Str => todo!(),
|
TypeKind::Str => todo!(),
|
||||||
|
TypeKind::Slice(_, _) => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -351,6 +353,15 @@ impl fmt::Display for TypeKind {
|
||||||
write!(f, "&{word} {}", inner.kind)
|
write!(f, "&{word} {}", inner.kind)
|
||||||
}
|
}
|
||||||
TypeKind::Struct(_, name) => write!(f, "{}", name),
|
TypeKind::Struct(_, name) => write!(f, "{}", name),
|
||||||
|
TypeKind::Slice(inner, size) => {
|
||||||
|
let size = if let Some(size) = size {
|
||||||
|
format!("; {size}")
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
};
|
||||||
|
|
||||||
|
write!(f, "[{}{size}]", inner.kind)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -477,6 +488,7 @@ pub enum PlaceElem {
|
||||||
Deref,
|
Deref,
|
||||||
Field { field_idx: usize },
|
Field { field_idx: usize },
|
||||||
Index { local: usize },
|
Index { local: usize },
|
||||||
|
ConstIndex { index: usize },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeKind {
|
impl TypeKind {
|
||||||
|
|
|
@ -645,15 +645,16 @@ fn find_expr_type(builder: &mut BodyBuilder, info: &ast::Expression) -> Option<T
|
||||||
.get_module_body()
|
.get_module_body()
|
||||||
.symbols
|
.symbols
|
||||||
.structs
|
.structs
|
||||||
.get(&info.name.name.name)
|
.get(&info.name.name)
|
||||||
.expect("struct not found");
|
.expect("struct not found");
|
||||||
ir::TypeKind::Struct(id, info.name.name.name.clone())
|
ir::TypeKind::Struct(id, info.name.name.clone())
|
||||||
}
|
}
|
||||||
ast::Expression::Cast(_, _new_ty, _) => {
|
ast::Expression::Cast(_, _new_ty, _) => {
|
||||||
// checks?
|
// checks?
|
||||||
|
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
ast::Expression::ArrayInit(_) => todo!(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -762,7 +763,7 @@ fn lower_expr(
|
||||||
.get_module_body()
|
.get_module_body()
|
||||||
.symbols
|
.symbols
|
||||||
.structs
|
.structs
|
||||||
.get(&info.name.name.name)
|
.get(&info.name.name)
|
||||||
.expect("struct not found");
|
.expect("struct not found");
|
||||||
let struct_body = builder.ctx.body.structs.get(&id).unwrap().clone();
|
let struct_body = builder.ctx.body.structs.get(&id).unwrap().clone();
|
||||||
let ty = TypeKind::Struct(id, struct_body.name.clone());
|
let ty = TypeKind::Struct(id, struct_body.name.clone());
|
||||||
|
@ -832,6 +833,45 @@ fn lower_expr(
|
||||||
|
|
||||||
(rvalue, kind, *span)
|
(rvalue, kind, *span)
|
||||||
}
|
}
|
||||||
|
ast::Expression::ArrayInit(info) => {
|
||||||
|
let ty = if let Some(type_hint) = type_hint {
|
||||||
|
type_hint.clone()
|
||||||
|
} else {
|
||||||
|
todo!()
|
||||||
|
};
|
||||||
|
|
||||||
|
let inner = if let TypeKind::Slice(inner, _) = &ty.kind {
|
||||||
|
inner
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
let local = builder.add_temp_local(ty.kind.clone());
|
||||||
|
builder.statements.push(Statement {
|
||||||
|
span: None,
|
||||||
|
kind: StatementKind::StorageLive(local),
|
||||||
|
});
|
||||||
|
let place = Place {
|
||||||
|
local,
|
||||||
|
projection: Default::default(),
|
||||||
|
};
|
||||||
|
for (i, x) in info.data.iter().enumerate() {
|
||||||
|
let (value, _ty, span) = lower_expr(builder, x, Some(inner))?;
|
||||||
|
let mut place = place.clone();
|
||||||
|
place.projection.push(PlaceElem::ConstIndex { index: i });
|
||||||
|
|
||||||
|
builder.statements.push(Statement {
|
||||||
|
span: Some(span),
|
||||||
|
kind: StatementKind::Assign(place, value),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
(
|
||||||
|
RValue::Use(Operand::Move(place), info.span),
|
||||||
|
ty.kind,
|
||||||
|
info.span,
|
||||||
|
)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1096,9 +1136,7 @@ fn lower_value(
|
||||||
span: None,
|
span: None,
|
||||||
kind: ir::TypeKind::Char,
|
kind: ir::TypeKind::Char,
|
||||||
},
|
},
|
||||||
kind: ir::ConstKind::Value(ir::ValueTree::Leaf(ir::ConstValue::U32(
|
kind: ir::ConstKind::Value(ir::ValueTree::Leaf(ir::ConstValue::U8((*value) as u8))),
|
||||||
(*value) as u32,
|
|
||||||
))),
|
|
||||||
}),
|
}),
|
||||||
TypeKind::Char,
|
TypeKind::Char,
|
||||||
*span,
|
*span,
|
||||||
|
@ -1475,82 +1513,106 @@ pub fn lower_type(
|
||||||
t: &ast::Type,
|
t: &ast::Type,
|
||||||
module_id: DefId,
|
module_id: DefId,
|
||||||
) -> Result<ir::TypeInfo, LoweringError> {
|
) -> Result<ir::TypeInfo, LoweringError> {
|
||||||
let mut ty = match t.name.name.as_str() {
|
let (mut ty, qualifiers) = match t {
|
||||||
"()" => ir::TypeInfo {
|
ast::Type::Basic {
|
||||||
span: Some(t.span),
|
name,
|
||||||
kind: ir::TypeKind::Unit,
|
generics: _,
|
||||||
},
|
qualifiers,
|
||||||
"u8" => ir::TypeInfo {
|
span,
|
||||||
span: Some(t.span),
|
} => {
|
||||||
kind: ir::TypeKind::Uint(ir::UintTy::U8),
|
let ty = match name.name.as_str() {
|
||||||
},
|
"()" => ir::TypeInfo {
|
||||||
"u16" => ir::TypeInfo {
|
span: Some(*span),
|
||||||
span: Some(t.span),
|
kind: ir::TypeKind::Unit,
|
||||||
kind: ir::TypeKind::Uint(ir::UintTy::U16),
|
},
|
||||||
},
|
"u8" => ir::TypeInfo {
|
||||||
"u32" => ir::TypeInfo {
|
span: Some(*span),
|
||||||
span: Some(t.span),
|
kind: ir::TypeKind::Uint(ir::UintTy::U8),
|
||||||
kind: ir::TypeKind::Uint(ir::UintTy::U32),
|
},
|
||||||
},
|
"u16" => ir::TypeInfo {
|
||||||
"u64" => ir::TypeInfo {
|
span: Some(*span),
|
||||||
span: Some(t.span),
|
kind: ir::TypeKind::Uint(ir::UintTy::U16),
|
||||||
kind: ir::TypeKind::Uint(ir::UintTy::U64),
|
},
|
||||||
},
|
"u32" => ir::TypeInfo {
|
||||||
"u128" => ir::TypeInfo {
|
span: Some(*span),
|
||||||
span: Some(t.span),
|
kind: ir::TypeKind::Uint(ir::UintTy::U32),
|
||||||
kind: ir::TypeKind::Uint(ir::UintTy::U128),
|
},
|
||||||
},
|
"u64" => ir::TypeInfo {
|
||||||
"i8" => ir::TypeInfo {
|
span: Some(*span),
|
||||||
span: Some(t.span),
|
kind: ir::TypeKind::Uint(ir::UintTy::U64),
|
||||||
kind: ir::TypeKind::Int(ir::IntTy::I8),
|
},
|
||||||
},
|
"u128" => ir::TypeInfo {
|
||||||
"i16" => ir::TypeInfo {
|
span: Some(*span),
|
||||||
span: Some(t.span),
|
kind: ir::TypeKind::Uint(ir::UintTy::U128),
|
||||||
kind: ir::TypeKind::Int(ir::IntTy::I16),
|
},
|
||||||
},
|
"i8" => ir::TypeInfo {
|
||||||
"i32" => ir::TypeInfo {
|
span: Some(*span),
|
||||||
span: Some(t.span),
|
kind: ir::TypeKind::Int(ir::IntTy::I8),
|
||||||
kind: ir::TypeKind::Int(ir::IntTy::I32),
|
},
|
||||||
},
|
"i16" => ir::TypeInfo {
|
||||||
"i64" => ir::TypeInfo {
|
span: Some(*span),
|
||||||
span: Some(t.span),
|
kind: ir::TypeKind::Int(ir::IntTy::I16),
|
||||||
kind: ir::TypeKind::Int(ir::IntTy::I64),
|
},
|
||||||
},
|
"i32" => ir::TypeInfo {
|
||||||
"i128" => ir::TypeInfo {
|
span: Some(*span),
|
||||||
span: Some(t.span),
|
kind: ir::TypeKind::Int(ir::IntTy::I32),
|
||||||
kind: ir::TypeKind::Int(ir::IntTy::I128),
|
},
|
||||||
},
|
"i64" => ir::TypeInfo {
|
||||||
"char" => ir::TypeInfo {
|
span: Some(*span),
|
||||||
span: Some(t.span),
|
kind: ir::TypeKind::Int(ir::IntTy::I64),
|
||||||
kind: ir::TypeKind::Char,
|
},
|
||||||
},
|
"i128" => ir::TypeInfo {
|
||||||
"bool" => ir::TypeInfo {
|
span: Some(*span),
|
||||||
span: Some(t.span),
|
kind: ir::TypeKind::Int(ir::IntTy::I128),
|
||||||
kind: ir::TypeKind::Bool,
|
},
|
||||||
},
|
"char" => ir::TypeInfo {
|
||||||
"str" => ir::TypeInfo {
|
span: Some(*span),
|
||||||
span: Some(t.span),
|
kind: ir::TypeKind::Char,
|
||||||
kind: ir::TypeKind::Str,
|
},
|
||||||
},
|
"bool" => ir::TypeInfo {
|
||||||
other => {
|
span: Some(*span),
|
||||||
let module = ctx.body.modules.get(&module_id).expect("module not found");
|
kind: ir::TypeKind::Bool,
|
||||||
if let Some(struct_id) = module.symbols.structs.get(other) {
|
},
|
||||||
let struct_body = ctx.body.structs.get(struct_id).unwrap();
|
"str" => ir::TypeInfo {
|
||||||
ir::TypeInfo {
|
span: Some(*span),
|
||||||
span: Some(struct_body.span),
|
kind: ir::TypeKind::Str,
|
||||||
kind: TypeKind::Struct(*struct_id, struct_body.name.clone()),
|
},
|
||||||
|
other => {
|
||||||
|
let module = ctx.body.modules.get(&module_id).expect("module not found");
|
||||||
|
if let Some(struct_id) = module.symbols.structs.get(other) {
|
||||||
|
let struct_body = ctx.body.structs.get(struct_id).unwrap();
|
||||||
|
ir::TypeInfo {
|
||||||
|
span: Some(struct_body.span),
|
||||||
|
kind: TypeKind::Struct(*struct_id, struct_body.name.clone()),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(LoweringError::UnrecognizedType {
|
||||||
|
span: name.span,
|
||||||
|
name: name.name.clone(),
|
||||||
|
file_id: module.file_id,
|
||||||
|
})?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
};
|
||||||
Err(LoweringError::UnrecognizedType {
|
(ty, qualifiers)
|
||||||
span: t.name.span,
|
}
|
||||||
name: t.name.name.clone(),
|
ast::Type::Array {
|
||||||
file_id: module.file_id,
|
of,
|
||||||
})?
|
size,
|
||||||
}
|
qualifiers,
|
||||||
|
span,
|
||||||
|
} => {
|
||||||
|
let ty = ir::TypeInfo {
|
||||||
|
span: Some(*span),
|
||||||
|
kind: ir::TypeKind::Slice(Box::new(lower_type(ctx, of, module_id)?), *size),
|
||||||
|
};
|
||||||
|
(ty, qualifiers)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for qualifier in t.qualifiers.iter().rev() {
|
let span = ty.span;
|
||||||
|
|
||||||
|
for qualifier in qualifiers.iter().rev() {
|
||||||
let kind = match qualifier {
|
let kind = match qualifier {
|
||||||
ast::TypeQualifier::Ref => TypeKind::Ref(false, Box::new(ty)),
|
ast::TypeQualifier::Ref => TypeKind::Ref(false, Box::new(ty)),
|
||||||
ast::TypeQualifier::RefMut => TypeKind::Ref(true, Box::new(ty)),
|
ast::TypeQualifier::RefMut => TypeKind::Ref(true, Box::new(ty)),
|
||||||
|
@ -1558,10 +1620,7 @@ pub fn lower_type(
|
||||||
ast::TypeQualifier::PtrMut => TypeKind::Ptr(true, Box::new(ty)),
|
ast::TypeQualifier::PtrMut => TypeKind::Ptr(true, Box::new(ty)),
|
||||||
};
|
};
|
||||||
|
|
||||||
ty = TypeInfo {
|
ty = TypeInfo { span, kind };
|
||||||
span: Some(t.span),
|
|
||||||
kind,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ty)
|
Ok(ty)
|
||||||
|
|
|
@ -151,34 +151,36 @@ pub(crate) TypeQualifier: ast::TypeQualifier = {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) Type: ast::Type = {
|
pub(crate) Type: ast::Type = {
|
||||||
<lo:@L> <qualifiers:TypeQualifier*> <name:Ident> <hi:@R> => ast::Type {
|
<lo:@L> <qualifiers:TypeQualifier*> <name:Ident> <hi:@R> => ast::Type::Basic {
|
||||||
name,
|
name,
|
||||||
generics: vec![],
|
generics: vec![],
|
||||||
qualifiers,
|
qualifiers,
|
||||||
span: ast::Span::new(lo, hi),
|
span: ast::Span::new(lo, hi),
|
||||||
},
|
},
|
||||||
<lo:@L> <qualifiers:TypeQualifier*> <name:Ident> "<" <generics:Comma<Type>> ">" <hi:@R> => ast::Type {
|
<lo:@L> <qualifiers:TypeQualifier*> <name:Ident> "<" <generics:Comma<Type>> ">" <hi:@R> => ast::Type::Basic {
|
||||||
name,
|
name,
|
||||||
generics,
|
generics,
|
||||||
qualifiers,
|
qualifiers,
|
||||||
span: ast::Span::new(lo, hi),
|
span: ast::Span::new(lo, hi),
|
||||||
},
|
},
|
||||||
|
<lo:@L> <qualifiers:TypeQualifier*> "[" <of:Type> "]" <hi:@R> => ast::Type::Array {
|
||||||
|
of: Box::new(of),
|
||||||
|
size: None,
|
||||||
|
qualifiers,
|
||||||
|
span: ast::Span::new(lo, hi),
|
||||||
|
},
|
||||||
|
<lo:@L> <qualifiers:TypeQualifier*> "[" <of:Type> ";" <size:"integer"> "]" <hi:@R> => ast::Type::Array {
|
||||||
|
of: Box::new(of),
|
||||||
|
size: Some(size.try_into().unwrap()),
|
||||||
|
qualifiers,
|
||||||
|
span: ast::Span::new(lo, hi),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For things like A::<T> { a: value }
|
/// For things like A::<T> { a: value }
|
||||||
pub(crate) IdentWithOptionalType: ast::Type = {
|
pub(crate) IdentWithGenerics: (ast::Ident, Vec<ast::Type>) = {
|
||||||
<lo:@L> <name:Ident> <hi:@R> => ast::Type {
|
<name:Ident> => (name, vec![]),
|
||||||
name,
|
<lo:@L> <name:Ident> "::" "<" <generics:Comma<Type>> ">" <hi:@R> => (name, generics),
|
||||||
generics: vec![],
|
|
||||||
qualifiers: vec![],
|
|
||||||
span: ast::Span::new(lo, hi),
|
|
||||||
},
|
|
||||||
<lo:@L> <name:Ident> "::" "<" <generics:Comma<Type>> ">" <hi:@R> => ast::Type {
|
|
||||||
name,
|
|
||||||
generics,
|
|
||||||
qualifiers: vec![],
|
|
||||||
span: ast::Span::new(lo, hi),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) PathExpr: ast::PathExpr = {
|
pub(crate) PathExpr: ast::PathExpr = {
|
||||||
|
@ -351,6 +353,7 @@ pub(crate) Expression: ast::Expression = {
|
||||||
#[precedence(level="5")] #[assoc(side="left")]
|
#[precedence(level="5")] #[assoc(side="left")]
|
||||||
<lo:@L> <a:Expression> "as" <b: Type> <hi:@R> => ast::Expression::Cast(Box::new(a), b, ast::Span::new(lo, hi)),
|
<lo:@L> <a:Expression> "as" <b: Type> <hi:@R> => ast::Expression::Cast(Box::new(a), b, ast::Span::new(lo, hi)),
|
||||||
"(" <StructInitExpr> ")" => ast::Expression::StructInit(<>),
|
"(" <StructInitExpr> ")" => ast::Expression::StructInit(<>),
|
||||||
|
<ArrayInitExpr> => ast::Expression::ArrayInit(<>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub BinaryFirstLvlOp: ast::BinaryOp = {
|
pub BinaryFirstLvlOp: ast::BinaryOp = {
|
||||||
|
@ -412,13 +415,21 @@ pub(crate) StructInitField: (ast::Ident, ast::StructInitField) = {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) StructInitExpr: ast::StructInitExpr = {
|
pub(crate) StructInitExpr: ast::StructInitExpr = {
|
||||||
<lo:@L> <name:IdentWithOptionalType> "{" <fields:Comma<StructInitField>> "}" <hi:@R> => ast::StructInitExpr {
|
<lo:@L> <name:IdentWithGenerics> "{" <fields:Comma<StructInitField>> "}" <hi:@R> => ast::StructInitExpr {
|
||||||
name,
|
name: name.0,
|
||||||
|
generics: name.1,
|
||||||
fields: fields.into_iter().collect(),
|
fields: fields.into_iter().collect(),
|
||||||
span: ast::Span::new(lo, hi),
|
span: ast::Span::new(lo, hi),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) ArrayInitExpr: ast::ArrayInitExpr = {
|
||||||
|
<lo:@L> "[" <data:Comma<Expression>> "]" <hi:@R> => ast::ArrayInitExpr {
|
||||||
|
data: data.into_iter().collect(),
|
||||||
|
span: ast::Span::new(lo, hi),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) FnParam: ast::FnParam = {
|
pub(crate) FnParam: ast::FnParam = {
|
||||||
<lo:@L> <name:Ident> ":" <arg_type:Type> <hi:@R> => ast::FnParam {
|
<lo:@L> <name:Ident> ":" <arg_type:Type> <hi:@R> => ast::FnParam {
|
||||||
name,
|
name,
|
||||||
|
|
Loading…
Reference in a new issue