added: expressions

This commit is contained in:
Sven Vogel 2024-05-28 15:34:21 +02:00
parent 9eddfd75bc
commit 5fae7a12c1
5 changed files with 179 additions and 5 deletions

82
src/llvm/expr.c Normal file
View File

@ -0,0 +1,82 @@
//
// Created by servostar on 5/28/24.
//
#include <llvm/expr.h>
#include <llvm/types.h>
BackendError impl_transmute(LLVMBackendCompileUnit* unit, LLVMLocalScope* scope,
LLVMBuilderRef builder, Transmute* transmute,
LLVMValueRef* llvm_result) {
// TODO: resolve sub expression
LLVMValueRef operand = NULL;
LLVMTypeRef target_type = NULL;
BackendError err = get_type_impl(unit, scope->func_scope->global_scope,
&transmute->targetType, &target_type);
// if target type is valid
if (err.kind == Success) {
*llvm_result =
LLVMBuildBitCast(builder, operand, target_type, "transmute");
}
return err;
}
static LLVMBool is_type_signed(const Type* type) {
switch (type->kind) {
case TypeKindPrimitive:
return 1;
case TypeKindComposite:
return type->impl.composite.sign == Signed;
default:
return 0;
}
}
BackendError impl_typecast(LLVMBackendCompileUnit* unit, LLVMLocalScope* scope,
LLVMBuilderRef builder, TypeCast* typecast,
LLVMValueRef* llvm_result) {
// TODO: resolve sub expression
LLVMValueRef operand = NULL;
LLVMTypeRef target_type = NULL;
BackendError err = get_type_impl(unit, scope->func_scope->global_scope,
&typecast->targetType, &target_type);
// if target type is valid
if (err.kind != Success) {
return err;
}
LLVMBool dst_signed = is_type_signed(&typecast->targetType);
// TODO: derive source type sign
const LLVMOpcode opcode =
LLVMGetCastOpcode(operand, 0, target_type, dst_signed);
*llvm_result =
LLVMBuildCast(builder, opcode, operand, target_type, "transmute");
return err;
}
BackendError impl_expr(LLVMBackendCompileUnit* unit, LLVMLocalScope* scope,
LLVMBuilderRef builder, Expression* expr,
LLVMValueRef* llvm_result) {
BackendError err = SUCCESS;
switch (expr->kind) {
case ExpressionKindConstant:
err = get_type_value(unit, scope->func_scope->global_scope,
&expr->impl.constant, llvm_result);
break;
case ExpressionKindTransmute:
err = impl_transmute(unit, scope, builder, &expr->impl.transmute,
llvm_result);
break;
case ExpressionKindTypeCast:
err = impl_typecast(unit, scope, builder, &expr->impl.typecast,
llvm_result);
break;
case ExpressionKindOperation:
break;
}
return err;
}

16
src/llvm/expr.h Normal file
View File

@ -0,0 +1,16 @@
//
// Created by servostar on 5/28/24.
//
#ifndef LLVM_BACKEND_EXPR_H
#define LLVM_BACKEND_EXPR_H
#include <codegen/backend.h>
#include <llvm-c/Types.h>
#include <llvm/func.h>
#include <llvm/parser.h>
BackendError impl_expr(LLVMBackendCompileUnit* unit, LLVMLocalScope* scope,
Expression* expr, LLVMValueRef* llvm_result);
#endif // LLVM_BACKEND_EXPR_H

View File

@ -6,10 +6,14 @@
#include <llvm/func.h>
#include <llvm/parser.h>
#include <llvm/stmt.h>
#include <sys/log.h>
BackendError impl_assign_stmt(LLVMBackendCompileUnit* unit,
LLVMBuilderRef builder, LLVMLocalScope* scope,
Assignment* assignment) {
const LLVMBuilderRef builder, const LLVMLocalScope* scope,
const Assignment* assignment) {
BackendError err = SUCCESS;
DEBUG("implementing assignment for variabel: %s", assignment->variable->name);
// TODO: resolve expression to LLVMValueRef
const LLVMValueRef llvm_value = NULL;
@ -18,11 +22,14 @@ BackendError impl_assign_stmt(LLVMBackendCompileUnit* unit,
case VariableKindDefinition:
const LLVMValueRef llvm_ptr =
get_variable(scope, assignment->variable->name);
LLVMBuildStore(builder, llvm_value, llvm_ptr);
break;
LLVMBuildStore(builder, llvm_value, llvm_ptr);
break;
case VariableKindBoxMember:
break;
// TODO: resolve LLVMValueRef from BoxAccess
break;
}
return err;
}
BackendError impl_stmt(LLVMBackendCompileUnit* unit, Statement* stmt) {}

View File

@ -9,6 +9,71 @@
#define BASE_BYTES 4
#define BITS_PER_BYTE 8
static BackendError get_const_primitive_value(PrimitiveType primitive,
LLVMTypeRef llvm_type,
const char* value,
LLVMValueRef* llvm_value) {
switch (primitive) {
case Int:
*llvm_value = LLVMConstIntOfString(llvm_type, value, 10);
break;
case Float:
*llvm_value = LLVMConstRealOfString(llvm_type, value);
break;
}
return SUCCESS;
}
static BackendError get_const_composite_value(CompositeType composite,
LLVMTypeRef llvm_type,
const char* value,
LLVMValueRef* llvm_value) {
return get_const_primitive_value(composite.primitive, llvm_type, value,
llvm_value);
}
BackendError get_const_type_value(LLVMBackendCompileUnit* unit,
LLVMGlobalScope* scope,
TypeValue* gemstone_value,
LLVMValueRef* llvm_value) {
BackendError err = new_backend_impl_error(
Implementation, gemstone_value->nodePtr, "No default value for type");
LLVMTypeRef llvm_type = NULL;
err = get_type_impl(unit, scope, &gemstone_value->type, &llvm_type);
if (err.kind != Success) {
return err;
}
switch (gemstone_value->type.kind) {
case TypeKindPrimitive:
err = get_const_primitive_value(gemstone_value->type.impl.primitive,
llvm_type, gemstone_value->value,
llvm_value);
break;
case TypeKindComposite:
err = get_const_composite_value(gemstone_value->type.impl.composite,
llvm_type, gemstone_value->value,
llvm_value);
break;
case TypeKindReference:
err =
new_backend_impl_error(Implementation, gemstone_value->nodePtr,
"reference cannot be constant value");
break;
case TypeKindBox:
err =
new_backend_impl_error(Implementation, gemstone_value->nodePtr,
"boxes cannot be constant value");
break;
default:
PANIC("invalid value kind: %ld", gemstone_value->type.kind);
}
return err;
}
BackendError impl_primtive_type(LLVMBackendCompileUnit* unit,
PrimitiveType primtive,
LLVMTypeRef* llvm_type) {

View File

@ -18,4 +18,8 @@ BackendError get_type_default_value(LLVMBackendCompileUnit* unit,
LLVMGlobalScope* scope, Type* gemstone_type,
LLVMValueRef* llvm_value);
BackendError get_type_value(LLVMBackendCompileUnit* unit,
LLVMGlobalScope* scope, TypeValue* gemstone_value,
LLVMValueRef* llvm_value);
#endif // LLVM_BACKEND_TYPES_H_