Codegen strings

This commit is contained in:
Sofia 2025-07-14 17:52:47 +03:00
parent 73a3b15fb6
commit 83475b144c
7 changed files with 37 additions and 15 deletions

View File

@ -369,6 +369,7 @@ impl ConstValue {
ConstValue::U32(_) => U32, ConstValue::U32(_) => U32,
ConstValue::U64(_) => U64, ConstValue::U64(_) => U64,
ConstValue::U128(_) => U128, ConstValue::U128(_) => U128,
ConstValue::String(val) => String(val.len() as u32),
ConstValue::Bool(_) => Bool, ConstValue::Bool(_) => Bool,
} }
} }
@ -389,6 +390,7 @@ impl Type {
Type::U128 => true, Type::U128 => true,
Type::Bool => true, Type::Bool => true,
Type::Void => false, Type::Void => false,
Type::String(_) => false,
Type::Ptr(_) => false, Type::Ptr(_) => false,
} }
} }
@ -407,6 +409,7 @@ impl Type {
Type::U128 => false, Type::U128 => false,
Type::Bool => false, Type::Bool => false,
Type::Void => false, Type::Void => false,
Type::String(_) => false,
Type::Ptr(_) => false, Type::Ptr(_) => false,
} }
} }

View File

@ -264,7 +264,7 @@ impl InstructionHolder {
use super::Instr::*; use super::Instr::*;
match &self.data.kind { match &self.data.kind {
Param(nth) => LLVMGetParam(function.value_ref, *nth as u32), Param(nth) => LLVMGetParam(function.value_ref, *nth as u32),
Constant(val) => val.as_llvm(module.context_ref), Constant(val) => val.as_llvm(module.context_ref, module.builder_ref),
Add(lhs, rhs) => { Add(lhs, rhs) => {
let lhs_val = module.values.get(&lhs).unwrap().value_ref; let lhs_val = module.values.get(&lhs).unwrap().value_ref;
let rhs_val = module.values.get(&rhs).unwrap().value_ref; let rhs_val = module.values.get(&rhs).unwrap().value_ref;
@ -350,7 +350,8 @@ impl InstructionHolder {
module.values.get(&ptr).unwrap().value_ref, module.values.get(&ptr).unwrap().value_ref,
), ),
ArrayAlloca(ty, len) => { ArrayAlloca(ty, len) => {
let array_len = ConstValue::U16(*len as u16).as_llvm(module.context_ref); let array_len = ConstValue::U16(*len as u16)
.as_llvm(module.context_ref, module.builder_ref);
LLVMBuildArrayAlloca( LLVMBuildArrayAlloca(
module.builder_ref, module.builder_ref,
ty.as_llvm(module.context_ref), ty.as_llvm(module.context_ref),
@ -364,7 +365,9 @@ impl InstructionHolder {
let mut indices: Vec<_> = indices let mut indices: Vec<_> = indices
.iter() .iter()
.map(|idx| ConstValue::U32(*idx).as_llvm(module.context_ref)) .map(|idx| {
ConstValue::U32(*idx).as_llvm(module.context_ref, module.builder_ref)
})
.collect(); .collect();
LLVMBuildGEP2( LLVMBuildGEP2(
@ -439,7 +442,7 @@ impl CmpPredicate {
} }
impl ConstValue { impl ConstValue {
fn as_llvm(&self, context: LLVMContextRef) -> LLVMValueRef { fn as_llvm(&self, context: LLVMContextRef, builder: LLVMBuilderRef) -> LLVMValueRef {
unsafe { unsafe {
let t = self.get_type().as_llvm(context); let t = self.get_type().as_llvm(context);
match self { match self {
@ -454,6 +457,9 @@ impl ConstValue {
ConstValue::U32(val) => LLVMConstInt(t, *val as u64, 1), ConstValue::U32(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::U64(val) => LLVMConstInt(t, *val as u64, 1), ConstValue::U64(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::U128(val) => LLVMConstInt(t, *val as u64, 1), ConstValue::U128(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::String(val) => {
LLVMBuildGlobalString(builder, into_cstring(val).as_ptr(), c"string".as_ptr())
}
} }
} }
} }
@ -472,6 +478,7 @@ impl Type {
Bool => LLVMInt1TypeInContext(context), Bool => LLVMInt1TypeInContext(context),
Void => LLVMVoidType(), Void => LLVMVoidType(),
Ptr(ty) => LLVMPointerType(ty.as_llvm(context), 0), Ptr(ty) => LLVMPointerType(ty.as_llvm(context), 0),
String(length) => LLVMArrayType(LLVMInt8TypeInContext(context), *length),
} }
} }
} }

View File

@ -200,6 +200,7 @@ pub enum Type {
U128, U128,
Bool, Bool,
Void, Void,
String(u32),
Ptr(Box<Type>), Ptr(Box<Type>),
} }
@ -216,6 +217,7 @@ pub enum ConstValue {
U64(u64), U64(u64),
U128(u128), U128(u128),
Bool(bool), Bool(bool),
String(String),
} }
#[derive(Clone, Hash)] #[derive(Clone, Hash)]

View File

@ -201,10 +201,10 @@ impl ast::BinaryOperator {
impl ast::Literal { impl ast::Literal {
fn mir(&self) -> mir::Literal { fn mir(&self) -> mir::Literal {
match *self { match &self {
ast::Literal::Number(v) => mir::Literal::Vague(mir::VagueLiteral::Number(v)), ast::Literal::Number(v) => mir::Literal::Vague(mir::VagueLiteral::Number(*v)),
ast::Literal::Bool(v) => mir::Literal::Bool(v), ast::Literal::Bool(v) => mir::Literal::Bool(*v),
ast::Literal::String(_) => todo!("process string literal"), ast::Literal::String(val) => mir::Literal::String(val.clone()),
} }
} }
} }

View File

@ -475,7 +475,7 @@ impl mir::Literal {
mir::Literal::U64(val) => ConstValue::U64(val), mir::Literal::U64(val) => ConstValue::U64(val),
mir::Literal::U128(val) => ConstValue::U128(val), mir::Literal::U128(val) => ConstValue::U128(val),
mir::Literal::Bool(val) => ConstValue::Bool(val), mir::Literal::Bool(val) => ConstValue::Bool(val),
mir::Literal::String(_) => todo!("impl string const codegen"), mir::Literal::String(val) => ConstValue::String(val.clone()),
mir::Literal::Vague(_) => panic!("Got vague literal!"), mir::Literal::Vague(_) => panic!("Got vague literal!"),
}) })
} }
@ -495,9 +495,9 @@ impl TypeKind {
TypeKind::U64 => Type::U64, TypeKind::U64 => Type::U64,
TypeKind::U128 => Type::U128, TypeKind::U128 => Type::U128,
TypeKind::Bool => Type::Bool, TypeKind::Bool => Type::Bool,
TypeKind::String => todo!("impl string type"), TypeKind::String(length) => Type::String(*length as u32),
TypeKind::Array(elem_t, _) => Type::Ptr(Box::new(elem_t.get_type())), TypeKind::Array(elem_t, _) => Type::Ptr(Box::new(elem_t.get_type())),
TypeKind::Void => panic!("Void not a supported type"), TypeKind::Void => Type::Void,
TypeKind::Vague(_) => panic!("Tried to compile a vague type!"), TypeKind::Vague(_) => panic!("Tried to compile a vague type!"),
} }
} }

View File

@ -59,7 +59,7 @@ pub enum TypeKind {
#[error("void")] #[error("void")]
Void, Void,
#[error("string")] #[error("string")]
String, String(usize),
#[error("[{0}; {1}]")] #[error("[{0}; {1}]")]
Array(Box<TypeKind>, u64), Array(Box<TypeKind>, u64),
#[error(transparent)] #[error(transparent)]
@ -102,7 +102,7 @@ impl TypeKind {
TypeKind::U32 => false, TypeKind::U32 => false,
TypeKind::U64 => false, TypeKind::U64 => false,
TypeKind::U128 => false, TypeKind::U128 => false,
TypeKind::String => false, TypeKind::String(_) => false,
TypeKind::Array(_, _) => false, TypeKind::Array(_, _) => false,
} }
} }
@ -123,7 +123,7 @@ impl TypeKind {
Bool => true, Bool => true,
Vague(_) => false, Vague(_) => false,
Void => false, Void => false,
TypeKind::String => false, TypeKind::String(_) => false,
Array(_, _) => false, Array(_, _) => false,
} }
} }
@ -165,7 +165,7 @@ impl Literal {
Literal::U64(_) => TypeKind::U64, Literal::U64(_) => TypeKind::U64,
Literal::U128(_) => TypeKind::U128, Literal::U128(_) => TypeKind::U128,
Literal::Bool(_) => TypeKind::Bool, Literal::Bool(_) => TypeKind::Bool,
Literal::String(_) => TypeKind::String, Literal::String(val) => TypeKind::String(val.len()),
Literal::Vague(VagueLiteral::Number(_)) => TypeKind::Vague(VagueType::Number), Literal::Vague(VagueLiteral::Number(_)) => TypeKind::Vague(VagueType::Number),
} }
} }

View File

@ -532,6 +532,16 @@ impl Literal {
(L::U64(_), TypeKind::U64) => self, (L::U64(_), TypeKind::U64) => self,
(L::U128(_), TypeKind::U128) => self, (L::U128(_), TypeKind::U128) => self,
(L::Bool(_), TypeKind::Bool) => self, (L::Bool(_), TypeKind::Bool) => self,
(L::String(val), TypeKind::String(len)) => {
if val.len() == *len {
L::String(val)
} else {
Err(ErrorKind::LiteralIncompatible(
L::String(val),
TypeKind::String(*len),
))?
}
}
// TODO make sure that v is actually able to fit in the // TODO make sure that v is actually able to fit in the
// requested type // requested type
(L::Vague(VagueL::Number(v)), TypeKind::I8) => L::I8(v as i8), (L::Vague(VagueL::Number(v)), TypeKind::I8) => L::I8(v as i8),