added: expressions
This commit is contained in:
parent
9eddfd75bc
commit
5fae7a12c1
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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) {}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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_
|
||||
|
|
Loading…
Reference in New Issue