Restructuring

This commit is contained in:
Krzosa Karol
2022-09-29 13:02:32 +02:00
parent cbf6ca8480
commit 65924967aa
5 changed files with 62 additions and 223 deletions

View File

@@ -2,11 +2,6 @@
// Use of this source code is governed by the GNU LGPLv3.0 license // Use of this source code is governed by the GNU LGPLv3.0 license
// a copy of which can be found in the LICENSE file. // 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) #define Set_BigInt_Allocator(x) BigInt_Allocator bigint_allocator(x)
struct BigInt_Allocator{ struct BigInt_Allocator{
Allocator *old; Allocator *old;
@@ -14,76 +9,6 @@ struct BigInt_Allocator{
~BigInt_Allocator(){bigint_allocator = old;} ~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 <inttypes.h>
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 function BigInt
bigint_u64(U64 value){ bigint_u64(U64 value){
BigInt result; BigInt result;

View File

@@ -4,8 +4,6 @@ struct Ast_File_Namespace;
struct Ast_File; struct Ast_File;
struct Ast_Module; struct Ast_Module;
struct Ast_Type; 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{ enum Token_Kind{
TK_End, TK_End,
@@ -155,30 +153,6 @@ struct Lexer{
// Parser::ast_arena - arena for asts // Parser::ast_arena - arena for asts
// Lexer::interns::string_allocator - arena for interns // 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{ struct Parse_Ctx:Lexer{
Allocator *perm; // Stores: AST, tokens, interns Allocator *perm; // Stores: AST, tokens, interns
@@ -212,9 +186,9 @@ struct Parse_Ctx:Lexer{
String_Builder gen; String_Builder gen;
String_Builder helper_builder; String_Builder helper_builder;
}; };
thread_local Parse_Ctx *pctx;
global B32 emit_line_directives;
function void init_type(); function void init_type();
function void lex_init(Allocator *token_string_arena, Allocator *map_allocator, Lexer *l); function void lex_init(Allocator *token_string_arena, Allocator *map_allocator, Lexer *l);
function String compile_to_c_code(); 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);

View File

@@ -231,10 +231,12 @@ For modules it's a bit different cause they should be distributed as valid.
#include "base.cpp" #include "base.cpp"
#include "base_unicode.cpp" #include "base_unicode.cpp"
#include "os_windows.cpp" #include "os_windows.cpp"
#include "c3_big_int.cpp" #include "c3_big_int.h"
#include "core_compiler.h" #include "core_compiler.h"
#include "core_lexing.cpp"
#include "core_types.h" #include "core_types.h"
#include "core_globals.cpp"
#include "c3_big_int.cpp"
#include "core_lexing.cpp"
#include "core_ast.cpp" #include "core_ast.cpp"
#include "core_parsing.cpp" #include "core_parsing.cpp"
#include "core_typechecking.h" #include "core_typechecking.h"

View File

@@ -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 "<unknown_type>";
}
//-----------------------------------------------------------------------------
// 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 function Resolve_Flag
inherit_flag(Resolve_Flag flag, B32 ast_can_be_null){ inherit_flag(Resolve_Flag flag, B32 ast_can_be_null){
unset_flag(flag, AST_CAN_BE_NULL); unset_flag(flag, AST_CAN_BE_NULL);

View File

@@ -105,120 +105,3 @@ struct Ast_Type{
}func; }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 "<unknown_type>";
}
//-----------------------------------------------------------------------------
// 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);
}