diff --git a/c3_big_int.h b/c3_big_int.h new file mode 100644 index 0000000..cdb8c7b --- /dev/null +++ b/c3_big_int.h @@ -0,0 +1,67 @@ +struct Token; +struct BigInt +{ + unsigned digit_count; + bool is_negative; + union { + uint64_t digit; + uint64_t *digits; + }; +}; + +#include +enum CmpRes +{ + CMP_LT, + CMP_GT, + CMP_EQ, +}; + +#define count_bigint_alloc() (bigint_allocator != thread_ctx.scratch ? bigint_allocation_count++ : 0) +#define malloc_arena(x) (count_bigint_alloc(), exp_alloc(bigint_allocator, x, AF_ZeroMemory)) +#define ALLOC_DIGITS(_digits) (uint64_t *)((_digits) ? malloc_arena(sizeof(uint64_t) * (_digits)) : NULL) +#define FATAL_ERROR(x) compiler_error(0, x) + +function void compiler_error(Token *token, const char *str, ...); +const char *bigint_to_error_string(Allocator *allocator, const BigInt *bigint, uint64_t base); +void bigint_init_unsigned(BigInt *big_int, uint64_t value); +void bigint_init_signed(BigInt *big_int, int64_t value); +void bigint_init_bigint(BigInt *dest, const BigInt *src); +void bigint_init_data(BigInt *dest, const uint64_t *digits, unsigned int digit_count, bool is_negative); +void bigint_negate(BigInt *dest, const BigInt *source); +size_t bigint_clz(const BigInt *big_int, size_t bit_count); +size_t bigint_ctz(const BigInt *big_int, size_t bit_count); +bool bigint_fits_in_bits(const BigInt *big_int, size_t bit_count, bool is_signed); +void bigint_write_twos_complement(const BigInt *big_int, uint8_t *buf, size_t bit_count, bool is_big_endian); +void bigint_read_twos_complement(BigInt *dest, const uint8_t *buf, size_t bit_count, bool is_big_endian, bool is_signed); +void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2); +void bigint_add_wrap(BigInt *dest, const BigInt *op1, const BigInt *op2, size_t bit_count, bool is_signed); +void bigint_sub(BigInt *dest, const BigInt *op1, const BigInt *op2); +void bigint_sub_wrap(BigInt *dest, const BigInt *op1, const BigInt *op2, size_t bit_count, bool is_signed); +void bigint_mul(BigInt *dest, const BigInt *op1, const BigInt *op2); +void bigint_mul_wrap(BigInt *dest, const BigInt *op1, const BigInt *op2, size_t bit_count, bool is_signed); +void bigint_rem(BigInt *dest, const BigInt *op1, const BigInt *op2); +void bigint_mod(BigInt *dest, const BigInt *op1, const BigInt *op2); +void bigint_shl(BigInt *dest, const BigInt *op1, const BigInt *op2); +void bigint_shl_int(BigInt *dest, const BigInt *op1, uint64_t shift); +void bigint_shl_trunc(BigInt *dest, const BigInt *op1, const BigInt *op2, size_t bit_count, bool is_signed); +void bigint_shr(BigInt *dest, const BigInt *op1, const BigInt *op2); +void bigint_div_floor(BigInt *dest, const BigInt *op1, const BigInt *op2); +void bigint_or(BigInt *dest, const BigInt *op1, const BigInt *op2); +void bigint_and(BigInt *dest, const BigInt *op1, const BigInt *op2); +void bigint_xor(BigInt *dest, const BigInt *op1, const BigInt *op2); +void bigint_negate_wrap(BigInt *dest, const BigInt *op, size_t bit_count); +void bigint_not(BigInt *dest, const BigInt *op, size_t bit_count, bool is_signed); +bool bigint_eql(BigInt a, BigInt b); +CmpRes bigint_cmp(const BigInt *op1, const BigInt *op2); +CmpRes bigint_cmp_zero(const BigInt *op); +uint32_t bigint_hash(BigInt x); +void bigint_print(BigInt *bigint, uint64_t base); +void bigint_fprint(FILE *file, BigInt *bigint, uint64_t base); +uint64_t bigint_as_unsigned(const BigInt *bigint); +int64_t bigint_as_signed(const BigInt *bigint); +double bigint_as_float(const BigInt *bigint); +void bigint_truncate(BigInt *dst, const BigInt *op, size_t bit_count, bool is_signed); +void bigint_incr(BigInt *x); +size_t bigint_popcount_signed(const BigInt *bi, size_t bit_count); +size_t bigint_popcount_unsigned(const BigInt *big_int); diff --git a/core_globals.cpp b/core_globals.cpp new file mode 100644 index 0000000..19e37bb --- /dev/null +++ b/core_globals.cpp @@ -0,0 +1,93 @@ +thread_local Parse_Ctx *pctx; +thread_local B32 emit_line_directives; + +Allocator *bigint_allocator; +global S64 bigint_allocation_count; + +//----------------------------------------------------------------------------- +// Interns / keywords +//----------------------------------------------------------------------------- +Intern_String keyword_struct; +Intern_String keyword_union; +Intern_String keyword_return; +Intern_String keyword_if; +Intern_String keyword_else; +Intern_String keyword_true; +Intern_String keyword_false; +Intern_String keyword_for; +Intern_String keyword_pass; +Intern_String keyword_default; +Intern_String keyword_switch; +Intern_String keyword_break; +Intern_String keyword_elif; +Intern_String keyword_assert; +Intern_String keyword_enum; + +Intern_String intern_sizeof; +Intern_String intern_alignof; +Intern_String intern_lengthof; +Intern_String intern_void; +Intern_String intern_foreign; +Intern_String intern_it; +Intern_String intern_strict; +Intern_String intern_flag; + +//----------------------------------------------------------------------------- +// Type globals +//----------------------------------------------------------------------------- +const SizeU pointer_size = sizeof(SizeU); +const SizeU pointer_align = __alignof(SizeU); +global Ast_Type type__void = {TYPE_VOID}; +global Ast_Type type__string = {TYPE_STRING, sizeof(String), __alignof(String)}; +global Ast_Type type__bool = {TYPE_BOOL, sizeof(bool), __alignof(bool)}; +global Ast_Type type__type = {TYPE_TYPE, sizeof(S64), __alignof(S64)}; + +global Ast_Type type__f32 = {TYPE_F32, sizeof(F32), __alignof(F32)}; +global Ast_Type type__f64 = {TYPE_F64, sizeof(F64), __alignof(F64)}; + +global Ast_Type type__s8 = {TYPE_S8, sizeof(S8), __alignof(S8)}; +global Ast_Type type__s16 = {TYPE_S16, sizeof(S16), __alignof(S16)}; +global Ast_Type type__s32 = {TYPE_S32, sizeof(S32), __alignof(S32)}; +global Ast_Type type__s64 = {TYPE_S64, sizeof(S64), __alignof(S64)}; + +global Ast_Type type__u8 = {TYPE_U8, sizeof(U8), __alignof(U8), true}; +global Ast_Type type__u16 = {TYPE_U16, sizeof(U16), __alignof(U16), true}; +global Ast_Type type__u32 = {TYPE_U32, sizeof(U32), __alignof(U32), true}; +global Ast_Type type__u64 = {TYPE_U64, sizeof(U64), __alignof(U64), true}; + +global Ast_Type type__untyped_bool = {TYPE_UNTYPED_BOOL, sizeof(bool), __alignof(bool)}; +global Ast_Type type__untyped_int = {TYPE_UNTYPED_INT, sizeof(S64), __alignof(S64)}; +global Ast_Type type__untyped_string = {TYPE_UNTYPED_STRING, sizeof(String), __alignof(String)}; +global Ast_Type type__untyped_float = {TYPE_UNTYPED_FLOAT, sizeof(double), __alignof(double)}; + +global Ast_Type type__char = {TYPE_CHAR, sizeof(char), __alignof(char)}; +global Ast_Type type__int = {TYPE_INT, sizeof(int), __alignof(int)}; +global Ast_Type *type_char = &type__char; +global Ast_Type *type_int = &type__int; +global Ast_Type *type_void = &type__void; + +global Ast_Type *type_pointer_to_char; // Needs to be inited at runtime +global Ast_Type *type_pointer_to_void; // Needs to be inited at runtime +global Ast_Type *type_any; // Needs to be inited at runtime + +global Ast_Type *type_type = &type__type; +global Ast_Type *type_string = &type__string; +global Ast_Type *type_bool = &type__bool; + +global Ast_Type *type_f32 = &type__f32; +global Ast_Type *type_f64 = &type__f64; + +global Ast_Type *type_s8 = &type__s8 ; +global Ast_Type *type_s16 = &type__s16; +global Ast_Type *type_s32 = &type__s32; +global Ast_Type *type_s64 = &type__s64; + +global Ast_Type *type_u8 = &type__u8 ; +global Ast_Type *type_u16 = &type__u16; +global Ast_Type *type_u32 = &type__u32; +global Ast_Type *type_u64 = &type__u64; + +global Ast_Type *untyped_string = &type__untyped_string; +global Ast_Type *untyped_bool = &type__untyped_bool; +global Ast_Type *untyped_int = &type__untyped_int; +global Ast_Type *untyped_float = &type__untyped_float; diff --git a/examples/function_overloading.kl b/examples/function_overloading.kl new file mode 100644 index 0000000..1ac997f --- /dev/null +++ b/examples/function_overloading.kl @@ -0,0 +1,24 @@ + +/* +@todo: Add function overloading +Current plan: + * allow insert_into_scope to insert multiple lambdas + * change resolve_name and search_for_decl to something + that can seek multiple lambda declarations + resolve them and return a match to hash or type + * change the order of lambda call resolution, probably would have to + hash the arguments first to match the lambda call + +*/ +// Add :: (a: int, b: int): int ;; return a + b +// Add :: (a: F32, b: F32): F32 ;; return a + b + +main :: (): int + a: F32 = 3 + b: F32 = 2 + c: int = 4 + d: int = 10 + // e := Add(a, b) + // f := Add(c, d) + + return 0 \ No newline at end of file