CORE_Static
This commit is contained in:
@@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
A statically typed systems programming language that **you shouldn't use**, I'm NOT joking.
|
A statically typed systems programming language that **you shouldn't use**, I'm NOT joking.
|
||||||
The basic premise of the language is simplicity and debuggability,
|
The basic premise of the language is simplicity and debuggability,
|
||||||
reinforcing already useful ideas from C,C++,Go,Odin,Jai and shaving off round edges. In the future it might become
|
reinforcing already useful ideas from C,C++,Go,Odin,Jai and shaving off round edges. In the future it might become a single/two file, easily embeddable library language with optional fixed-size allocation scheme and stb libraries style design.
|
||||||
a single/two file, easily embeddable library language with optional fixed-size allocation scheme.
|
|
||||||
|
|
||||||
## Simple drawing to window example
|
## Simple drawing to window example
|
||||||
|
|
||||||
|
|||||||
84
base.cpp
84
base.cpp
@@ -117,7 +117,7 @@ typedef double F64;
|
|||||||
#define F64MIN DBL_MIN
|
#define F64MIN DBL_MIN
|
||||||
|
|
||||||
#define api
|
#define api
|
||||||
#define function static
|
#define CORE_Static static
|
||||||
#define global static
|
#define global static
|
||||||
#define assert(x) do{if(!(x))Breakpoint;}while(0)
|
#define assert(x) do{if(!(x))Breakpoint;}while(0)
|
||||||
#define assert_message(x,...) assert(x)
|
#define assert_message(x,...) assert(x)
|
||||||
@@ -229,7 +229,7 @@ union Rect2I {
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Utilities
|
// Utilities
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
function size_t
|
CORE_Static size_t
|
||||||
get_align_offset(size_t size, size_t align){
|
get_align_offset(size_t size, size_t align){
|
||||||
size_t mask = align - 1;
|
size_t mask = align - 1;
|
||||||
size_t val = size & mask;
|
size_t val = size & mask;
|
||||||
@@ -239,20 +239,20 @@ get_align_offset(size_t size, size_t align){
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
function size_t
|
CORE_Static size_t
|
||||||
align_up(size_t size, size_t align){
|
align_up(size_t size, size_t align){
|
||||||
size_t result = size + get_align_offset(size, align);
|
size_t result = size + get_align_offset(size, align);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function size_t
|
CORE_Static size_t
|
||||||
align_down(size_t size, size_t align){
|
align_down(size_t size, size_t align){
|
||||||
size += 1; // Make sure 8 when align is 8 doesn't get rounded down to 0
|
size += 1; // Make sure 8 when align is 8 doesn't get rounded down to 0
|
||||||
size_t result = size - (align - get_align_offset(size, align));
|
size_t result = size - (align - get_align_offset(size, align));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
memory_copy(void *dst, void *src, size_t size){
|
memory_copy(void *dst, void *src, size_t size){
|
||||||
U8 *d = (U8*)dst;
|
U8 *d = (U8*)dst;
|
||||||
U8 *s = (U8*)src;
|
U8 *s = (U8*)src;
|
||||||
@@ -261,7 +261,7 @@ memory_copy(void *dst, void *src, size_t size){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
memory_zero(void *p, size_t size){
|
memory_zero(void *p, size_t size){
|
||||||
U8 *pp = (U8 *)p;
|
U8 *pp = (U8 *)p;
|
||||||
for(size_t i = 0; i < size; i++)
|
for(size_t i = 0; i < size; i++)
|
||||||
@@ -306,7 +306,7 @@ T clamp(T min, T val, T max){
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
function U64
|
CORE_Static U64
|
||||||
hash_string(String string) {
|
hash_string(String string) {
|
||||||
U64 hash = (U64)14695981039346656037ULL;
|
U64 hash = (U64)14695981039346656037ULL;
|
||||||
for (U64 i = 0; i < string.len; i++) {
|
for (U64 i = 0; i < string.len; i++) {
|
||||||
@@ -316,19 +316,19 @@ hash_string(String string) {
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
function U64
|
CORE_Static U64
|
||||||
hash_u64(U64 x) {
|
hash_u64(U64 x) {
|
||||||
x *= 0xff51afd7ed558ccd;
|
x *= 0xff51afd7ed558ccd;
|
||||||
x ^= x >> 32;
|
x ^= x >> 32;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
function U64
|
CORE_Static U64
|
||||||
hash_ptr(const void *ptr) {
|
hash_ptr(const void *ptr) {
|
||||||
return hash_u64((uintptr_t)ptr);
|
return hash_u64((uintptr_t)ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
function U64
|
CORE_Static U64
|
||||||
hash_mix(U64 x, U64 y) {
|
hash_mix(U64 x, U64 y) {
|
||||||
// @note: murmur hash 3 mixer but I add the 'y'
|
// @note: murmur hash 3 mixer but I add the 'y'
|
||||||
// which means it's probably bad, hopefully better
|
// which means it's probably bad, hopefully better
|
||||||
@@ -341,14 +341,14 @@ hash_mix(U64 x, U64 y) {
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
function U64
|
CORE_Static U64
|
||||||
is_pow2(U64 x) {
|
is_pow2(U64 x) {
|
||||||
assert(x != 0);
|
assert(x != 0);
|
||||||
B32 result = (x & (x - 1llu)) == 0;
|
B32 result = (x & (x - 1llu)) == 0;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function U64
|
CORE_Static U64
|
||||||
wrap_around_pow2(U64 x, U64 power_of_2) {
|
wrap_around_pow2(U64 x, U64 power_of_2) {
|
||||||
assert(is_pow2(power_of_2));
|
assert(is_pow2(power_of_2));
|
||||||
U64 r = (((x)&((power_of_2)-1llu)));
|
U64 r = (((x)&((power_of_2)-1llu)));
|
||||||
@@ -487,10 +487,10 @@ struct OS_Memory{
|
|||||||
size_t commit, reserve;
|
size_t commit, reserve;
|
||||||
U8 *data;
|
U8 *data;
|
||||||
};
|
};
|
||||||
function OS_Memory os_reserve(size_t size);
|
CORE_Static OS_Memory os_reserve(size_t size);
|
||||||
function B32 os_commit(OS_Memory *m, size_t size);
|
CORE_Static B32 os_commit(OS_Memory *m, size_t size);
|
||||||
function void os_release(OS_Memory *m);
|
CORE_Static void os_release(OS_Memory *m);
|
||||||
function B32 os_decommit_pos(OS_Memory *m, size_t pos);
|
CORE_Static B32 os_decommit_pos(OS_Memory *m, size_t pos);
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Memory arenas
|
// Memory arenas
|
||||||
@@ -504,34 +504,34 @@ struct Arena{
|
|||||||
size_t len;
|
size_t len;
|
||||||
String debug_string;
|
String debug_string;
|
||||||
};
|
};
|
||||||
function void arena_init(Arena *arena, String debug_name);
|
CORE_Static void arena_init(Arena *arena, String debug_name);
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
arena_pop_pos(Arena *arena, size_t pos){
|
arena_pop_pos(Arena *arena, size_t pos){
|
||||||
pos = clamp_top(pos, arena->len);
|
pos = clamp_top(pos, arena->len);
|
||||||
arena->len = pos;
|
arena->len = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void *
|
CORE_Static void *
|
||||||
arena_pop(Arena *arena, size_t size){
|
arena_pop(Arena *arena, size_t size){
|
||||||
size = clamp_top(size, arena->len);
|
size = clamp_top(size, arena->len);
|
||||||
arena->len -= size;
|
arena->len -= size;
|
||||||
return arena->memory.data + arena->len;
|
return arena->memory.data + arena->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
arena_release(Arena *arena){
|
arena_release(Arena *arena){
|
||||||
os_release(&arena->memory);
|
os_release(&arena->memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
arena_clear(Arena *arena){
|
arena_clear(Arena *arena){
|
||||||
arena_pop_pos(arena, 0);
|
arena_pop_pos(arena, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define arena_push_array(a, T, size,...) (T *)arena_push_size(a, sizeof(T)*(size),##__VA_ARGS__)
|
#define arena_push_array(a, T, size,...) (T *)arena_push_size(a, sizeof(T)*(size),##__VA_ARGS__)
|
||||||
#define arena_push_type(a, T, ...) arena_push_array(a, T, 1,##__VA_ARGS__)
|
#define arena_push_type(a, T, ...) arena_push_array(a, T, 1,##__VA_ARGS__)
|
||||||
function void *
|
CORE_Static void *
|
||||||
arena_push_size(Arena *a, size_t size, Alloc_Flag flags = AF_None){
|
arena_push_size(Arena *a, size_t size, Alloc_Flag flags = AF_None){
|
||||||
size_t generous_size = size + a->alignment;
|
size_t generous_size = size + a->alignment;
|
||||||
if(a->len+generous_size>a->memory.commit){
|
if(a->len+generous_size>a->memory.commit){
|
||||||
@@ -554,7 +554,7 @@ arena_push_size(Arena *a, size_t size, Alloc_Flag flags = AF_None){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
arena_init(Arena *a, String debug_name){
|
arena_init(Arena *a, String debug_name){
|
||||||
a->memory = os_reserve(default_reserve_size);
|
a->memory = os_reserve(default_reserve_size);
|
||||||
a->alignment = default_alignment;
|
a->alignment = default_alignment;
|
||||||
@@ -615,7 +615,7 @@ struct Scratch{
|
|||||||
Scratch(Scratch &arena, Scratch &a2);
|
Scratch(Scratch &arena, Scratch &a2);
|
||||||
};
|
};
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
thread_ctx_init(){
|
thread_ctx_init(){
|
||||||
arena_init(thread_ctx.scratch, "Scratch1"_s);
|
arena_init(thread_ctx.scratch, "Scratch1"_s);
|
||||||
arena_init(thread_ctx.scratch+1, "Scratch2"_s);
|
arena_init(thread_ctx.scratch+1, "Scratch2"_s);
|
||||||
@@ -741,7 +741,7 @@ struct Array{
|
|||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
function Array<T>
|
CORE_Static Array<T>
|
||||||
array_make(Arena *a, S64 size = 16){
|
array_make(Arena *a, S64 size = 16){
|
||||||
Array<T> result = {};
|
Array<T> result = {};
|
||||||
result.init(a, size);
|
result.init(a, size);
|
||||||
@@ -756,7 +756,7 @@ array_make(Arena *a, S64 size = 16){
|
|||||||
#define log_info_no_nl(...) handle_log_message(Log_Kind_Normal_No_NewLine, __LINE__, __FILE__,##__VA_ARGS__)
|
#define log_info_no_nl(...) handle_log_message(Log_Kind_Normal_No_NewLine, __LINE__, __FILE__,##__VA_ARGS__)
|
||||||
#define log_trace(...) handle_log_message(Log_Kind_Trace, __LINE__, __FILE__,##__VA_ARGS__)
|
#define log_trace(...) handle_log_message(Log_Kind_Trace, __LINE__, __FILE__,##__VA_ARGS__)
|
||||||
#define log_error(...) handle_log_message(Log_Kind_Error, __LINE__, __FILE__,##__VA_ARGS__)
|
#define log_error(...) handle_log_message(Log_Kind_Error, __LINE__, __FILE__,##__VA_ARGS__)
|
||||||
function void
|
CORE_Static void
|
||||||
handle_log_message(Log_Kind kind, int line, const char *file, const char *str, ...){
|
handle_log_message(Log_Kind kind, int line, const char *file, const char *str, ...){
|
||||||
if(kind == Log_Kind_Trace) return;
|
if(kind == Log_Kind_Trace) return;
|
||||||
|
|
||||||
@@ -806,9 +806,9 @@ struct Map{
|
|||||||
S64 len;
|
S64 len;
|
||||||
S64 cap;
|
S64 cap;
|
||||||
};
|
};
|
||||||
function void map_insert(Map *map, U64 key, void *val);
|
CORE_Static void map_insert(Map *map, U64 key, void *val);
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
map_grow(Map *map, S64 new_size){
|
map_grow(Map *map, S64 new_size){
|
||||||
new_size = max((S64)16, new_size);
|
new_size = max((S64)16, new_size);
|
||||||
assert(new_size > map->cap);
|
assert(new_size > map->cap);
|
||||||
@@ -829,14 +829,14 @@ map_grow(Map *map, S64 new_size){
|
|||||||
*map = new_map;
|
*map = new_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Map
|
CORE_Static Map
|
||||||
map_make(Arena *a, S64 size){
|
map_make(Arena *a, S64 size){
|
||||||
Map result = {a};
|
Map result = {a};
|
||||||
map_grow(&result, size);
|
map_grow(&result, size);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
map_insert(Map *map, U64 key, void *val){
|
map_insert(Map *map, U64 key, void *val){
|
||||||
assert(val);
|
assert(val);
|
||||||
assert(key);
|
assert(key);
|
||||||
@@ -869,7 +869,7 @@ map_insert(Map *map, U64 key, void *val){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Map_Key_Value *
|
CORE_Static Map_Key_Value *
|
||||||
map_base_get(Map *map, U64 key){
|
map_base_get(Map *map, U64 key){
|
||||||
if(map->len == 0) return 0;
|
if(map->len == 0) return 0;
|
||||||
assert(key);
|
assert(key);
|
||||||
@@ -892,14 +892,14 @@ map_base_get(Map *map, U64 key){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function void *
|
CORE_Static void *
|
||||||
map_get(Map *map, U64 key){
|
map_get(Map *map, U64 key){
|
||||||
Map_Key_Value *result = map_base_get(map, key);
|
Map_Key_Value *result = map_base_get(map, key);
|
||||||
if(result && result->occupied) return result->value;
|
if(result && result->occupied) return result->value;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void *
|
CORE_Static void *
|
||||||
map_remove(Map *map, U64 key){
|
map_remove(Map *map, U64 key){
|
||||||
Map_Key_Value *kv = map_base_get(map, key);
|
Map_Key_Value *kv = map_base_get(map, key);
|
||||||
if(kv){
|
if(kv){
|
||||||
@@ -909,27 +909,27 @@ map_remove(Map *map, U64 key){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void *
|
CORE_Static void *
|
||||||
map_get(Map *map, void *pointer){
|
map_get(Map *map, void *pointer){
|
||||||
return map_get(map, (U64)pointer);
|
return map_get(map, (U64)pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
function void *
|
CORE_Static void *
|
||||||
map_get(Map *map, Intern_String string){
|
map_get(Map *map, Intern_String string){
|
||||||
return map_get(map, hash_string(string.s));
|
return map_get(map, hash_string(string.s));
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
map_insert(Map *map, void *key, void *value){
|
map_insert(Map *map, void *key, void *value){
|
||||||
map_insert(map, (U64)key, value);
|
map_insert(map, (U64)key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
map_insert(Map *map, Intern_String key, void *value){
|
map_insert(Map *map, Intern_String key, void *value){
|
||||||
map_insert(map, hash_string(key.s), value);
|
map_insert(map, hash_string(key.s), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
map_test(){
|
map_test(){
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
Map map = {scratch};
|
Map map = {scratch};
|
||||||
@@ -953,7 +953,7 @@ struct Intern_Table{
|
|||||||
U8 *last_keyword;
|
U8 *last_keyword;
|
||||||
};
|
};
|
||||||
|
|
||||||
function Intern_Table
|
CORE_Static Intern_Table
|
||||||
intern_table_make(Arena *string_allocator, Arena *map_allocator, S64 initial_size = 32){
|
intern_table_make(Arena *string_allocator, Arena *map_allocator, S64 initial_size = 32){
|
||||||
Intern_Table result = {};
|
Intern_Table result = {};
|
||||||
result.map = map_make(map_allocator, initial_size);
|
result.map = map_make(map_allocator, initial_size);
|
||||||
@@ -961,7 +961,7 @@ intern_table_make(Arena *string_allocator, Arena *map_allocator, S64 initial_siz
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Intern_String
|
CORE_Static Intern_String
|
||||||
intern_string(Intern_Table *t, String string){
|
intern_string(Intern_Table *t, String string){
|
||||||
assert(t->string_allocator);
|
assert(t->string_allocator);
|
||||||
U64 hash = hash_string(string);
|
U64 hash = hash_string(string);
|
||||||
@@ -984,7 +984,7 @@ intern_string(Intern_Table *t, String string){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
test_intern_table(){
|
test_intern_table(){
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
Intern_Table table = intern_table_make(scratch, scratch);
|
Intern_Table table = intern_table_make(scratch, scratch);
|
||||||
@@ -995,7 +995,7 @@ test_intern_table(){
|
|||||||
assert(intern3.str != intern2.str);
|
assert(intern3.str != intern2.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Arena
|
CORE_Static Arena
|
||||||
arena_sub(Arena *base, size_t size, String debug_name) {
|
arena_sub(Arena *base, size_t size, String debug_name) {
|
||||||
Arena result = {};
|
Arena result = {};
|
||||||
result.memory.data = (U8 *)arena_push_size(base, size);
|
result.memory.data = (U8 *)arena_push_size(base, size);
|
||||||
|
|||||||
@@ -1596,7 +1596,7 @@ api Vec4 normalize(Vec4 a) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function
|
CORE_Static
|
||||||
Mat4 mat4_identity() {
|
Mat4 mat4_identity() {
|
||||||
Mat4 result = {};
|
Mat4 result = {};
|
||||||
result.p[0][0] = 1;
|
result.p[0][0] = 1;
|
||||||
@@ -1606,7 +1606,7 @@ Mat4 mat4_identity() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function
|
CORE_Static
|
||||||
Mat4 mat4_scale(Vec3 a) {
|
Mat4 mat4_scale(Vec3 a) {
|
||||||
Mat4 result = {};
|
Mat4 result = {};
|
||||||
result.p[0][0] = a.x;
|
result.p[0][0] = a.x;
|
||||||
@@ -1616,7 +1616,7 @@ Mat4 mat4_scale(Vec3 a) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function
|
CORE_Static
|
||||||
Mat4 mat4_translation(Vec3 a) {
|
Mat4 mat4_translation(Vec3 a) {
|
||||||
return {
|
return {
|
||||||
1, 0, 0, a.x,
|
1, 0, 0, a.x,
|
||||||
@@ -1626,7 +1626,7 @@ Mat4 mat4_translation(Vec3 a) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function
|
CORE_Static
|
||||||
Mat4 mat4_rotation_z(float rotation) {
|
Mat4 mat4_rotation_z(float rotation) {
|
||||||
float s = sinf(rotation);
|
float s = sinf(rotation);
|
||||||
float c = cosf(rotation);
|
float c = cosf(rotation);
|
||||||
@@ -1639,7 +1639,7 @@ Mat4 mat4_rotation_z(float rotation) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function
|
CORE_Static
|
||||||
Mat4 mat4_rotation_y(float rotation) {
|
Mat4 mat4_rotation_y(float rotation) {
|
||||||
float s = sinf(rotation);
|
float s = sinf(rotation);
|
||||||
float c = cosf(rotation);
|
float c = cosf(rotation);
|
||||||
@@ -1652,7 +1652,7 @@ Mat4 mat4_rotation_y(float rotation) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function
|
CORE_Static
|
||||||
Mat4 mat4_rotation_x(float rotation) {
|
Mat4 mat4_rotation_x(float rotation) {
|
||||||
float s = sinf(rotation);
|
float s = sinf(rotation);
|
||||||
float c = cosf(rotation);
|
float c = cosf(rotation);
|
||||||
@@ -1667,7 +1667,7 @@ Mat4 mat4_rotation_x(float rotation) {
|
|||||||
|
|
||||||
constexpr F32 deg2rad = (PI32 / 180.f); // @Usage: degree * deg2rad = radians;
|
constexpr F32 deg2rad = (PI32 / 180.f); // @Usage: degree * deg2rad = radians;
|
||||||
constexpr F32 rad2deg = (180.f / PI32);
|
constexpr F32 rad2deg = (180.f / PI32);
|
||||||
function
|
CORE_Static
|
||||||
Mat4 mat4_perspective(float fov, float window_x, float window_y, float znear, float zfar) {
|
Mat4 mat4_perspective(float fov, float window_x, float window_y, float znear, float zfar) {
|
||||||
float aspect_ratio = window_y / window_x;
|
float aspect_ratio = window_y / window_x;
|
||||||
float f = (1.f / tanf((fov/2.f)*deg2rad));
|
float f = (1.f / tanf((fov/2.f)*deg2rad));
|
||||||
@@ -1680,7 +1680,7 @@ Mat4 mat4_perspective(float fov, float window_x, float window_y, float znear, fl
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Mat4 mat4_look_at(Vec3 pos, Vec3 target, Vec3 up) {
|
CORE_Static Mat4 mat4_look_at(Vec3 pos, Vec3 target, Vec3 up) {
|
||||||
Vec3 z = normalize(target - pos);
|
Vec3 z = normalize(target - pos);
|
||||||
Vec3 x = normalize(cross(up, z));
|
Vec3 x = normalize(cross(up, z));
|
||||||
Vec3 y = cross(z, x);
|
Vec3 y = cross(z, x);
|
||||||
@@ -1693,7 +1693,7 @@ function Mat4 mat4_look_at(Vec3 pos, Vec3 target, Vec3 up) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function
|
CORE_Static
|
||||||
Mat4 mat4_transpose(Mat4 a) {
|
Mat4 mat4_transpose(Mat4 a) {
|
||||||
Mat4 result = a;
|
Mat4 result = a;
|
||||||
result.p[0][1] = result.p[1][0];
|
result.p[0][1] = result.p[1][0];
|
||||||
@@ -1705,7 +1705,7 @@ Mat4 mat4_transpose(Mat4 a) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function
|
CORE_Static
|
||||||
Mat4 mat4_translate(Mat4 a, Vec3 translation) {
|
Mat4 mat4_translate(Mat4 a, Vec3 translation) {
|
||||||
a.p[0][0] += translation.x;
|
a.p[0][0] += translation.x;
|
||||||
a.p[0][1] += translation.y;
|
a.p[0][1] += translation.y;
|
||||||
|
|||||||
@@ -1,39 +1,39 @@
|
|||||||
|
|
||||||
function U8
|
CORE_Static U8
|
||||||
to_lower_case(U8 a) {
|
to_lower_case(U8 a) {
|
||||||
if (a >= 'A' && a <= 'Z')
|
if (a >= 'A' && a <= 'Z')
|
||||||
a += 32;
|
a += 32;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
function U8
|
CORE_Static U8
|
||||||
to_upper_case(U8 a) {
|
to_upper_case(U8 a) {
|
||||||
if (a >= 'a' && a <= 'z')
|
if (a >= 'a' && a <= 'z')
|
||||||
a -= 32;
|
a -= 32;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
function U8
|
CORE_Static U8
|
||||||
char_to_lower(U8 c){
|
char_to_lower(U8 c){
|
||||||
if(c >= 'A' && c <= 'Z')
|
if(c >= 'A' && c <= 'Z')
|
||||||
c += 32;
|
c += 32;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
function U8
|
CORE_Static U8
|
||||||
char_to_upper(U8 c){
|
char_to_upper(U8 c){
|
||||||
if(c >= 'a' && c <= 'z')
|
if(c >= 'a' && c <= 'z')
|
||||||
c -= 32;
|
c -= 32;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
is_whitespace(U8 w) {
|
is_whitespace(U8 w) {
|
||||||
bool result = w == '\n' || w == ' ' || w == '\t' || w == '\v' || w == '\r';
|
bool result = w == '\n' || w == ' ' || w == '\t' || w == '\v' || w == '\r';
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
is_alphabetic(U8 a) {
|
is_alphabetic(U8 a) {
|
||||||
if ((a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z')) {
|
if ((a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z')) {
|
||||||
return true;
|
return true;
|
||||||
@@ -41,19 +41,19 @@ is_alphabetic(U8 a) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
is_number(U8 a) {
|
is_number(U8 a) {
|
||||||
B32 result = a >= '0' && a <= '9';
|
B32 result = a >= '0' && a <= '9';
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
is_alphanumeric(U8 a) {
|
is_alphanumeric(U8 a) {
|
||||||
B32 result = is_number(a) || is_alphabetic(a);
|
B32 result = is_number(a) || is_alphabetic(a);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
string_compare(String a, String b, B32 ignore_case = false) {
|
string_compare(String a, String b, B32 ignore_case = false) {
|
||||||
if (a.len != b.len)
|
if (a.len != b.len)
|
||||||
return false;
|
return false;
|
||||||
@@ -70,12 +70,12 @@ string_compare(String a, String b, B32 ignore_case = false) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
operator==(String a, String b){
|
operator==(String a, String b){
|
||||||
return string_compare(a,b);
|
return string_compare(a,b);
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_copy(Arena *a, String string){
|
string_copy(Arena *a, String string){
|
||||||
U8 *copy = arena_push_array(a, U8, string.len+1);
|
U8 *copy = arena_push_array(a, U8, string.len+1);
|
||||||
memory_copy(copy, string.str, string.len);
|
memory_copy(copy, string.str, string.len);
|
||||||
@@ -83,7 +83,7 @@ string_copy(Arena *a, String string){
|
|||||||
return String{copy, string.len};
|
return String{copy, string.len};
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_fmtv(Arena *a, const char *str, va_list args1) {
|
string_fmtv(Arena *a, const char *str, va_list args1) {
|
||||||
va_list args2;
|
va_list args2;
|
||||||
va_copy(args2, args1);
|
va_copy(args2, args1);
|
||||||
@@ -103,7 +103,7 @@ va_start(args1, str); \
|
|||||||
String result = string_fmtv(alloc, str, args1); \
|
String result = string_fmtv(alloc, str, args1); \
|
||||||
va_end(args1)
|
va_end(args1)
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_fmt(Arena *a, const char *str, ...) {
|
string_fmt(Arena *a, const char *str, ...) {
|
||||||
STRING_FMT(a, str, result);
|
STRING_FMT(a, str, result);
|
||||||
return result;
|
return result;
|
||||||
@@ -202,7 +202,7 @@ struct String_Builder{
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function String_Builder
|
CORE_Static String_Builder
|
||||||
string_builder_make(Arena *a, S64 first_block_size = 4096){
|
string_builder_make(Arena *a, S64 first_block_size = 4096){
|
||||||
String_Builder sb = {a};
|
String_Builder sb = {a};
|
||||||
sb.init(first_block_size);
|
sb.init(first_block_size);
|
||||||
@@ -214,7 +214,7 @@ enum String_Builder_Flag{
|
|||||||
String_Builder_Flag_AddSize = 0,
|
String_Builder_Flag_AddSize = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_flatten(Arena *a, String_Builder *b, String_Builder_Flag flags = String_Builder_Flag_None){
|
string_flatten(Arena *a, String_Builder *b, String_Builder_Flag flags = String_Builder_Flag_None){
|
||||||
// @Note(Krzosa): Compute size to allocate
|
// @Note(Krzosa): Compute size to allocate
|
||||||
S64 size = 1;
|
S64 size = 1;
|
||||||
@@ -240,7 +240,7 @@ string_flatten(Arena *a, String_Builder *b, String_Builder_Flag flags = String_B
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
test_string_builder(){
|
test_string_builder(){
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
String_Builder sb = string_builder_make(scratch, 4);
|
String_Builder sb = string_builder_make(scratch, 4);
|
||||||
@@ -255,7 +255,7 @@ test_string_builder(){
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// String ops
|
// String ops
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
function void
|
CORE_Static void
|
||||||
string_path_normalize(String s) {
|
string_path_normalize(String s) {
|
||||||
for (S64 i = 0; i < s.len; i++) {
|
for (S64 i = 0; i < s.len; i++) {
|
||||||
if (s.str[i] == '\\')
|
if (s.str[i] == '\\')
|
||||||
@@ -263,7 +263,7 @@ string_path_normalize(String s) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_make(char *str, S64 len) {
|
string_make(char *str, S64 len) {
|
||||||
String result;
|
String result;
|
||||||
result.str = (U8 *)str;
|
result.str = (U8 *)str;
|
||||||
@@ -271,19 +271,19 @@ string_make(char *str, S64 len) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_make(U8 *str, S64 len) {
|
string_make(U8 *str, S64 len) {
|
||||||
return string_make((char*)str, len);
|
return string_make((char*)str, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_chop(String string, S64 len) {
|
string_chop(String string, S64 len) {
|
||||||
len = clamp_top(len, string.len);
|
len = clamp_top(len, string.len);
|
||||||
String result = string_make(string.str, string.len - len);
|
String result = string_make(string.str, string.len - len);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_skip(String string, S64 len) {
|
string_skip(String string, S64 len) {
|
||||||
len = clamp_top(len, string.len);
|
len = clamp_top(len, string.len);
|
||||||
S64 remain = string.len - len;
|
S64 remain = string.len - len;
|
||||||
@@ -291,7 +291,7 @@ string_skip(String string, S64 len) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_get_postfix(String string, S64 len) {
|
string_get_postfix(String string, S64 len) {
|
||||||
len = clamp_top(len, string.len);
|
len = clamp_top(len, string.len);
|
||||||
S64 remain_len = string.len - len;
|
S64 remain_len = string.len - len;
|
||||||
@@ -299,14 +299,14 @@ string_get_postfix(String string, S64 len) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_get_prefix(String string, S64 len) {
|
string_get_prefix(String string, S64 len) {
|
||||||
len = clamp_top(len, string.len);
|
len = clamp_top(len, string.len);
|
||||||
String result = string_make(string.str, len);
|
String result = string_make(string.str, len);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_slice(String string, S64 first_index, S64 one_past_last_index) {
|
string_slice(String string, S64 first_index, S64 one_past_last_index) {
|
||||||
assert_message(first_index < one_past_last_index, "string_slice, first_index is bigger then one_past_last_index");
|
assert_message(first_index < one_past_last_index, "string_slice, first_index is bigger then one_past_last_index");
|
||||||
assert_message(string.len > 0, "Slicing string of length 0! Might be an error!");
|
assert_message(string.len > 0, "Slicing string of length 0! Might be an error!");
|
||||||
@@ -325,7 +325,7 @@ string_slice(String string, S64 first_index, S64 one_past_last_index) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_trim(String string) {
|
string_trim(String string) {
|
||||||
if (string.len == 0) return string;
|
if (string.len == 0) return string;
|
||||||
|
|
||||||
@@ -354,7 +354,7 @@ string_trim(String string) {
|
|||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_trim_end(String string) {
|
string_trim_end(String string) {
|
||||||
S64 whitespace_end = string.len;
|
S64 whitespace_end = string.len;
|
||||||
for (; whitespace_end != 0; whitespace_end--) {
|
for (; whitespace_end != 0; whitespace_end--) {
|
||||||
@@ -367,7 +367,7 @@ string_trim_end(String string) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_to_lower_case(Arena *arena, String s) {
|
string_to_lower_case(Arena *arena, String s) {
|
||||||
String copy = string_copy(arena, s);
|
String copy = string_copy(arena, s);
|
||||||
for (U64 i = 0; i < copy.len; i++) {
|
for (U64 i = 0; i < copy.len; i++) {
|
||||||
@@ -376,7 +376,7 @@ string_to_lower_case(Arena *arena, String s) {
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_to_upper_case(Arena *arena, String s) {
|
string_to_upper_case(Arena *arena, String s) {
|
||||||
String copy = string_copy(arena, s);
|
String copy = string_copy(arena, s);
|
||||||
for (U64 i = 0; i < copy.len; i++) {
|
for (U64 i = 0; i < copy.len; i++) {
|
||||||
@@ -392,7 +392,7 @@ enum {
|
|||||||
MatchFlag_IgnoreCase=2,
|
MatchFlag_IgnoreCase=2,
|
||||||
};
|
};
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
string_find(String string, String find, MatchFlag flags, S64 *index_out) {
|
string_find(String string, String find, MatchFlag flags, S64 *index_out) {
|
||||||
B32 result = false;
|
B32 result = false;
|
||||||
if (flags & MatchFlag_FindLast) {
|
if (flags & MatchFlag_FindLast) {
|
||||||
@@ -422,21 +422,21 @@ string_find(String string, String find, MatchFlag flags, S64 *index_out) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_chop_last_slash(String s) {
|
string_chop_last_slash(String s) {
|
||||||
String result = s;
|
String result = s;
|
||||||
string_find(s, "/"_s, MatchFlag_FindLast, &result.len);
|
string_find(s, "/"_s, MatchFlag_FindLast, &result.len);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_chop_last_period(String s) {
|
string_chop_last_period(String s) {
|
||||||
String result = s;
|
String result = s;
|
||||||
string_find(s, "."_s, MatchFlag_FindLast, &result.len);
|
string_find(s, "."_s, MatchFlag_FindLast, &result.len);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_skip_to_last_slash(String s) {
|
string_skip_to_last_slash(String s) {
|
||||||
S64 pos;
|
S64 pos;
|
||||||
String result = s;
|
String result = s;
|
||||||
@@ -446,7 +446,7 @@ string_skip_to_last_slash(String s) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_skip_to_last_period(String s) {
|
string_skip_to_last_period(String s) {
|
||||||
S64 pos;
|
S64 pos;
|
||||||
String result = s;
|
String result = s;
|
||||||
@@ -456,14 +456,14 @@ string_skip_to_last_period(String s) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function S64
|
CORE_Static S64
|
||||||
string_len(char *string){
|
string_len(char *string){
|
||||||
S64 len = 0;
|
S64 len = 0;
|
||||||
while(*string++!=0)len++;
|
while(*string++!=0)len++;
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_from_cstring(char *string){
|
string_from_cstring(char *string){
|
||||||
String result;
|
String result;
|
||||||
result.str = (U8 *)string;
|
result.str = (U8 *)string;
|
||||||
@@ -476,7 +476,7 @@ struct String_Replace {
|
|||||||
String replace;
|
String replace;
|
||||||
};
|
};
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_replace(Arena *arena, String string, Array<String_Replace> pairs){
|
string_replace(Arena *arena, String string, Array<String_Replace> pairs){
|
||||||
Scratch scratch(arena);
|
Scratch scratch(arena);
|
||||||
String_Builder builder = {scratch};
|
String_Builder builder = {scratch};
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ struct UTF32_Result{
|
|||||||
B32 error;
|
B32 error;
|
||||||
};
|
};
|
||||||
|
|
||||||
function UTF32_Result
|
CORE_Static UTF32_Result
|
||||||
utf8_to_utf32(U8 *c, S64 max_advance) {
|
utf8_to_utf32(U8 *c, S64 max_advance) {
|
||||||
UTF32_Result result = {};
|
UTF32_Result result = {};
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ struct UTF16_Result{
|
|||||||
B32 error;
|
B32 error;
|
||||||
};
|
};
|
||||||
|
|
||||||
function UTF16_Result
|
CORE_Static UTF16_Result
|
||||||
utf32_to_utf16(U32 codepoint){
|
utf32_to_utf16(U32 codepoint){
|
||||||
UTF16_Result result = {};
|
UTF16_Result result = {};
|
||||||
if (codepoint < 0x10000) {
|
if (codepoint < 0x10000) {
|
||||||
@@ -100,7 +100,7 @@ struct UTF8_Result{
|
|||||||
B32 error;
|
B32 error;
|
||||||
};
|
};
|
||||||
|
|
||||||
function UTF8_Result
|
CORE_Static UTF8_Result
|
||||||
utf32_to_utf8(U32 codepoint) {
|
utf32_to_utf8(U32 codepoint) {
|
||||||
UTF8_Result result = {};
|
UTF8_Result result = {};
|
||||||
if (codepoint <= 0x7F) {
|
if (codepoint <= 0x7F) {
|
||||||
@@ -132,7 +132,7 @@ utf32_to_utf8(U32 codepoint) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function UTF32_Result
|
CORE_Static UTF32_Result
|
||||||
utf16_to_utf32(U16 *c, S32 max_advance) {
|
utf16_to_utf32(U16 *c, S32 max_advance) {
|
||||||
UTF32_Result result = {};
|
UTF32_Result result = {};
|
||||||
if(max_advance >= 1){
|
if(max_advance >= 1){
|
||||||
@@ -158,7 +158,7 @@ utf16_to_utf32(U16 *c, S32 max_advance) {
|
|||||||
break; \
|
break; \
|
||||||
}
|
}
|
||||||
|
|
||||||
function String32
|
CORE_Static String32
|
||||||
string16_to_string32(Arena *allocator, String16 string){
|
string16_to_string32(Arena *allocator, String16 string){
|
||||||
String32 result = {arena_push_array(allocator, U32, string.len+1)};
|
String32 result = {arena_push_array(allocator, U32, string.len+1)};
|
||||||
for(S64 i = 0; i < string.len;){
|
for(S64 i = 0; i < string.len;){
|
||||||
@@ -174,7 +174,7 @@ string16_to_string32(Arena *allocator, String16 string){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String32
|
CORE_Static String32
|
||||||
string8_to_string32(Arena *allocator, String string){
|
string8_to_string32(Arena *allocator, String string){
|
||||||
String32 result = {arena_push_array(allocator, U32, string.len+1)};
|
String32 result = {arena_push_array(allocator, U32, string.len+1)};
|
||||||
for(S64 i = 0; i < string.len;){
|
for(S64 i = 0; i < string.len;){
|
||||||
@@ -189,7 +189,7 @@ string8_to_string32(Arena *allocator, String string){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String16
|
CORE_Static String16
|
||||||
string8_to_string16(Arena *allocator, String in){
|
string8_to_string16(Arena *allocator, String in){
|
||||||
String16 result = {arena_push_array(allocator, U16, (in.len*2)+1)}; // @Note(Krzosa): Should be more then enough space
|
String16 result = {arena_push_array(allocator, U16, (in.len*2)+1)}; // @Note(Krzosa): Should be more then enough space
|
||||||
for(S64 i = 0; i < in.len;){
|
for(S64 i = 0; i < in.len;){
|
||||||
@@ -211,7 +211,7 @@ string8_to_string16(Arena *allocator, String in){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string16_to_string8(Arena *allocator, String16 in){
|
string16_to_string8(Arena *allocator, String16 in){
|
||||||
String result = {arena_push_array(allocator, U8, in.len*4+1)};
|
String result = {arena_push_array(allocator, U8, in.len*4+1)};
|
||||||
for(S64 i = 0; i < in.len;){
|
for(S64 i = 0; i < in.len;){
|
||||||
@@ -232,7 +232,7 @@ string16_to_string8(Arena *allocator, String16 in){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
string_compare(String16 a, String16 b){
|
string_compare(String16 a, String16 b){
|
||||||
if(a.len != b.len) return false;
|
if(a.len != b.len) return false;
|
||||||
for(S64 i = 0; i < a.len; i++){
|
for(S64 i = 0; i < a.len; i++){
|
||||||
@@ -241,7 +241,7 @@ string_compare(String16 a, String16 b){
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
string_compare(String32 a, String32 b){
|
string_compare(String32 a, String32 b){
|
||||||
if(a.len != b.len) return false;
|
if(a.len != b.len) return false;
|
||||||
for(S64 i = 0; i < a.len; i++){
|
for(S64 i = 0; i < a.len; i++){
|
||||||
@@ -250,14 +250,14 @@ string_compare(String32 a, String32 b){
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function S64
|
CORE_Static S64
|
||||||
widechar_len(wchar_t *string){
|
widechar_len(wchar_t *string){
|
||||||
S64 len = 0;
|
S64 len = 0;
|
||||||
while(*string++!=0)len++;
|
while(*string++!=0)len++;
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String16
|
CORE_Static String16
|
||||||
string16_from_widechar(wchar_t *string){
|
string16_from_widechar(wchar_t *string){
|
||||||
String16 result;
|
String16 result;
|
||||||
result.str = (U16 *)string;
|
result.str = (U16 *)string;
|
||||||
@@ -265,7 +265,7 @@ string16_from_widechar(wchar_t *string){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string16_copy(Arena *a, String string){
|
string16_copy(Arena *a, String string){
|
||||||
U8 *copy = arena_push_array(a, U8, string.len+1);
|
U8 *copy = arena_push_array(a, U8, string.len+1);
|
||||||
memory_copy(copy, string.str, string.len);
|
memory_copy(copy, string.str, string.len);
|
||||||
@@ -273,7 +273,7 @@ string16_copy(Arena *a, String string){
|
|||||||
return String{copy, string.len};
|
return String{copy, string.len};
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
test_unicode(){
|
test_unicode(){
|
||||||
assert(utf8_to_utf32((U8 *)"A", 1).out_str == 'A');
|
assert(utf8_to_utf32((U8 *)"A", 1).out_str == 'A');
|
||||||
assert(utf8_to_utf32((U8 *)"ć", 2).out_str == 0x107);
|
assert(utf8_to_utf32((U8 *)"ć", 2).out_str == 0x107);
|
||||||
|
|||||||
@@ -10,35 +10,35 @@ struct BigInt_Arena{
|
|||||||
~BigInt_Arena(){bigint_allocator = old;}
|
~BigInt_Arena(){bigint_allocator = old;}
|
||||||
};
|
};
|
||||||
|
|
||||||
function BigInt
|
CORE_Static BigInt
|
||||||
bigint_u64(U64 value){
|
bigint_u64(U64 value){
|
||||||
BigInt result;
|
BigInt result;
|
||||||
bigint_init_unsigned(&result, value);
|
bigint_init_unsigned(&result, value);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function BigInt
|
CORE_Static BigInt
|
||||||
bigint_s64(S64 value){
|
bigint_s64(S64 value){
|
||||||
BigInt result;
|
BigInt result;
|
||||||
bigint_init_signed(&result, value);
|
bigint_init_signed(&result, value);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function BigInt
|
CORE_Static BigInt
|
||||||
bigint_mul(const BigInt *a, const BigInt *b){
|
bigint_mul(const BigInt *a, const BigInt *b){
|
||||||
BigInt result;
|
BigInt result;
|
||||||
bigint_mul(&result, a, b);
|
bigint_mul(&result, a, b);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function BigInt
|
CORE_Static BigInt
|
||||||
bigint_add(const BigInt *a, const BigInt *b){
|
bigint_add(const BigInt *a, const BigInt *b){
|
||||||
BigInt result;
|
BigInt result;
|
||||||
bigint_add(&result, a, b);
|
bigint_add(&result, a, b);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function BigInt
|
CORE_Static BigInt
|
||||||
bigint_copy(Arena *allocator, BigInt *src){
|
bigint_copy(Arena *allocator, BigInt *src){
|
||||||
BigInt dest = {};
|
BigInt dest = {};
|
||||||
if (src->digit_count == 0){
|
if (src->digit_count == 0){
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ enum CmpRes
|
|||||||
#define ALLOC_DIGITS(_digits) (uint64_t *)((_digits) ? malloc_arena(sizeof(uint64_t) * (_digits)) : NULL)
|
#define ALLOC_DIGITS(_digits) (uint64_t *)((_digits) ? malloc_arena(sizeof(uint64_t) * (_digits)) : NULL)
|
||||||
#define FATAL_ERROR(x) compiler_error(0, x)
|
#define FATAL_ERROR(x) compiler_error(0, x)
|
||||||
|
|
||||||
function void compiler_error(Token *token, const char *str, ...);
|
CORE_Static void compiler_error(Token *token, const char *str, ...);
|
||||||
const char *bigint_to_error_string(Arena *allocator, const BigInt *bigint, uint64_t base);
|
const char *bigint_to_error_string(Arena *allocator, const BigInt *bigint, uint64_t base);
|
||||||
void bigint_init_unsigned(BigInt *big_int, uint64_t value);
|
void bigint_init_unsigned(BigInt *big_int, uint64_t value);
|
||||||
void bigint_init_signed(BigInt *big_int, int64_t value);
|
void bigint_init_signed(BigInt *big_int, int64_t value);
|
||||||
|
|||||||
92
core_ast.cpp
92
core_ast.cpp
@@ -302,7 +302,7 @@ struct Ast_Decl: Ast{
|
|||||||
result->di = ++pctx->unique_ids
|
result->di = ++pctx->unique_ids
|
||||||
|
|
||||||
#define ast_new(T,kind,pos,flags) (T *)_ast_new(sizeof(T), kind, pos, flags)
|
#define ast_new(T,kind,pos,flags) (T *)_ast_new(sizeof(T), kind, pos, flags)
|
||||||
function Ast *
|
CORE_Static Ast *
|
||||||
_ast_new(size_t size, Ast_Kind kind, Token *pos, Ast_Flag flags = 0){
|
_ast_new(size_t size, Ast_Kind kind, Token *pos, Ast_Flag flags = 0){
|
||||||
Ast *result = (Ast *)arena_push_size(pctx->perm, size, AF_ZeroMemory);
|
Ast *result = (Ast *)arena_push_size(pctx->perm, size, AF_ZeroMemory);
|
||||||
result->flags = flags;
|
result->flags = flags;
|
||||||
@@ -313,7 +313,7 @@ _ast_new(size_t size, Ast_Kind kind, Token *pos, Ast_Flag flags = 0){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Atom *
|
CORE_Static Ast_Atom *
|
||||||
ast_str(Token *pos, Intern_String string){
|
ast_str(Token *pos, Intern_String string){
|
||||||
AST_NEW(Atom, VALUE, pos, AST_EXPR | AST_ATOM);
|
AST_NEW(Atom, VALUE, pos, AST_EXPR | AST_ATOM);
|
||||||
result->type = untyped_string;
|
result->type = untyped_string;
|
||||||
@@ -321,14 +321,14 @@ ast_str(Token *pos, Intern_String string){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Atom *
|
CORE_Static Ast_Atom *
|
||||||
ast_ident(Token *pos, Intern_String string){
|
ast_ident(Token *pos, Intern_String string){
|
||||||
AST_NEW(Atom, IDENT, pos, AST_EXPR | AST_ATOM);
|
AST_NEW(Atom, IDENT, pos, AST_EXPR | AST_ATOM);
|
||||||
result->intern_val = string;
|
result->intern_val = string;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Atom *
|
CORE_Static Ast_Atom *
|
||||||
ast_bool(Token *pos, B32 bool_val){
|
ast_bool(Token *pos, B32 bool_val){
|
||||||
AST_NEW(Atom, VALUE, pos, AST_EXPR | AST_ATOM);
|
AST_NEW(Atom, VALUE, pos, AST_EXPR | AST_ATOM);
|
||||||
result->bool_val = bool_val;
|
result->bool_val = bool_val;
|
||||||
@@ -336,7 +336,7 @@ ast_bool(Token *pos, B32 bool_val){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Atom *
|
CORE_Static Ast_Atom *
|
||||||
ast_float(Token *pos, F64 value){
|
ast_float(Token *pos, F64 value){
|
||||||
AST_NEW(Atom, VALUE, pos, AST_EXPR | AST_ATOM);
|
AST_NEW(Atom, VALUE, pos, AST_EXPR | AST_ATOM);
|
||||||
result->type = untyped_float;
|
result->type = untyped_float;
|
||||||
@@ -344,7 +344,7 @@ ast_float(Token *pos, F64 value){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Atom *
|
CORE_Static Ast_Atom *
|
||||||
ast_int(Token *pos, BigInt val){
|
ast_int(Token *pos, BigInt val){
|
||||||
AST_NEW(Atom, VALUE, pos, AST_EXPR | AST_ATOM);
|
AST_NEW(Atom, VALUE, pos, AST_EXPR | AST_ATOM);
|
||||||
result->type = untyped_int;
|
result->type = untyped_int;
|
||||||
@@ -352,12 +352,12 @@ ast_int(Token *pos, BigInt val){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Atom *
|
CORE_Static Ast_Atom *
|
||||||
ast_int(Token *pos, U64 value){
|
ast_int(Token *pos, U64 value){
|
||||||
return ast_int(pos, bigint_u64(value));
|
return ast_int(pos, bigint_u64(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Expr *
|
CORE_Static Ast_Expr *
|
||||||
ast_expr_binary(Ast_Expr *left, Ast_Expr *right, Token *op){
|
ast_expr_binary(Ast_Expr *left, Ast_Expr *right, Token *op){
|
||||||
AST_NEW(Binary, BINARY, op, AST_EXPR);
|
AST_NEW(Binary, BINARY, op, AST_EXPR);
|
||||||
result->op = op->kind;
|
result->op = op->kind;
|
||||||
@@ -366,7 +366,7 @@ ast_expr_binary(Ast_Expr *left, Ast_Expr *right, Token *op){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Call *
|
CORE_Static Ast_Call *
|
||||||
ast_call(Token *pos, Ast_Expr *name, Array<Ast_Call_Item *> exprs){
|
ast_call(Token *pos, Ast_Expr *name, Array<Ast_Call_Item *> exprs){
|
||||||
// name here specifies also typespec for compound expressions !
|
// name here specifies also typespec for compound expressions !
|
||||||
AST_NEW(Call, CALL, pos, AST_EXPR);
|
AST_NEW(Call, CALL, pos, AST_EXPR);
|
||||||
@@ -375,7 +375,7 @@ ast_call(Token *pos, Ast_Expr *name, Array<Ast_Call_Item *> exprs){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Call_Item *
|
CORE_Static Ast_Call_Item *
|
||||||
ast_call_item(Token *pos, Ast_Atom *name, Ast_Expr *index, Ast_Expr *item){
|
ast_call_item(Token *pos, Ast_Atom *name, Ast_Expr *index, Ast_Expr *item){
|
||||||
AST_NEW(Call_Item, CALL_ITEM, pos, AST_EXPR);
|
AST_NEW(Call_Item, CALL_ITEM, pos, AST_EXPR);
|
||||||
result->name = name;
|
result->name = name;
|
||||||
@@ -384,7 +384,7 @@ ast_call_item(Token *pos, Ast_Atom *name, Ast_Expr *index, Ast_Expr *item){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Expr *
|
CORE_Static Ast_Expr *
|
||||||
ast_expr_unary(Token *pos, Token_Kind op, Ast_Expr *expr){
|
ast_expr_unary(Token *pos, Token_Kind op, Ast_Expr *expr){
|
||||||
AST_NEW(Unary, UNARY, pos, AST_EXPR);
|
AST_NEW(Unary, UNARY, pos, AST_EXPR);
|
||||||
result->flags = AST_EXPR;
|
result->flags = AST_EXPR;
|
||||||
@@ -393,7 +393,7 @@ ast_expr_unary(Token *pos, Token_Kind op, Ast_Expr *expr){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Expr *
|
CORE_Static Ast_Expr *
|
||||||
ast_expr_index(Token *pos, Ast_Expr *expr, Ast_Expr *index){
|
ast_expr_index(Token *pos, Ast_Expr *expr, Ast_Expr *index){
|
||||||
AST_NEW(Index, INDEX, pos, AST_EXPR);
|
AST_NEW(Index, INDEX, pos, AST_EXPR);
|
||||||
result->flags = AST_EXPR;
|
result->flags = AST_EXPR;
|
||||||
@@ -402,7 +402,7 @@ ast_expr_index(Token *pos, Ast_Expr *expr, Ast_Expr *index){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Lambda *
|
CORE_Static Ast_Lambda *
|
||||||
ast_lambda(Token *pos, Array<Ast_Decl *> params, Array<Ast_Expr *> ret, Ast_Scope *scope){
|
ast_lambda(Token *pos, Array<Ast_Decl *> params, Array<Ast_Expr *> ret, Ast_Scope *scope){
|
||||||
AST_NEW(Lambda, LAMBDA_EXPR, pos, AST_EXPR);
|
AST_NEW(Lambda, LAMBDA_EXPR, pos, AST_EXPR);
|
||||||
result->flags = AST_EXPR;
|
result->flags = AST_EXPR;
|
||||||
@@ -412,14 +412,14 @@ ast_lambda(Token *pos, Array<Ast_Decl *> params, Array<Ast_Expr *> ret, Ast_Scop
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_If *
|
CORE_Static Ast_If *
|
||||||
ast_if(Token *pos, Array<Ast_If_Node *> ifs){
|
ast_if(Token *pos, Array<Ast_If_Node *> ifs){
|
||||||
AST_NEW(If, IF, pos, AST_STMT);
|
AST_NEW(If, IF, pos, AST_STMT);
|
||||||
result->ifs = ifs.tight_copy(pctx->perm);
|
result->ifs = ifs.tight_copy(pctx->perm);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_For *
|
CORE_Static Ast_For *
|
||||||
ast_for(Token *pos, Ast_Expr *init, Ast_Expr *cond, Ast_Expr *iter, Ast_Scope *scope){
|
ast_for(Token *pos, Ast_Expr *init, Ast_Expr *cond, Ast_Expr *iter, Ast_Scope *scope){
|
||||||
AST_NEW(For, FOR, pos, AST_STMT);
|
AST_NEW(For, FOR, pos, AST_STMT);
|
||||||
result->init = init;
|
result->init = init;
|
||||||
@@ -429,19 +429,19 @@ ast_for(Token *pos, Ast_Expr *init, Ast_Expr *cond, Ast_Expr *iter, Ast_Scope *s
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Pass *
|
CORE_Static Ast_Pass *
|
||||||
ast_pass(Token *pos){
|
ast_pass(Token *pos){
|
||||||
AST_NEW(Pass, PASS, pos, AST_STMT);
|
AST_NEW(Pass, PASS, pos, AST_STMT);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Break *
|
CORE_Static Ast_Break *
|
||||||
ast_break(Token *pos){
|
ast_break(Token *pos){
|
||||||
AST_NEW(Break, BREAK, pos, AST_STMT);
|
AST_NEW(Break, BREAK, pos, AST_STMT);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Return *
|
CORE_Static Ast_Return *
|
||||||
ast_return(Token *pos, Array<Ast_Expr *> expr){
|
ast_return(Token *pos, Array<Ast_Expr *> expr){
|
||||||
AST_NEW(Return, RETURN, pos, AST_STMT);
|
AST_NEW(Return, RETURN, pos, AST_STMT);
|
||||||
if(expr.len){
|
if(expr.len){
|
||||||
@@ -451,7 +451,7 @@ ast_return(Token *pos, Array<Ast_Expr *> expr){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_If_Node *
|
CORE_Static Ast_If_Node *
|
||||||
ast_if_node(Token *pos, Ast_Expr *init, Ast_Expr *expr, Ast_Scope *scope){
|
ast_if_node(Token *pos, Ast_Expr *init, Ast_Expr *expr, Ast_Scope *scope){
|
||||||
AST_NEW(If_Node, IF_NODE, pos, AST_STMT);
|
AST_NEW(If_Node, IF_NODE, pos, AST_STMT);
|
||||||
result->scope = scope;
|
result->scope = scope;
|
||||||
@@ -463,14 +463,14 @@ ast_if_node(Token *pos, Ast_Expr *init, Ast_Expr *expr, Ast_Scope *scope){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Array *
|
CORE_Static Ast_Array *
|
||||||
ast_array(Token *pos, Ast_Expr *expr){
|
ast_array(Token *pos, Ast_Expr *expr){
|
||||||
AST_NEW(Array, ARRAY, pos, AST_EXPR);
|
AST_NEW(Array, ARRAY, pos, AST_EXPR);
|
||||||
result->expr = expr;
|
result->expr = expr;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Scope *
|
CORE_Static Ast_Scope *
|
||||||
begin_decl_scope(Arena *scratch, Token *pos){
|
begin_decl_scope(Arena *scratch, Token *pos){
|
||||||
AST_NEW(Scope, SCOPE, pos, AST_DECL);
|
AST_NEW(Scope, SCOPE, pos, AST_DECL);
|
||||||
result->file = pctx->currently_parsed_file;
|
result->file = pctx->currently_parsed_file;
|
||||||
@@ -482,12 +482,12 @@ begin_decl_scope(Arena *scratch, Token *pos){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
finalize_decl_scope(Ast_Scope *scope){
|
finalize_decl_scope(Ast_Scope *scope){
|
||||||
pctx->currently_parsed_scope = scope->parent_scope;
|
pctx->currently_parsed_scope = scope->parent_scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Scope *
|
CORE_Static Ast_Scope *
|
||||||
begin_stmt_scope(Arena *scratch, Token *pos){
|
begin_stmt_scope(Arena *scratch, Token *pos){
|
||||||
AST_NEW(Scope, SCOPE, pos, AST_STMT);
|
AST_NEW(Scope, SCOPE, pos, AST_STMT);
|
||||||
result->stmts = {scratch};
|
result->stmts = {scratch};
|
||||||
@@ -500,20 +500,20 @@ begin_stmt_scope(Arena *scratch, Token *pos){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
finalize_stmt_scope(Ast_Scope *scope){
|
finalize_stmt_scope(Ast_Scope *scope){
|
||||||
scope->stmts = scope->stmts.tight_copy(pctx->perm);
|
scope->stmts = scope->stmts.tight_copy(pctx->perm);
|
||||||
pctx->currently_parsed_scope = scope->parent_scope;
|
pctx->currently_parsed_scope = scope->parent_scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Decl *
|
CORE_Static Ast_Decl *
|
||||||
ast_struct(Token *pos, Ast_Scope *scope){
|
ast_struct(Token *pos, Ast_Scope *scope){
|
||||||
AST_NEW(Decl, STRUCT, pos, AST_DECL | AST_AGGREGATE);
|
AST_NEW(Decl, STRUCT, pos, AST_DECL | AST_AGGREGATE);
|
||||||
result->scope = scope;
|
result->scope = scope;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Decl *
|
CORE_Static Ast_Decl *
|
||||||
ast_enum(Token *pos, Ast_Expr *typespec, Ast_Scope *scope){
|
ast_enum(Token *pos, Ast_Expr *typespec, Ast_Scope *scope){
|
||||||
AST_NEW(Decl, ENUM, pos, AST_DECL | AST_AGGREGATE);
|
AST_NEW(Decl, ENUM, pos, AST_DECL | AST_AGGREGATE);
|
||||||
result->scope = scope;
|
result->scope = scope;
|
||||||
@@ -521,7 +521,7 @@ ast_enum(Token *pos, Ast_Expr *typespec, Ast_Scope *scope){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Decl *
|
CORE_Static Ast_Decl *
|
||||||
ast_var(Token *pos, Ast_Expr *typespec, Intern_String name, Ast_Expr *expr){
|
ast_var(Token *pos, Ast_Expr *typespec, Intern_String name, Ast_Expr *expr){
|
||||||
AST_NEW(Decl, VAR, pos, AST_DECL);
|
AST_NEW(Decl, VAR, pos, AST_DECL);
|
||||||
result->name = name;
|
result->name = name;
|
||||||
@@ -530,7 +530,7 @@ ast_var(Token *pos, Ast_Expr *typespec, Intern_String name, Ast_Expr *expr){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Decl *
|
CORE_Static Ast_Decl *
|
||||||
ast_const(Token *pos, Intern_String name, Value value){
|
ast_const(Token *pos, Intern_String name, Value value){
|
||||||
AST_NEW(Decl, CONST, pos, AST_DECL);
|
AST_NEW(Decl, CONST, pos, AST_DECL);
|
||||||
result->value = value;
|
result->value = value;
|
||||||
@@ -538,7 +538,7 @@ ast_const(Token *pos, Intern_String name, Value value){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Decl *
|
CORE_Static Ast_Decl *
|
||||||
ast_const(Token *pos, Intern_String name, Ast_Expr *expr){
|
ast_const(Token *pos, Intern_String name, Ast_Expr *expr){
|
||||||
AST_NEW(Decl, CONST, pos, AST_DECL);
|
AST_NEW(Decl, CONST, pos, AST_DECL);
|
||||||
result->expr = expr;
|
result->expr = expr;
|
||||||
@@ -546,7 +546,7 @@ ast_const(Token *pos, Intern_String name, Ast_Expr *expr){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Decl *
|
CORE_Static Ast_Decl *
|
||||||
ast_type(Token *pos, Intern_String name, Ast_Type *type){
|
ast_type(Token *pos, Intern_String name, Ast_Type *type){
|
||||||
AST_NEW(Decl, TYPE, pos, AST_DECL);
|
AST_NEW(Decl, TYPE, pos, AST_DECL);
|
||||||
result->type = type_type;
|
result->type = type_type;
|
||||||
@@ -555,7 +555,7 @@ ast_type(Token *pos, Intern_String name, Ast_Type *type){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Scope *
|
CORE_Static Ast_Scope *
|
||||||
ast_decl_scope(Token *pos, Arena *allocator, Ast_File *file){
|
ast_decl_scope(Token *pos, Arena *allocator, Ast_File *file){
|
||||||
AST_NEW(Scope, SCOPE, pos, AST_DECL);
|
AST_NEW(Scope, SCOPE, pos, AST_DECL);
|
||||||
result->file = file;
|
result->file = file;
|
||||||
@@ -565,7 +565,7 @@ ast_decl_scope(Token *pos, Arena *allocator, Ast_File *file){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Decl *
|
CORE_Static Ast_Decl *
|
||||||
ast_namespace(Token *pos, Ast_Scope *module, Intern_String name){
|
ast_namespace(Token *pos, Ast_Scope *module, Intern_String name){
|
||||||
AST_NEW(Decl, NAMESPACE, pos, AST_DECL);
|
AST_NEW(Decl, NAMESPACE, pos, AST_DECL);
|
||||||
result->scope = module;
|
result->scope = module;
|
||||||
@@ -573,7 +573,7 @@ ast_namespace(Token *pos, Ast_Scope *module, Intern_String name){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Builtin *
|
CORE_Static Ast_Builtin *
|
||||||
ast_runtime_assert(Token *pos, Ast_Expr *expr, Intern_String message){
|
ast_runtime_assert(Token *pos, Ast_Expr *expr, Intern_String message){
|
||||||
AST_NEW(Builtin, RUNTIME_ASSERT, pos, AST_EXPR);
|
AST_NEW(Builtin, RUNTIME_ASSERT, pos, AST_EXPR);
|
||||||
result->expr = expr;
|
result->expr = expr;
|
||||||
@@ -581,7 +581,7 @@ ast_runtime_assert(Token *pos, Ast_Expr *expr, Intern_String message){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Builtin *
|
CORE_Static Ast_Builtin *
|
||||||
ast_constant_assert(Token *pos, Ast_Expr *expr, Intern_String message){
|
ast_constant_assert(Token *pos, Ast_Expr *expr, Intern_String message){
|
||||||
AST_NEW(Builtin, CONSTANT_ASSERT, pos, AST_EXPR);
|
AST_NEW(Builtin, CONSTANT_ASSERT, pos, AST_EXPR);
|
||||||
result->expr = expr;
|
result->expr = expr;
|
||||||
@@ -589,28 +589,28 @@ ast_constant_assert(Token *pos, Ast_Expr *expr, Intern_String message){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Builtin *
|
CORE_Static Ast_Builtin *
|
||||||
ast_sizeof(Token *pos, Ast_Expr *expr){
|
ast_sizeof(Token *pos, Ast_Expr *expr){
|
||||||
AST_NEW(Builtin, SIZE_OF, pos, AST_EXPR);
|
AST_NEW(Builtin, SIZE_OF, pos, AST_EXPR);
|
||||||
result->expr = expr;
|
result->expr = expr;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Builtin *
|
CORE_Static Ast_Builtin *
|
||||||
ast_len(Token *pos, Ast_Expr *expr){
|
ast_len(Token *pos, Ast_Expr *expr){
|
||||||
AST_NEW(Builtin, LENGTH_OF, pos, AST_EXPR);
|
AST_NEW(Builtin, LENGTH_OF, pos, AST_EXPR);
|
||||||
result->expr = expr;
|
result->expr = expr;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Builtin *
|
CORE_Static Ast_Builtin *
|
||||||
ast_alignof(Token *pos, Ast_Expr *expr){
|
ast_alignof(Token *pos, Ast_Expr *expr){
|
||||||
AST_NEW(Builtin, ALIGN_OF, pos, AST_EXPR);
|
AST_NEW(Builtin, ALIGN_OF, pos, AST_EXPR);
|
||||||
result->expr = expr;
|
result->expr = expr;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Var_Unpack *
|
CORE_Static Ast_Var_Unpack *
|
||||||
ast_var_unpack(Token *pos, Array<Ast_Decl *> vars, Ast_Expr *expr){
|
ast_var_unpack(Token *pos, Array<Ast_Decl *> vars, Ast_Expr *expr){
|
||||||
AST_NEW(Var_Unpack, VAR_UNPACK, pos, AST_STMT);
|
AST_NEW(Var_Unpack, VAR_UNPACK, pos, AST_STMT);
|
||||||
result->vars = vars.tight_copy(pctx->perm);
|
result->vars = vars.tight_copy(pctx->perm);
|
||||||
@@ -621,7 +621,7 @@ ast_var_unpack(Token *pos, Array<Ast_Decl *> vars, Ast_Expr *expr){
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Value
|
// Value
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
function Value
|
CORE_Static Value
|
||||||
value_bool(B32 v){
|
value_bool(B32 v){
|
||||||
Value value;
|
Value value;
|
||||||
value.bool_val = v;
|
value.bool_val = v;
|
||||||
@@ -629,7 +629,7 @@ value_bool(B32 v){
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Value
|
CORE_Static Value
|
||||||
value_int(BigInt b){
|
value_int(BigInt b){
|
||||||
Value value;
|
Value value;
|
||||||
value.big_int_val = b;
|
value.big_int_val = b;
|
||||||
@@ -637,7 +637,7 @@ value_int(BigInt b){
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Value
|
CORE_Static Value
|
||||||
value_int(S64 s64){
|
value_int(S64 s64){
|
||||||
Value value;
|
Value value;
|
||||||
value.type = untyped_int;
|
value.type = untyped_int;
|
||||||
@@ -645,7 +645,7 @@ value_int(S64 s64){
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Value
|
CORE_Static Value
|
||||||
value_float(F64 b){
|
value_float(F64 b){
|
||||||
Value value;
|
Value value;
|
||||||
value.f64_val = b;
|
value.f64_val = b;
|
||||||
@@ -653,7 +653,7 @@ value_float(F64 b){
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Value
|
CORE_Static Value
|
||||||
value_float(BigInt a){
|
value_float(BigInt a){
|
||||||
Value value;
|
Value value;
|
||||||
value.f64_val = bigint_as_float(&a);
|
value.f64_val = bigint_as_float(&a);
|
||||||
@@ -661,19 +661,19 @@ value_float(BigInt a){
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
is_ident(Ast *ast){
|
is_ident(Ast *ast){
|
||||||
B32 result = ast->kind == AST_IDENT;
|
B32 result = ast->kind == AST_IDENT;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
is_binary(Ast *ast){
|
is_binary(Ast *ast){
|
||||||
B32 result = ast->kind == AST_BINARY;
|
B32 result = ast->kind == AST_BINARY;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
is_atom(Ast *ast){
|
is_atom(Ast *ast){
|
||||||
B32 result = is_flag_set(ast->flags, AST_ATOM);
|
B32 result = is_flag_set(ast->flags, AST_ATOM);
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -4,17 +4,17 @@
|
|||||||
global S32 global_indent;
|
global S32 global_indent;
|
||||||
global S32 is_inside_struct;
|
global S32 is_inside_struct;
|
||||||
|
|
||||||
function void gen_ast(Ast *ast);
|
CORE_Static void gen_ast(Ast *ast);
|
||||||
function bool gen_expr(Ast_Expr *ast);
|
CORE_Static bool gen_expr(Ast_Expr *ast);
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
gen_indent(){
|
gen_indent(){
|
||||||
for(S32 i = 0; i < global_indent; i++) gen(" ");
|
for(S32 i = 0; i < global_indent; i++) gen(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
global Intern_String last_filename;
|
global Intern_String last_filename;
|
||||||
global int last_line;
|
global int last_line;
|
||||||
function void
|
CORE_Static void
|
||||||
gen_line(Ast *node){
|
gen_line(Ast *node){
|
||||||
if(emit_line_directives){
|
if(emit_line_directives){
|
||||||
last_line = node->pos->line+1;
|
last_line = node->pos->line+1;
|
||||||
@@ -26,14 +26,14 @@ gen_line(Ast *node){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
gen_last_line(){
|
gen_last_line(){
|
||||||
if(emit_line_directives){
|
if(emit_line_directives){
|
||||||
genln("#line %d", last_line);
|
genln("#line %d", last_line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_scope_name(Arena *a, Ast_Scope *scope){
|
string_scope_name(Arena *a, Ast_Scope *scope){
|
||||||
String string = {};
|
String string = {};
|
||||||
if(scope->parent_scope) string = string_scope_name(a, scope->parent_scope);
|
if(scope->parent_scope) string = string_scope_name(a, scope->parent_scope);
|
||||||
@@ -42,14 +42,14 @@ string_scope_name(Arena *a, Ast_Scope *scope){
|
|||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
gen_scope_name(Ast_Scope *scope){
|
gen_scope_name(Ast_Scope *scope){
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
String string = string_scope_name(scratch, scope);
|
String string = string_scope_name(scratch, scope);
|
||||||
gen("%.*s", (int)string.len, string.str);
|
gen("%.*s", (int)string.len, string.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
unique_name(Arena *allocator, Ast *ast){
|
unique_name(Arena *allocator, Ast *ast){
|
||||||
Scratch scratch(allocator);
|
Scratch scratch(allocator);
|
||||||
String result = string_scope_name(scratch, ast->parent_scope);
|
String result = string_scope_name(scratch, ast->parent_scope);
|
||||||
@@ -59,7 +59,7 @@ unique_name(Arena *allocator, Ast *ast){
|
|||||||
}
|
}
|
||||||
|
|
||||||
global String prefixed_string_type;
|
global String prefixed_string_type;
|
||||||
function const char *
|
CORE_Static const char *
|
||||||
get_ctype_name_for_type(Ast_Type *type){
|
get_ctype_name_for_type(Ast_Type *type){
|
||||||
switch(type->kind){
|
switch(type->kind){
|
||||||
case TYPE_VOID: return "void";
|
case TYPE_VOID: return "void";
|
||||||
@@ -84,7 +84,7 @@ get_ctype_name_for_type(Ast_Type *type){
|
|||||||
return "<unknown_type>";
|
return "<unknown_type>";
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_simple_decl_prefix(Arena *a, Ast_Type *ast){
|
string_simple_decl_prefix(Arena *a, Ast_Type *ast){
|
||||||
switch(ast->kind){
|
switch(ast->kind){
|
||||||
case TYPE_POINTER:{
|
case TYPE_POINTER:{
|
||||||
@@ -121,7 +121,7 @@ string_simple_decl_prefix(Arena *a, Ast_Type *ast){
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_simple_decl_postfix(Arena *a, Ast_Type *ast){
|
string_simple_decl_postfix(Arena *a, Ast_Type *ast){
|
||||||
switch(ast->kind){
|
switch(ast->kind){
|
||||||
case TYPE_POINTER:
|
case TYPE_POINTER:
|
||||||
@@ -140,7 +140,7 @@ string_simple_decl_postfix(Arena *a, Ast_Type *ast){
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
string_simple_decl(Arena *a, Ast_Type *ast, Intern_String name = {}){
|
string_simple_decl(Arena *a, Ast_Type *ast, Intern_String name = {}){
|
||||||
if(ast->kind == TYPE_LAMBDA) {
|
if(ast->kind == TYPE_LAMBDA) {
|
||||||
String prefix = string_simple_decl_prefix(a, ast->func.ret);
|
String prefix = string_simple_decl_prefix(a, ast->func.ret);
|
||||||
@@ -165,14 +165,14 @@ string_simple_decl(Arena *a, Ast_Type *ast, Intern_String name = {}){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
gen_simple_decl(Ast_Type *ast, Intern_String name = {}){
|
gen_simple_decl(Ast_Type *ast, Intern_String name = {}){
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
String string = string_simple_decl(scratch, ast, name);
|
String string = string_simple_decl(scratch, ast, name);
|
||||||
gen("%.*s", (int)string.len, string.str);
|
gen("%.*s", (int)string.len, string.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
gen_string_simple_decl(Arena *a, Ast_Type *ast, String name){
|
gen_string_simple_decl(Arena *a, Ast_Type *ast, String name){
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
String string = string_simple_decl(scratch, ast, pctx->intern(name));
|
String string = string_simple_decl(scratch, ast, pctx->intern(name));
|
||||||
@@ -180,7 +180,7 @@ gen_string_simple_decl(Arena *a, Ast_Type *ast, String name){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
get_type_postfix(Ast_Type *type){
|
get_type_postfix(Ast_Type *type){
|
||||||
switch(type->kind) {
|
switch(type->kind) {
|
||||||
case TYPE_F32: return "f"_s; break;
|
case TYPE_F32: return "f"_s; break;
|
||||||
@@ -197,7 +197,7 @@ get_type_postfix(Ast_Type *type){
|
|||||||
return ""_s;
|
return ""_s;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
gen_value(Token *pos, Value a){
|
gen_value(Token *pos, Value a){
|
||||||
if(is_untyped(a.type)) compiler_error(pos, "Internal compiler error: Untyped got propagated to the codegen stage");
|
if(is_untyped(a.type)) compiler_error(pos, "Internal compiler error: Untyped got propagated to the codegen stage");
|
||||||
|
|
||||||
@@ -250,7 +250,7 @@ gen_value(Token *pos, Value a){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
gen_stmt_scope(Ast_Scope *scope, B32 switch_case_gen_break = 0){
|
gen_stmt_scope(Ast_Scope *scope, B32 switch_case_gen_break = 0){
|
||||||
gen("{");
|
gen("{");
|
||||||
global_indent++;
|
global_indent++;
|
||||||
@@ -270,7 +270,7 @@ enum {
|
|||||||
DONT_EMIT_VALUE = 1,
|
DONT_EMIT_VALUE = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
gen_pointer(Ast_Expr *expr){
|
gen_pointer(Ast_Expr *expr){
|
||||||
gen("&");
|
gen("&");
|
||||||
if(is_flag_set(expr->flags, AST_IS_LVALUE)){
|
if(is_flag_set(expr->flags, AST_IS_LVALUE)){
|
||||||
@@ -286,7 +286,7 @@ gen_pointer(Ast_Expr *expr){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
gen_try_any_or_slice(Ast_Expr *expr, Ast_Type *decl_type){
|
gen_try_any_or_slice(Ast_Expr *expr, Ast_Type *decl_type){
|
||||||
|
|
||||||
// We want normal values to get boxed as Any pointers
|
// We want normal values to get boxed as Any pointers
|
||||||
@@ -305,7 +305,7 @@ gen_try_any_or_slice(Ast_Expr *expr, Ast_Type *decl_type){
|
|||||||
else gen_expr(expr);
|
else gen_expr(expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
gen_var(Ast_Decl *decl, B32 emit_value, B32 scope_names){
|
gen_var(Ast_Decl *decl, B32 emit_value, B32 scope_names){
|
||||||
if(is_flag_set(decl->flags, AST_FOREIGN)) gen("extern ");
|
if(is_flag_set(decl->flags, AST_FOREIGN)) gen("extern ");
|
||||||
gen_simple_decl(decl->type, decl->name);
|
gen_simple_decl(decl->type, decl->name);
|
||||||
@@ -327,7 +327,7 @@ gen_var(Ast_Decl *decl, B32 emit_value, B32 scope_names){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
gen_lambda(Intern_String name, Ast_Lambda *lambda, B32 generate_block = true){
|
gen_lambda(Intern_String name, Ast_Lambda *lambda, B32 generate_block = true){
|
||||||
gen_simple_decl(lambda->resolved_type->func.ret, name);
|
gen_simple_decl(lambda->resolved_type->func.ret, name);
|
||||||
gen("(");
|
gen("(");
|
||||||
@@ -344,7 +344,7 @@ gen_lambda(Intern_String name, Ast_Lambda *lambda, B32 generate_block = true){
|
|||||||
else gen(";");
|
else gen(";");
|
||||||
}
|
}
|
||||||
|
|
||||||
function bool
|
CORE_Static bool
|
||||||
gen_expr(Ast_Expr *ast){
|
gen_expr(Ast_Expr *ast){
|
||||||
switch(ast->kind){
|
switch(ast->kind){
|
||||||
CASE(IDENT, Atom){
|
CASE(IDENT, Atom){
|
||||||
@@ -515,7 +515,7 @@ gen_expr(Ast_Expr *ast){
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
gen_ast(Ast *ast){
|
gen_ast(Ast *ast){
|
||||||
switch(ast->kind){
|
switch(ast->kind){
|
||||||
|
|
||||||
@@ -767,7 +767,7 @@ gen_ast(Ast *ast){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
compile_to_c_code(){
|
compile_to_c_code(){
|
||||||
generating_time_begin = os_time();
|
generating_time_begin = os_time();
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
lex_init(Arena *token_string_arena, Arena *map_allocator, Lexer *l){
|
lex_init(Arena *token_string_arena, Arena *map_allocator, Lexer *l){
|
||||||
l->arena = token_string_arena;
|
l->arena = token_string_arena;
|
||||||
l->tokens = array_make<Token>(token_string_arena, 4096*4);
|
l->tokens = array_make<Token>(token_string_arena, 4096*4);
|
||||||
@@ -74,7 +74,7 @@ op_info_table[19].op = l->intern("!"_s);
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
parse_init(Parse_Ctx *ctx, Arena *perm_allocator){
|
parse_init(Parse_Ctx *ctx, Arena *perm_allocator){
|
||||||
pctx = ctx;
|
pctx = ctx;
|
||||||
ctx->perm = perm_allocator;
|
ctx->perm = perm_allocator;
|
||||||
@@ -97,7 +97,7 @@ parse_init(Parse_Ctx *ctx, Arena *perm_allocator){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
begin_compilation(){
|
begin_compilation(){
|
||||||
init_ctx_time_begin = os_time();
|
init_ctx_time_begin = os_time();
|
||||||
Parse_Ctx *ctx = arena_push_type(&pernament_arena, Parse_Ctx, AF_ZeroMemory);
|
Parse_Ctx *ctx = arena_push_type(&pernament_arena, Parse_Ctx, AF_ZeroMemory);
|
||||||
@@ -105,13 +105,13 @@ begin_compilation(){
|
|||||||
init_ctx_time_end = os_time();
|
init_ctx_time_end = os_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
destroy_compiler(){
|
destroy_compiler(){
|
||||||
arena_clear(pctx->perm);
|
arena_clear(pctx->perm);
|
||||||
arena_clear(&pctx->stage_arena);
|
arena_clear(&pctx->stage_arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
insert_builtin_type_into_scope(Ast_Scope *p, String name, Ast_Type *type){
|
insert_builtin_type_into_scope(Ast_Scope *p, String name, Ast_Type *type){
|
||||||
Intern_String string = pctx->intern(name);
|
Intern_String string = pctx->intern(name);
|
||||||
Ast_Decl *decl = ast_type(0, string, type);
|
Ast_Decl *decl = ast_type(0, string, type);
|
||||||
@@ -124,7 +124,7 @@ insert_builtin_type_into_scope(Ast_Scope *p, String name, Ast_Type *type){
|
|||||||
|
|
||||||
global F64 parsing_time_begin;
|
global F64 parsing_time_begin;
|
||||||
global F64 parsing_time_end;
|
global F64 parsing_time_end;
|
||||||
function void
|
CORE_Static void
|
||||||
parse_all_modules(){
|
parse_all_modules(){
|
||||||
parsing_time_begin = os_time();
|
parsing_time_begin = os_time();
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ parse_all_modules(){
|
|||||||
parsing_time_end = os_time();
|
parsing_time_end = os_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Module *
|
CORE_Static Ast_Module *
|
||||||
add_module(Token *pos, Intern_String filename, B32 command_line_module){
|
add_module(Token *pos, Intern_String filename, B32 command_line_module){
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
String absolute_file_path = {};
|
String absolute_file_path = {};
|
||||||
@@ -204,7 +204,7 @@ add_module(Token *pos, Intern_String filename, B32 command_line_module){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
resolve_everything_in_module(Ast_Module *module){
|
resolve_everything_in_module(Ast_Module *module){
|
||||||
if(module->state == MODULE_RESOLVED) return;
|
if(module->state == MODULE_RESOLVED) return;
|
||||||
resolving_time_begin = os_time();
|
resolving_time_begin = os_time();
|
||||||
@@ -222,7 +222,7 @@ resolve_everything_in_module(Ast_Module *module){
|
|||||||
resolving_time_end = os_time();
|
resolving_time_end = os_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
compile_file_to_string(String filename){
|
compile_file_to_string(String filename){
|
||||||
total_time = os_time();
|
total_time = os_time();
|
||||||
begin_compilation();
|
begin_compilation();
|
||||||
@@ -300,7 +300,7 @@ const U32 COMPILE_PRINT_ALLOCATOR_STATS_BEFORE_DESTROY = 0x2;
|
|||||||
const U32 COMPILE_AND_RUN = 0x4;
|
const U32 COMPILE_AND_RUN = 0x4;
|
||||||
const U32 COMPILE_TESTING = 0x8;
|
const U32 COMPILE_TESTING = 0x8;
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
compile_file(String filename, U32 compile_flags = COMPILE_NULL){
|
compile_file(String filename, U32 compile_flags = COMPILE_NULL){
|
||||||
if(is_flag_set(compile_flags, COMPILE_AND_RUN)){
|
if(is_flag_set(compile_flags, COMPILE_AND_RUN)){
|
||||||
log_info_no_nl("%Q - ", filename);
|
log_info_no_nl("%Q - ", filename);
|
||||||
|
|||||||
@@ -186,11 +186,11 @@ struct Parse_Ctx:Lexer{
|
|||||||
String_Builder helper_builder;
|
String_Builder helper_builder;
|
||||||
};
|
};
|
||||||
|
|
||||||
function void init_type();
|
CORE_Static void init_type();
|
||||||
function void lex_init(Arena *token_string_arena, Arena *map_allocator, Lexer *l);
|
CORE_Static void lex_init(Arena *token_string_arena, Arena *map_allocator, Lexer *l);
|
||||||
function String compile_to_c_code();
|
CORE_Static String compile_to_c_code();
|
||||||
function Ast_Module *ast_module(Token *pos, Intern_String filename);
|
CORE_Static Ast_Module *ast_module(Token *pos, Intern_String filename);
|
||||||
function void insert_builtin_types_into_scope(Ast_Scope *p);
|
CORE_Static void insert_builtin_types_into_scope(Ast_Scope *p);
|
||||||
function void insert_into_scope(Ast_Scope *scope, Ast_Decl *decl);
|
CORE_Static void insert_into_scope(Ast_Scope *scope, Ast_Decl *decl);
|
||||||
function Ast_Type *type_incomplete(Ast *ast);
|
CORE_Static Ast_Type *type_incomplete(Ast *ast);
|
||||||
function Ast_Expr *parse_expr(S64 minbp = 0);
|
CORE_Static Ast_Expr *parse_expr(S64 minbp = 0);
|
||||||
@@ -15,7 +15,7 @@ for i in meta.token_simple_expr:
|
|||||||
print(f""" {{{{}}, "{i[0].upper()}"_s, TK_{i[0]}, {int(i[2]&meta.BINARY_EXPR>0)}, {int(i[2]&meta.UNARY_EXPR>0)}}},""")
|
print(f""" {{{{}}, "{i[0].upper()}"_s, TK_{i[0]}, {int(i[2]&meta.BINARY_EXPR>0)}, {int(i[2]&meta.UNARY_EXPR>0)}}},""")
|
||||||
print("};")
|
print("};")
|
||||||
|
|
||||||
print("""function Operator_Info *
|
print("""CORE_Static Operator_Info *
|
||||||
get_operator_info(Token_Kind op){
|
get_operator_info(Token_Kind op){
|
||||||
switch(op){""")
|
switch(op){""")
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ for i in meta.token_simple_expr:
|
|||||||
print(" default: {}\n }")
|
print(" default: {}\n }")
|
||||||
print(" return 0;\n}")
|
print(" return 0;\n}")
|
||||||
|
|
||||||
print("""function Operator_Info *
|
print("""CORE_Static Operator_Info *
|
||||||
get_operator_info(Intern_String op){
|
get_operator_info(Intern_String op){
|
||||||
if(0){}""")
|
if(0){}""")
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ Operator_Info op_info_table[] = {
|
|||||||
{{}, "NEG"_s, TK_Neg, 0, 1},
|
{{}, "NEG"_s, TK_Neg, 0, 1},
|
||||||
{{}, "NOT"_s, TK_Not, 0, 1},
|
{{}, "NOT"_s, TK_Not, 0, 1},
|
||||||
};
|
};
|
||||||
function Operator_Info *
|
CORE_Static Operator_Info *
|
||||||
get_operator_info(Token_Kind op){
|
get_operator_info(Token_Kind op){
|
||||||
switch(op){
|
switch(op){
|
||||||
case TK_Mul: return op_info_table + 0;
|
case TK_Mul: return op_info_table + 0;
|
||||||
@@ -89,7 +89,7 @@ get_operator_info(Token_Kind op){
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
function Operator_Info *
|
CORE_Static Operator_Info *
|
||||||
get_operator_info(Intern_String op){
|
get_operator_info(Intern_String op){
|
||||||
if(0){}
|
if(0){}
|
||||||
else if(op_info_table[0].op.str == op.str) return op_info_table + 0;
|
else if(op_info_table[0].op.str == op.str) return op_info_table + 0;
|
||||||
|
|||||||
@@ -3,59 +3,59 @@ force_inline B32 token_is_assign(Token *token){return token_is_assign(token->kin
|
|||||||
force_inline B32 token_is_compare(Token_Kind token){return token >= TK_FirstCompare && token <= TK_LastCompare;}
|
force_inline B32 token_is_compare(Token_Kind token){return token >= TK_FirstCompare && token <= TK_LastCompare;}
|
||||||
force_inline B32 token_is_compare(Token *token){return token_is_compare(token->kind);}
|
force_inline B32 token_is_compare(Token *token){return token_is_compare(token->kind);}
|
||||||
|
|
||||||
function U8
|
CORE_Static U8
|
||||||
lexc(Lex_Stream *s){
|
lexc(Lex_Stream *s){
|
||||||
return s->stream.str[s->iter];
|
return s->stream.str[s->iter];
|
||||||
}
|
}
|
||||||
|
|
||||||
function U8
|
CORE_Static U8
|
||||||
lexci(Lex_Stream *s, S32 i){
|
lexci(Lex_Stream *s, S32 i){
|
||||||
return s->stream.str[s->iter+i];
|
return s->stream.str[s->iter+i];
|
||||||
}
|
}
|
||||||
|
|
||||||
function U8 *
|
CORE_Static U8 *
|
||||||
lexcp(Lex_Stream *s){
|
lexcp(Lex_Stream *s){
|
||||||
return s->stream.str + s->iter;
|
return s->stream.str + s->iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
lex_is_whitespace(U8 c){
|
lex_is_whitespace(U8 c){
|
||||||
B32 result = c == ' ' || c == '\r';
|
B32 result = c == ' ' || c == '\r';
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
lex_is_alphabetic(U8 c){
|
lex_is_alphabetic(U8 c){
|
||||||
B32 result = (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
|
B32 result = (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
lex_is_numeric(U8 c){
|
lex_is_numeric(U8 c){
|
||||||
B32 result = c >= '0' && c <= '9';
|
B32 result = c >= '0' && c <= '9';
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
lex_is_numeric_base16(U8 c){
|
lex_is_numeric_base16(U8 c){
|
||||||
B32 result = (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') ||
|
B32 result = (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') ||
|
||||||
(c >= 'a' && c <= 'f');
|
(c >= 'a' && c <= 'f');
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
lex_is_alphanumeric(U8 c){
|
lex_is_alphanumeric(U8 c){
|
||||||
B32 result = lex_is_numeric(c) || lex_is_alphabetic(c);
|
B32 result = lex_is_numeric(c) || lex_is_alphabetic(c);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
lex_set_len(Lex_Stream *s, Token *token){
|
lex_set_len(Lex_Stream *s, Token *token){
|
||||||
assert(lexcp(s) >= token->str);
|
assert(lexcp(s) >= token->str);
|
||||||
token->len = lexcp(s) - token->str;
|
token->len = lexcp(s) - token->str;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
lex_set_keywords(Lexer *lexer, Array<String> keywords){
|
lex_set_keywords(Lexer *lexer, Array<String> keywords){
|
||||||
Intern_String keyword = {};
|
Intern_String keyword = {};
|
||||||
For(keywords){
|
For(keywords){
|
||||||
@@ -66,19 +66,19 @@ lex_set_keywords(Lexer *lexer, Array<String> keywords){
|
|||||||
lexer->interns.last_keyword = keyword.str;
|
lexer->interns.last_keyword = keyword.str;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
lex_is_keyword(Intern_Table *lexer, Intern_String keyword){
|
lex_is_keyword(Intern_Table *lexer, Intern_String keyword){
|
||||||
B32 result = keyword.str >= lexer->first_keyword && keyword.str <= lexer->last_keyword;
|
B32 result = keyword.str >= lexer->first_keyword && keyword.str <= lexer->last_keyword;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
token_error(Token *t, String error_val){
|
token_error(Token *t, String error_val){
|
||||||
t->kind = TK_Error;
|
t->kind = TK_Error;
|
||||||
t->error_val = error_val;
|
t->error_val = error_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
lex_parse_u64(Lexer *lexer, Token *t, S64 base){
|
lex_parse_u64(Lexer *lexer, Token *t, S64 base){
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
Set_BigInt_Arena(scratch);
|
Set_BigInt_Arena(scratch);
|
||||||
@@ -103,7 +103,7 @@ lex_parse_u64(Lexer *lexer, Token *t, S64 base){
|
|||||||
t->int_val = bigint_copy(lexer->arena, &result);
|
t->int_val = bigint_copy(lexer->arena, &result);
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
lex_parse_f64(Token *t){
|
lex_parse_f64(Token *t){
|
||||||
t->kind = TK_Float;
|
t->kind = TK_Float;
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
@@ -113,7 +113,7 @@ lex_parse_f64(Token *t){
|
|||||||
t->f64_val = strtod(buffer, 0);
|
t->f64_val = strtod(buffer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
lex_advance(Lex_Stream *s){
|
lex_advance(Lex_Stream *s){
|
||||||
if(s->iter >= s->stream.len){
|
if(s->iter >= s->stream.len){
|
||||||
return;
|
return;
|
||||||
@@ -128,7 +128,7 @@ lex_advance(Lex_Stream *s){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
lex_parse_string(Lex_Stream *s, Token *t, U8 c){
|
lex_parse_string(Lex_Stream *s, Token *t, U8 c){
|
||||||
for(;;){
|
for(;;){
|
||||||
if(lexc(s) == '\\') lex_advance(s);
|
if(lexc(s) == '\\') lex_advance(s);
|
||||||
@@ -145,7 +145,7 @@ lex_parse_string(Lex_Stream *s, Token *t, U8 c){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
lex_parse_ident(Intern_Table *table, Lex_Stream *s, Token *t){
|
lex_parse_ident(Intern_Table *table, Lex_Stream *s, Token *t){
|
||||||
while(lex_is_alphanumeric(lexc(s)) || lexc(s) == '_')
|
while(lex_is_alphanumeric(lexc(s)) || lexc(s) == '_')
|
||||||
lex_advance(s);
|
lex_advance(s);
|
||||||
@@ -174,7 +174,7 @@ lex_parse_ident(Intern_Table *table, Lex_Stream *s, Token *t){
|
|||||||
} \
|
} \
|
||||||
break
|
break
|
||||||
|
|
||||||
function Token
|
CORE_Static Token
|
||||||
token_make(Lexer *lexer, U8 *str, Intern_String file, int line, U8 *line_begin){
|
token_make(Lexer *lexer, U8 *str, Intern_String file, int line, U8 *line_begin){
|
||||||
Token t = {};
|
Token t = {};
|
||||||
t.str = str;
|
t.str = str;
|
||||||
@@ -185,12 +185,12 @@ token_make(Lexer *lexer, U8 *str, Intern_String file, int line, U8 *line_begin){
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Token
|
CORE_Static Token
|
||||||
token_make(Lexer *lexer){
|
token_make(Lexer *lexer){
|
||||||
return token_make(lexer, lexcp(&lexer->stream), lexer->stream.file, lexer->stream.line, lexer->stream.line_begin);
|
return token_make(lexer, lexcp(&lexer->stream), lexer->stream.file, lexer->stream.line, lexer->stream.line_begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Token *
|
CORE_Static Token *
|
||||||
lex_last_indent_token(Lex_Stream *s){
|
lex_last_indent_token(Lex_Stream *s){
|
||||||
if(s->indent_stack.len > 0){
|
if(s->indent_stack.len > 0){
|
||||||
return *s->indent_stack.last();
|
return *s->indent_stack.last();
|
||||||
@@ -198,13 +198,13 @@ lex_last_indent_token(Lex_Stream *s){
|
|||||||
return &token_null;
|
return &token_null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
lex_is_scope(Token *t){
|
lex_is_scope(Token *t){
|
||||||
B32 result = t->kind == OPEN_SCOPE || t->kind == CLOSE_SCOPE || t->kind == SAME_SCOPE;
|
B32 result = t->kind == OPEN_SCOPE || t->kind == CLOSE_SCOPE || t->kind == SAME_SCOPE;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
lex_unwind_indent_stack(Token *t, Lex_Stream *s, Array<Token> *array){
|
lex_unwind_indent_stack(Token *t, Lex_Stream *s, Array<Token> *array){
|
||||||
for(S64 i = s->indent_stack.len-1; i >= 0; i-=1){
|
for(S64 i = s->indent_stack.len-1; i >= 0; i-=1){
|
||||||
auto it = s->indent_stack.data[i];
|
auto it = s->indent_stack.data[i];
|
||||||
@@ -227,7 +227,7 @@ lex_unwind_indent_stack(Token *t, Lex_Stream *s, Array<Token> *array){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
lex__stream(Lexer *lexer){
|
lex__stream(Lexer *lexer){
|
||||||
Intern_Table *table = &lexer->interns;
|
Intern_Table *table = &lexer->interns;
|
||||||
Array<Token> *array = &lexer->tokens;
|
Array<Token> *array = &lexer->tokens;
|
||||||
@@ -250,7 +250,7 @@ lex__stream(Lexer *lexer){
|
|||||||
// of same scope.
|
// of same scope.
|
||||||
// parse_decl doesn't require preceding new line
|
// parse_decl doesn't require preceding new line
|
||||||
//
|
//
|
||||||
// in that way new lines act as commas in function params
|
// in that way new lines act as commas in CORE_Static params
|
||||||
// seeing a comma means that there is a next thing to parse
|
// seeing a comma means that there is a next thing to parse
|
||||||
// and it's easy to parse stuff using a do while loop
|
// and it's easy to parse stuff using a do while loop
|
||||||
|
|
||||||
@@ -585,14 +585,14 @@ lex__stream(Lexer *lexer){
|
|||||||
#undef CASE3
|
#undef CASE3
|
||||||
}
|
}
|
||||||
|
|
||||||
function Lexer
|
CORE_Static Lexer
|
||||||
lex_make(Arena *token_string_arena, Arena *map_allocator){
|
lex_make(Arena *token_string_arena, Arena *map_allocator){
|
||||||
Lexer result = {};
|
Lexer result = {};
|
||||||
lex_init(token_string_arena, map_allocator, &result);
|
lex_init(token_string_arena, map_allocator, &result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
lex_restream(Lexer *lexer, String istream, String file){
|
lex_restream(Lexer *lexer, String istream, String file){
|
||||||
lexer->stream = {};
|
lexer->stream = {};
|
||||||
lexer->stream.stream = istream;
|
lexer->stream.stream = istream;
|
||||||
@@ -605,7 +605,7 @@ lex_restream(Lexer *lexer, String istream, String file){
|
|||||||
lex__stream(lexer);
|
lex__stream(lexer);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Lexer
|
CORE_Static Lexer
|
||||||
lex_stream(Arena *token_string_arena, Arena *map_allocator, String istream, String file){
|
lex_stream(Arena *token_string_arena, Arena *map_allocator, String istream, String file){
|
||||||
Lexer result = lex_make(token_string_arena, map_allocator);
|
Lexer result = lex_make(token_string_arena, map_allocator);
|
||||||
lex_restream(&result, istream, file);
|
lex_restream(&result, istream, file);
|
||||||
@@ -616,7 +616,7 @@ lex_stream(Arena *token_string_arena, Arena *map_allocator, String istream, Stri
|
|||||||
// Token metadata
|
// Token metadata
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
function const char *
|
CORE_Static const char *
|
||||||
name(Token_Kind kind){
|
name(Token_Kind kind){
|
||||||
switch(kind){
|
switch(kind){
|
||||||
case TK_End: return "End of stream";
|
case TK_End: return "End of stream";
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
function Ast_Decl *parse_decl(B32 is_global);
|
CORE_Static Ast_Decl *parse_decl(B32 is_global);
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
print_token_line(Token *token){
|
print_token_line(Token *token){
|
||||||
if(!token) return;
|
if(!token) return;
|
||||||
|
|
||||||
@@ -23,14 +23,14 @@ print_token_line(Token *token){
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
print_token_context(Token *token){
|
print_token_context(Token *token){
|
||||||
if(!token) return;
|
if(!token) return;
|
||||||
printf("\n");
|
printf("\n");
|
||||||
print_token_line(token);
|
print_token_line(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
compiler_error(Token *token1, Token *token2, const char *str, ...){
|
compiler_error(Token *token1, Token *token2, const char *str, ...){
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
STRING_FMT(scratch, str, string);
|
STRING_FMT(scratch, str, string);
|
||||||
@@ -56,7 +56,7 @@ compiler_error(Token *token1, Token *token2, const char *str, ...){
|
|||||||
Breakpoint;
|
Breakpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
compiler_error(Token *token, const char *str, ...){
|
compiler_error(Token *token, const char *str, ...){
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
STRING_FMT(scratch, str, string);
|
STRING_FMT(scratch, str, string);
|
||||||
@@ -75,7 +75,7 @@ compiler_error(Token *token, const char *str, ...){
|
|||||||
Breakpoint;
|
Breakpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Token *
|
CORE_Static Token *
|
||||||
token_get(S64 i = 0){
|
token_get(S64 i = 0){
|
||||||
i += pctx->token_iter;
|
i += pctx->token_iter;
|
||||||
if(i >= pctx->tokens.len){
|
if(i >= pctx->tokens.len){
|
||||||
@@ -85,14 +85,14 @@ token_get(S64 i = 0){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Token *
|
CORE_Static Token *
|
||||||
token_is_scope(){
|
token_is_scope(){
|
||||||
Token *token = token_get();
|
Token *token = token_get();
|
||||||
if(lex_is_scope(token)) return token;
|
if(lex_is_scope(token)) return token;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Token *
|
CORE_Static Token *
|
||||||
token_next(){
|
token_next(){
|
||||||
Token *token = token_get();
|
Token *token = token_get();
|
||||||
if(lex_is_scope(token)) pctx->indent = token->indent;
|
if(lex_is_scope(token)) pctx->indent = token->indent;
|
||||||
@@ -100,7 +100,7 @@ token_next(){
|
|||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Token *
|
CORE_Static Token *
|
||||||
token_is(Token_Kind kind, S64 lookahead = 0){
|
token_is(Token_Kind kind, S64 lookahead = 0){
|
||||||
Token *token = token_get(lookahead);
|
Token *token = token_get(lookahead);
|
||||||
if(token->kind == kind){
|
if(token->kind == kind){
|
||||||
@@ -109,7 +109,7 @@ token_is(Token_Kind kind, S64 lookahead = 0){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Token *
|
CORE_Static Token *
|
||||||
token_is_keyword(Intern_String keyword, S64 lookahead = 0){
|
token_is_keyword(Intern_String keyword, S64 lookahead = 0){
|
||||||
Token *token = token_get(lookahead);
|
Token *token = token_get(lookahead);
|
||||||
if(token->kind == TK_Keyword){
|
if(token->kind == TK_Keyword){
|
||||||
@@ -120,7 +120,7 @@ token_is_keyword(Intern_String keyword, S64 lookahead = 0){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Token *
|
CORE_Static Token *
|
||||||
token_match_pound(Intern_String string){
|
token_match_pound(Intern_String string){
|
||||||
Token *token = token_get();
|
Token *token = token_get();
|
||||||
if(token->kind == TK_Pound){
|
if(token->kind == TK_Pound){
|
||||||
@@ -131,7 +131,7 @@ token_match_pound(Intern_String string){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Token *
|
CORE_Static Token *
|
||||||
token_match(Token_Kind kind){
|
token_match(Token_Kind kind){
|
||||||
Token *token = token_get();
|
Token *token = token_get();
|
||||||
if(token->kind == kind){
|
if(token->kind == kind){
|
||||||
@@ -140,7 +140,7 @@ token_match(Token_Kind kind){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Token *
|
CORE_Static Token *
|
||||||
token_match(Token_Kind a, Token_Kind b){
|
token_match(Token_Kind a, Token_Kind b){
|
||||||
Token *ta = token_get();
|
Token *ta = token_get();
|
||||||
Token *tb = token_get(1);
|
Token *tb = token_get(1);
|
||||||
@@ -151,7 +151,7 @@ token_match(Token_Kind a, Token_Kind b){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Token *
|
CORE_Static Token *
|
||||||
token_match_keyword(Intern_String string){
|
token_match_keyword(Intern_String string){
|
||||||
Token *token = token_get();
|
Token *token = token_get();
|
||||||
if(token->kind == TK_Keyword){
|
if(token->kind == TK_Keyword){
|
||||||
@@ -163,7 +163,7 @@ token_match_keyword(Intern_String string){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Token *
|
CORE_Static Token *
|
||||||
token_expect(Token_Kind kind){
|
token_expect(Token_Kind kind){
|
||||||
Token *token = token_get();
|
Token *token = token_get();
|
||||||
if(token->kind == kind) return token_next();
|
if(token->kind == kind) return token_next();
|
||||||
@@ -171,7 +171,7 @@ token_expect(Token_Kind kind){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Expr *
|
CORE_Static Ast_Expr *
|
||||||
parse_init_stmt(Ast_Expr *expr){
|
parse_init_stmt(Ast_Expr *expr){
|
||||||
Token *token = token_get();
|
Token *token = token_get();
|
||||||
if(token->kind == TK_ColonAssign && expr->kind != AST_IDENT)
|
if(token->kind == TK_ColonAssign && expr->kind != AST_IDENT)
|
||||||
@@ -195,7 +195,7 @@ parse_init_stmt(Ast_Expr *expr){
|
|||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Call *
|
CORE_Static Ast_Call *
|
||||||
parse_expr_call(Ast_Expr *left, Token_Kind close_kind){
|
parse_expr_call(Ast_Expr *left, Token_Kind close_kind){
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
Token *pos = token_get();
|
Token *pos = token_get();
|
||||||
@@ -235,14 +235,14 @@ parse_expr_call(Ast_Expr *left, Token_Kind close_kind){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Expr *
|
CORE_Static Ast_Expr *
|
||||||
parse_optional_type(){
|
parse_optional_type(){
|
||||||
Ast_Expr *result = 0;
|
Ast_Expr *result = 0;
|
||||||
if(token_match(TK_Colon)) result = parse_expr();
|
if(token_match(TK_Colon)) result = parse_expr();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Scope *
|
CORE_Static Ast_Scope *
|
||||||
parse_stmt_scope(Ast_Scope *scope_defined_outside = 0){
|
parse_stmt_scope(Ast_Scope *scope_defined_outside = 0){
|
||||||
Ast_Scope *scope = scope_defined_outside;
|
Ast_Scope *scope = scope_defined_outside;
|
||||||
|
|
||||||
@@ -431,7 +431,7 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside = 0){
|
|||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Lambda *
|
CORE_Static Ast_Lambda *
|
||||||
parse_lambda(Token *token){
|
parse_lambda(Token *token){
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
|
|
||||||
@@ -479,7 +479,7 @@ parse_lambda(Token *token){
|
|||||||
struct Binding_Power{S64 left;S64 right;};
|
struct Binding_Power{S64 left;S64 right;};
|
||||||
enum Binding{Binding_Prefix,Binding_Infix,Binding_Postfix};
|
enum Binding{Binding_Prefix,Binding_Infix,Binding_Postfix};
|
||||||
|
|
||||||
function Binding_Power
|
CORE_Static Binding_Power
|
||||||
binding_power(Binding binding, Token_Kind kind){
|
binding_power(Binding binding, Token_Kind kind){
|
||||||
if(binding == Binding_Prefix) goto Prefix;
|
if(binding == Binding_Prefix) goto Prefix;
|
||||||
if(binding == Binding_Infix) goto Infix;
|
if(binding == Binding_Infix) goto Infix;
|
||||||
@@ -544,7 +544,7 @@ binding_power(Binding binding, Token_Kind kind){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Expr *
|
CORE_Static Ast_Expr *
|
||||||
parse_expr(S64 min_bp){
|
parse_expr(S64 min_bp){
|
||||||
Ast_Expr *left = 0;
|
Ast_Expr *left = 0;
|
||||||
Token *token = token_next();
|
Token *token = token_next();
|
||||||
@@ -651,14 +651,14 @@ parse_expr(S64 min_bp){
|
|||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Expr *
|
CORE_Static Ast_Expr *
|
||||||
parse_assign_expr(){
|
parse_assign_expr(){
|
||||||
Ast_Expr *result = 0;
|
Ast_Expr *result = 0;
|
||||||
if(token_match(TK_Assign)) result = parse_expr();
|
if(token_match(TK_Assign)) result = parse_expr();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Decl *
|
CORE_Static Ast_Decl *
|
||||||
parse_struct(Token *pos){
|
parse_struct(Token *pos){
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
|
|
||||||
@@ -682,7 +682,7 @@ parse_struct(Token *pos){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Decl *
|
CORE_Static Ast_Decl *
|
||||||
parse_enum(Token *pos){
|
parse_enum(Token *pos){
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
Ast_Expr *typespec = parse_optional_type();
|
Ast_Expr *typespec = parse_optional_type();
|
||||||
@@ -706,7 +706,7 @@ parse_enum(Token *pos){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
add_implicit_import(Ast_Scope *scope, Ast_Scope *to_add){
|
add_implicit_import(Ast_Scope *scope, Ast_Scope *to_add){
|
||||||
B32 found = false;
|
B32 found = false;
|
||||||
Iter(&scope->implicit_imports){
|
Iter(&scope->implicit_imports){
|
||||||
@@ -722,7 +722,7 @@ add_implicit_import(Ast_Scope *scope, Ast_Scope *to_add){
|
|||||||
|
|
||||||
enum{ GLOBAL_IMPLICIT_LOAD = 1 };
|
enum{ GLOBAL_IMPLICIT_LOAD = 1 };
|
||||||
|
|
||||||
function Ast_File *
|
CORE_Static Ast_File *
|
||||||
register_ast_file(Token *pos, String absolute_file_path, Ast_Module *module, B32 global_implicit_load){
|
register_ast_file(Token *pos, String absolute_file_path, Ast_Module *module, B32 global_implicit_load){
|
||||||
Ast_File *file = 0;
|
Ast_File *file = 0;
|
||||||
|
|
||||||
@@ -762,7 +762,7 @@ register_ast_file(Token *pos, String absolute_file_path, Ast_Module *module, B32
|
|||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Intern_String
|
CORE_Static Intern_String
|
||||||
preprocess_filename(Token *token_filename){
|
preprocess_filename(Token *token_filename){
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
String filename = token_filename->intern_val.s;
|
String filename = token_filename->intern_val.s;
|
||||||
@@ -774,7 +774,7 @@ preprocess_filename(Token *token_filename){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_File *
|
CORE_Static Ast_File *
|
||||||
parse_load(B32 global_implicit_load){
|
parse_load(B32 global_implicit_load){
|
||||||
Token *file = token_expect(TK_StringLit);
|
Token *file = token_expect(TK_StringLit);
|
||||||
Intern_String filename = preprocess_filename(file);
|
Intern_String filename = preprocess_filename(file);
|
||||||
@@ -783,8 +783,8 @@ parse_load(B32 global_implicit_load){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Module *add_module(Token *pos, Intern_String filename, B32 command_line_module = false);
|
CORE_Static Ast_Module *add_module(Token *pos, Intern_String filename, B32 command_line_module = false);
|
||||||
function Ast_Module *
|
CORE_Static Ast_Module *
|
||||||
parse_import(B32 global_implicit_import){
|
parse_import(B32 global_implicit_import){
|
||||||
Token *file = token_expect(TK_StringLit);
|
Token *file = token_expect(TK_StringLit);
|
||||||
Intern_String filename = preprocess_filename(file);
|
Intern_String filename = preprocess_filename(file);
|
||||||
@@ -800,7 +800,7 @@ Needs peeking only because I didn't want to duplicate code
|
|||||||
for parsing statements and it makes code nicer.
|
for parsing statements and it makes code nicer.
|
||||||
Statements can have named syntax i :=
|
Statements can have named syntax i :=
|
||||||
*/
|
*/
|
||||||
function Ast_Decl *
|
CORE_Static Ast_Decl *
|
||||||
parse_decl(B32 is_global){
|
parse_decl(B32 is_global){
|
||||||
Ast_Decl *result = 0;
|
Ast_Decl *result = 0;
|
||||||
if(is_global) {
|
if(is_global) {
|
||||||
@@ -906,7 +906,7 @@ parse_decl(B32 is_global){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
parse_file(Ast_File *file){
|
parse_file(Ast_File *file){
|
||||||
assert(file);
|
assert(file);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
function Resolve_Flag
|
CORE_Static 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);
|
||||||
set_flag(flag, ast_can_be_null);
|
set_flag(flag, ast_can_be_null);
|
||||||
@@ -9,7 +9,7 @@ inherit_flag(Resolve_Flag flag, B32 ast_can_be_null){
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Operands
|
// Operands
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
function Operand
|
CORE_Static Operand
|
||||||
operand(Ast_Decl *decl){
|
operand(Ast_Decl *decl){
|
||||||
Operand result = {};
|
Operand result = {};
|
||||||
result.type = decl->type;
|
result.type = decl->type;
|
||||||
@@ -30,7 +30,7 @@ operand_type(Ast_Type *type) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Operand
|
CORE_Static Operand
|
||||||
operand_int(BigInt big_int){
|
operand_int(BigInt big_int){
|
||||||
Operand result = {};
|
Operand result = {};
|
||||||
result.type = untyped_int;
|
result.type = untyped_int;
|
||||||
@@ -40,7 +40,7 @@ operand_int(BigInt big_int){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Operand
|
CORE_Static Operand
|
||||||
operand_str(Intern_String intern_val){
|
operand_str(Intern_String intern_val){
|
||||||
Operand result = {};
|
Operand result = {};
|
||||||
result.type = type_string;
|
result.type = type_string;
|
||||||
@@ -50,7 +50,7 @@ operand_str(Intern_String intern_val){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Operand
|
CORE_Static Operand
|
||||||
operand_lambda(Ast_Type *type){
|
operand_lambda(Ast_Type *type){
|
||||||
Operand result = {};
|
Operand result = {};
|
||||||
result.type = type;
|
result.type = type;
|
||||||
@@ -59,7 +59,7 @@ operand_lambda(Ast_Type *type){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Operand
|
CORE_Static Operand
|
||||||
operand_const_rvalue(Value value){
|
operand_const_rvalue(Value value){
|
||||||
Operand result = {};
|
Operand result = {};
|
||||||
result.is_const = true;
|
result.is_const = true;
|
||||||
@@ -67,7 +67,7 @@ operand_const_rvalue(Value value){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Operand
|
CORE_Static Operand
|
||||||
operand_lvalue_set_flag_on_node(Ast_Type *type, Ast *ast){
|
operand_lvalue_set_flag_on_node(Ast_Type *type, Ast *ast){
|
||||||
Operand result = {};
|
Operand result = {};
|
||||||
result.type = type;
|
result.type = type;
|
||||||
@@ -77,7 +77,7 @@ operand_lvalue_set_flag_on_node(Ast_Type *type, Ast *ast){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Operand
|
CORE_Static Operand
|
||||||
operand_rvalue(Ast_Type *type){
|
operand_rvalue(Ast_Type *type){
|
||||||
Operand result = {};
|
Operand result = {};
|
||||||
result.type = type;
|
result.type = type;
|
||||||
@@ -86,7 +86,7 @@ operand_rvalue(Ast_Type *type){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Type *
|
CORE_Static Ast_Type *
|
||||||
get_default_type_from_untyped(Ast_Type *type){
|
get_default_type_from_untyped(Ast_Type *type){
|
||||||
switch(type->kind){
|
switch(type->kind){
|
||||||
case TYPE_UNTYPED_INT: return type_s64; break;
|
case TYPE_UNTYPED_INT: return type_s64; break;
|
||||||
@@ -98,19 +98,19 @@ get_default_type_from_untyped(Ast_Type *type){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
try_converting_untyped_to_default_type(Value *op){
|
try_converting_untyped_to_default_type(Value *op){
|
||||||
if(is_untyped(op->type)){
|
if(is_untyped(op->type)){
|
||||||
op->type = get_default_type_from_untyped(op->type);
|
op->type = get_default_type_from_untyped(op->type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
try_converting_untyped_to_default_type(Operand *op){
|
try_converting_untyped_to_default_type(Operand *op){
|
||||||
try_converting_untyped_to_default_type(&op->value);
|
try_converting_untyped_to_default_type(&op->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
check_value_bounds(Token *pos, Value *a){
|
check_value_bounds(Token *pos, Value *a){
|
||||||
if(!is_int(a->type)) return;
|
if(!is_int(a->type)) return;
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ check_value_bounds(Token *pos, Value *a){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
convert_untyped_to_typed(Token *pos, Value *a, Ast_Type *new_type){
|
convert_untyped_to_typed(Token *pos, Value *a, Ast_Type *new_type){
|
||||||
assert(new_type);
|
assert(new_type);
|
||||||
if(a->type == 0) return;
|
if(a->type == 0) return;
|
||||||
@@ -149,7 +149,7 @@ convert_untyped_to_typed(Token *pos, Value *a, Ast_Type *new_type){
|
|||||||
check_value_bounds(pos, a);
|
check_value_bounds(pos, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Type *
|
CORE_Static Ast_Type *
|
||||||
convert_untyped_to_typed(Token *pos, Ast_Type *type, Ast_Type *new_type){
|
convert_untyped_to_typed(Token *pos, Ast_Type *type, Ast_Type *new_type){
|
||||||
Value value = {};
|
Value value = {};
|
||||||
value.type = type;
|
value.type = type;
|
||||||
@@ -157,7 +157,7 @@ convert_untyped_to_typed(Token *pos, Ast_Type *type, Ast_Type *new_type){
|
|||||||
return value.type;
|
return value.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
make_sure_types_are_compatible_for_constant_evaluation(Token *pos, Value *a, Value *b){
|
make_sure_types_are_compatible_for_constant_evaluation(Token *pos, Value *a, Value *b){
|
||||||
if((is_pointer(a->type) && is_int(b->type)) || (is_pointer(b->type) && is_int(a->type))){
|
if((is_pointer(a->type) && is_int(b->type)) || (is_pointer(b->type) && is_int(a->type))){
|
||||||
return;
|
return;
|
||||||
@@ -187,7 +187,7 @@ make_sure_types_are_compatible_for_constant_evaluation(Token *pos, Value *a, Val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Value
|
CORE_Static Value
|
||||||
compare_values(Token *pos, Token_Kind op, Value a, Value b, bool is_const){
|
compare_values(Token *pos, Token_Kind op, Value a, Value b, bool is_const){
|
||||||
if(is_enum(a.type) && (a.type == b.type))
|
if(is_enum(a.type) && (a.type == b.type))
|
||||||
goto skip_eval;
|
goto skip_eval;
|
||||||
@@ -253,7 +253,7 @@ compare_values(Token *pos, Token_Kind op, Value a, Value b, bool is_const){
|
|||||||
return value_bool(result);
|
return value_bool(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Value
|
CORE_Static Value
|
||||||
eval_binary(Token *pos, Token_Kind op, Value a, Value b, bool is_const){
|
eval_binary(Token *pos, Token_Kind op, Value a, Value b, bool is_const){
|
||||||
if(token_is_compare(op))
|
if(token_is_compare(op))
|
||||||
return compare_values(pos, op, a, b, is_const);
|
return compare_values(pos, op, a, b, is_const);
|
||||||
@@ -309,7 +309,7 @@ eval_binary(Token *pos, Token_Kind op, Value a, Value b, bool is_const){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function S64
|
CORE_Static S64
|
||||||
digit_count(const Value *a){
|
digit_count(const Value *a){
|
||||||
S64 digit_count = a->big_int_val.digit_count*64;
|
S64 digit_count = a->big_int_val.digit_count*64;
|
||||||
if(is_typed(a->type)){
|
if(is_typed(a->type)){
|
||||||
@@ -318,7 +318,7 @@ digit_count(const Value *a){
|
|||||||
return digit_count;
|
return digit_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
eval_unary(Token *pos, Token_Kind op, Operand *operand){
|
eval_unary(Token *pos, Token_Kind op, Operand *operand){
|
||||||
Value *a = &operand->value;
|
Value *a = &operand->value;
|
||||||
Ast_Type *type = a->type;
|
Ast_Type *type = a->type;
|
||||||
@@ -376,7 +376,7 @@ eval_unary(Token *pos, Token_Kind op, Operand *operand){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
make_sure_value_is_compatible_with_type(Token *pos, Operand *expr, Ast_Type *type, Typecheck_Flag debug_flag){
|
make_sure_value_is_compatible_with_type(Token *pos, Operand *expr, Ast_Type *type, Typecheck_Flag debug_flag){
|
||||||
if(type == expr->type){
|
if(type == expr->type){
|
||||||
assert(type);
|
assert(type);
|
||||||
@@ -423,7 +423,7 @@ make_sure_value_is_compatible_with_type(Token *pos, Operand *expr, Ast_Type *typ
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define rewrite_into_const(ast,T,s) _rewrite_into_const(ast,sizeof(T),s)
|
#define rewrite_into_const(ast,T,s) _rewrite_into_const(ast,sizeof(T),s)
|
||||||
function void _rewrite_into_const(Ast *node, U64 ast_size, Value value){
|
CORE_Static void _rewrite_into_const(Ast *node, U64 ast_size, Value value){
|
||||||
auto ast = (Ast_Atom *)node;
|
auto ast = (Ast_Atom *)node;
|
||||||
assert(ast_size >= sizeof(Ast_Atom));
|
assert(ast_size >= sizeof(Ast_Atom));
|
||||||
set_flag(ast->flags, AST_ATOM);
|
set_flag(ast->flags, AST_ATOM);
|
||||||
@@ -438,7 +438,7 @@ function void _rewrite_into_const(Ast *node, U64 ast_size, Value value){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
inside_scope_search(Scope_Search *search, Ast_Scope *scope, int level){
|
inside_scope_search(Scope_Search *search, Ast_Scope *scope, int level){
|
||||||
if(scope->visit_id == search->scope_visit_id) return;
|
if(scope->visit_id == search->scope_visit_id) return;
|
||||||
scope->visit_id = search->scope_visit_id;
|
scope->visit_id = search->scope_visit_id;
|
||||||
@@ -468,7 +468,7 @@ inside_scope_search(Scope_Search *search, Ast_Scope *scope, int level){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
scope_search(Scope_Search *search){
|
scope_search(Scope_Search *search){
|
||||||
// Climb the scope tree and search each scope in module and also
|
// Climb the scope tree and search each scope in module and also
|
||||||
// search in implicitly imported scopes
|
// search in implicitly imported scopes
|
||||||
@@ -488,7 +488,7 @@ scope_search(Scope_Search *search){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Scope_Search
|
CORE_Static Scope_Search
|
||||||
make_scope_search(Arena *arena, Ast_Scope *scope, Intern_String name){
|
make_scope_search(Arena *arena, Ast_Scope *scope, Intern_String name){
|
||||||
Scope_Search result = {};
|
Scope_Search result = {};
|
||||||
result.results.allocator = arena;
|
result.results.allocator = arena;
|
||||||
@@ -500,7 +500,7 @@ make_scope_search(Arena *arena, Ast_Scope *scope, Intern_String name){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Decl *
|
CORE_Static Ast_Decl *
|
||||||
search_for_single_decl(Ast_Scope *scope, Intern_String name){
|
search_for_single_decl(Ast_Scope *scope, Intern_String name){
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
Scope_Search search = make_scope_search(scratch, scope, name);
|
Scope_Search search = make_scope_search(scratch, scope, name);
|
||||||
@@ -516,7 +516,7 @@ search_for_single_decl(Ast_Scope *scope, Intern_String name){
|
|||||||
return search.results.data[0];
|
return search.results.data[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Decl *
|
CORE_Static Ast_Decl *
|
||||||
resolve_name(Ast_Scope *scope, Token *pos, Intern_String name, Search_Flag search_flags){
|
resolve_name(Ast_Scope *scope, Token *pos, Intern_String name, Search_Flag search_flags){
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
Scope_Search search = make_scope_search(scratch, scope, name);
|
Scope_Search search = make_scope_search(scratch, scope, name);
|
||||||
@@ -544,7 +544,7 @@ resolve_name(Ast_Scope *scope, Token *pos, Intern_String name, Search_Flag searc
|
|||||||
return decl;
|
return decl;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Decl *
|
CORE_Static Ast_Decl *
|
||||||
resolve_operator_overload(Ast_Scope *scope, Ast_Type *left, Ast_Type *right, Token *pos, Token_Kind op, U64 argument_hash){
|
resolve_operator_overload(Ast_Scope *scope, Ast_Type *left, Ast_Type *right, Token *pos, Token_Kind op, U64 argument_hash){
|
||||||
Operator_Info *op_info = get_operator_info(op);
|
Operator_Info *op_info = get_operator_info(op);
|
||||||
if(op_info == 0) return 0;
|
if(op_info == 0) return 0;
|
||||||
@@ -578,7 +578,7 @@ resolve_operator_overload(Ast_Scope *scope, Ast_Type *left, Ast_Type *right, Tok
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
insert_into_scope(Ast_Scope *scope, Ast_Decl *decl){
|
insert_into_scope(Ast_Scope *scope, Ast_Decl *decl){
|
||||||
// This function is called when resolving statements
|
// This function is called when resolving statements
|
||||||
// inside code blocks, inserting lambda arguments into scope
|
// inside code blocks, inserting lambda arguments into scope
|
||||||
@@ -606,7 +606,7 @@ insert_into_scope(Ast_Scope *scope, Ast_Decl *decl){
|
|||||||
// int == untyped_int => bool
|
// int == untyped_int => bool
|
||||||
// need to propagate int to untyped_int
|
// need to propagate int to untyped_int
|
||||||
//
|
//
|
||||||
function void
|
CORE_Static void
|
||||||
try_propagating_resolved_type_to_untyped_literals(Ast *ast, Ast_Type *type, Ast_Type *additional_not_bool_type = 0){
|
try_propagating_resolved_type_to_untyped_literals(Ast *ast, Ast_Type *type, Ast_Type *additional_not_bool_type = 0){
|
||||||
if(!type) compiler_error(ast->pos, "Internal compiler error: Type passed to try_propagating_resolved_type_to_untyped_literals is null");
|
if(!type) compiler_error(ast->pos, "Internal compiler error: Type passed to try_propagating_resolved_type_to_untyped_literals is null");
|
||||||
if(!ast) return;
|
if(!ast) return;
|
||||||
@@ -665,7 +665,7 @@ try_propagating_resolved_type_to_untyped_literals(Ast *ast, Ast_Type *type, Ast_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Type *
|
CORE_Static Ast_Type *
|
||||||
resolve_typespec(Ast_Expr *ast, Resolve_Flag flags){
|
resolve_typespec(Ast_Expr *ast, Resolve_Flag flags){
|
||||||
if(!ast && is_flag_set(flags, AST_CAN_BE_NULL))
|
if(!ast && is_flag_set(flags, AST_CAN_BE_NULL))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -679,7 +679,7 @@ resolve_typespec(Ast_Expr *ast, Resolve_Flag flags){
|
|||||||
return resolved.type_val;
|
return resolved.type_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Operand
|
CORE_Static Operand
|
||||||
resolve_and_require_bool(const char *error, Ast_Expr *expr, Resolve_Flag flags){
|
resolve_and_require_bool(const char *error, Ast_Expr *expr, Resolve_Flag flags){
|
||||||
if(!expr){
|
if(!expr){
|
||||||
if(flags == AST_CAN_BE_NULL)
|
if(flags == AST_CAN_BE_NULL)
|
||||||
@@ -696,7 +696,7 @@ resolve_and_require_bool(const char *error, Ast_Expr *expr, Resolve_Flag flags){
|
|||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Operand
|
CORE_Static Operand
|
||||||
require_const_int(Ast_Expr *expr, Resolve_Flag flags){
|
require_const_int(Ast_Expr *expr, Resolve_Flag flags){
|
||||||
Operand op = resolve_expr(expr, flags, 0, 0);
|
Operand op = resolve_expr(expr, flags, 0, 0);
|
||||||
|
|
||||||
@@ -713,9 +713,9 @@ require_const_int(Ast_Expr *expr, Resolve_Flag flags){
|
|||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @note: Ret is return value of function passed down the stack
|
// @note: Ret is return value of CORE_Static passed down the stack
|
||||||
// to check if type matches
|
// to check if type matches
|
||||||
function void
|
CORE_Static void
|
||||||
resolve_stmt(Ast *ast, Ast_Type *ret){
|
resolve_stmt(Ast *ast, Ast_Type *ret){
|
||||||
if(!ast) return;
|
if(!ast) return;
|
||||||
assert(ast->parent_scope->kind == AST_SCOPE);
|
assert(ast->parent_scope->kind == AST_SCOPE);
|
||||||
@@ -883,7 +883,7 @@ resolve_stmt(Ast *ast, Ast_Type *ret){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Type *
|
CORE_Static Ast_Type *
|
||||||
resolve_lambda_type(Ast_Lambda *lambda){
|
resolve_lambda_type(Ast_Lambda *lambda){
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
Array<Ast_Type *> args = {scratch};
|
Array<Ast_Type *> args = {scratch};
|
||||||
@@ -907,7 +907,7 @@ resolve_lambda_type(Ast_Lambda *lambda){
|
|||||||
return type_lambda(lambda, ret, args);
|
return type_lambda(lambda, ret, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
try_resolving_lambda_scope(Operand *op, Ast_Lambda *lambda, Ast_Type *lambda_type){
|
try_resolving_lambda_scope(Operand *op, Ast_Lambda *lambda, Ast_Type *lambda_type){
|
||||||
if(lambda->scope){
|
if(lambda->scope){
|
||||||
For(lambda->args){
|
For(lambda->args){
|
||||||
@@ -924,7 +924,7 @@ try_resolving_lambda_scope(Operand *op, Ast_Lambda *lambda, Ast_Type *lambda_typ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Operand
|
CORE_Static Operand
|
||||||
resolve_cast(Ast_Binary *node){
|
resolve_cast(Ast_Binary *node){
|
||||||
Operand expr = resolve_expr(node->left, AST_CANT_BE_NULL, 0, 0);
|
Operand expr = resolve_expr(node->left, AST_CANT_BE_NULL, 0, 0);
|
||||||
Ast_Type *type = resolve_typespec(node->right, AST_CANT_BE_NULL);
|
Ast_Type *type = resolve_typespec(node->right, AST_CANT_BE_NULL);
|
||||||
@@ -983,7 +983,7 @@ resolve_cast(Ast_Binary *node){
|
|||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
resolve_compound_array(Ast_Call *node, Ast_Type *type){
|
resolve_compound_array(Ast_Call *node, Ast_Type *type){
|
||||||
Ast_Type *item_type = type->arr.base;
|
Ast_Type *item_type = type->arr.base;
|
||||||
S64 size = type->arr.size;
|
S64 size = type->arr.size;
|
||||||
@@ -1018,7 +1018,7 @@ resolve_compound_array(Ast_Call *node, Ast_Type *type){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
resolve_compound_struct(Ast_Call *node, Ast_Type *type){
|
resolve_compound_struct(Ast_Call *node, Ast_Type *type){
|
||||||
S64 default_counter = 0;
|
S64 default_counter = 0;
|
||||||
For(node->exprs){
|
For(node->exprs){
|
||||||
@@ -1076,7 +1076,7 @@ resolve_compound_struct(Ast_Call *node, Ast_Type *type){
|
|||||||
For(type->agg.members) it.visited = false;
|
For(type->agg.members) it.visited = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Expr *
|
CORE_Static Ast_Expr *
|
||||||
unpack_ast_call_expr_for_builtin(Ast_Call *call){
|
unpack_ast_call_expr_for_builtin(Ast_Call *call){
|
||||||
if(call->exprs.len != 1) {
|
if(call->exprs.len != 1) {
|
||||||
compiler_error(call->pos, "Expected exactly 1 argument inside a builtin function call got instead %d", (int)call->exprs.len);
|
compiler_error(call->pos, "Expected exactly 1 argument inside a builtin function call got instead %d", (int)call->exprs.len);
|
||||||
@@ -1084,7 +1084,7 @@ unpack_ast_call_expr_for_builtin(Ast_Call *call){
|
|||||||
return call->exprs[0]->item;
|
return call->exprs[0]->item;
|
||||||
}
|
}
|
||||||
|
|
||||||
function bool
|
CORE_Static bool
|
||||||
expr_atom_is_equal_intern(Ast_Expr *expr, Intern_String intern){
|
expr_atom_is_equal_intern(Ast_Expr *expr, Intern_String intern){
|
||||||
assert(expr->kind == AST_IDENT || expr->kind == AST_BINARY);
|
assert(expr->kind == AST_IDENT || expr->kind == AST_BINARY);
|
||||||
if(expr->kind == AST_IDENT){
|
if(expr->kind == AST_IDENT){
|
||||||
@@ -1096,7 +1096,7 @@ expr_atom_is_equal_intern(Ast_Expr *expr, Intern_String intern){
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Operand
|
CORE_Static Operand
|
||||||
resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_and_const_string_context, Ast_Scope *field_access_scope){
|
resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_and_const_string_context, Ast_Scope *field_access_scope){
|
||||||
if(!ast && is_flag_set(flags, AST_CAN_BE_NULL)) return {};
|
if(!ast && is_flag_set(flags, AST_CAN_BE_NULL)) return {};
|
||||||
assert(is_flag_set(ast->flags, AST_EXPR));
|
assert(is_flag_set(ast->flags, AST_EXPR));
|
||||||
@@ -1587,7 +1587,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_and_const_str
|
|||||||
invalid_return;
|
invalid_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Type *
|
CORE_Static Ast_Type *
|
||||||
get_type_base(Ast_Type *type){
|
get_type_base(Ast_Type *type){
|
||||||
switch(type->kind){
|
switch(type->kind){
|
||||||
case TYPE_POINTER: case TYPE_SLICE: case TYPE_ARRAY: return get_type_base(type->base);
|
case TYPE_POINTER: case TYPE_SLICE: case TYPE_ARRAY: return get_type_base(type->base);
|
||||||
@@ -1595,7 +1595,7 @@ get_type_base(Ast_Type *type){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
resolve_decl(Ast_Decl *ast){
|
resolve_decl(Ast_Decl *ast){
|
||||||
if(ast->state == DECL_RESOLVED)
|
if(ast->state == DECL_RESOLVED)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -40,9 +40,9 @@ enum{
|
|||||||
RESOLVE_NAME_MAKE_SURE_OPERATOR_OVERLOAD_IS_NOT_EVER_CALLED = bit_flag(2),
|
RESOLVE_NAME_MAKE_SURE_OPERATOR_OVERLOAD_IS_NOT_EVER_CALLED = bit_flag(2),
|
||||||
};
|
};
|
||||||
|
|
||||||
function Operand resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context, Ast_Scope *field_access_scope);
|
CORE_Static Operand resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context, Ast_Scope *field_access_scope);
|
||||||
function void resolve_decl(Ast_Decl *ast);
|
CORE_Static void resolve_decl(Ast_Decl *ast);
|
||||||
function Ast_Decl *resolve_name(Ast_Scope *parent_scope, Token *pos, Intern_String name, Search_Flag search_flags = 0);
|
CORE_Static Ast_Decl *resolve_name(Ast_Scope *parent_scope, Token *pos, Intern_String name, Search_Flag search_flags = 0);
|
||||||
function String gen_string_simple_decl(Arena *a, Ast_Type *ast, String name = {}, Ast_Scope *scope = 0, bool scope_names = true);
|
CORE_Static String gen_string_simple_decl(Arena *a, Ast_Type *ast, String name = {}, Ast_Scope *scope = 0, bool scope_names = true);
|
||||||
#define CASE(kind,type) case AST_##kind: { Ast_##type *node = (Ast_##type *)ast;
|
#define CASE(kind,type) case AST_##kind: { Ast_##type *node = (Ast_##type *)ast;
|
||||||
#define BREAK() } break
|
#define BREAK() } break
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
function const char *
|
CORE_Static const char *
|
||||||
get_name_of_type(Ast_Type *type){
|
get_name_of_type(Ast_Type *type){
|
||||||
switch(type->kind){
|
switch(type->kind){
|
||||||
case TYPE_VOID: return "void";
|
case TYPE_VOID: return "void";
|
||||||
@@ -57,7 +57,7 @@ force_inline B32 is_numeric(Ast_Type *type){
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Hash consed types
|
// Hash consed types
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
function Ast_Type *
|
CORE_Static Ast_Type *
|
||||||
type_new(Arena *allocator, Ast_Type_Kind kind, size_t size, size_t align){
|
type_new(Arena *allocator, Ast_Type_Kind kind, size_t size, size_t align){
|
||||||
Ast_Type *result = arena_push_type(allocator, Ast_Type, AF_ZeroMemory);
|
Ast_Type *result = arena_push_type(allocator, Ast_Type, AF_ZeroMemory);
|
||||||
result->kind = kind;
|
result->kind = kind;
|
||||||
@@ -68,7 +68,7 @@ type_new(Arena *allocator, Ast_Type_Kind kind, size_t size, size_t align){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Type *
|
CORE_Static Ast_Type *
|
||||||
type_copy(Arena *a, Ast_Type *type){
|
type_copy(Arena *a, Ast_Type *type){
|
||||||
// @warning: This changes type id !!!!
|
// @warning: This changes type id !!!!
|
||||||
Ast_Type *result = arena_push_type(a, Ast_Type);
|
Ast_Type *result = arena_push_type(a, Ast_Type);
|
||||||
@@ -78,7 +78,7 @@ type_copy(Arena *a, Ast_Type *type){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Type *
|
CORE_Static Ast_Type *
|
||||||
type_pointer(Ast_Type *base){
|
type_pointer(Ast_Type *base){
|
||||||
Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, (void *)base);
|
Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, (void *)base);
|
||||||
if(!result){
|
if(!result){
|
||||||
@@ -91,7 +91,7 @@ type_pointer(Ast_Type *base){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Type *
|
CORE_Static Ast_Type *
|
||||||
type_slice(Ast_Type *base, Ast *ast){
|
type_slice(Ast_Type *base, Ast *ast){
|
||||||
U64 hash_base = hash_ptr(base);
|
U64 hash_base = hash_ptr(base);
|
||||||
U64 hash = hash_mix(hash_base, hash_u64(ARRAY_SIZE_SLICE));
|
U64 hash = hash_mix(hash_base, hash_u64(ARRAY_SIZE_SLICE));
|
||||||
@@ -111,7 +111,7 @@ type_slice(Ast_Type *base, Ast *ast){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Type *
|
CORE_Static Ast_Type *
|
||||||
type_try_tupling(Array<Ast_Type *> types, Ast *ast){
|
type_try_tupling(Array<Ast_Type *> types, Ast *ast){
|
||||||
if(types.len == 0) return type_void;
|
if(types.len == 0) return type_void;
|
||||||
if(types.len == 1) return types[0];
|
if(types.len == 1) return types[0];
|
||||||
@@ -142,7 +142,7 @@ type_try_tupling(Array<Ast_Type *> types, Ast *ast){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Type *
|
CORE_Static Ast_Type *
|
||||||
type_array(Ast_Type *base, S64 size){
|
type_array(Ast_Type *base, S64 size){
|
||||||
U64 hash_base = hash_ptr(base);
|
U64 hash_base = hash_ptr(base);
|
||||||
U64 hash = hash_mix(hash_base, hash_u64(size));
|
U64 hash = hash_mix(hash_base, hash_u64(size));
|
||||||
@@ -177,7 +177,7 @@ calculate_hash_for_arguments(Ast_Type *a){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Type *
|
CORE_Static Ast_Type *
|
||||||
type_lambda(Ast *ast, Array<Ast_Type *> return_vals, Array<Ast_Type *> args){
|
type_lambda(Ast *ast, Array<Ast_Type *> return_vals, Array<Ast_Type *> args){
|
||||||
Ast_Type *ret = type_try_tupling(return_vals, ast);
|
Ast_Type *ret = type_try_tupling(return_vals, ast);
|
||||||
U64 hash_without_ret = 13;
|
U64 hash_without_ret = 13;
|
||||||
@@ -201,7 +201,7 @@ type_lambda(Ast *ast, Array<Ast_Type *> return_vals, Array<Ast_Type *> args){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Type *
|
CORE_Static Ast_Type *
|
||||||
type_enum(Ast_Decl *ast, Ast_Type *type){
|
type_enum(Ast_Decl *ast, Ast_Type *type){
|
||||||
if(!type){
|
if(!type){
|
||||||
type = type_s64;
|
type = type_s64;
|
||||||
@@ -213,15 +213,15 @@ type_enum(Ast_Decl *ast, Ast_Type *type){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Type *
|
CORE_Static Ast_Type *
|
||||||
type_incomplete(Ast *ast){
|
type_incomplete(Ast *ast){
|
||||||
Ast_Type *result = type_new(pctx->perm, TYPE_INCOMPLETE, 0, 0);
|
Ast_Type *result = type_new(pctx->perm, TYPE_INCOMPLETE, 0, 0);
|
||||||
result->ast = ast;
|
result->ast = ast;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void type_complete(Ast_Type *type);
|
CORE_Static void type_complete(Ast_Type *type);
|
||||||
function void
|
CORE_Static void
|
||||||
type_struct_complete(Ast_Type *type, Ast_Decl *node){
|
type_struct_complete(Ast_Type *type, Ast_Decl *node){
|
||||||
assert(node->kind == AST_STRUCT);
|
assert(node->kind == AST_STRUCT);
|
||||||
// @todo: compute size, alignement, offset !!!
|
// @todo: compute size, alignement, offset !!!
|
||||||
@@ -253,7 +253,7 @@ type_struct_complete(Ast_Type *type, Ast_Decl *node){
|
|||||||
node->unique_name = pctx->intern(string_fmt(scratch, "%Q%Q", symbol_prefix, node->name));
|
node->unique_name = pctx->intern(string_fmt(scratch, "%Q%Q", symbol_prefix, node->name));
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
type_complete(Ast_Type *type){
|
type_complete(Ast_Type *type){
|
||||||
if(!type) {
|
if(!type) {
|
||||||
return;
|
return;
|
||||||
@@ -269,13 +269,13 @@ type_complete(Ast_Type *type){
|
|||||||
add(pctx->perm, &pctx->ordered_decls, (Ast_Decl *)type->ast);
|
add(pctx->perm, &pctx->ordered_decls, (Ast_Decl *)type->ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
init_type(){
|
init_type(){
|
||||||
type_pointer_to_char = type_pointer(type_char);
|
type_pointer_to_char = type_pointer(type_char);
|
||||||
type_pointer_to_void = type_pointer(type_void);
|
type_pointer_to_void = type_pointer(type_void);
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
typename_base(String_Builder *sb, Ast_Type *type){
|
typename_base(String_Builder *sb, Ast_Type *type){
|
||||||
switch(type->kind){
|
switch(type->kind){
|
||||||
case TYPE_INCOMPLETE: sb->addf("INCOMPLETE"); break;
|
case TYPE_INCOMPLETE: sb->addf("INCOMPLETE"); break;
|
||||||
@@ -321,7 +321,7 @@ typename_base(String_Builder *sb, Ast_Type *type){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
get_typename(Arena *a, Ast_Type *type){
|
get_typename(Arena *a, Ast_Type *type){
|
||||||
pctx->helper_builder.addf("[");
|
pctx->helper_builder.addf("[");
|
||||||
typename_base(&pctx->helper_builder, type);
|
typename_base(&pctx->helper_builder, type);
|
||||||
@@ -331,7 +331,7 @@ get_typename(Arena *a, Ast_Type *type){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
typestring(Ast_Type *type){
|
typestring(Ast_Type *type){
|
||||||
return get_typename(&pctx->stage_arena, type);
|
return get_typename(&pctx->stage_arena, type);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ struct Ast_Type{
|
|||||||
struct{
|
struct{
|
||||||
Ast_Type * ret;
|
Ast_Type * ret;
|
||||||
Array<Ast_Type *> args;
|
Array<Ast_Type *> args;
|
||||||
U64 hash_without_ret;
|
U64 hash_without_ret;
|
||||||
}func;
|
}func;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
26
os_linux.cpp
26
os_linux.cpp
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#define POSIX_PAGE_SIZE 4096
|
#define POSIX_PAGE_SIZE 4096
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
os_write_file(String filename, String filecontent){
|
os_write_file(String filename, String filecontent){
|
||||||
FILE *f = fopen((const char *)filename.str, "w");
|
FILE *f = fopen((const char *)filename.str, "w");
|
||||||
if(f){
|
if(f){
|
||||||
@@ -20,7 +20,7 @@ os_write_file(String filename, String filecontent){
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
os_read_file(Arena *a, String name){
|
os_read_file(Arena *a, String name){
|
||||||
String result = {0};
|
String result = {0};
|
||||||
FILE *f = fopen((char *)name.str, "rb");
|
FILE *f = fopen((char *)name.str, "rb");
|
||||||
@@ -37,7 +37,7 @@ os_read_file(Arena *a, String name){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
os_get_exe_dir(Arena *a){
|
os_get_exe_dir(Arena *a){
|
||||||
char buffer[PATH_MAX] = {};
|
char buffer[PATH_MAX] = {};
|
||||||
if (readlink("/proc/self/exe", buffer, PATH_MAX) == -1) {
|
if (readlink("/proc/self/exe", buffer, PATH_MAX) == -1) {
|
||||||
@@ -51,7 +51,7 @@ os_get_exe_dir(Arena *a){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
os_get_absolute_path(Arena *a, String path){
|
os_get_absolute_path(Arena *a, String path){
|
||||||
assert(path.str[path.len] == 0);
|
assert(path.str[path.len] == 0);
|
||||||
char buffer[PATH_MAX] = {};
|
char buffer[PATH_MAX] = {};
|
||||||
@@ -61,7 +61,7 @@ os_get_absolute_path(Arena *a, String path){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
os_does_file_exist(String path){
|
os_does_file_exist(String path){
|
||||||
B32 result = false;
|
B32 result = false;
|
||||||
assert(path.str[path.len] == 0);
|
assert(path.str[path.len] == 0);
|
||||||
@@ -72,14 +72,14 @@ os_does_file_exist(String path){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
os_get_working_dir(Arena *allocator){
|
os_get_working_dir(Arena *allocator){
|
||||||
char *buffer = arena_push_array(allocator, char, PATH_MAX);
|
char *buffer = arena_push_array(allocator, char, PATH_MAX);
|
||||||
char *result = getcwd(buffer, PATH_MAX);
|
char *result = getcwd(buffer, PATH_MAX);
|
||||||
return string_from_cstring(result);
|
return string_from_cstring(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Array<OS_File_Info>
|
CORE_Static Array<OS_File_Info>
|
||||||
os_list_dir(Arena *a, String dir, U32 flags = LIST_RECURSE_INTO_DIRS){
|
os_list_dir(Arena *a, String dir, U32 flags = LIST_RECURSE_INTO_DIRS){
|
||||||
Scratch scratch(a);
|
Scratch scratch(a);
|
||||||
Array<String> dirs_to_read = {scratch};
|
Array<String> dirs_to_read = {scratch};
|
||||||
@@ -127,7 +127,7 @@ os_list_dir(Arena *a, String dir, U32 flags = LIST_RECURSE_INTO_DIRS){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function U8 *
|
CORE_Static U8 *
|
||||||
os_advance_commit(OS_Memory *m, size_t *commit_size, size_t page_size) {
|
os_advance_commit(OS_Memory *m, size_t *commit_size, size_t page_size) {
|
||||||
size_t aligned_up_commit = align_up(*commit_size, page_size);
|
size_t aligned_up_commit = align_up(*commit_size, page_size);
|
||||||
size_t to_be_total_commited_size = aligned_up_commit + m->commit;
|
size_t to_be_total_commited_size = aligned_up_commit + m->commit;
|
||||||
@@ -141,7 +141,7 @@ os_advance_commit(OS_Memory *m, size_t *commit_size, size_t page_size) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function OS_Memory
|
CORE_Static OS_Memory
|
||||||
os_reserve(size_t size) {
|
os_reserve(size_t size) {
|
||||||
OS_Memory result = {};
|
OS_Memory result = {};
|
||||||
size_t size_aligned = align_up(size, POSIX_PAGE_SIZE);
|
size_t size_aligned = align_up(size, POSIX_PAGE_SIZE);
|
||||||
@@ -153,7 +153,7 @@ os_reserve(size_t size) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
os_commit(OS_Memory *m, size_t commit) {
|
os_commit(OS_Memory *m, size_t commit) {
|
||||||
B32 result = false;
|
B32 result = false;
|
||||||
U8 * pointer = os_advance_commit(m, &commit, POSIX_PAGE_SIZE);
|
U8 * pointer = os_advance_commit(m, &commit, POSIX_PAGE_SIZE);
|
||||||
@@ -168,7 +168,7 @@ os_commit(OS_Memory *m, size_t commit) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
os_release(OS_Memory *m) {
|
os_release(OS_Memory *m) {
|
||||||
int result = munmap(m->data, m->reserve);
|
int result = munmap(m->data, m->reserve);
|
||||||
assert_message(result == 0, "OS1 POSIX Debug Error: Failed to release virtual memory using munmap");
|
assert_message(result == 0, "OS1 POSIX Debug Error: Failed to release virtual memory using munmap");
|
||||||
@@ -177,7 +177,7 @@ os_release(OS_Memory *m) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function U64
|
CORE_Static U64
|
||||||
os_get_microseconds() {
|
os_get_microseconds() {
|
||||||
timespec ts;
|
timespec ts;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
@@ -185,7 +185,7 @@ os_get_microseconds() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function F64
|
CORE_Static F64
|
||||||
os_time(){
|
os_time(){
|
||||||
F64 time = (F64)os_get_microseconds();
|
F64 time = (F64)os_get_microseconds();
|
||||||
F64 result = time / 1000000.0; // Microseconds to seconds
|
F64 result = time / 1000000.0; // Microseconds to seconds
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
const size_t os_page_size = 4096;
|
const size_t os_page_size = 4096;
|
||||||
|
|
||||||
function OS_Memory
|
CORE_Static OS_Memory
|
||||||
os_reserve(size_t size){
|
os_reserve(size_t size){
|
||||||
OS_Memory result = {};
|
OS_Memory result = {};
|
||||||
size_t adjusted_size = align_up(size, os_page_size);
|
size_t adjusted_size = align_up(size, os_page_size);
|
||||||
@@ -14,7 +14,7 @@ os_reserve(size_t size){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
os_commit(OS_Memory *m, size_t size){
|
os_commit(OS_Memory *m, size_t size){
|
||||||
size_t commit = align_up(size, os_page_size);
|
size_t commit = align_up(size, os_page_size);
|
||||||
size_t total_commit = m->commit + commit;
|
size_t total_commit = m->commit + commit;
|
||||||
@@ -29,7 +29,7 @@ os_commit(OS_Memory *m, size_t size){
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
os_release(OS_Memory *m){
|
os_release(OS_Memory *m){
|
||||||
BOOL result = VirtualFree(m->data, 0, MEM_RELEASE);
|
BOOL result = VirtualFree(m->data, 0, MEM_RELEASE);
|
||||||
assert_message(result != 0, "Failed to release OS_Memory");
|
assert_message(result != 0, "Failed to release OS_Memory");
|
||||||
@@ -40,7 +40,7 @@ os_release(OS_Memory *m){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
os_decommit_pos(OS_Memory *m, size_t pos){
|
os_decommit_pos(OS_Memory *m, size_t pos){
|
||||||
size_t aligned = align_down(pos, os_page_size);
|
size_t aligned = align_down(pos, os_page_size);
|
||||||
size_t adjusted_pos = clamp_top(aligned, m->commit);
|
size_t adjusted_pos = clamp_top(aligned, m->commit);
|
||||||
@@ -56,7 +56,7 @@ os_decommit_pos(OS_Memory *m, size_t pos){
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
CORE_Static void
|
||||||
test_os_memory(){
|
test_os_memory(){
|
||||||
assert(align_down(4096, 4096) == 4096);
|
assert(align_down(4096, 4096) == 4096);
|
||||||
assert(align_down(4095, 4096) == 0);
|
assert(align_down(4095, 4096) == 0);
|
||||||
@@ -103,7 +103,7 @@ api F64 os_time() {
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Filesystem
|
// Filesystem
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
function B32
|
CORE_Static B32
|
||||||
os_write_file(String filename, String filecontent){
|
os_write_file(String filename, String filecontent){
|
||||||
FILE *f = fopen((const char *)filename.str, "w");
|
FILE *f = fopen((const char *)filename.str, "w");
|
||||||
if(f){
|
if(f){
|
||||||
@@ -114,7 +114,7 @@ os_write_file(String filename, String filecontent){
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
os_read_file(Arena *a, String name){
|
os_read_file(Arena *a, String name){
|
||||||
String result = {0};
|
String result = {0};
|
||||||
FILE *f = fopen((char *)name.str, "rb");
|
FILE *f = fopen((char *)name.str, "rb");
|
||||||
@@ -131,7 +131,7 @@ os_read_file(Arena *a, String name){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
os_get_working_dir(Arena *a){
|
os_get_working_dir(Arena *a){
|
||||||
wchar_t buffer[2048];
|
wchar_t buffer[2048];
|
||||||
DWORD written = GetCurrentDirectoryW(2048, buffer);
|
DWORD written = GetCurrentDirectoryW(2048, buffer);
|
||||||
@@ -142,7 +142,7 @@ os_get_working_dir(Arena *a){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
os_get_exe_dir(Arena *a){
|
os_get_exe_dir(Arena *a){
|
||||||
wchar_t buffer[2048];
|
wchar_t buffer[2048];
|
||||||
DWORD written = GetModuleFileNameW(0, buffer, 2048);
|
DWORD written = GetModuleFileNameW(0, buffer, 2048);
|
||||||
@@ -157,7 +157,7 @@ os_get_exe_dir(Arena *a){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function String
|
CORE_Static String
|
||||||
os_get_absolute_path(Arena *a, String path){
|
os_get_absolute_path(Arena *a, String path){
|
||||||
Scratch scratch(a);
|
Scratch scratch(a);
|
||||||
String16 path16 = string8_to_string16(scratch, path);
|
String16 path16 = string8_to_string16(scratch, path);
|
||||||
@@ -172,7 +172,7 @@ os_get_absolute_path(Arena *a, String path){
|
|||||||
return absolute;
|
return absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
CORE_Static B32
|
||||||
os_does_file_exist(String path){
|
os_does_file_exist(String path){
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
String16 path16 = string8_to_string16(scratch, path);
|
String16 path16 = string8_to_string16(scratch, path);
|
||||||
@@ -181,7 +181,7 @@ os_does_file_exist(String path){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Array<OS_File_Info>
|
CORE_Static Array<OS_File_Info>
|
||||||
os_list_dir(Arena *a, String dir, U32 flags = LIST_NO_FLAGS){
|
os_list_dir(Arena *a, String dir, U32 flags = LIST_NO_FLAGS){
|
||||||
Scratch scratch(a);
|
Scratch scratch(a);
|
||||||
Array<String> dirs_to_read = {scratch};
|
Array<String> dirs_to_read = {scratch};
|
||||||
|
|||||||
186
stb_sprintf.h
186
stb_sprintf.h
@@ -309,19 +309,19 @@ static void stbsp__lead_sign(stbsp__uint32 fl, char *sign)
|
|||||||
static STBSP__ASAN stbsp__uint32 stbsp__strlen_limited(char const *s, stbsp__uint32 limit)
|
static STBSP__ASAN stbsp__uint32 stbsp__strlen_limited(char const *s, stbsp__uint32 limit)
|
||||||
{
|
{
|
||||||
char const * sn = s;
|
char const * sn = s;
|
||||||
|
|
||||||
// get up to 4-byte alignment
|
// get up to 4-byte alignment
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (((stbsp__uintptr)sn & 3) == 0)
|
if (((stbsp__uintptr)sn & 3) == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!limit || *sn == 0)
|
if (!limit || *sn == 0)
|
||||||
return (stbsp__uint32)(sn - s);
|
return (stbsp__uint32)(sn - s);
|
||||||
|
|
||||||
++sn;
|
++sn;
|
||||||
--limit;
|
--limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// scan over 4 bytes at a time to find terminating 0
|
// scan over 4 bytes at a time to find terminating 0
|
||||||
// this will intentionally scan up to 3 bytes past the end of buffers,
|
// this will intentionally scan up to 3 bytes past the end of buffers,
|
||||||
// but becase it works 4B aligned, it will never cross page boundaries
|
// but becase it works 4B aligned, it will never cross page boundaries
|
||||||
@@ -332,17 +332,17 @@ static STBSP__ASAN stbsp__uint32 stbsp__strlen_limited(char const *s, stbsp__uin
|
|||||||
// bit hack to find if there's a 0 byte in there
|
// bit hack to find if there's a 0 byte in there
|
||||||
if ((v - 0x01010101) & (~v) & 0x80808080UL)
|
if ((v - 0x01010101) & (~v) & 0x80808080UL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
sn += 4;
|
sn += 4;
|
||||||
limit -= 4;
|
limit -= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle the last few characters to find actual size
|
// handle the last few characters to find actual size
|
||||||
while (limit && *sn) {
|
while (limit && *sn) {
|
||||||
++sn;
|
++sn;
|
||||||
--limit;
|
--limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (stbsp__uint32)(sn - s);
|
return (stbsp__uint32)(sn - s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,13 +353,13 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
|
|||||||
char *bf;
|
char *bf;
|
||||||
char const *f;
|
char const *f;
|
||||||
int tlen = 0;
|
int tlen = 0;
|
||||||
|
|
||||||
bf = buf;
|
bf = buf;
|
||||||
f = fmt;
|
f = fmt;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
stbsp__int32 fw, pr, tz;
|
stbsp__int32 fw, pr, tz;
|
||||||
stbsp__uint32 fl;
|
stbsp__uint32 fl;
|
||||||
|
|
||||||
// macros for the callback buffer stuff
|
// macros for the callback buffer stuff
|
||||||
#define stbsp__chk_cb_bufL(bytes) \
|
#define stbsp__chk_cb_bufL(bytes) \
|
||||||
{ \
|
{ \
|
||||||
@@ -387,7 +387,7 @@ int lg = STB_SPRINTF_MIN - (int)(bf - buf); \
|
|||||||
if (cl > lg) \
|
if (cl > lg) \
|
||||||
cl = lg; \
|
cl = lg; \
|
||||||
}
|
}
|
||||||
|
|
||||||
// fast copy everything up to the next % (or end of string)
|
// fast copy everything up to the next % (or end of string)
|
||||||
for (;;) {
|
for (;;) {
|
||||||
while (((stbsp__uintptr)f) & 3) {
|
while (((stbsp__uintptr)f) & 3) {
|
||||||
@@ -431,15 +431,15 @@ cl = lg; \
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
scandd:
|
scandd:
|
||||||
|
|
||||||
++f;
|
++f;
|
||||||
|
|
||||||
// ok, we have a percent, read the modifiers first
|
// ok, we have a percent, read the modifiers first
|
||||||
fw = 0;
|
fw = 0;
|
||||||
pr = -1;
|
pr = -1;
|
||||||
fl = 0;
|
fl = 0;
|
||||||
tz = 0;
|
tz = 0;
|
||||||
|
|
||||||
// flags
|
// flags
|
||||||
for (;;) {
|
for (;;) {
|
||||||
switch (f[0]) {
|
switch (f[0]) {
|
||||||
@@ -495,7 +495,7 @@ cl = lg; \
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
flags_done:
|
flags_done:
|
||||||
|
|
||||||
// get the field width
|
// get the field width
|
||||||
if (f[0] == '*') {
|
if (f[0] == '*') {
|
||||||
fw = va_arg(va, stbsp__uint32);
|
fw = va_arg(va, stbsp__uint32);
|
||||||
@@ -520,7 +520,7 @@ cl = lg; \
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle integer size overrides
|
// handle integer size overrides
|
||||||
switch (f[0]) {
|
switch (f[0]) {
|
||||||
// are we halfwidth?
|
// are we halfwidth?
|
||||||
@@ -567,7 +567,7 @@ cl = lg; \
|
|||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle each replacement
|
// handle each replacement
|
||||||
switch (f[0]) {
|
switch (f[0]) {
|
||||||
#define STBSP__NUMSZ 512 // big enough for e308 (with commas) or e-307
|
#define STBSP__NUMSZ 512 // big enough for e308 (with commas) or e-307
|
||||||
@@ -584,7 +584,7 @@ cl = lg; \
|
|||||||
#endif
|
#endif
|
||||||
stbsp__int32 dp;
|
stbsp__int32 dp;
|
||||||
char const *sn;
|
char const *sn;
|
||||||
|
|
||||||
case 'Q':
|
case 'Q':
|
||||||
str = va_arg(va, String);
|
str = va_arg(va, String);
|
||||||
if (str.str == 0 && str.len != 0)
|
if (str.str == 0 && str.len != 0)
|
||||||
@@ -598,7 +598,7 @@ cl = lg; \
|
|||||||
dp = 0;
|
dp = 0;
|
||||||
cs = 0;
|
cs = 0;
|
||||||
goto scopy;
|
goto scopy;
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
// get the string
|
// get the string
|
||||||
s = va_arg(va, char *);
|
s = va_arg(va, char *);
|
||||||
@@ -614,7 +614,7 @@ cl = lg; \
|
|||||||
cs = 0;
|
cs = 0;
|
||||||
// copy the string in
|
// copy the string in
|
||||||
goto scopy;
|
goto scopy;
|
||||||
|
|
||||||
case 'c': // char
|
case 'c': // char
|
||||||
// get the character
|
// get the character
|
||||||
s = num + STBSP__NUMSZ - 1;
|
s = num + STBSP__NUMSZ - 1;
|
||||||
@@ -626,13 +626,13 @@ cl = lg; \
|
|||||||
dp = 0;
|
dp = 0;
|
||||||
cs = 0;
|
cs = 0;
|
||||||
goto scopy;
|
goto scopy;
|
||||||
|
|
||||||
case 'n': // weird write-bytes specifier
|
case 'n': // weird write-bytes specifier
|
||||||
{
|
{
|
||||||
int *d = va_arg(va, int *);
|
int *d = va_arg(va, int *);
|
||||||
*d = tlen + (int)(bf - buf);
|
*d = tlen + (int)(bf - buf);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
#ifdef STB_SPRINTF_NOFLOAT
|
#ifdef STB_SPRINTF_NOFLOAT
|
||||||
case 'A': // float
|
case 'A': // float
|
||||||
case 'a': // hex float
|
case 'a': // hex float
|
||||||
@@ -660,11 +660,11 @@ cl = lg; \
|
|||||||
// read the double into a string
|
// read the double into a string
|
||||||
if (stbsp__real_to_parts((stbsp__int64 *)&n64, &dp, fv))
|
if (stbsp__real_to_parts((stbsp__int64 *)&n64, &dp, fv))
|
||||||
fl |= STBSP__NEGATIVE;
|
fl |= STBSP__NEGATIVE;
|
||||||
|
|
||||||
s = num + 64;
|
s = num + 64;
|
||||||
|
|
||||||
stbsp__lead_sign(fl, lead);
|
stbsp__lead_sign(fl, lead);
|
||||||
|
|
||||||
if (dp == -1023)
|
if (dp == -1023)
|
||||||
dp = (n64) ? -1022 : 0;
|
dp = (n64) ? -1022 : 0;
|
||||||
else
|
else
|
||||||
@@ -673,7 +673,7 @@ cl = lg; \
|
|||||||
if (pr < 15)
|
if (pr < 15)
|
||||||
n64 += ((((stbsp__uint64)8) << 56) >> (pr * 4));
|
n64 += ((((stbsp__uint64)8) << 56) >> (pr * 4));
|
||||||
// add leading chars
|
// add leading chars
|
||||||
|
|
||||||
#ifdef STB_SPRINTF_MSVC_MODE
|
#ifdef STB_SPRINTF_MSVC_MODE
|
||||||
*s++ = '0';
|
*s++ = '0';
|
||||||
*s++ = 'x';
|
*s++ = 'x';
|
||||||
@@ -687,7 +687,7 @@ cl = lg; \
|
|||||||
if (pr)
|
if (pr)
|
||||||
*s++ = stbsp__period;
|
*s++ = stbsp__period;
|
||||||
sn = s;
|
sn = s;
|
||||||
|
|
||||||
// print the bits
|
// print the bits
|
||||||
n = pr;
|
n = pr;
|
||||||
if (n > 13)
|
if (n > 13)
|
||||||
@@ -699,7 +699,7 @@ cl = lg; \
|
|||||||
*s++ = h[(n64 >> 60) & 15];
|
*s++ = h[(n64 >> 60) & 15];
|
||||||
n64 <<= 4;
|
n64 <<= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// print the expo
|
// print the expo
|
||||||
tail[1] = h[17];
|
tail[1] = h[17];
|
||||||
if (dp < 0) {
|
if (dp < 0) {
|
||||||
@@ -716,13 +716,13 @@ cl = lg; \
|
|||||||
--n;
|
--n;
|
||||||
dp /= 10;
|
dp /= 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
dp = (int)(s - sn);
|
dp = (int)(s - sn);
|
||||||
l = (int)(s - (num + 64));
|
l = (int)(s - (num + 64));
|
||||||
s = num + 64;
|
s = num + 64;
|
||||||
cs = 1 + (3 << 24);
|
cs = 1 + (3 << 24);
|
||||||
goto scopy;
|
goto scopy;
|
||||||
|
|
||||||
case 'G': // float
|
case 'G': // float
|
||||||
case 'g': // float
|
case 'g': // float
|
||||||
h = (f[0] == 'G') ? hexu : hex;
|
h = (f[0] == 'G') ? hexu : hex;
|
||||||
@@ -734,7 +734,7 @@ cl = lg; \
|
|||||||
// read the double into a string
|
// read the double into a string
|
||||||
if (stbsp__real_to_str(&sn, &l, num, &dp, fv, (pr - 1) | 0x80000000))
|
if (stbsp__real_to_str(&sn, &l, num, &dp, fv, (pr - 1) | 0x80000000))
|
||||||
fl |= STBSP__NEGATIVE;
|
fl |= STBSP__NEGATIVE;
|
||||||
|
|
||||||
// clamp the precision and delete extra zeros after clamp
|
// clamp the precision and delete extra zeros after clamp
|
||||||
n = pr;
|
n = pr;
|
||||||
if (l > (stbsp__uint32)pr)
|
if (l > (stbsp__uint32)pr)
|
||||||
@@ -743,7 +743,7 @@ cl = lg; \
|
|||||||
--pr;
|
--pr;
|
||||||
--l;
|
--l;
|
||||||
}
|
}
|
||||||
|
|
||||||
// should we use %e
|
// should we use %e
|
||||||
if ((dp <= -4) || (dp > (stbsp__int32)n)) {
|
if ((dp <= -4) || (dp > (stbsp__int32)n)) {
|
||||||
if (pr > (stbsp__int32)l)
|
if (pr > (stbsp__int32)l)
|
||||||
@@ -759,7 +759,7 @@ cl = lg; \
|
|||||||
pr = -dp + ((pr > (stbsp__int32)l) ? (stbsp__int32) l : pr);
|
pr = -dp + ((pr > (stbsp__int32)l) ? (stbsp__int32) l : pr);
|
||||||
}
|
}
|
||||||
goto dofloatfromg;
|
goto dofloatfromg;
|
||||||
|
|
||||||
case 'E': // float
|
case 'E': // float
|
||||||
case 'e': // float
|
case 'e': // float
|
||||||
h = (f[0] == 'E') ? hexu : hex;
|
h = (f[0] == 'E') ? hexu : hex;
|
||||||
@@ -781,10 +781,10 @@ cl = lg; \
|
|||||||
s = num + 64;
|
s = num + 64;
|
||||||
// handle leading chars
|
// handle leading chars
|
||||||
*s++ = sn[0];
|
*s++ = sn[0];
|
||||||
|
|
||||||
if (pr)
|
if (pr)
|
||||||
*s++ = stbsp__period;
|
*s++ = stbsp__period;
|
||||||
|
|
||||||
// handle after decimal
|
// handle after decimal
|
||||||
if ((l - 1) > (stbsp__uint32)pr)
|
if ((l - 1) > (stbsp__uint32)pr)
|
||||||
l = pr + 1;
|
l = pr + 1;
|
||||||
@@ -816,7 +816,7 @@ cl = lg; \
|
|||||||
}
|
}
|
||||||
cs = 1 + (3 << 24); // how many tens
|
cs = 1 + (3 << 24); // how many tens
|
||||||
goto flt_lead;
|
goto flt_lead;
|
||||||
|
|
||||||
case 'f': // float
|
case 'f': // float
|
||||||
fv = va_arg(va, double);
|
fv = va_arg(va, double);
|
||||||
doafloat:
|
doafloat:
|
||||||
@@ -848,7 +848,7 @@ cl = lg; \
|
|||||||
goto scopy;
|
goto scopy;
|
||||||
}
|
}
|
||||||
s = num + 64;
|
s = num + 64;
|
||||||
|
|
||||||
// handle the three decimal varieties
|
// handle the three decimal varieties
|
||||||
if (dp <= 0) {
|
if (dp <= 0) {
|
||||||
stbsp__int32 i;
|
stbsp__int32 i;
|
||||||
@@ -957,7 +957,7 @@ cl = lg; \
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pr = 0;
|
pr = 0;
|
||||||
|
|
||||||
// handle k,m,g,t
|
// handle k,m,g,t
|
||||||
if (fl & STBSP__METRIC_SUFFIX) {
|
if (fl & STBSP__METRIC_SUFFIX) {
|
||||||
char idx;
|
char idx;
|
||||||
@@ -982,14 +982,14 @@ cl = lg; \
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
flt_lead:
|
flt_lead:
|
||||||
// get the length that we copied
|
// get the length that we copied
|
||||||
l = (stbsp__uint32)(s - (num + 64));
|
l = (stbsp__uint32)(s - (num + 64));
|
||||||
s = num + 64;
|
s = num + 64;
|
||||||
goto scopy;
|
goto scopy;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case 'B': // upper binary
|
case 'B': // upper binary
|
||||||
case 'b': // lower binary
|
case 'b': // lower binary
|
||||||
h = (f[0] == 'B') ? hexu : hex;
|
h = (f[0] == 'B') ? hexu : hex;
|
||||||
@@ -1001,7 +1001,7 @@ cl = lg; \
|
|||||||
}
|
}
|
||||||
l = (8 << 4) | (1 << 8);
|
l = (8 << 4) | (1 << 8);
|
||||||
goto radixnum;
|
goto radixnum;
|
||||||
|
|
||||||
case 'o': // octal
|
case 'o': // octal
|
||||||
h = hexu;
|
h = hexu;
|
||||||
lead[0] = 0;
|
lead[0] = 0;
|
||||||
@@ -1011,13 +1011,13 @@ cl = lg; \
|
|||||||
}
|
}
|
||||||
l = (3 << 4) | (3 << 8);
|
l = (3 << 4) | (3 << 8);
|
||||||
goto radixnum;
|
goto radixnum;
|
||||||
|
|
||||||
case 'p': // pointer
|
case 'p': // pointer
|
||||||
fl |= (sizeof(void *) == 8) ? STBSP__INTMAX : 0;
|
fl |= (sizeof(void *) == 8) ? STBSP__INTMAX : 0;
|
||||||
pr = sizeof(void *) * 2;
|
pr = sizeof(void *) * 2;
|
||||||
fl &= ~STBSP__LEADINGZERO; // 'p' only prints the pointer with zeros
|
fl &= ~STBSP__LEADINGZERO; // 'p' only prints the pointer with zeros
|
||||||
// fall through - to X
|
// fall through - to X
|
||||||
|
|
||||||
case 'X': // upper hex
|
case 'X': // upper hex
|
||||||
case 'x': // lower hex
|
case 'x': // lower hex
|
||||||
h = (f[0] == 'X') ? hexu : hex;
|
h = (f[0] == 'X') ? hexu : hex;
|
||||||
@@ -1034,7 +1034,7 @@ cl = lg; \
|
|||||||
n64 = va_arg(va, stbsp__uint64);
|
n64 = va_arg(va, stbsp__uint64);
|
||||||
else
|
else
|
||||||
n64 = va_arg(va, stbsp__uint32);
|
n64 = va_arg(va, stbsp__uint32);
|
||||||
|
|
||||||
s = num + STBSP__NUMSZ;
|
s = num + STBSP__NUMSZ;
|
||||||
dp = 0;
|
dp = 0;
|
||||||
// clear tail, and clear leading if value is zero
|
// clear tail, and clear leading if value is zero
|
||||||
@@ -1067,7 +1067,7 @@ cl = lg; \
|
|||||||
l = (stbsp__uint32)((num + STBSP__NUMSZ) - s);
|
l = (stbsp__uint32)((num + STBSP__NUMSZ) - s);
|
||||||
// copy it
|
// copy it
|
||||||
goto scopy;
|
goto scopy;
|
||||||
|
|
||||||
case 'u': // unsigned
|
case 'u': // unsigned
|
||||||
case 'i':
|
case 'i':
|
||||||
case 'd': // integer
|
case 'd': // integer
|
||||||
@@ -1087,7 +1087,7 @@ cl = lg; \
|
|||||||
fl |= STBSP__NEGATIVE;
|
fl |= STBSP__NEGATIVE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef STB_SPRINTF_NOFLOAT
|
#ifndef STB_SPRINTF_NOFLOAT
|
||||||
if (fl & STBSP__METRIC_SUFFIX) {
|
if (fl & STBSP__METRIC_SUFFIX) {
|
||||||
if (n64 < 1024)
|
if (n64 < 1024)
|
||||||
@@ -1098,11 +1098,11 @@ cl = lg; \
|
|||||||
goto doafloat;
|
goto doafloat;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// convert to string
|
// convert to string
|
||||||
s = num + STBSP__NUMSZ;
|
s = num + STBSP__NUMSZ;
|
||||||
l = 0;
|
l = 0;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// do in 32-bit chunks (avoid lots of 64-bit divides even with constant denominators)
|
// do in 32-bit chunks (avoid lots of 64-bit divides even with constant denominators)
|
||||||
char *o = s - 8;
|
char *o = s - 8;
|
||||||
@@ -1144,10 +1144,10 @@ cl = lg; \
|
|||||||
*--s = '0';
|
*--s = '0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tail[0] = 0;
|
tail[0] = 0;
|
||||||
stbsp__lead_sign(fl, lead);
|
stbsp__lead_sign(fl, lead);
|
||||||
|
|
||||||
// get the length that we copied
|
// get the length that we copied
|
||||||
l = (stbsp__uint32)((num + STBSP__NUMSZ) - s);
|
l = (stbsp__uint32)((num + STBSP__NUMSZ) - s);
|
||||||
if (l == 0) {
|
if (l == 0) {
|
||||||
@@ -1157,7 +1157,7 @@ cl = lg; \
|
|||||||
cs = l + (3 << 24);
|
cs = l + (3 << 24);
|
||||||
if (pr < 0)
|
if (pr < 0)
|
||||||
pr = 0;
|
pr = 0;
|
||||||
|
|
||||||
scopy:
|
scopy:
|
||||||
// get fw=leading/trailing space, pr=leading zeros
|
// get fw=leading/trailing space, pr=leading zeros
|
||||||
if (pr < (stbsp__int32)l)
|
if (pr < (stbsp__int32)l)
|
||||||
@@ -1167,7 +1167,7 @@ cl = lg; \
|
|||||||
fw = n;
|
fw = n;
|
||||||
fw -= n;
|
fw -= n;
|
||||||
pr -= l;
|
pr -= l;
|
||||||
|
|
||||||
// handle right justify and leading zeros
|
// handle right justify and leading zeros
|
||||||
if ((fl & STBSP__LEFTJUST) == 0) {
|
if ((fl & STBSP__LEFTJUST) == 0) {
|
||||||
if (fl & STBSP__LEADINGZERO) // if leading zeros, everything is in pr
|
if (fl & STBSP__LEADINGZERO) // if leading zeros, everything is in pr
|
||||||
@@ -1178,12 +1178,12 @@ cl = lg; \
|
|||||||
fl &= ~STBSP__TRIPLET_COMMA; // if no leading zeros, then no commas
|
fl &= ~STBSP__TRIPLET_COMMA; // if no leading zeros, then no commas
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy the spaces and/or zeros
|
// copy the spaces and/or zeros
|
||||||
if (fw + pr) {
|
if (fw + pr) {
|
||||||
stbsp__int32 i;
|
stbsp__int32 i;
|
||||||
stbsp__uint32 c;
|
stbsp__uint32 c;
|
||||||
|
|
||||||
// copy leading spaces (or when doing %8.4d stuff)
|
// copy leading spaces (or when doing %8.4d stuff)
|
||||||
if ((fl & STBSP__LEFTJUST) == 0)
|
if ((fl & STBSP__LEFTJUST) == 0)
|
||||||
while (fw > 0) {
|
while (fw > 0) {
|
||||||
@@ -1206,7 +1206,7 @@ cl = lg; \
|
|||||||
}
|
}
|
||||||
stbsp__chk_cb_buf(1);
|
stbsp__chk_cb_buf(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy leader
|
// copy leader
|
||||||
sn = lead + 1;
|
sn = lead + 1;
|
||||||
while (lead[0]) {
|
while (lead[0]) {
|
||||||
@@ -1218,7 +1218,7 @@ cl = lg; \
|
|||||||
}
|
}
|
||||||
stbsp__chk_cb_buf(1);
|
stbsp__chk_cb_buf(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy leading zeros
|
// copy leading zeros
|
||||||
c = cs >> 24;
|
c = cs >> 24;
|
||||||
cs &= 0xffffff;
|
cs &= 0xffffff;
|
||||||
@@ -1250,7 +1250,7 @@ cl = lg; \
|
|||||||
stbsp__chk_cb_buf(1);
|
stbsp__chk_cb_buf(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy leader if there is still one
|
// copy leader if there is still one
|
||||||
sn = lead + 1;
|
sn = lead + 1;
|
||||||
while (lead[0]) {
|
while (lead[0]) {
|
||||||
@@ -1263,7 +1263,7 @@ cl = lg; \
|
|||||||
}
|
}
|
||||||
stbsp__chk_cb_buf(1);
|
stbsp__chk_cb_buf(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy the string
|
// copy the string
|
||||||
n = l;
|
n = l;
|
||||||
while (n) {
|
while (n) {
|
||||||
@@ -1282,7 +1282,7 @@ cl = lg; \
|
|||||||
}
|
}
|
||||||
stbsp__chk_cb_buf(1);
|
stbsp__chk_cb_buf(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy trailing zeros
|
// copy trailing zeros
|
||||||
while (tz) {
|
while (tz) {
|
||||||
stbsp__int32 i;
|
stbsp__int32 i;
|
||||||
@@ -1305,7 +1305,7 @@ cl = lg; \
|
|||||||
}
|
}
|
||||||
stbsp__chk_cb_buf(1);
|
stbsp__chk_cb_buf(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy tail if there is one
|
// copy tail if there is one
|
||||||
sn = tail + 1;
|
sn = tail + 1;
|
||||||
while (tail[0]) {
|
while (tail[0]) {
|
||||||
@@ -1318,7 +1318,7 @@ cl = lg; \
|
|||||||
}
|
}
|
||||||
stbsp__chk_cb_buf(1);
|
stbsp__chk_cb_buf(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle the left justify
|
// handle the left justify
|
||||||
if (fl & STBSP__LEFTJUST)
|
if (fl & STBSP__LEFTJUST)
|
||||||
if (fw > 0) {
|
if (fw > 0) {
|
||||||
@@ -1343,7 +1343,7 @@ cl = lg; \
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // unknown, just copy code
|
default: // unknown, just copy code
|
||||||
s = num + STBSP__NUMSZ - 1;
|
s = num + STBSP__NUMSZ - 1;
|
||||||
*s = f[0];
|
*s = f[0];
|
||||||
@@ -1359,12 +1359,12 @@ cl = lg; \
|
|||||||
++f;
|
++f;
|
||||||
}
|
}
|
||||||
endfmt:
|
endfmt:
|
||||||
|
|
||||||
if (!callback)
|
if (!callback)
|
||||||
*bf = 0;
|
*bf = 0;
|
||||||
else
|
else
|
||||||
stbsp__flush_cb();
|
stbsp__flush_cb();
|
||||||
|
|
||||||
done:
|
done:
|
||||||
return tlen + (int)(bf - buf);
|
return tlen + (int)(bf - buf);
|
||||||
}
|
}
|
||||||
@@ -1409,10 +1409,10 @@ static char *stbsp__clamp_callback(const char *buf, void *user, int len)
|
|||||||
{
|
{
|
||||||
stbsp__context *c = (stbsp__context *)user;
|
stbsp__context *c = (stbsp__context *)user;
|
||||||
c->length += len;
|
c->length += len;
|
||||||
|
|
||||||
if (len > c->count)
|
if (len > c->count)
|
||||||
len = c->count;
|
len = c->count;
|
||||||
|
|
||||||
if (len) {
|
if (len) {
|
||||||
if (buf != c->buf) {
|
if (buf != c->buf) {
|
||||||
const char *s, *se;
|
const char *s, *se;
|
||||||
@@ -1427,7 +1427,7 @@ static char *stbsp__clamp_callback(const char *buf, void *user, int len)
|
|||||||
c->buf += len;
|
c->buf += len;
|
||||||
c->count -= len;
|
c->count -= len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->count <= 0)
|
if (c->count <= 0)
|
||||||
return c->tmp;
|
return c->tmp;
|
||||||
return (c->count >= STB_SPRINTF_MIN) ? c->buf : c->tmp; // go direct into buffer if you can
|
return (c->count >= STB_SPRINTF_MIN) ? c->buf : c->tmp; // go direct into buffer if you can
|
||||||
@@ -1437,7 +1437,7 @@ static char * stbsp__count_clamp_callback( const char * buf, void * user, int le
|
|||||||
{
|
{
|
||||||
stbsp__context * c = (stbsp__context*)user;
|
stbsp__context * c = (stbsp__context*)user;
|
||||||
(void) sizeof(buf);
|
(void) sizeof(buf);
|
||||||
|
|
||||||
c->length += len;
|
c->length += len;
|
||||||
return c->tmp; // go direct into buffer if you can
|
return c->tmp; // go direct into buffer if you can
|
||||||
}
|
}
|
||||||
@@ -1445,30 +1445,30 @@ static char * stbsp__count_clamp_callback( const char * buf, void * user, int le
|
|||||||
STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsnprintf )( char * buf, int count, char const * fmt, va_list va )
|
STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsnprintf )( char * buf, int count, char const * fmt, va_list va )
|
||||||
{
|
{
|
||||||
stbsp__context c;
|
stbsp__context c;
|
||||||
|
|
||||||
if ( (count == 0) && !buf )
|
if ( (count == 0) && !buf )
|
||||||
{
|
{
|
||||||
c.length = 0;
|
c.length = 0;
|
||||||
|
|
||||||
STB_SPRINTF_DECORATE( vsprintfcb )( stbsp__count_clamp_callback, &c, c.tmp, fmt, va );
|
STB_SPRINTF_DECORATE( vsprintfcb )( stbsp__count_clamp_callback, &c, c.tmp, fmt, va );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int l;
|
int l;
|
||||||
|
|
||||||
c.buf = buf;
|
c.buf = buf;
|
||||||
c.count = count;
|
c.count = count;
|
||||||
c.length = 0;
|
c.length = 0;
|
||||||
|
|
||||||
STB_SPRINTF_DECORATE( vsprintfcb )( stbsp__clamp_callback, &c, stbsp__clamp_callback(0,&c,0), fmt, va );
|
STB_SPRINTF_DECORATE( vsprintfcb )( stbsp__clamp_callback, &c, stbsp__clamp_callback(0,&c,0), fmt, va );
|
||||||
|
|
||||||
// zero-terminate
|
// zero-terminate
|
||||||
l = (int)( c.buf - buf );
|
l = (int)( c.buf - buf );
|
||||||
if ( l >= count ) // should never be greater, only equal (or less) than count
|
if ( l >= count ) // should never be greater, only equal (or less) than count
|
||||||
l = count - 1;
|
l = count - 1;
|
||||||
buf[l] = 0;
|
buf[l] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.length;
|
return c.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1477,10 +1477,10 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(snprintf)(char *buf, int count, char c
|
|||||||
int result;
|
int result;
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start(va, fmt);
|
va_start(va, fmt);
|
||||||
|
|
||||||
result = STB_SPRINTF_DECORATE(vsnprintf)(buf, count, fmt, va);
|
result = STB_SPRINTF_DECORATE(vsnprintf)(buf, count, fmt, va);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1507,15 +1507,15 @@ static stbsp__int32 stbsp__real_to_parts(stbsp__int64 *bits, stbsp__int32 *expo,
|
|||||||
{
|
{
|
||||||
double d;
|
double d;
|
||||||
stbsp__int64 b = 0;
|
stbsp__int64 b = 0;
|
||||||
|
|
||||||
// load value and round at the frac_digits
|
// load value and round at the frac_digits
|
||||||
d = value;
|
d = value;
|
||||||
|
|
||||||
STBSP__COPYFP(b, d);
|
STBSP__COPYFP(b, d);
|
||||||
|
|
||||||
*bits = b & ((((stbsp__uint64)1) << 52) - 1);
|
*bits = b & ((((stbsp__uint64)1) << 52) - 1);
|
||||||
*expo = (stbsp__int32)(((b >> 52) & 2047) - 1023);
|
*expo = (stbsp__int32)(((b >> 52) & 2047) - 1023);
|
||||||
|
|
||||||
return (stbsp__int32)((stbsp__uint64) b >> 63);
|
return (stbsp__int32)((stbsp__uint64) b >> 63);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1658,7 +1658,7 @@ static void stbsp__raise_to_power10(double *ohi, double *olo, double d, stbsp__i
|
|||||||
} else {
|
} else {
|
||||||
stbsp__int32 e, et, eb;
|
stbsp__int32 e, et, eb;
|
||||||
double p2h, p2l;
|
double p2h, p2l;
|
||||||
|
|
||||||
e = power;
|
e = power;
|
||||||
if (power < 0)
|
if (power < 0)
|
||||||
e = -e;
|
e = -e;
|
||||||
@@ -1666,7 +1666,7 @@ static void stbsp__raise_to_power10(double *ohi, double *olo, double d, stbsp__i
|
|||||||
if (et > 13)
|
if (et > 13)
|
||||||
et = 13;
|
et = 13;
|
||||||
eb = e - (et * 23);
|
eb = e - (et * 23);
|
||||||
|
|
||||||
ph = d;
|
ph = d;
|
||||||
pl = 0.0;
|
pl = 0.0;
|
||||||
if (power < 0) {
|
if (power < 0) {
|
||||||
@@ -1722,14 +1722,14 @@ static stbsp__int32 stbsp__real_to_str(char const **start, stbsp__uint32 *len, c
|
|||||||
double d;
|
double d;
|
||||||
stbsp__int64 bits = 0;
|
stbsp__int64 bits = 0;
|
||||||
stbsp__int32 expo, e, ng, tens;
|
stbsp__int32 expo, e, ng, tens;
|
||||||
|
|
||||||
d = value;
|
d = value;
|
||||||
STBSP__COPYFP(bits, d);
|
STBSP__COPYFP(bits, d);
|
||||||
expo = (stbsp__int32)((bits >> 52) & 2047);
|
expo = (stbsp__int32)((bits >> 52) & 2047);
|
||||||
ng = (stbsp__int32)((stbsp__uint64) bits >> 63);
|
ng = (stbsp__int32)((stbsp__uint64) bits >> 63);
|
||||||
if (ng)
|
if (ng)
|
||||||
d = -d;
|
d = -d;
|
||||||
|
|
||||||
if (expo == 2047) // is nan or inf?
|
if (expo == 2047) // is nan or inf?
|
||||||
{
|
{
|
||||||
*start = (bits & ((((stbsp__uint64)1) << 52) - 1)) ? "NaN" : "Inf";
|
*start = (bits & ((((stbsp__uint64)1) << 52) - 1)) ? "NaN" : "Inf";
|
||||||
@@ -1737,7 +1737,7 @@ static stbsp__int32 stbsp__real_to_str(char const **start, stbsp__uint32 *len, c
|
|||||||
*len = 3;
|
*len = 3;
|
||||||
return ng;
|
return ng;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expo == 0) // is zero or denormal
|
if (expo == 0) // is zero or denormal
|
||||||
{
|
{
|
||||||
if (((stbsp__uint64) bits << 1) == 0) // do zero
|
if (((stbsp__uint64) bits << 1) == 0) // do zero
|
||||||
@@ -1757,26 +1757,26 @@ static stbsp__int32 stbsp__real_to_str(char const **start, stbsp__uint32 *len, c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the decimal exponent as well as the decimal bits of the value
|
// find the decimal exponent as well as the decimal bits of the value
|
||||||
{
|
{
|
||||||
double ph, pl;
|
double ph, pl;
|
||||||
|
|
||||||
// log10 estimate - very specifically tweaked to hit or undershoot by no more than 1 of log10 of all expos 1..2046
|
// log10 estimate - very specifically tweaked to hit or undershoot by no more than 1 of log10 of all expos 1..2046
|
||||||
tens = expo - 1023;
|
tens = expo - 1023;
|
||||||
tens = (tens < 0) ? ((tens * 617) / 2048) : (((tens * 1233) / 4096) + 1);
|
tens = (tens < 0) ? ((tens * 617) / 2048) : (((tens * 1233) / 4096) + 1);
|
||||||
|
|
||||||
// move the significant bits into position and stick them into an int
|
// move the significant bits into position and stick them into an int
|
||||||
stbsp__raise_to_power10(&ph, &pl, d, 18 - tens);
|
stbsp__raise_to_power10(&ph, &pl, d, 18 - tens);
|
||||||
|
|
||||||
// get full as much precision from double-double as possible
|
// get full as much precision from double-double as possible
|
||||||
stbsp__ddtoS64(bits, ph, pl);
|
stbsp__ddtoS64(bits, ph, pl);
|
||||||
|
|
||||||
// check if we undershot
|
// check if we undershot
|
||||||
if (((stbsp__uint64)bits) >= stbsp__tento19th)
|
if (((stbsp__uint64)bits) >= stbsp__tento19th)
|
||||||
++tens;
|
++tens;
|
||||||
}
|
}
|
||||||
|
|
||||||
// now do the rounding in integer land
|
// now do the rounding in integer land
|
||||||
frac_digits = (frac_digits & 0x80000000) ? ((frac_digits & 0x7ffffff) + 1) : (tens + frac_digits);
|
frac_digits = (frac_digits & 0x80000000) ? ((frac_digits & 0x7ffffff) + 1) : (tens + frac_digits);
|
||||||
if ((frac_digits < 24)) {
|
if ((frac_digits < 24)) {
|
||||||
@@ -1802,7 +1802,7 @@ static stbsp__int32 stbsp__real_to_str(char const **start, stbsp__uint32 *len, c
|
|||||||
}
|
}
|
||||||
noround:;
|
noround:;
|
||||||
}
|
}
|
||||||
|
|
||||||
// kill long trailing runs of zeros
|
// kill long trailing runs of zeros
|
||||||
if (bits) {
|
if (bits) {
|
||||||
stbsp__uint32 n;
|
stbsp__uint32 n;
|
||||||
@@ -1819,7 +1819,7 @@ static stbsp__int32 stbsp__real_to_str(char const **start, stbsp__uint32 *len, c
|
|||||||
bits = n;
|
bits = n;
|
||||||
donez:;
|
donez:;
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert to string
|
// convert to string
|
||||||
out += 64;
|
out += 64;
|
||||||
e = 0;
|
e = 0;
|
||||||
@@ -1852,7 +1852,7 @@ static stbsp__int32 stbsp__real_to_str(char const **start, stbsp__uint32 *len, c
|
|||||||
++e;
|
++e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*decimal_pos = tens;
|
*decimal_pos = tens;
|
||||||
*start = out;
|
*start = out;
|
||||||
*len = e;
|
*len = e;
|
||||||
|
|||||||
Reference in New Issue
Block a user