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/func.h>
|
||||||
#include <llvm/parser.h>
|
#include <llvm/parser.h>
|
||||||
#include <llvm/stmt.h>
|
#include <llvm/stmt.h>
|
||||||
|
#include <sys/log.h>
|
||||||
|
|
||||||
BackendError impl_assign_stmt(LLVMBackendCompileUnit* unit,
|
BackendError impl_assign_stmt(LLVMBackendCompileUnit* unit,
|
||||||
LLVMBuilderRef builder, LLVMLocalScope* scope,
|
const LLVMBuilderRef builder, const LLVMLocalScope* scope,
|
||||||
Assignment* assignment) {
|
const Assignment* assignment) {
|
||||||
|
BackendError err = SUCCESS;
|
||||||
|
DEBUG("implementing assignment for variabel: %s", assignment->variable->name);
|
||||||
|
|
||||||
// TODO: resolve expression to LLVMValueRef
|
// TODO: resolve expression to LLVMValueRef
|
||||||
const LLVMValueRef llvm_value = NULL;
|
const LLVMValueRef llvm_value = NULL;
|
||||||
|
|
||||||
|
@ -21,8 +25,11 @@ BackendError impl_assign_stmt(LLVMBackendCompileUnit* unit,
|
||||||
LLVMBuildStore(builder, llvm_value, llvm_ptr);
|
LLVMBuildStore(builder, llvm_value, llvm_ptr);
|
||||||
break;
|
break;
|
||||||
case VariableKindBoxMember:
|
case VariableKindBoxMember:
|
||||||
|
// TODO: resolve LLVMValueRef from BoxAccess
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
BackendError impl_stmt(LLVMBackendCompileUnit* unit, Statement* stmt) {}
|
BackendError impl_stmt(LLVMBackendCompileUnit* unit, Statement* stmt) {}
|
||||||
|
|
|
@ -9,6 +9,71 @@
|
||||||
#define BASE_BYTES 4
|
#define BASE_BYTES 4
|
||||||
#define BITS_PER_BYTE 8
|
#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,
|
BackendError impl_primtive_type(LLVMBackendCompileUnit* unit,
|
||||||
PrimitiveType primtive,
|
PrimitiveType primtive,
|
||||||
LLVMTypeRef* llvm_type) {
|
LLVMTypeRef* llvm_type) {
|
||||||
|
|
|
@ -18,4 +18,8 @@ BackendError get_type_default_value(LLVMBackendCompileUnit* unit,
|
||||||
LLVMGlobalScope* scope, Type* gemstone_type,
|
LLVMGlobalScope* scope, Type* gemstone_type,
|
||||||
LLVMValueRef* llvm_value);
|
LLVMValueRef* llvm_value);
|
||||||
|
|
||||||
|
BackendError get_type_value(LLVMBackendCompileUnit* unit,
|
||||||
|
LLVMGlobalScope* scope, TypeValue* gemstone_value,
|
||||||
|
LLVMValueRef* llvm_value);
|
||||||
|
|
||||||
#endif // LLVM_BACKEND_TYPES_H_
|
#endif // LLVM_BACKEND_TYPES_H_
|
||||||
|
|
Loading…
Reference in New Issue