Support for subscripts. Added helloworld.

This commit is contained in:
Christoffer Lerno
2019-12-11 17:22:48 +01:00
parent fc3bd57ecf
commit 946ca18cee
10 changed files with 181 additions and 196 deletions

View File

@@ -154,6 +154,6 @@ add_executable(c3c
src/compiler/llvm_codegen_type.c src/compiler/llvm_codegen_type.c
src/compiler/llvm_codegen_function.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})

View File

@@ -0,0 +1,8 @@
module helloworld;
func void printf(char *str);
func void main()
{
printf("Hello World!\n");
}

View File

@@ -92,6 +92,17 @@ func int main(int x)
Test2 efe; Test2 efe;
efe.t.a = 3; efe.t.a = 3;
if (efe.t.a > 2) printf("Works!\n"); 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; byte a = 2;
short b = 3; short b = 3;
@@ -103,8 +114,21 @@ JUMP:
i = i + 1; i = i + 1;
//@hello(); //@hello();
printf("Hello worldABC" "D" "E\u2701\n"); printf("Hello worldABC" "D" "E\u2701\n");
float f = 10.0; float f = 3.0;
float* pf = &f; 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; if (*pf > i) goto JUMP;
goto EX; goto EX;
YEF: YEF:
@@ -161,5 +185,6 @@ func void test2(int* x, int y, int z)
i = i - 1; i = i - 1;
ui = ui - 1; ui = ui - 1;
x + 1; x + 1;
// TODO x + 1; int j1 = x[0];
j1 = *x;
} }

View File

@@ -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) 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; size_t digit_bit_index = index % 64;
const uint64_t *digits = bigint_ptr(big_int); const uint64_t *digits = bigint_ptr(big_int);
uint64_t digit = digits[digit_index]; 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) 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;;) 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) if (digit_index == last_digit_index)
{ {
buf[buf_index + byte_index - unwritten_byte_count] = byte; 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; if (byte_index == 0) break;
byte_index -= 1; byte_index -= 1;
x >>= 8; x >>= 8U;
} }
if (digit_index == 0) break; 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 < 8 && (digit_index + 1 < digit_count || byte_index < bytes_in_last_digit);
byte_index += 1) byte_index += 1)
{ {
uint8_t byte = (uint8_t) (x & 0xff); uint8_t byte = (uint8_t) (x & 0xffU);
buf[buf_index] = byte; buf[buf_index] = byte;
buf_index += 1; 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]; uint8_t byte = buf[buf_index];
buf_index += 1; buf_index += 1;
digit <<= 8; digit <<= 8U;
digit |= byte; digit |= byte;
} }
digits[dest->digit_count - 1] = digit; 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; u[m + n] = u_carry;
// D2. [Initialize j.] Set j to m. This is the loop counter over the places. // D2. [Initialize j.] Set j to m. This is the loop counter over the places.
int j = m; int j = (int)m;
do do
{ {
// D3. [Calculate q'.]. // 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) if (shift)
{ {
uint32_t carry = 0; 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; r[i] = (u[i] >> shift) | carry;
carry = u[i] << (32 - shift); 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 else
{ {
for (int i = n - 1; i >= 0; i--) for (int i = (int)n - 1; i >= 0; i--)
{ {
r[i] = u[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 divisor = V[0];
uint32_t rem = 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]); uint64_t partial_dividend = make_64(rem, U[i]);
if (partial_dividend == 0) 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); return bigint->is_negative ? bigint_as_signed(bigint) : bigint_as_unsigned(bigint);
} }
BigInt div; BigInt div;
uint64_t mult = 0x100000000000ull; uint64_t mult = 0x100000000000ULL;
long double mul = 1; long double mul = 1;
bigint_init_unsigned(&div, mult); bigint_init_unsigned(&div, mult);
BigInt current; BigInt current;

View File

@@ -538,125 +538,6 @@ bool vapt(Expr* left, Type *from, Type *canonical, Type *type, CastType cast_typ
TODO 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) bool cast_to_runtime(Expr *expr)

View File

@@ -27,6 +27,8 @@ static bool expr_is_ltype(Expr *expr)
return expr->unary_expr.operator == TOKEN_STAR; return expr->unary_expr.operator == TOKEN_STAR;
case EXPR_ACCESS: case EXPR_ACCESS:
return expr_is_ltype(expr->access_expr.parent); return expr_is_ltype(expr->access_expr.parent);
case EXPR_SUBSCRIPT:
return true;
default: default:
return false; return false;
} }
@@ -163,7 +165,6 @@ static inline bool sema_expr_analyse_call(Context *context, Type *to, Expr *expr
default: default:
SEMA_ERROR(expr->loc, "The expression cannot be called."); SEMA_ERROR(expr->loc, "The expression cannot be called.");
return false; 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) static inline bool sema_expr_analyse_subscript(Context *context, Type *to, Expr *expr)
{ {
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 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) 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 UNREACHABLE
} }
bool sema_analyse_expr(Context *context, Type *to, Expr *expr) bool sema_analyse_expr(Context *context, Type *to, Expr *expr)
{ {
switch (expr->resolve_status) switch (expr->resolve_status)

View File

@@ -5,54 +5,63 @@
#include "llvm_codegen_internal.h" #include "llvm_codegen_internal.h"
#include "compiler_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) LLVMValueRef gencontext_emit_address(GenContext *context, Expr *expr)
{ {
switch (expr->expr_kind) switch (expr->expr_kind)
{ {
case EXPR_IDENTIFIER: case EXPR_IDENTIFIER:
return expr->identifier_expr.decl->var.backend_ref; 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_CONST:
case EXPR_TYPE: 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_POISONED:
case EXPR_TRY: case EXPR_TRY:
case EXPR_SIZEOF: case EXPR_SIZEOF:
UNREACHABLE
case EXPR_BINARY: case EXPR_BINARY:
TODO;
case EXPR_CONDITIONAL: case EXPR_CONDITIONAL:
TODO;
case EXPR_POST_UNARY: case EXPR_POST_UNARY:
TODO;
case EXPR_TYPE_ACCESS: case EXPR_TYPE_ACCESS:
TODO
case EXPR_CALL: case EXPR_CALL:
TODO
case EXPR_SUBSCRIPT:
TODO
case EXPR_STRUCT_VALUE: case EXPR_STRUCT_VALUE:
TODO
case EXPR_STRUCT_INIT_VALUES: case EXPR_STRUCT_INIT_VALUES:
TODO
case EXPR_INITIALIZER_LIST: case EXPR_INITIALIZER_LIST:
TODO
case EXPR_EXPRESSION_LIST: case EXPR_EXPRESSION_LIST:
TODO
case EXPR_CAST: case EXPR_CAST:
TODO UNREACHABLE
} }
return NULL; UNREACHABLE
} }
static inline LLVMValueRef gencontext_emit_cast_expr(GenContext *context, Expr *expr) 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) return type_convert_will_trunc(expr->type, expr->cast_expr.expr->type)
? LLVMBuildTrunc(context->builder, rhs, BACKEND_TYPE(expr->type), "siuitrunc") ? LLVMBuildTrunc(context->builder, rhs, BACKEND_TYPE(expr->type), "siuitrunc")
: LLVMBuildZExt(context->builder, rhs, BACKEND_TYPE(expr->type), "siuiext"); : LLVMBuildZExt(context->builder, rhs, BACKEND_TYPE(expr->type), "siuiext");
break;
case CAST_SIFP: case CAST_SIFP:
return LLVMBuildSIToFP(context->builder, rhs, BACKEND_TYPE(expr->type), "sifp"); return LLVMBuildSIToFP(context->builder, rhs, BACKEND_TYPE(expr->type), "sifp");
case CAST_XIPTR: case CAST_XIPTR:
@@ -421,7 +429,7 @@ LLVMValueRef gencontext_emit_const_expr(GenContext *context, Expr *expr)
LLVMSetInitializer(global_name, LLVMConstStringInContext(context->context, LLVMSetInitializer(global_name, LLVMConstStringInContext(context->context,
expr->const_expr.string.chars, expr->const_expr.string.chars,
expr->const_expr.string.len, expr->const_expr.string.len,
1)); 0));
return global_name; return global_name;
} }
} }
@@ -444,6 +452,48 @@ LLVMValueRef gencontext_emit_call_expr(GenContext *context, Expr *expr)
LLVMSetInstructionCallConv(fncallret, LLVMX86StdcallCallConv); 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) LLVMValueRef gencontext_emit_expr(GenContext *context, Expr *expr)
{ {
switch (expr->expr_kind) switch (expr->expr_kind)
@@ -452,8 +502,6 @@ LLVMValueRef gencontext_emit_expr(GenContext *context, Expr *expr)
UNREACHABLE UNREACHABLE
case EXPR_UNARY: case EXPR_UNARY:
return gencontext_emit_unary_expr(context, expr); return gencontext_emit_unary_expr(context, expr);
case EXPR_TRY:
break;
case EXPR_CONST: case EXPR_CONST:
return gencontext_emit_const_expr(context, expr); return gencontext_emit_const_expr(context, expr);
case EXPR_BINARY: case EXPR_BINARY:
@@ -463,33 +511,28 @@ LLVMValueRef gencontext_emit_expr(GenContext *context, Expr *expr)
case EXPR_POST_UNARY: case EXPR_POST_UNARY:
return gencontext_emit_post_unary_expr(context, expr); return gencontext_emit_post_unary_expr(context, expr);
case EXPR_TYPE: case EXPR_TYPE:
break; case EXPR_SIZEOF:
case EXPR_IDENTIFIER:
return gencontext_emit_identifier_expr(context, expr);
case EXPR_TYPE_ACCESS: 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: case EXPR_CALL:
return gencontext_emit_call_expr(context, expr); return gencontext_emit_call_expr(context, expr);
case EXPR_SIZEOF:
break;
case EXPR_SUBSCRIPT:
break;
case EXPR_ACCESS: case EXPR_ACCESS:
{ return gencontext_emit_access_expr(context, expr);
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, "");
}
case EXPR_STRUCT_VALUE: case EXPR_STRUCT_VALUE:
break; return gencontext_emit_struct_value_expr(context, expr);
case EXPR_STRUCT_INIT_VALUES: case EXPR_STRUCT_INIT_VALUES:
break; return gencontext_emit_struct_init_values_expr(context, expr);
case EXPR_INITIALIZER_LIST: case EXPR_INITIALIZER_LIST:
break; return gencontext_emit_initializer_list_expr(context, expr);
case EXPR_EXPRESSION_LIST: case EXPR_EXPRESSION_LIST:
break; return gencontext_emit_expression_list_expr(context, expr);
case EXPR_CAST: case EXPR_CAST:
return gencontext_emit_cast_expr(context, expr); return gencontext_emit_cast_expr(context, expr);
} }
TODO UNREACHABLE
} }

View File

@@ -13,5 +13,5 @@ void bench_begin(void)
} }
double bench_mark(void) double bench_mark(void)
{ {
return (clock() - begin) / (double)CLOCKS_PER_SEC; return (double)(clock() - begin) / (double)CLOCKS_PER_SEC;
} }

View File

@@ -59,7 +59,6 @@ char *read_file(const char *path, size_t *return_size)
if (file == NULL) if (file == NULL)
{ {
error_exit("Could not open file \"%s\".\n", path); error_exit("Could not open file \"%s\".\n", path);
exit(74);
} }
fseek(file, 0L, SEEK_END); fseek(file, 0L, SEEK_END);

View File

@@ -28,11 +28,11 @@ static inline bool is_power_of_two(uint64_t x)
static inline uint32_t nextHighestPowerOf2(uint32_t v) static inline uint32_t nextHighestPowerOf2(uint32_t v)
{ {
v--; v--;
v |= v >> 1u; v |= v >> 1U;
v |= v >> 2u; v |= v >> 2U;
v |= v >> 4u; v |= v >> 4U;
v |= v >> 8u; v |= v >> 8U;
v |= v >> 16u; v |= v >> 16U;
v++; v++;
return 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'; return c == '0' || c == '1';
} }
static inline bool is_binary_or_(c) static inline bool is_binary_or_(char c)
{ {
switch (c) switch (c)
{ {
@@ -251,10 +251,10 @@ static inline void* _expand(void *vec, size_t element_size)
header->size++; header->size++;
if (header->size == header->capacity) 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)); memcpy(new_array, header, element_size * header->capacity + sizeof(_VHeader));
header = new_array; header = new_array;
new_array->capacity = header->capacity << 1u; new_array->capacity = header->capacity << 1U;
vec = header + 1; vec = header + 1;
} }
return vec; return vec;