feature: added logical operators
This commit is contained in:
parent
28a4f619a0
commit
3ba11ec97b
|
@ -5,17 +5,17 @@
|
||||||
#include <llvm/expr.h>
|
#include <llvm/expr.h>
|
||||||
#include <llvm/types.h>
|
#include <llvm/types.h>
|
||||||
|
|
||||||
BackendError impl_bitwise_operation(LLVMBackendCompileUnit* unit,
|
BackendError impl_bitwise_operation(LLVMBackendCompileUnit *unit,
|
||||||
LLVMLocalScope* scope,
|
LLVMLocalScope *scope,
|
||||||
LLVMBuilderRef builder,
|
LLVMBuilderRef builder,
|
||||||
Operation* operation,
|
Operation *operation,
|
||||||
LLVMValueRef* llvm_result) {
|
LLVMValueRef *llvm_result) {
|
||||||
// TODO: resolve lhs and rhs or op
|
// TODO: resolve lhs and rhs or op
|
||||||
LLVMValueRef rhs = NULL;
|
LLVMValueRef rhs = NULL;
|
||||||
LLVMValueRef lhs = NULL;
|
LLVMValueRef lhs = NULL;
|
||||||
LLVMValueRef op = NULL;
|
LLVMValueRef op = NULL;
|
||||||
|
|
||||||
if (operation->kind == BitwiseNot) {
|
if (operation->impl.bitwise == BitwiseNot) {
|
||||||
// single operand
|
// single operand
|
||||||
} else {
|
} else {
|
||||||
// two operands
|
// two operands
|
||||||
|
@ -39,11 +39,29 @@ BackendError impl_bitwise_operation(LLVMBackendCompileUnit* unit,
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
BackendError impl_logical_operation(LLVMBackendCompileUnit* unit,
|
/**
|
||||||
LLVMLocalScope* scope,
|
* @brief Convert any integral type (integer) to a boolean value.
|
||||||
|
* A boolean value hereby meaning an integer of the same type as the input
|
||||||
|
* value but with the value of either 0 or one.
|
||||||
|
* @param builder
|
||||||
|
* @param integral
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static LLVMValueRef convert_integral_to_boolean(
|
||||||
|
LLVMBuilderRef builder, LLVMValueRef integral) {
|
||||||
|
// type of input
|
||||||
|
LLVMTypeRef valueType = LLVMTypeOf(integral);
|
||||||
|
// zero value of same type as integral
|
||||||
|
LLVMValueRef zero = LLVMConstIntOfString(valueType, "0", 10);
|
||||||
|
// returns 1 if integral is not zero and zero otherwise
|
||||||
|
return LLVMBuildICmp(builder, LLVMIntNE, zero, integral, "to boolean");
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError impl_logical_operation(LLVMBackendCompileUnit *unit,
|
||||||
|
LLVMLocalScope *scope,
|
||||||
LLVMBuilderRef builder,
|
LLVMBuilderRef builder,
|
||||||
Operation* operation,
|
Operation *operation,
|
||||||
LLVMValueRef* llvm_result) {
|
LLVMValueRef *llvm_result) {
|
||||||
// TODO: resolve lhs and rhs or op
|
// TODO: resolve lhs and rhs or op
|
||||||
LLVMValueRef rhs = NULL;
|
LLVMValueRef rhs = NULL;
|
||||||
LLVMValueRef lhs = NULL;
|
LLVMValueRef lhs = NULL;
|
||||||
|
@ -51,8 +69,11 @@ BackendError impl_logical_operation(LLVMBackendCompileUnit* unit,
|
||||||
|
|
||||||
if (operation->kind == BitwiseNot) {
|
if (operation->kind == BitwiseNot) {
|
||||||
// single operand
|
// single operand
|
||||||
|
op = convert_integral_to_boolean(builder, op);
|
||||||
} else {
|
} else {
|
||||||
// two operands
|
// two operands
|
||||||
|
lhs = convert_integral_to_boolean(builder, lhs);
|
||||||
|
rhs = convert_integral_to_boolean(builder, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (operation->impl.bitwise) {
|
switch (operation->impl.bitwise) {
|
||||||
|
@ -74,9 +95,9 @@ BackendError impl_logical_operation(LLVMBackendCompileUnit* unit,
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
BackendError impl_operation(LLVMBackendCompileUnit* unit, LLVMLocalScope* scope,
|
BackendError impl_operation(LLVMBackendCompileUnit *unit, LLVMLocalScope *scope,
|
||||||
LLVMBuilderRef builder, Operation* operation,
|
LLVMBuilderRef builder, Operation *operation,
|
||||||
LLVMValueRef* llvm_result) {
|
LLVMValueRef *llvm_result) {
|
||||||
switch (operation->kind) {
|
switch (operation->kind) {
|
||||||
case Bitwise:
|
case Bitwise:
|
||||||
impl_bitwise_operation(unit, scope, builder, operation,
|
impl_bitwise_operation(unit, scope, builder, operation,
|
||||||
|
@ -89,9 +110,9 @@ BackendError impl_operation(LLVMBackendCompileUnit* unit, LLVMLocalScope* scope,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BackendError impl_transmute(LLVMBackendCompileUnit* unit, LLVMLocalScope* scope,
|
BackendError impl_transmute(LLVMBackendCompileUnit *unit, LLVMLocalScope *scope,
|
||||||
LLVMBuilderRef builder, Transmute* transmute,
|
LLVMBuilderRef builder, Transmute *transmute,
|
||||||
LLVMValueRef* llvm_result) {
|
LLVMValueRef *llvm_result) {
|
||||||
// TODO: resolve sub expression
|
// TODO: resolve sub expression
|
||||||
LLVMValueRef operand = NULL;
|
LLVMValueRef operand = NULL;
|
||||||
LLVMTypeRef target_type = NULL;
|
LLVMTypeRef target_type = NULL;
|
||||||
|
@ -100,13 +121,13 @@ BackendError impl_transmute(LLVMBackendCompileUnit* unit, LLVMLocalScope* scope,
|
||||||
// if target type is valid
|
// if target type is valid
|
||||||
if (err.kind == Success) {
|
if (err.kind == Success) {
|
||||||
*llvm_result =
|
*llvm_result =
|
||||||
LLVMBuildBitCast(builder, operand, target_type, "transmute");
|
LLVMBuildBitCast(builder, operand, target_type, "transmute");
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static LLVMBool is_type_signed(const Type* type) {
|
static LLVMBool is_type_signed(const Type *type) {
|
||||||
switch (type->kind) {
|
switch (type->kind) {
|
||||||
case TypeKindPrimitive:
|
case TypeKindPrimitive:
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -117,9 +138,9 @@ static LLVMBool is_type_signed(const Type* type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BackendError impl_typecast(LLVMBackendCompileUnit* unit, LLVMLocalScope* scope,
|
BackendError impl_typecast(LLVMBackendCompileUnit *unit, LLVMLocalScope *scope,
|
||||||
LLVMBuilderRef builder, TypeCast* typecast,
|
LLVMBuilderRef builder, TypeCast *typecast,
|
||||||
LLVMValueRef* llvm_result) {
|
LLVMValueRef *llvm_result) {
|
||||||
// TODO: resolve sub expression
|
// TODO: resolve sub expression
|
||||||
LLVMValueRef operand = NULL;
|
LLVMValueRef operand = NULL;
|
||||||
LLVMTypeRef target_type = NULL;
|
LLVMTypeRef target_type = NULL;
|
||||||
|
@ -133,15 +154,16 @@ BackendError impl_typecast(LLVMBackendCompileUnit* unit, LLVMLocalScope* scope,
|
||||||
LLVMBool dst_signed = is_type_signed(&typecast->targetType);
|
LLVMBool dst_signed = is_type_signed(&typecast->targetType);
|
||||||
// TODO: derive source type sign
|
// TODO: derive source type sign
|
||||||
const LLVMOpcode opcode =
|
const LLVMOpcode opcode =
|
||||||
LLVMGetCastOpcode(operand, 0, target_type, dst_signed);
|
LLVMGetCastOpcode(operand, 0, target_type, dst_signed);
|
||||||
*llvm_result =
|
*llvm_result =
|
||||||
LLVMBuildCast(builder, opcode, operand, target_type, "transmute");
|
LLVMBuildCast(builder, opcode, operand, target_type, "transmute");
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
BackendError impl_expr(LLVMBackendCompileUnit* unit, LLVMLocalScope* scope,
|
|
||||||
LLVMBuilderRef builder, Expression* expr,
|
BackendError impl_expr(LLVMBackendCompileUnit *unit, LLVMLocalScope *scope,
|
||||||
LLVMValueRef* llvm_result) {
|
LLVMBuilderRef builder, Expression *expr,
|
||||||
|
LLVMValueRef *llvm_result) {
|
||||||
BackendError err = SUCCESS;
|
BackendError err = SUCCESS;
|
||||||
|
|
||||||
switch (expr->kind) {
|
switch (expr->kind) {
|
||||||
|
|
|
@ -210,25 +210,6 @@ LLVMGlobalScope* new_global_scope() {
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
LLVMLocalScope* new_local_scope(LLVMGlobalScope* global_scope,
|
|
||||||
LLVMLocalScope* parent_scope) {
|
|
||||||
DEBUG("creating local scope...");
|
|
||||||
LLVMLocalScope* scope = malloc(sizeof(LLVMLocalScope));
|
|
||||||
|
|
||||||
scope->variables = g_hash_table_new(g_str_hash, g_str_equal);
|
|
||||||
scope->params = g_hash_table_new(g_str_hash, g_str_equal);
|
|
||||||
scope->global_scope = global_scope;
|
|
||||||
scope->parent_scope = parent_scope;
|
|
||||||
|
|
||||||
return scope;
|
|
||||||
}
|
|
||||||
|
|
||||||
void delete_local_scope(LLVMLocalScope* scope) {
|
|
||||||
DEBUG("deleting global scope...");
|
|
||||||
g_hash_table_unref(scope->variables);
|
|
||||||
free(scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
void delete_global_scope(LLVMGlobalScope* scope) {
|
void delete_global_scope(LLVMGlobalScope* scope) {
|
||||||
DEBUG("deleting global scope...");
|
DEBUG("deleting global scope...");
|
||||||
g_hash_table_unref(scope->functions);
|
g_hash_table_unref(scope->functions);
|
||||||
|
|
Loading…
Reference in New Issue