mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 03:51:18 +00:00
Support for subscripts. Added helloworld.
This commit is contained in:
@@ -154,6 +154,6 @@ add_executable(c3c
|
||||
src/compiler/llvm_codegen_type.c
|
||||
src/compiler/llvm_codegen_function.c)
|
||||
|
||||
target_compile_options(c3c PRIVATE -Werror -Wall -Wextra -Wno-unused-function -Wno-unused-variable -Wno-unused-parameter)
|
||||
target_compile_options(c3c PRIVATE -Wimplicit-int -Werror -Wall -Wextra -Wno-unused-function -Wno-unused-variable -Wno-unused-parameter)
|
||||
|
||||
target_link_libraries(c3c ${llvm_libs})
|
||||
target_link_libraries(c3c m ${llvm_libs})
|
||||
8
resources/testfragments/helloworld.c3
Normal file
8
resources/testfragments/helloworld.c3
Normal file
@@ -0,0 +1,8 @@
|
||||
module helloworld;
|
||||
|
||||
func void printf(char *str);
|
||||
|
||||
func void main()
|
||||
{
|
||||
printf("Hello World!\n");
|
||||
}
|
||||
@@ -92,6 +92,17 @@ func int main(int x)
|
||||
Test2 efe;
|
||||
efe.t.a = 3;
|
||||
if (efe.t.a > 2) printf("Works!\n");
|
||||
int ef = 3;
|
||||
int *eff = &ef;
|
||||
eff[0] = 4;
|
||||
byte *ex = cast(byte *, eff);
|
||||
ex[0] = 5;
|
||||
if (eff[0] == 5) printf("Works-5!\n");
|
||||
ex[1] = 5;
|
||||
if (eff[0] == 5 + 5 * 256) printf("Works-5*256!\n");
|
||||
if (ef == 4) printf("Works5!\n");
|
||||
if (ef == 4) printf("Works1!\n");
|
||||
ef = 0;
|
||||
/*
|
||||
byte a = 2;
|
||||
short b = 3;
|
||||
@@ -103,8 +114,21 @@ JUMP:
|
||||
i = i + 1;
|
||||
//@hello();
|
||||
printf("Hello worldABC" "D" "E\u2701\n");
|
||||
float f = 10.0;
|
||||
float f = 3.0;
|
||||
float* pf = &f;
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
printf("c0\n");
|
||||
case 1:
|
||||
printf("c1\n");
|
||||
case 2:
|
||||
printf("c2\n");
|
||||
case 3:
|
||||
printf("c3\n");
|
||||
default:
|
||||
printf("default\n");
|
||||
}
|
||||
if (*pf > i) goto JUMP;
|
||||
goto EX;
|
||||
YEF:
|
||||
@@ -161,5 +185,6 @@ func void test2(int* x, int y, int z)
|
||||
i = i - 1;
|
||||
ui = ui - 1;
|
||||
x + 1;
|
||||
// TODO x + 1;
|
||||
int j1 = x[0];
|
||||
j1 = *x;
|
||||
}
|
||||
@@ -27,7 +27,7 @@ static inline const uint64_t *bigint_ptr(const BigInt *big_int)
|
||||
}
|
||||
|
||||
|
||||
#define alloc_digits(_digits) (_digits ? malloc_arena(sizeof(uint64_t) * _digits) : NULL)
|
||||
#define alloc_digits(_digits) ((_digits) ? malloc_arena(sizeof(uint64_t) * (_digits)) : NULL)
|
||||
|
||||
static void normalize(BigInt *big_int)
|
||||
{
|
||||
@@ -76,7 +76,7 @@ static bool bit_at_index(const BigInt *big_int, size_t index)
|
||||
size_t digit_bit_index = index % 64;
|
||||
const uint64_t *digits = bigint_ptr(big_int);
|
||||
uint64_t digit = digits[digit_index];
|
||||
return ((digit >> digit_bit_index) & 0x1) == 0x1;
|
||||
return ((digit >> digit_bit_index) & 0x1U) == 0x1U;
|
||||
}
|
||||
|
||||
uint32_t bigint_hash(BigInt x)
|
||||
@@ -392,7 +392,7 @@ void bigint_write_twos_complement(const BigInt *big_int, uint8_t *buf, size_t bi
|
||||
|
||||
for (size_t byte_index = 7;;)
|
||||
{
|
||||
uint8_t byte = (uint8_t) (x & 0xff);
|
||||
uint8_t byte = (uint8_t) (x & 0xffU);
|
||||
if (digit_index == last_digit_index)
|
||||
{
|
||||
buf[buf_index + byte_index - unwritten_byte_count] = byte;
|
||||
@@ -405,7 +405,7 @@ void bigint_write_twos_complement(const BigInt *big_int, uint8_t *buf, size_t bi
|
||||
|
||||
if (byte_index == 0) break;
|
||||
byte_index -= 1;
|
||||
x >>= 8;
|
||||
x >>= 8U;
|
||||
}
|
||||
|
||||
if (digit_index == 0) break;
|
||||
@@ -432,10 +432,10 @@ void bigint_write_twos_complement(const BigInt *big_int, uint8_t *buf, size_t bi
|
||||
byte_index < 8 && (digit_index + 1 < digit_count || byte_index < bytes_in_last_digit);
|
||||
byte_index += 1)
|
||||
{
|
||||
uint8_t byte = (uint8_t) (x & 0xff);
|
||||
uint8_t byte = (uint8_t) (x & 0xffU);
|
||||
buf[buf_index] = byte;
|
||||
buf_index += 1;
|
||||
x >>= 8;
|
||||
x >>= 8U;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -492,7 +492,7 @@ void bigint_read_twos_complement(BigInt *dest, const uint8_t *buf, size_t bit_co
|
||||
{
|
||||
uint8_t byte = buf[buf_index];
|
||||
buf_index += 1;
|
||||
digit <<= 8;
|
||||
digit <<= 8U;
|
||||
digit |= byte;
|
||||
}
|
||||
digits[dest->digit_count - 1] = digit;
|
||||
@@ -937,7 +937,7 @@ static void KnuthDiv(uint32_t *u, uint32_t *v, uint32_t *q, uint32_t *r, unsigne
|
||||
u[m + n] = u_carry;
|
||||
|
||||
// D2. [Initialize j.] Set j to m. This is the loop counter over the places.
|
||||
int j = m;
|
||||
int j = (int)m;
|
||||
do
|
||||
{
|
||||
// D3. [Calculate q'.].
|
||||
@@ -1016,7 +1016,7 @@ static void KnuthDiv(uint32_t *u, uint32_t *v, uint32_t *q, uint32_t *r, unsigne
|
||||
if (shift)
|
||||
{
|
||||
uint32_t carry = 0;
|
||||
for (int i = n - 1; i >= 0; i--)
|
||||
for (int i = (int)n - 1; i >= 0; i--)
|
||||
{
|
||||
r[i] = (u[i] >> shift) | carry;
|
||||
carry = u[i] << (32 - shift);
|
||||
@@ -1024,7 +1024,7 @@ static void KnuthDiv(uint32_t *u, uint32_t *v, uint32_t *q, uint32_t *r, unsigne
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = n - 1; i >= 0; i--)
|
||||
for (int i = (int)n - 1; i >= 0; i--)
|
||||
{
|
||||
r[i] = u[i];
|
||||
}
|
||||
@@ -1151,7 +1151,7 @@ static void bigint_unsigned_division(const BigInt *op1, const BigInt *op2, BigIn
|
||||
{
|
||||
uint32_t divisor = V[0];
|
||||
uint32_t rem = 0;
|
||||
for (int i = m; i >= 0; i--)
|
||||
for (int i = (int)m; i >= 0; i--)
|
||||
{
|
||||
uint64_t partial_dividend = make_64(rem, U[i]);
|
||||
if (partial_dividend == 0)
|
||||
@@ -2076,7 +2076,7 @@ long double bigint_as_float(const BigInt *bigint)
|
||||
return bigint->is_negative ? bigint_as_signed(bigint) : bigint_as_unsigned(bigint);
|
||||
}
|
||||
BigInt div;
|
||||
uint64_t mult = 0x100000000000ull;
|
||||
uint64_t mult = 0x100000000000ULL;
|
||||
long double mul = 1;
|
||||
bigint_init_unsigned(&div, mult);
|
||||
BigInt current;
|
||||
|
||||
@@ -538,125 +538,6 @@ bool vapt(Expr* left, Type *from, Type *canonical, Type *type, CastType cast_typ
|
||||
TODO
|
||||
}
|
||||
|
||||
CastFunc conversion(TypeKind from, Type *to)
|
||||
{
|
||||
switch (from)
|
||||
{
|
||||
case TYPE_POISONED:
|
||||
return &erro;
|
||||
case TYPE_VOID:
|
||||
return &erro;
|
||||
case TYPE_BOOL:
|
||||
if (type_is_integer(to)) return &boxi;
|
||||
if (type_is_float(to)) return &bofp;
|
||||
return &erro;
|
||||
case TYPE_ERROR_UNION:
|
||||
TODO
|
||||
case TYPE_I8:
|
||||
case TYPE_I16:
|
||||
case TYPE_I32:
|
||||
case TYPE_I64:
|
||||
case TYPE_IXX:
|
||||
if (type_is_unsigned_integer(to)) return &siui;
|
||||
if (type_is_signed_integer(to)) return &sisi;
|
||||
if (type_is_float(to)) return &sifp;
|
||||
if (to == type_bool) return &xibo;
|
||||
if (to->type_kind == TYPE_POINTER) return &ptxi;
|
||||
return &erro;
|
||||
case TYPE_U8:
|
||||
case TYPE_U16:
|
||||
case TYPE_U32:
|
||||
case TYPE_U64:
|
||||
case TYPE_UXX:
|
||||
if (type_is_unsigned_integer(to)) return &uiui;
|
||||
if (type_is_signed_integer(to)) return &uisi;
|
||||
if (type_is_float(to)) return &uifp;
|
||||
if (to == type_bool) return &xibo;
|
||||
if (to->type_kind == TYPE_POINTER) return &ptxi;
|
||||
return &erro;
|
||||
case TYPE_F32:
|
||||
case TYPE_F64:
|
||||
case TYPE_FXX:
|
||||
if (type_is_unsigned_integer(to)) return &fpui;
|
||||
if (type_is_signed_integer(to)) return &fpsi;
|
||||
if (to == type_bool) return &fpbo;
|
||||
if (type_is_float(to)) return &fpfp;
|
||||
return &erro;
|
||||
case TYPE_POINTER:
|
||||
if (type_is_integer(to)) return &ptxi;
|
||||
if (to->type_kind == TYPE_BOOL) return &ptbo;
|
||||
if (to->type_kind == TYPE_POINTER) return &ptpt;
|
||||
if (to->type_kind == TYPE_FUNC) return &ptfu;
|
||||
if (to->type_kind == TYPE_VARARRAY) return &ptva;
|
||||
return &erro;
|
||||
case TYPE_ENUM:
|
||||
if (type_is_integer(to)) return &enxi;
|
||||
return &erro;
|
||||
case TYPE_ERROR:
|
||||
if (type_is_integer(to)) return &erxi;
|
||||
return &erro;
|
||||
case TYPE_FUNC:
|
||||
if (type_is_integer(to)) return &ptxi;
|
||||
if (to->type_kind == TYPE_POINTER) return &fupt;
|
||||
return &erro;
|
||||
case TYPE_STRUCT:
|
||||
if (to->type_kind == TYPE_STRUCT) return &stst;
|
||||
if (to->type_kind == TYPE_UNION) return &stun;
|
||||
return &erro;
|
||||
case TYPE_UNION:
|
||||
if (to->type_kind == TYPE_STRUCT) return &unst;
|
||||
if (to->type_kind == TYPE_UNION) return &unun;
|
||||
return &erro;
|
||||
case TYPE_TYPEDEF:
|
||||
UNREACHABLE
|
||||
case TYPE_STRING:
|
||||
if (to->type_kind == TYPE_POINTER) return &strpt;
|
||||
return &erro;
|
||||
case TYPE_ARRAY:
|
||||
return &erro;
|
||||
case TYPE_VARARRAY:
|
||||
if (to->type_kind == TYPE_SUBARRAY) return &vasa;
|
||||
if (to->type_kind == TYPE_VARARRAY) return &vava;
|
||||
if (to->type_kind == TYPE_POINTER) return &vapt;
|
||||
return &erro;
|
||||
case TYPE_SUBARRAY:
|
||||
if (to->type_kind == TYPE_POINTER) return &sapt;
|
||||
// if (to->type_kind == )
|
||||
return &erro;
|
||||
}
|
||||
UNREACHABLE
|
||||
}
|
||||
|
||||
Type t_cpy = { .name = "cpy" };
|
||||
Type t_err = { .name = "err" };
|
||||
|
||||
Type *ARITHMETIC_PROMOTION[19][19] = {
|
||||
//other bool, char, short, int, long, ctint, byte, ushort, int, ulong, ctuint, float, double, ctreal, user, ptr, str, arr, varr // from:
|
||||
{ &t_u1, &t_i8, &t_i16, &t_i32, &t_i64, &t_u1, &t_u8, &t_u16, &t_u32, &t_u64, &t_u1, &t_f32, &t_f64, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err }, // bool
|
||||
{ &t_i8, &t_i8, &t_i16, &t_i32, &t_i64, &t_i8, &t_i8, &t_i16, &t_i32, &t_i64, &t_i8, &t_f32, &t_f64, &t_err, &t_err, &t_isz, &t_err, &t_err, &t_err }, // char
|
||||
{ &t_i16, &t_i16, &t_i16, &t_i32, &t_i64, &t_i16, &t_i16, &t_i16, &t_i32, &t_i64, &t_i16, &t_f32, &t_f64, &t_err, &t_err, &t_isz, &t_err, &t_err, &t_err }, // short
|
||||
{ &t_i32, &t_i32, &t_i32, &t_i32, &t_i64, &t_i32, &t_i32, &t_i32, &t_i32, &t_i64, &t_i32, &t_f32, &t_f64, &t_err, &t_err, &t_isz, &t_err, &t_err, &t_err }, // int
|
||||
{ &t_i64, &t_i64, &t_i64, &t_i64, &t_i64, &t_i64, &t_i64, &t_i64, &t_i64, &t_i64, &t_i64, &t_f32, &t_f64, &t_err, &t_err, &t_isz, &t_err, &t_err, &t_err }, // long
|
||||
{ &t_u1, &t_i8, &t_i16, &t_i32, &t_i64, &t_ixx, &t_i8, &t_i16, &t_i32, &t_i64, &t_ixx, &t_f32, &t_f64, &t_fxx, &t_err, &t_isz, &t_err, &t_err, &t_err }, // ixx
|
||||
{ &t_u8, &t_i8, &t_i16, &t_i32, &t_i64, &t_u8, &t_u8, &t_u16, &t_u32, &t_i64, &t_uxx, &t_f32, &t_f64, &t_err, &t_err, &t_usz, &t_err, &t_err, &t_err }, // byte
|
||||
{ &t_u16, &t_i16, &t_i16, &t_i32, &t_i64, &t_u16, &t_u16, &t_u16, &t_u32, &t_i64, &t_uxx, &t_f32, &t_f64, &t_err, &t_err, &t_usz, &t_err, &t_err, &t_err }, // ushort
|
||||
{ &t_u32, &t_i32, &t_i32, &t_i32, &t_i64, &t_u32, &t_u32, &t_u32, &t_u32, &t_i64, &t_uxx, &t_f32, &t_f64, &t_err, &t_err, &t_usz, &t_err, &t_err, &t_err }, // uint
|
||||
{ &t_u64, &t_i64, &t_i64, &t_i64, &t_i64, &t_u64, &t_u64, &t_u64, &t_u64, &t_i64, &t_uxx, &t_f32, &t_f64, &t_err, &t_err, &t_usz, &t_err, &t_err, &t_err }, // ulong
|
||||
{ &t_u1, &t_i8, &t_i16, &t_i32, &t_i64, &t_uxx, &t_u8, &t_u16, &t_u32, &t_u64, &t_uxx, &t_f32, &t_f64, &t_fxx, &t_err, &t_usz, &t_err, &t_err, &t_err }, // uxx
|
||||
{ &t_f32, &t_f32, &t_f32, &t_f32, &t_f32, &t_f32, &t_f32, &t_f32, &t_f32, &t_f32, &t_f32, &t_f32, &t_f64, &t_f32, &t_err, &t_err, &t_err, &t_err, &t_err }, // float
|
||||
{ &t_f64, &t_f64, &t_f64, &t_f64, &t_f64, &t_f64, &t_f64, &t_f64, &t_f64, &t_f64, &t_f64, &t_f64, &t_f64, &t_f64, &t_err, &t_err, &t_err, &t_err, &t_err }, // double
|
||||
{ &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_f32, &t_f64, &t_fxx, &t_err, &t_err, &t_err, &t_err, &t_err }, // fxx
|
||||
{ &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err }, // user
|
||||
{ &t_err, &t_cpy, &t_cpy, &t_cpy, &t_cpy, &t_cpy, &t_cpy, &t_cpy, &t_cpy, &t_cpy, &t_cpy, &t_cpy, &t_err, &t_err, &t_err, &t_cpy, &t_err, &t_err, &t_err }, // ptr
|
||||
{ &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err }, // str
|
||||
{ &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err }, // arr
|
||||
{ &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err, &t_err }, // varr
|
||||
};
|
||||
|
||||
static inline bool cannot_convert(TypeKind type_kind)
|
||||
{
|
||||
return type_kind <= TYPE_VOID || type_kind > TYPE_ARRAY;
|
||||
}
|
||||
|
||||
|
||||
bool cast_to_runtime(Expr *expr)
|
||||
|
||||
@@ -27,6 +27,8 @@ static bool expr_is_ltype(Expr *expr)
|
||||
return expr->unary_expr.operator == TOKEN_STAR;
|
||||
case EXPR_ACCESS:
|
||||
return expr_is_ltype(expr->access_expr.parent);
|
||||
case EXPR_SUBSCRIPT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -163,7 +165,6 @@ static inline bool sema_expr_analyse_call(Context *context, Type *to, Expr *expr
|
||||
default:
|
||||
SEMA_ERROR(expr->loc, "The expression cannot be called.");
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +180,33 @@ static inline bool sema_expr_analyse_struct_init_values(Context *context, Type *
|
||||
|
||||
static inline bool sema_expr_analyse_subscript(Context *context, Type *to, Expr *expr)
|
||||
{
|
||||
TODO
|
||||
if (!sema_analyse_expr(context, NULL, expr->subscript_expr.expr)) return false;
|
||||
|
||||
Type *type = expr->subscript_expr.expr->type->canonical;
|
||||
Type *inner_type;
|
||||
switch (type->type_kind)
|
||||
{
|
||||
case TYPE_POINTER:
|
||||
inner_type = type->pointer;
|
||||
break;
|
||||
case TYPE_VARARRAY:
|
||||
case TYPE_ARRAY:
|
||||
inner_type = type->array.base;
|
||||
break;
|
||||
case TYPE_SUBARRAY:
|
||||
TODO
|
||||
case TYPE_STRING:
|
||||
inner_type = type_char;
|
||||
break;
|
||||
default:
|
||||
SEMA_ERROR(expr->subscript_expr.expr->loc, "Cannot index '%s'.", type_to_error_string(type));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sema_analyse_expr(context, type_isize, expr->subscript_expr.index)) return false;
|
||||
|
||||
expr->type = inner_type;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool sema_expr_analyse_method_function(Context *context, Expr *expr, Decl *decl, bool is_pointer)
|
||||
@@ -1445,6 +1472,8 @@ static inline bool sema_analyse_expr_dispatch(Context *context, Type *to, Expr *
|
||||
}
|
||||
UNREACHABLE
|
||||
}
|
||||
|
||||
|
||||
bool sema_analyse_expr(Context *context, Type *to, Expr *expr)
|
||||
{
|
||||
switch (expr->resolve_status)
|
||||
|
||||
@@ -5,54 +5,63 @@
|
||||
#include "llvm_codegen_internal.h"
|
||||
#include "compiler_internal.h"
|
||||
|
||||
static inline LLVMValueRef gencontext_emit_subscript_addr(GenContext *context, Expr *expr)
|
||||
{
|
||||
LLVMValueRef index = gencontext_emit_expr(context, expr->subscript_expr.index);
|
||||
switch (expr->subscript_expr.expr->type->canonical->type_kind)
|
||||
{
|
||||
case TYPE_ARRAY:
|
||||
TODO
|
||||
case TYPE_POINTER:
|
||||
return LLVMBuildGEP(context->builder,
|
||||
gencontext_emit_expr(context, expr->subscript_expr.expr),
|
||||
&index, 1, "[]");
|
||||
case TYPE_VARARRAY:
|
||||
case TYPE_SUBARRAY:
|
||||
case TYPE_STRING:
|
||||
TODO
|
||||
default:
|
||||
UNREACHABLE
|
||||
}
|
||||
}
|
||||
|
||||
static inline LLVMValueRef gencontext_emit_access_addr(GenContext *context, Expr *expr)
|
||||
{
|
||||
LLVMValueRef value = gencontext_emit_address(context, expr->access_expr.parent);
|
||||
return LLVMBuildStructGEP(context->builder, value, (unsigned)expr->access_expr.index, "");
|
||||
}
|
||||
|
||||
LLVMValueRef gencontext_emit_address(GenContext *context, Expr *expr)
|
||||
{
|
||||
switch (expr->expr_kind)
|
||||
{
|
||||
case EXPR_IDENTIFIER:
|
||||
return expr->identifier_expr.decl->var.backend_ref;
|
||||
case EXPR_UNARY:
|
||||
assert(unaryop_from_token(expr->unary_expr.operator) == UNARYOP_DEREF);
|
||||
return gencontext_emit_expr(context, expr->unary_expr.expr);
|
||||
case EXPR_ACCESS:
|
||||
return gencontext_emit_access_addr(context, expr);
|
||||
case EXPR_SUBSCRIPT:
|
||||
return gencontext_emit_subscript_addr(context, expr);
|
||||
case EXPR_CONST:
|
||||
case EXPR_TYPE:
|
||||
UNREACHABLE
|
||||
case EXPR_UNARY:
|
||||
{
|
||||
UnaryOp op = unaryop_from_token(expr->unary_expr.operator);
|
||||
assert(op == UNARYOP_DEREF);
|
||||
return gencontext_emit_expr(context, expr->unary_expr.expr);
|
||||
}
|
||||
case EXPR_ACCESS:
|
||||
{
|
||||
LLVMValueRef value = gencontext_emit_address(context, expr->access_expr.parent);
|
||||
return LLVMBuildStructGEP(context->builder, value, (unsigned)expr->access_expr.index, "");
|
||||
}
|
||||
case EXPR_POISONED:
|
||||
case EXPR_TRY:
|
||||
case EXPR_SIZEOF:
|
||||
UNREACHABLE
|
||||
case EXPR_BINARY:
|
||||
TODO;
|
||||
case EXPR_CONDITIONAL:
|
||||
TODO;
|
||||
case EXPR_POST_UNARY:
|
||||
TODO;
|
||||
case EXPR_TYPE_ACCESS:
|
||||
TODO
|
||||
case EXPR_CALL:
|
||||
TODO
|
||||
case EXPR_SUBSCRIPT:
|
||||
TODO
|
||||
case EXPR_STRUCT_VALUE:
|
||||
TODO
|
||||
case EXPR_STRUCT_INIT_VALUES:
|
||||
TODO
|
||||
case EXPR_INITIALIZER_LIST:
|
||||
TODO
|
||||
case EXPR_EXPRESSION_LIST:
|
||||
TODO
|
||||
case EXPR_CAST:
|
||||
TODO
|
||||
UNREACHABLE
|
||||
}
|
||||
return NULL;
|
||||
UNREACHABLE
|
||||
}
|
||||
|
||||
static inline LLVMValueRef gencontext_emit_cast_expr(GenContext *context, Expr *expr)
|
||||
@@ -98,7 +107,6 @@ static inline LLVMValueRef gencontext_emit_cast_expr(GenContext *context, Expr *
|
||||
return type_convert_will_trunc(expr->type, expr->cast_expr.expr->type)
|
||||
? LLVMBuildTrunc(context->builder, rhs, BACKEND_TYPE(expr->type), "siuitrunc")
|
||||
: LLVMBuildZExt(context->builder, rhs, BACKEND_TYPE(expr->type), "siuiext");
|
||||
break;
|
||||
case CAST_SIFP:
|
||||
return LLVMBuildSIToFP(context->builder, rhs, BACKEND_TYPE(expr->type), "sifp");
|
||||
case CAST_XIPTR:
|
||||
@@ -421,7 +429,7 @@ LLVMValueRef gencontext_emit_const_expr(GenContext *context, Expr *expr)
|
||||
LLVMSetInitializer(global_name, LLVMConstStringInContext(context->context,
|
||||
expr->const_expr.string.chars,
|
||||
expr->const_expr.string.len,
|
||||
1));
|
||||
0));
|
||||
return global_name;
|
||||
}
|
||||
}
|
||||
@@ -444,6 +452,48 @@ LLVMValueRef gencontext_emit_call_expr(GenContext *context, Expr *expr)
|
||||
LLVMSetInstructionCallConv(fncallret, LLVMX86StdcallCallConv);
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static inline LLVMValueRef gencontext_emit_access_expr(GenContext *context, Expr *expr)
|
||||
{
|
||||
// Improve, add string description to the access?
|
||||
LLVMValueRef value = gencontext_emit_address(context, expr->access_expr.parent);
|
||||
LLVMValueRef val = LLVMBuildStructGEP(context->builder, value, (unsigned)expr->access_expr.index, "");
|
||||
return LLVMBuildLoad2(context->builder, gencontext_get_llvm_type(context, expr->type), val, "");
|
||||
}
|
||||
|
||||
static inline LLVMValueRef gencontext_emit_expression_list_expr(GenContext *context, Expr *expr)
|
||||
{
|
||||
LLVMValueRef value = NULL;
|
||||
VECEACH(expr->expression_list, i)
|
||||
{
|
||||
value = gencontext_emit_expr(context, expr->expression_list[i]);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline LLVMValueRef gencontext_emit_struct_value_expr(GenContext *context, Expr *expr)
|
||||
{
|
||||
TODO
|
||||
}
|
||||
|
||||
static inline LLVMValueRef gencontext_emit_initializer_list_expr(GenContext *context, Expr *expr)
|
||||
{
|
||||
TODO
|
||||
}
|
||||
|
||||
static inline LLVMValueRef gencontext_emit_struct_init_values_expr(GenContext *context, Expr *expr)
|
||||
{
|
||||
TODO
|
||||
}
|
||||
|
||||
static inline LLVMValueRef gencontext_load_expr(GenContext *context, LLVMValueRef value)
|
||||
{
|
||||
return LLVMBuildLoad(context->builder, value, "");
|
||||
}
|
||||
|
||||
LLVMValueRef gencontext_emit_expr(GenContext *context, Expr *expr)
|
||||
{
|
||||
switch (expr->expr_kind)
|
||||
@@ -452,8 +502,6 @@ LLVMValueRef gencontext_emit_expr(GenContext *context, Expr *expr)
|
||||
UNREACHABLE
|
||||
case EXPR_UNARY:
|
||||
return gencontext_emit_unary_expr(context, expr);
|
||||
case EXPR_TRY:
|
||||
break;
|
||||
case EXPR_CONST:
|
||||
return gencontext_emit_const_expr(context, expr);
|
||||
case EXPR_BINARY:
|
||||
@@ -463,33 +511,28 @@ LLVMValueRef gencontext_emit_expr(GenContext *context, Expr *expr)
|
||||
case EXPR_POST_UNARY:
|
||||
return gencontext_emit_post_unary_expr(context, expr);
|
||||
case EXPR_TYPE:
|
||||
break;
|
||||
case EXPR_IDENTIFIER:
|
||||
return gencontext_emit_identifier_expr(context, expr);
|
||||
case EXPR_SIZEOF:
|
||||
case EXPR_TYPE_ACCESS:
|
||||
break;
|
||||
case EXPR_TRY:
|
||||
// These are folded in the semantic analysis step.
|
||||
UNREACHABLE
|
||||
case EXPR_IDENTIFIER:
|
||||
case EXPR_SUBSCRIPT:
|
||||
return gencontext_load_expr(context, gencontext_emit_address(context, expr));
|
||||
case EXPR_CALL:
|
||||
return gencontext_emit_call_expr(context, expr);
|
||||
case EXPR_SIZEOF:
|
||||
break;
|
||||
case EXPR_SUBSCRIPT:
|
||||
break;
|
||||
case EXPR_ACCESS:
|
||||
{
|
||||
LLVMValueRef value = gencontext_emit_address(context, expr->access_expr.parent);
|
||||
LLVMValueRef val = LLVMBuildStructGEP(context->builder, value, (unsigned)expr->access_expr.index, "");
|
||||
return LLVMBuildLoad2(context->builder, gencontext_get_llvm_type(context, expr->type), val, "");
|
||||
}
|
||||
return gencontext_emit_access_expr(context, expr);
|
||||
case EXPR_STRUCT_VALUE:
|
||||
break;
|
||||
return gencontext_emit_struct_value_expr(context, expr);
|
||||
case EXPR_STRUCT_INIT_VALUES:
|
||||
break;
|
||||
return gencontext_emit_struct_init_values_expr(context, expr);
|
||||
case EXPR_INITIALIZER_LIST:
|
||||
break;
|
||||
return gencontext_emit_initializer_list_expr(context, expr);
|
||||
case EXPR_EXPRESSION_LIST:
|
||||
break;
|
||||
return gencontext_emit_expression_list_expr(context, expr);
|
||||
case EXPR_CAST:
|
||||
return gencontext_emit_cast_expr(context, expr);
|
||||
}
|
||||
TODO
|
||||
UNREACHABLE
|
||||
}
|
||||
@@ -13,5 +13,5 @@ void bench_begin(void)
|
||||
}
|
||||
double bench_mark(void)
|
||||
{
|
||||
return (clock() - begin) / (double)CLOCKS_PER_SEC;
|
||||
return (double)(clock() - begin) / (double)CLOCKS_PER_SEC;
|
||||
}
|
||||
@@ -59,7 +59,6 @@ char *read_file(const char *path, size_t *return_size)
|
||||
if (file == NULL)
|
||||
{
|
||||
error_exit("Could not open file \"%s\".\n", path);
|
||||
exit(74);
|
||||
}
|
||||
|
||||
fseek(file, 0L, SEEK_END);
|
||||
|
||||
@@ -28,11 +28,11 @@ static inline bool is_power_of_two(uint64_t x)
|
||||
static inline uint32_t nextHighestPowerOf2(uint32_t v)
|
||||
{
|
||||
v--;
|
||||
v |= v >> 1u;
|
||||
v |= v >> 2u;
|
||||
v |= v >> 4u;
|
||||
v |= v >> 8u;
|
||||
v |= v >> 16u;
|
||||
v |= v >> 1U;
|
||||
v |= v >> 2U;
|
||||
v |= v >> 4U;
|
||||
v |= v >> 8U;
|
||||
v |= v >> 16U;
|
||||
v++;
|
||||
return v;
|
||||
}
|
||||
@@ -66,12 +66,12 @@ static inline bool is_oct_or_(char c)
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool is_binary(c)
|
||||
static inline bool is_binary(char c)
|
||||
{
|
||||
return c == '0' || c == '1';
|
||||
}
|
||||
|
||||
static inline bool is_binary_or_(c)
|
||||
static inline bool is_binary_or_(char c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
@@ -251,10 +251,10 @@ static inline void* _expand(void *vec, size_t element_size)
|
||||
header->size++;
|
||||
if (header->size == header->capacity)
|
||||
{
|
||||
_VHeader *new_array = _vec_new(element_size, header->capacity << 1u);
|
||||
_VHeader *new_array = _vec_new(element_size, header->capacity << 1U);
|
||||
memcpy(new_array, header, element_size * header->capacity + sizeof(_VHeader));
|
||||
header = new_array;
|
||||
new_array->capacity = header->capacity << 1u;
|
||||
new_array->capacity = header->capacity << 1U;
|
||||
vec = header + 1;
|
||||
}
|
||||
return vec;
|
||||
|
||||
Reference in New Issue
Block a user