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