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

View File

@ -264,7 +264,7 @@ impl InstructionHolder {
use super::Instr::*;
match &self.data.kind {
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) => {
let lhs_val = module.values.get(&lhs).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,
),
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(
module.builder_ref,
ty.as_llvm(module.context_ref),
@ -364,7 +365,9 @@ impl InstructionHolder {
let mut indices: Vec<_> = indices
.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();
LLVMBuildGEP2(
@ -439,7 +442,7 @@ impl CmpPredicate {
}
impl ConstValue {
fn as_llvm(&self, context: LLVMContextRef) -> LLVMValueRef {
fn as_llvm(&self, context: LLVMContextRef, builder: LLVMBuilderRef) -> LLVMValueRef {
unsafe {
let t = self.get_type().as_llvm(context);
match self {
@ -454,6 +457,9 @@ impl ConstValue {
ConstValue::U32(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::String(val) => {
LLVMBuildGlobalString(builder, into_cstring(val).as_ptr(), c"string".as_ptr())
}
}
}
}
@ -472,6 +478,7 @@ impl Type {
Bool => LLVMInt1TypeInContext(context),
Void => LLVMVoidType(),
Ptr(ty) => LLVMPointerType(ty.as_llvm(context), 0),
String(length) => LLVMArrayType(LLVMInt8TypeInContext(context), *length),
}
}
}

View File

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

View File

@ -201,10 +201,10 @@ impl ast::BinaryOperator {
impl ast::Literal {
fn mir(&self) -> mir::Literal {
match *self {
ast::Literal::Number(v) => mir::Literal::Vague(mir::VagueLiteral::Number(v)),
ast::Literal::Bool(v) => mir::Literal::Bool(v),
ast::Literal::String(_) => todo!("process string literal"),
match &self {
ast::Literal::Number(v) => mir::Literal::Vague(mir::VagueLiteral::Number(*v)),
ast::Literal::Bool(v) => mir::Literal::Bool(*v),
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::U128(val) => ConstValue::U128(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!"),
})
}
@ -495,9 +495,9 @@ impl TypeKind {
TypeKind::U64 => Type::U64,
TypeKind::U128 => Type::U128,
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::Void => panic!("Void not a supported type"),
TypeKind::Void => Type::Void,
TypeKind::Vague(_) => panic!("Tried to compile a vague type!"),
}
}

View File

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

View File

@ -532,6 +532,16 @@ impl Literal {
(L::U64(_), TypeKind::U64) => self,
(L::U128(_), TypeKind::U128) => 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
// requested type
(L::Vague(VagueL::Number(v)), TypeKind::I8) => L::I8(v as i8),