Add support for comparison operators
Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
parent
92c8509125
commit
71c337a3f4
@ -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, "")
|
||||
|
@ -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 ---
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user