diff --git a/reid-llvm-lib/src/builder.rs b/reid-llvm-lib/src/builder.rs index 943c437..d254ec3 100644 --- a/reid-llvm-lib/src/builder.rs +++ b/reid-llvm-lib/src/builder.rs @@ -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, } } diff --git a/reid-llvm-lib/src/compile.rs b/reid-llvm-lib/src/compile.rs index 88eaf85..7ad7604 100644 --- a/reid-llvm-lib/src/compile.rs +++ b/reid-llvm-lib/src/compile.rs @@ -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), } } } diff --git a/reid-llvm-lib/src/lib.rs b/reid-llvm-lib/src/lib.rs index 9686576..db1351b 100644 --- a/reid-llvm-lib/src/lib.rs +++ b/reid-llvm-lib/src/lib.rs @@ -200,6 +200,7 @@ pub enum Type { U128, Bool, Void, + String(u32), Ptr(Box), } @@ -216,6 +217,7 @@ pub enum ConstValue { U64(u64), U128(u128), Bool(bool), + String(String), } #[derive(Clone, Hash)] diff --git a/reid/src/ast/process.rs b/reid/src/ast/process.rs index caad577..7562286 100644 --- a/reid/src/ast/process.rs +++ b/reid/src/ast/process.rs @@ -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()), } } } diff --git a/reid/src/codegen.rs b/reid/src/codegen.rs index 730c6a4..672b83f 100644 --- a/reid/src/codegen.rs +++ b/reid/src/codegen.rs @@ -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!"), } } diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index 48422e1..278e282 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -59,7 +59,7 @@ pub enum TypeKind { #[error("void")] Void, #[error("string")] - String, + String(usize), #[error("[{0}; {1}]")] Array(Box, 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), } } diff --git a/reid/src/mir/typecheck.rs b/reid/src/mir/typecheck.rs index 52abf45..d94c97a 100644 --- a/reid/src/mir/typecheck.rs +++ b/reid/src/mir/typecheck.rs @@ -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),