From 65924967aa83c1122670d2033743672f5aafb9b0 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Thu, 29 Sep 2022 13:02:32 +0200 Subject: [PATCH] Restructuring --- c3_big_int.cpp | 75 --------------------------- core_compiler.h | 32 ++---------- core_main.cpp | 6 ++- core_typechecking.cpp | 55 ++++++++++++++++++++ core_types.h | 117 ------------------------------------------ 5 files changed, 62 insertions(+), 223 deletions(-) diff --git a/c3_big_int.cpp b/c3_big_int.cpp index bc2b8d4..86e3f96 100644 --- a/c3_big_int.cpp +++ b/c3_big_int.cpp @@ -2,11 +2,6 @@ // Use of this source code is governed by the GNU LGPLv3.0 license // a copy of which can be found in the LICENSE file. -struct Token; -Allocator *bigint_allocator; -global S64 bigint_allocation_count; -function void compiler_error(Token *token, const char *str, ...); - #define Set_BigInt_Allocator(x) BigInt_Allocator bigint_allocator(x) struct BigInt_Allocator{ Allocator *old; @@ -14,76 +9,6 @@ struct BigInt_Allocator{ ~BigInt_Allocator(){bigint_allocator = old;} }; -#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) - -struct BigInt -{ - unsigned digit_count; - bool is_negative; - union { - uint64_t digit; - uint64_t *digits; - }; -}; - -#include -enum CmpRes -{ - CMP_LT, - CMP_GT, - CMP_EQ, -}; - -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); - -//----------------------------------------------------------------------------- -// -//----------------------------------------------------------------------------- function BigInt bigint_u64(U64 value){ BigInt result; diff --git a/core_compiler.h b/core_compiler.h index 5df26b4..90dfbd2 100644 --- a/core_compiler.h +++ b/core_compiler.h @@ -4,8 +4,6 @@ struct Ast_File_Namespace; struct Ast_File; struct Ast_Module; struct Ast_Type; -function Ast_Module *ast_module(Token *pos, Intern_String filename); -function void insert_builtin_types_into_scope(Ast_Scope *p); enum Token_Kind{ TK_End, @@ -155,30 +153,6 @@ struct Lexer{ // Parser::ast_arena - arena for asts // Lexer::interns::string_allocator - arena for interns // -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; struct Parse_Ctx:Lexer{ Allocator *perm; // Stores: AST, tokens, interns @@ -212,9 +186,9 @@ struct Parse_Ctx:Lexer{ String_Builder gen; String_Builder helper_builder; }; -thread_local Parse_Ctx *pctx; -global B32 emit_line_directives; function void init_type(); function void lex_init(Allocator *token_string_arena, Allocator *map_allocator, Lexer *l); -function String compile_to_c_code(); \ No newline at end of file +function String compile_to_c_code(); +function Ast_Module *ast_module(Token *pos, Intern_String filename); +function void insert_builtin_types_into_scope(Ast_Scope *p); diff --git a/core_main.cpp b/core_main.cpp index 8c3f4bb..29d3ce0 100644 --- a/core_main.cpp +++ b/core_main.cpp @@ -231,10 +231,12 @@ For modules it's a bit different cause they should be distributed as valid. #include "base.cpp" #include "base_unicode.cpp" #include "os_windows.cpp" -#include "c3_big_int.cpp" +#include "c3_big_int.h" #include "core_compiler.h" -#include "core_lexing.cpp" #include "core_types.h" +#include "core_globals.cpp" +#include "c3_big_int.cpp" +#include "core_lexing.cpp" #include "core_ast.cpp" #include "core_parsing.cpp" #include "core_typechecking.h" diff --git a/core_typechecking.cpp b/core_typechecking.cpp index eb19e49..f3b40d9 100644 --- a/core_typechecking.cpp +++ b/core_typechecking.cpp @@ -1,4 +1,59 @@ +function const char * +name(Ast_Type *type){ + switch(type->kind){ + case TYPE_VOID: return "void"; + case TYPE_BOOL: return "Bool"; + case TYPE_STRING: return "String"; + case TYPE_CHAR: return "char"; + case TYPE_F32: return "F32"; + case TYPE_F64: return "F64"; + case TYPE_S8: return "S8"; + case TYPE_INT: return "int"; + case TYPE_S16: return "S16"; + case TYPE_S32: return "S32"; + case TYPE_S64: return "S64"; + case TYPE_U8: return "U8"; + case TYPE_U16: return "U16"; + case TYPE_U32: return "U32"; + case TYPE_U64: return "U64"; + case TYPE_TUPLE: return "Tuple"; + case TYPE_TYPE: return "Type"; + invalid_default_case; + } + return ""; +} + +//----------------------------------------------------------------------------- +// Type constructors and utillities +//----------------------------------------------------------------------------- +force_inline B32 is_any(Ast_Type *a){return a == type_any;} +force_inline B32 is_struct(Ast_Type *a){return a->kind == TYPE_STRUCT;} +force_inline B32 is_lambda(Ast_Type *a){return a->kind == TYPE_LAMBDA;} +force_inline B32 is_array(Ast_Type *a){return a->kind == TYPE_ARRAY;} +force_inline B32 is_slice(Ast_Type *a){return a->kind == TYPE_SLICE;} +force_inline B32 is_tuple(Ast_Type *a){return a->kind == TYPE_TUPLE;} +force_inline B32 is_enum(Ast_Type *a){return a->kind == TYPE_ENUM;} +force_inline B32 is_pointer(Ast_Type *a){return a->kind == TYPE_POINTER;} +force_inline B32 is_void(Ast_Type *a){return a->kind == TYPE_VOID;} +force_inline B32 is_void_pointer(Ast_Type *a){return a == type_pointer_to_void;} +force_inline B32 is_string(Ast_Type *a){return a->kind == TYPE_STRING || a->kind == TYPE_UNTYPED_STRING || a == type_pointer_to_char;} +force_inline B32 is_untyped_int(Ast_Type *a){return a->kind == TYPE_UNTYPED_INT;} +force_inline B32 is_typed_int(Ast_Type *a){return (a->kind >= TYPE_S64 && a->kind <= TYPE_U8);} +force_inline B32 is_int(Ast_Type *a){return (a->kind >= TYPE_S64 && a->kind <= TYPE_U8) || a->kind == TYPE_UNTYPED_INT;} +force_inline B32 is_signed_int(Ast_Type *a){return !a->is_unsigned;} +force_inline B32 is_unsigned_int(Ast_Type *a){return a->is_unsigned;} +force_inline B32 is_float(Ast_Type *a){return a->kind == TYPE_F32 || a->kind == TYPE_F64 || a->kind == TYPE_UNTYPED_FLOAT;} +force_inline B32 is_f32(Ast_Type *a){return a->kind == TYPE_F32;} +force_inline B32 is_f64(Ast_Type *a){return a->kind == TYPE_F64;} +force_inline B32 is_bool(Ast_Type *a){return a->kind == TYPE_BOOL || a->kind == TYPE_UNTYPED_BOOL;} +force_inline B32 is_untyped(Ast_Type *a){return a->kind >= TYPE_UNTYPED_FIRST && a->kind <= TYPE_UNTYPED_LAST;} +force_inline B32 is_typed(Ast_Type *a){return !is_untyped(a);} +force_inline B32 is_numeric(Ast_Type *type){ + return (type->kind >= TYPE_UNTYPED_FIRST_NUMERIC && type->kind <= TYPE_UNTYPED_LAST_NUMERIC) || + (type->kind >= TYPE_FIRST_NUMERIC && type->kind <= TYPE_LAST_NUMERIC); +} + function Resolve_Flag inherit_flag(Resolve_Flag flag, B32 ast_can_be_null){ unset_flag(flag, AST_CAN_BE_NULL); diff --git a/core_types.h b/core_types.h index 2a82923..73cf5cb 100644 --- a/core_types.h +++ b/core_types.h @@ -105,120 +105,3 @@ struct Ast_Type{ }func; }; }; - -function const char * -name(Ast_Type *type){ - switch(type->kind){ - case TYPE_VOID: return "void"; - case TYPE_BOOL: return "Bool"; - case TYPE_STRING: return "String"; - case TYPE_CHAR: return "char"; - case TYPE_F32: return "F32"; - case TYPE_F64: return "F64"; - case TYPE_S8: return "S8"; - case TYPE_INT: return "int"; - case TYPE_S16: return "S16"; - case TYPE_S32: return "S32"; - case TYPE_S64: return "S64"; - case TYPE_U8: return "U8"; - case TYPE_U16: return "U16"; - case TYPE_U32: return "U32"; - case TYPE_U64: return "U64"; - case TYPE_TUPLE: return "Tuple"; - case TYPE_TYPE: return "Type"; - invalid_default_case; - } - return ""; -} - -//----------------------------------------------------------------------------- -// 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; - -//----------------------------------------------------------------------------- -// Type constructors and utillities -//----------------------------------------------------------------------------- -force_inline B32 is_any(Ast_Type *a){return a == type_any;} -force_inline B32 is_struct(Ast_Type *a){return a->kind == TYPE_STRUCT;} -force_inline B32 is_lambda(Ast_Type *a){return a->kind == TYPE_LAMBDA;} -force_inline B32 is_array(Ast_Type *a){return a->kind == TYPE_ARRAY;} -force_inline B32 is_slice(Ast_Type *a){return a->kind == TYPE_SLICE;} -force_inline B32 is_tuple(Ast_Type *a){return a->kind == TYPE_TUPLE;} -force_inline B32 is_enum(Ast_Type *a){return a->kind == TYPE_ENUM;} -force_inline B32 is_pointer(Ast_Type *a){return a->kind == TYPE_POINTER;} -force_inline B32 is_void(Ast_Type *a){return a->kind == TYPE_VOID;} -force_inline B32 is_void_pointer(Ast_Type *a){return a == type_pointer_to_void;} -force_inline B32 is_string(Ast_Type *a){return a->kind == TYPE_STRING || a->kind == TYPE_UNTYPED_STRING || a == type_pointer_to_char;} -force_inline B32 is_untyped_int(Ast_Type *a){return a->kind == TYPE_UNTYPED_INT;} -force_inline B32 is_typed_int(Ast_Type *a){return (a->kind >= TYPE_S64 && a->kind <= TYPE_U8);} -force_inline B32 is_int(Ast_Type *a){return (a->kind >= TYPE_S64 && a->kind <= TYPE_U8) || a->kind == TYPE_UNTYPED_INT;} -force_inline B32 is_signed_int(Ast_Type *a){return !a->is_unsigned;} -force_inline B32 is_unsigned_int(Ast_Type *a){return a->is_unsigned;} -force_inline B32 is_float(Ast_Type *a){return a->kind == TYPE_F32 || a->kind == TYPE_F64 || a->kind == TYPE_UNTYPED_FLOAT;} -force_inline B32 is_f32(Ast_Type *a){return a->kind == TYPE_F32;} -force_inline B32 is_f64(Ast_Type *a){return a->kind == TYPE_F64;} -force_inline B32 is_bool(Ast_Type *a){return a->kind == TYPE_BOOL || a->kind == TYPE_UNTYPED_BOOL;} -force_inline B32 is_untyped(Ast_Type *a){return a->kind >= TYPE_UNTYPED_FIRST && a->kind <= TYPE_UNTYPED_LAST;} -force_inline B32 is_typed(Ast_Type *a){return !is_untyped(a);} - -force_inline B32 -is_numeric(Ast_Type *type){ - return (type->kind >= TYPE_UNTYPED_FIRST_NUMERIC && type->kind <= TYPE_UNTYPED_LAST_NUMERIC) || - (type->kind >= TYPE_FIRST_NUMERIC && type->kind <= TYPE_LAST_NUMERIC); -} \ No newline at end of file