Restructuring
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
117
core_types.h
117
core_types.h
@@ -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);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user