Add support for comparison operators

Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
Slendi 2024-03-01 15:30:25 +02:00
parent 92c8509125
commit 71c337a3f4
4 changed files with 121 additions and 8 deletions

View File

@ -254,6 +254,72 @@ generate_llvm :: proc(ctx: LLVMContextRef, mod: LLVMModuleRef, builder: LLVMBuil
return LLVMBuildURem(builder, lhs, rhs, "modtmp")
}
}
case .BitwiseLeftShift:
return LLVMBuildShl(builder, lhs, rhs, "shltmp")
case .BitwiseRightShift:
if is_signed {
return LLVMBuildAShr(builder, lhs, rhs, "ashrtmp")
} else {
return LLVMBuildLShr(builder, lhs, rhs, "lshrtmp")
}
case .BitwiseAnd:
return LLVMBuildAnd(builder, lhs, rhs, "andtmp")
case .BitwiseOr:
return LLVMBuildOr(builder, lhs, rhs, "ortmp")
case .BitwiseXOR:
return LLVMBuildXor(builder, lhs, rhs, "xortmp")
case .Equals:
if is_float {
return LLVMBuildFCmp(builder, .LLVMRealOEQ, lhs, rhs, "eqtmp")
} else {
return LLVMBuildICmp(builder, .LLVMIntEQ, lhs, rhs, "eqtmp")
}
case .NotEquals:
if is_float {
return LLVMBuildFCmp(builder, .LLVMRealONE, lhs, rhs, "neqtmp")
} else {
return LLVMBuildICmp(builder, .LLVMIntNE, lhs, rhs, "neqtmp")
}
case .LessThan:
if is_float {
return LLVMBuildFCmp(builder, .LLVMRealOLT, lhs, rhs, "lttmp")
} else {
if is_signed {
return LLVMBuildICmp(builder, .LLVMIntSLT, lhs, rhs, "lttmp")
} else {
return LLVMBuildICmp(builder, .LLVMIntULT, lhs, rhs, "lttmp")
}
}
case .LessThanOrEqual:
if is_float {
return LLVMBuildFCmp(builder, .LLVMRealOLE, lhs, rhs, "letmp")
} else {
if is_signed {
return LLVMBuildICmp(builder, .LLVMIntSLE, lhs, rhs, "letmp")
} else {
return LLVMBuildICmp(builder, .LLVMIntULE, lhs, rhs, "letmp")
}
}
case .GreaterThan:
if is_float {
return LLVMBuildFCmp(builder, .LLVMRealOGT, lhs, rhs, "gttmp")
} else {
if is_signed {
return LLVMBuildICmp(builder, .LLVMIntSGT, lhs, rhs, "gttmp")
} else {
return LLVMBuildICmp(builder, .LLVMIntUGT, lhs, rhs, "gttmp")
}
}
case .GreaterThanOrEqual:
if is_float {
return LLVMBuildFCmp(builder, .LLVMRealOGE, lhs, rhs, "getmp")
} else {
if is_signed {
return LLVMBuildICmp(builder, .LLVMIntSGE, lhs, rhs, "getmp")
} else {
return LLVMBuildICmp(builder, .LLVMIntUGE, lhs, rhs, "getmp")
}
}
case:
fmt.panicf("LLVM-C: Unexpected binary expression kind: {}", op)
}
@ -273,7 +339,16 @@ generate_llvm :: proc(ctx: LLVMContextRef, mod: LLVMModuleRef, builder: LLVMBuil
if condition == nil {
return
}
int_32_type := LLVMInt32TypeInContext(ctx)
int_32_type : LLVMTypeRef
if condition_node.return_type.kind == .Float {
if condition_node.return_type.bit_size == 64 {
int_32_type = LLVMDoubleTypeInContext(ctx)
} else {
int_32_type = LLVMFloatTypeInContext(ctx)
}
} else {
int_32_type = LLVMIntTypeInContext(ctx, uint(condition_node.return_type.bit_size))
}
comparison_res := LLVMBuildICmp(builder, .LLVMIntNE, condition, LLVMConstInt(int_32_type, 0, LLVMBool(1)), "")
true_block := LLVMAppendBasicBlockInContext(ctx, function, "")

View File

@ -59,6 +59,25 @@ LLVMIntPredicate :: enum {
LLVMIntSLE,
}
LLVMRealPredicate :: enum {
LLVMRealPredicateFalse,
LLVMRealOEQ,
LLVMRealOGT,
LLVMRealOGE,
LLVMRealOLT,
LLVMRealOLE,
LLVMRealONE,
LLVMRealORD,
LLVMRealUNO,
LLVMRealUEQ,
LLVMRealUGT,
LLVMRealUGE,
LLVMRealULT,
LLVMRealULE,
LLVMRealUNE,
LLVMRealPredicateTrue
};
@(default_calling_convention = "std")
foreign llvmc {
LLVMContextCreate :: proc() -> LLVMContextRef ---
@ -89,6 +108,8 @@ foreign llvmc {
LLVMVoidTypeInContext :: proc(C: LLVMContextRef) -> LLVMTypeRef ---
LLVMGetTypeKind :: proc(Ty: LLVMTypeRef) -> LLVMTypeKind ---
LLVMArrayType2 :: proc(ElementType: LLVMTypeRef, ElementCount: u64) -> LLVMTypeRef ---
LLVMPointerType :: proc(ElementType: LLVMTypeRef, AddressSpace: uint) -> LLVMTypeRef ---
@ -128,6 +149,16 @@ foreign llvmc {
LLVMBuildBr :: proc(Builder: LLVMBuilderRef, Dest: LLVMBasicBlockRef) -> LLVMValueRef ---
LLVMBuildCondBr :: proc(Builder: LLVMBuilderRef, If: LLVMValueRef, Then: LLVMBasicBlockRef, Else: LLVMBasicBlockRef) -> LLVMValueRef ---
LLVMBuildICmp :: proc(Builder: LLVMBuilderRef, Predicate: LLVMIntPredicate, LHS: LLVMValueRef, RHS: LLVMValueRef, Name: cstring) -> LLVMValueRef ---
LLVMBuildFCmp :: proc(Builder: LLVMBuilderRef, Predicate: LLVMRealPredicate, LHS: LLVMValueRef, RHS: LLVMValueRef, Name: cstring) -> LLVMValueRef ---
LLVMBuildAnd :: proc(Builder: LLVMBuilderRef, LHS: LLVMValueRef, RHS: LLVMValueRef, Name: cstring) -> LLVMValueRef ---
LLVMBuildOr :: proc(Builder: LLVMBuilderRef, LHS: LLVMValueRef, RHS: LLVMValueRef, Name: cstring) -> LLVMValueRef ---
LLVMBuildXor :: proc(Builder: LLVMBuilderRef, LHS: LLVMValueRef, RHS: LLVMValueRef, Name: cstring) -> LLVMValueRef ---
LLVMBuildNot :: proc(Builder: LLVMBuilderRef, Val: LLVMValueRef, Name: cstring) -> LLVMValueRef ---
LLVMBuildShl :: proc(Builder: LLVMBuilderRef, LHS: LLVMValueRef, RHS: LLVMValueRef, Name: cstring) -> LLVMValueRef ---
LLVMBuildLShr :: proc(Builder: LLVMBuilderRef, LHS: LLVMValueRef, RHS: LLVMValueRef, Name: cstring) -> LLVMValueRef ---
LLVMBuildAShr :: proc(Builder: LLVMBuilderRef, LHS: LLVMValueRef, RHS: LLVMValueRef, Name: cstring) -> LLVMValueRef ---
LLVMBuildShr :: proc(Builder: LLVMBuilderRef, LHS: LLVMValueRef, RHS: LLVMValueRef, Name: cstring) -> LLVMValueRef ---
LLVMBuildPhi :: proc(Builder: LLVMBuilderRef, Ty: LLVMTypeRef, Name: cstring) -> LLVMValueRef ---

View File

@ -237,7 +237,10 @@ type_check :: proc(ast: ^Node, parent_ast: ^Node) {
)
}
ast.return_type = ast.children[0].return_type
if ast.value_token_kind == .Assign {
ast.return_type = nil
if !scope_stack[len(scope_stack) - 1].variable_mutability_definitions[get_character_sum_of_dyn_arr(&ast.children[0].value.([dynamic]u8))] {
append(&g_message_list,
message_create(
@ -247,10 +250,12 @@ type_check :: proc(ast: ^Node, parent_ast: ^Node) {
),
)
}
} else if ast.value_token_kind == .Equals || ast.value_token_kind == .NotEquals ||
ast.value_token_kind == .GreaterThan || ast.value_token_kind == .GreaterThanOrEqual ||
ast.value_token_kind == .LessThan || ast.value_token_kind == .LessThanOrEqual {
ast.return_type = type_create_integer(1, true)
}
ast.return_type = ast.children[0].return_type
// FIXME: Verify that the operation is possible
case .UnaryExpression:
// FIXME: Verify that the operation is possible

View File

@ -7,16 +7,18 @@
\name 123.0 456.0
let arr: []i32, arr2: [69]u8, ptr: ^i32
\let arr: []i32, arr2: [69]u8, ptr: ^i32
fn put_i32(val: i32) i32
let amogus := 500 + (put_i32 8008135)
\let amogus := 500 + (put_i32 8008135)
\
\put_i32 69 * amogus + 420
put_i32 69 * amogus + 420
let a b := 5 1
if 0 {
if 0 {
if a == 5 {
if b {
put_i32 123
} else {
put_i32 69