mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 23:58:50 +00:00
Update ImplicitValue "architecture"
This commit is contained in:
@@ -1,15 +1,6 @@
|
|||||||
#import "fmt.odin"
|
#import "fmt.odin"
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
Vec3 :: struct {
|
|
||||||
x, y: i16
|
|
||||||
z: ?i32
|
|
||||||
}
|
|
||||||
a := [..]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
|
|
||||||
offset: u8 = 2
|
|
||||||
ptr := ^a[4]
|
|
||||||
|
|
||||||
|
|
||||||
fmt.println((ptr+offset) - ptr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-8
@@ -406,8 +406,9 @@ print_any_to_buffer :: proc(buf: ^[]byte, arg: any) {
|
|||||||
|
|
||||||
|
|
||||||
case Array:
|
case Array:
|
||||||
print_string_to_buffer(buf, "[")
|
bprintf(buf, "[%]%{", info.count, info.elem)
|
||||||
defer print_string_to_buffer(buf, "]")
|
defer print_string_to_buffer(buf, "}")
|
||||||
|
|
||||||
|
|
||||||
for i := 0; i < info.count; i++ {
|
for i := 0; i < info.count; i++ {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
@@ -420,8 +421,8 @@ print_any_to_buffer :: proc(buf: ^[]byte, arg: any) {
|
|||||||
|
|
||||||
case Slice:
|
case Slice:
|
||||||
slice := arg.data as ^[]byte
|
slice := arg.data as ^[]byte
|
||||||
print_string_to_buffer(buf, "[")
|
bprintf(buf, "[]%{", info.elem)
|
||||||
defer print_string_to_buffer(buf, "]")
|
defer print_string_to_buffer(buf, "}")
|
||||||
|
|
||||||
for i := 0; i < slice.count; i++ {
|
for i := 0; i < slice.count; i++ {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
@@ -443,8 +444,8 @@ print_any_to_buffer :: proc(buf: ^[]byte, arg: any) {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
print_string_to_buffer(buf, "<")
|
bprintf(buf, "{%}%{", info.count, info.elem)
|
||||||
defer print_string_to_buffer(buf, ">")
|
defer print_string_to_buffer(buf, "}")
|
||||||
|
|
||||||
if is_bool(info.elem) {
|
if is_bool(info.elem) {
|
||||||
return
|
return
|
||||||
@@ -461,8 +462,7 @@ print_any_to_buffer :: proc(buf: ^[]byte, arg: any) {
|
|||||||
|
|
||||||
|
|
||||||
case Struct:
|
case Struct:
|
||||||
print_string_to_buffer(buf, "struct")
|
bprintf(buf, "%{", arg.type_info)
|
||||||
print_string_to_buffer(buf, "{")
|
|
||||||
defer print_string_to_buffer(buf, "}")
|
defer print_string_to_buffer(buf, "}")
|
||||||
|
|
||||||
for i := 0; i < info.fields.count; i++ {
|
for i := 0; i < info.fields.count; i++ {
|
||||||
|
|||||||
+1
-1
@@ -138,7 +138,7 @@ murmur64 :: proc(data_: rawptr, len: int) -> u64 {
|
|||||||
len -= 4
|
len -= 4
|
||||||
}
|
}
|
||||||
|
|
||||||
data8 := slice_ptr(ptr_offset(data.data, i) as ^u8, 3) // NOTE(bill): This is unsafe
|
data8 := slice_ptr((data.data+i) as ^u8, 3) // NOTE(bill): This is unsafe
|
||||||
|
|
||||||
match len {
|
match len {
|
||||||
case 3: h2 ~= data8[2] as u32 << 16; fallthrough
|
case 3: h2 ~= data8[2] as u32 << 16; fallthrough
|
||||||
|
|||||||
+44
-2
@@ -181,6 +181,23 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
|
|||||||
{STR_LIT("enum_to_string"), 1, false, Expr_Expr},
|
{STR_LIT("enum_to_string"), 1, false, Expr_Expr},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ImplicitValueId {
|
||||||
|
ImplicitValue_Invalid,
|
||||||
|
|
||||||
|
ImplicitValue_context,
|
||||||
|
|
||||||
|
ImplicitValue_Count,
|
||||||
|
};
|
||||||
|
struct ImplicitValueInfo {
|
||||||
|
String name;
|
||||||
|
String backing_name;
|
||||||
|
Type * type;
|
||||||
|
};
|
||||||
|
// NOTE(bill): This is initialized later
|
||||||
|
gb_global ImplicitValueInfo implicit_value_infos[ImplicitValue_Count] = {};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct CheckerContext {
|
struct CheckerContext {
|
||||||
Scope *scope;
|
Scope *scope;
|
||||||
DeclInfo *decl;
|
DeclInfo *decl;
|
||||||
@@ -199,6 +216,8 @@ struct CheckerInfo {
|
|||||||
Map<isize> type_info_map; // Key: Type *
|
Map<isize> type_info_map; // Key: Type *
|
||||||
Map<AstFile *> files; // Key: String
|
Map<AstFile *> files; // Key: String
|
||||||
isize type_info_index;
|
isize type_info_index;
|
||||||
|
|
||||||
|
Entity * implicit_values[ImplicitValue_Count];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Checker {
|
struct Checker {
|
||||||
@@ -423,8 +442,9 @@ Entity *scope_insert_entity(Scope *s, Entity *entity) {
|
|||||||
String name = entity->token.string;
|
String name = entity->token.string;
|
||||||
HashKey key = hash_string(name);
|
HashKey key = hash_string(name);
|
||||||
Entity **found = map_get(&s->elements, key);
|
Entity **found = map_get(&s->elements, key);
|
||||||
if (found)
|
if (found) {
|
||||||
return *found;
|
return *found;
|
||||||
|
}
|
||||||
map_set(&s->elements, key, entity);
|
map_set(&s->elements, key, entity);
|
||||||
if (entity->scope == NULL) {
|
if (entity->scope == NULL) {
|
||||||
entity->scope = s;
|
entity->scope = s;
|
||||||
@@ -950,8 +970,17 @@ void init_preload_types(Checker *c) {
|
|||||||
t_context = e->type;
|
t_context = e->type;
|
||||||
t_context_ptr = make_type_pointer(c->allocator, t_context);
|
t_context_ptr = make_type_pointer(c->allocator, t_context);
|
||||||
|
|
||||||
add_global_entity(make_entity_implicit_value(gb_heap_allocator(), make_string("context"), t_context));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_implicit_value(Checker *c, ImplicitValueId id, String name, String backing_name, Type *type) {
|
||||||
|
ImplicitValueInfo info = {name, backing_name, type};
|
||||||
|
Entity *value = make_entity_implicit_value(c->allocator, info.name, info.type, id);
|
||||||
|
Entity *prev = scope_insert_entity(c->global_scope, value);
|
||||||
|
GB_ASSERT(prev == NULL);
|
||||||
|
implicit_value_infos[id] = info;
|
||||||
|
c->info.implicit_values[id] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_parsed_files(Checker *c) {
|
void check_parsed_files(Checker *c) {
|
||||||
@@ -1228,11 +1257,24 @@ void check_parsed_files(Checker *c) {
|
|||||||
check_global_entity(c, Entity_TypeName);
|
check_global_entity(c, Entity_TypeName);
|
||||||
|
|
||||||
init_preload_types(c);
|
init_preload_types(c);
|
||||||
|
add_implicit_value(c, ImplicitValue_context, make_string("context"), make_string("__context"), t_context);
|
||||||
|
|
||||||
check_global_entity(c, Entity_Constant);
|
check_global_entity(c, Entity_Constant);
|
||||||
check_global_entity(c, Entity_Procedure);
|
check_global_entity(c, Entity_Procedure);
|
||||||
check_global_entity(c, Entity_Variable);
|
check_global_entity(c, Entity_Variable);
|
||||||
|
|
||||||
|
for (isize i = 1; i < ImplicitValue_Count; i++) {
|
||||||
|
// NOTE(bill): First is invalid
|
||||||
|
Entity *e = c->info.implicit_values[i];
|
||||||
|
GB_ASSERT(e->kind == Entity_ImplicitValue);
|
||||||
|
|
||||||
|
ImplicitValueInfo *ivi = &implicit_value_infos[i];
|
||||||
|
Entity *backing = scope_lookup_entity(e->scope, ivi->backing_name);
|
||||||
|
GB_ASSERT(backing != NULL);
|
||||||
|
e->ImplicitValue.backing = backing;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Check procedure bodies
|
// Check procedure bodies
|
||||||
for_array(i, c->procs) {
|
for_array(i, c->procs) {
|
||||||
ProcedureInfo *pi = &c->procs[i];
|
ProcedureInfo *pi = &c->procs[i];
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ struct Scope;
|
|||||||
struct Checker;
|
struct Checker;
|
||||||
struct Type;
|
struct Type;
|
||||||
enum BuiltinProcId;
|
enum BuiltinProcId;
|
||||||
|
enum ImplicitValueId;
|
||||||
|
|
||||||
#define ENTITY_KINDS \
|
#define ENTITY_KINDS \
|
||||||
ENTITY_KIND(Invalid), \
|
ENTITY_KIND(Invalid), \
|
||||||
@@ -63,10 +64,13 @@ struct Entity {
|
|||||||
String path;
|
String path;
|
||||||
String name;
|
String name;
|
||||||
Scope *scope;
|
Scope *scope;
|
||||||
b32 used;
|
b32 used;
|
||||||
} ImportName;
|
} ImportName;
|
||||||
struct {} Nil;
|
struct {} Nil;
|
||||||
struct {} ImplicitValue;
|
struct {
|
||||||
|
ImplicitValueId id;
|
||||||
|
Entity * backing;
|
||||||
|
} ImplicitValue;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -160,9 +164,10 @@ Entity *make_entity_nil(gbAllocator a, String name, Type *type) {
|
|||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity *make_entity_implicit_value(gbAllocator a, String name, Type *type) {
|
Entity *make_entity_implicit_value(gbAllocator a, String name, Type *type, ImplicitValueId id) {
|
||||||
Token token = make_token_ident(name);
|
Token token = make_token_ident(name);
|
||||||
Entity *entity = alloc_entity(a, Entity_ImplicitValue, NULL, token, type);
|
Entity *entity = alloc_entity(a, Entity_ImplicitValue, NULL, token, type);
|
||||||
|
entity->ImplicitValue.id = id;
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3677,7 +3677,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
|||||||
|
|
||||||
default: {
|
default: {
|
||||||
gbString str = type_to_string(type);
|
gbString str = type_to_string(type);
|
||||||
error(ast_node_token(node), "Invalid or unyet supported compound literal type `%s`", str);
|
error(ast_node_token(node), "Invalid compound literal type `%s`", str);
|
||||||
gb_string_free(str);
|
gb_string_free(str);
|
||||||
goto error;
|
goto error;
|
||||||
} break;
|
} break;
|
||||||
@@ -4187,6 +4187,11 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
|
|||||||
str = write_expr_to_string(str, pt->type);
|
str = write_expr_to_string(str, pt->type);
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
|
case_ast_node(mt, MaybeType, node);
|
||||||
|
str = gb_string_appendc(str, "?");
|
||||||
|
str = write_expr_to_string(str, mt->type);
|
||||||
|
case_end;
|
||||||
|
|
||||||
case_ast_node(at, ArrayType, node);
|
case_ast_node(at, ArrayType, node);
|
||||||
str = gb_string_appendc(str, "[");
|
str = gb_string_appendc(str, "[");
|
||||||
str = write_expr_to_string(str, at->count);
|
str = write_expr_to_string(str, at->count);
|
||||||
|
|||||||
+10
-6
@@ -1102,8 +1102,9 @@ i64 type_size_of(BaseTypeSizes s, gbAllocator allocator, Type *t) {
|
|||||||
BasicKind kind = t->Basic.kind;
|
BasicKind kind = t->Basic.kind;
|
||||||
if (kind < gb_count_of(basic_type_sizes)) {
|
if (kind < gb_count_of(basic_type_sizes)) {
|
||||||
i64 size = basic_type_sizes[kind];
|
i64 size = basic_type_sizes[kind];
|
||||||
if (size > 0)
|
if (size > 0) {
|
||||||
return size;
|
return size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (kind == Basic_string) {
|
if (kind == Basic_string) {
|
||||||
return 2 * s.word_size;
|
return 2 * s.word_size;
|
||||||
@@ -1114,8 +1115,9 @@ i64 type_size_of(BaseTypeSizes s, gbAllocator allocator, Type *t) {
|
|||||||
|
|
||||||
case Type_Array: {
|
case Type_Array: {
|
||||||
i64 count = t->Array.count;
|
i64 count = t->Array.count;
|
||||||
if (count == 0)
|
if (count == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
i64 align = type_align_of(s, allocator, t->Array.elem);
|
i64 align = type_align_of(s, allocator, t->Array.elem);
|
||||||
i64 size = type_size_of(s, allocator, t->Array.elem);
|
i64 size = type_size_of(s, allocator, t->Array.elem);
|
||||||
i64 alignment = align_formula(size, align);
|
i64 alignment = align_formula(size, align);
|
||||||
@@ -1124,8 +1126,9 @@ i64 type_size_of(BaseTypeSizes s, gbAllocator allocator, Type *t) {
|
|||||||
|
|
||||||
case Type_Vector: {
|
case Type_Vector: {
|
||||||
i64 count = t->Vector.count;
|
i64 count = t->Vector.count;
|
||||||
if (count == 0)
|
if (count == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
// i64 align = type_align_of(s, allocator, t->Vector.elem);
|
// i64 align = type_align_of(s, allocator, t->Vector.elem);
|
||||||
i64 bit_size = 8*type_size_of(s, allocator, t->Vector.elem);
|
i64 bit_size = 8*type_size_of(s, allocator, t->Vector.elem);
|
||||||
if (is_type_boolean(t->Vector.elem)) {
|
if (is_type_boolean(t->Vector.elem)) {
|
||||||
@@ -1169,8 +1172,9 @@ i64 type_size_of(BaseTypeSizes s, gbAllocator allocator, Type *t) {
|
|||||||
// NOTE(bill): Zeroth field is invalid
|
// NOTE(bill): Zeroth field is invalid
|
||||||
for (isize i = 1; i < count; i++) {
|
for (isize i = 1; i < count; i++) {
|
||||||
i64 size = type_size_of(s, allocator, t->Record.fields[i]->type);
|
i64 size = type_size_of(s, allocator, t->Record.fields[i]->type);
|
||||||
if (max < size)
|
if (max < size) {
|
||||||
max = size;
|
max = size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// NOTE(bill): Align to int
|
// NOTE(bill): Align to int
|
||||||
i64 align = type_align_of(s, allocator, t);
|
i64 align = type_align_of(s, allocator, t);
|
||||||
@@ -1184,8 +1188,9 @@ i64 type_size_of(BaseTypeSizes s, gbAllocator allocator, Type *t) {
|
|||||||
i64 max = 0;
|
i64 max = 0;
|
||||||
for (isize i = 0; i < count; i++) {
|
for (isize i = 0; i < count; i++) {
|
||||||
i64 size = type_size_of(s, allocator, t->Record.fields[i]->type);
|
i64 size = type_size_of(s, allocator, t->Record.fields[i]->type);
|
||||||
if (max < size)
|
if (max < size) {
|
||||||
max = size;
|
max = size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// TODO(bill): Is this how it should work?
|
// TODO(bill): Is this how it should work?
|
||||||
i64 align = type_align_of(s, allocator, t);
|
i64 align = type_align_of(s, allocator, t);
|
||||||
@@ -1211,7 +1216,6 @@ i64 type_offset_of(BaseTypeSizes s, gbAllocator allocator, Type *t, isize index)
|
|||||||
return t->Record.struct_offsets[index];
|
return t->Record.struct_offsets[index];
|
||||||
}
|
}
|
||||||
} else if (t->kind == Type_Basic) {
|
} else if (t->kind == Type_Basic) {
|
||||||
gb_printf_err("here!!\n");
|
|
||||||
if (t->Basic.kind == Basic_string) {
|
if (t->Basic.kind == Basic_string) {
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 0: return 0;
|
case 0: return 0;
|
||||||
|
|||||||
+17
-23
@@ -2306,21 +2306,22 @@ void ssa_slice_bounds_check(ssaProcedure *proc, Token token, ssaValue *low, ssaV
|
|||||||
}
|
}
|
||||||
|
|
||||||
ssaValue *ssa_find_global_variable(ssaProcedure *proc, String name) {
|
ssaValue *ssa_find_global_variable(ssaProcedure *proc, String name) {
|
||||||
ssaValue *value = *map_get(&proc->module->members, hash_string(name));
|
ssaValue **value = map_get(&proc->module->members, hash_string(name));
|
||||||
return value;
|
GB_ASSERT_MSG(value != NULL, "Unable to find global variable `%.*s`", LIT(name));
|
||||||
|
return *value;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssaValue *ssa_emit_implicit_value(ssaProcedure *proc, Entity *e) {
|
ssaValue *ssa_find_implicit_value_backing(ssaProcedure *proc, ImplicitValueId id) {
|
||||||
String name = e->token.string;
|
Entity *e = proc->module->info->implicit_values[id];
|
||||||
ssaValue *g = NULL;
|
GB_ASSERT(e->kind == Entity_ImplicitValue);
|
||||||
if (name == "context") {
|
Entity *backing = e->ImplicitValue.backing;
|
||||||
g = ssa_emit_load(proc, ssa_find_global_variable(proc, make_string("__context")));
|
ssaValue **value = map_get(&proc->module->values, hash_pointer(backing));
|
||||||
}
|
GB_ASSERT_MSG(value != NULL, "Unable to find implicit value backing `%.*s`", LIT(backing->token.string));
|
||||||
GB_ASSERT(g != NULL);
|
return *value;
|
||||||
return g;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue *tv) {
|
ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue *tv) {
|
||||||
switch (expr->kind) {
|
switch (expr->kind) {
|
||||||
case_ast_node(bl, BasicLit, expr);
|
case_ast_node(bl, BasicLit, expr);
|
||||||
@@ -2338,7 +2339,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
|||||||
} else if (e->kind == Entity_Nil) {
|
} else if (e->kind == Entity_Nil) {
|
||||||
return ssa_make_value_nil(proc->module->allocator, tv->type);
|
return ssa_make_value_nil(proc->module->allocator, tv->type);
|
||||||
} else if (e->kind == Entity_ImplicitValue) {
|
} else if (e->kind == Entity_ImplicitValue) {
|
||||||
return ssa_emit_implicit_value(proc, e);
|
return ssa_emit_load(proc, ssa_find_implicit_value_backing(proc, e->ImplicitValue.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *found = map_get(&proc->module->values, hash_pointer(e));
|
auto *found = map_get(&proc->module->values, hash_pointer(e));
|
||||||
@@ -3069,8 +3070,6 @@ ssaValue *ssa_build_expr(ssaProcedure *proc, AstNode *expr) {
|
|||||||
if (tv->value.kind != ExactValue_Invalid) {
|
if (tv->value.kind != ExactValue_Invalid) {
|
||||||
if (tv->value.kind == ExactValue_String) {
|
if (tv->value.kind == ExactValue_String) {
|
||||||
ssa_emit_comment(proc, make_string("Emit string constant"));
|
ssa_emit_comment(proc, make_string("Emit string constant"));
|
||||||
|
|
||||||
// TODO(bill): Optimize by not allocating everytime
|
|
||||||
if (tv->value.value_string.len > 0) {
|
if (tv->value.value_string.len > 0) {
|
||||||
return ssa_emit_global_string(proc, tv->value.value_string);
|
return ssa_emit_global_string(proc, tv->value.value_string);
|
||||||
} else {
|
} else {
|
||||||
@@ -3084,8 +3083,7 @@ ssaValue *ssa_build_expr(ssaProcedure *proc, AstNode *expr) {
|
|||||||
|
|
||||||
ssaValue *value = NULL;
|
ssaValue *value = NULL;
|
||||||
if (tv->mode == Addressing_Variable) {
|
if (tv->mode == Addressing_Variable) {
|
||||||
ssaAddr addr = ssa_build_addr(proc, expr);
|
value = ssa_lvalue_load(proc, ssa_build_addr(proc, expr));
|
||||||
value = ssa_lvalue_load(proc, addr);
|
|
||||||
} else {
|
} else {
|
||||||
value = ssa_build_single_expr(proc, expr, tv);
|
value = ssa_build_single_expr(proc, expr, tv);
|
||||||
}
|
}
|
||||||
@@ -3122,8 +3120,6 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
|
|||||||
|
|
||||||
Entity *e = entity_of_ident(proc->module->info, expr);
|
Entity *e = entity_of_ident(proc->module->info, expr);
|
||||||
TypeAndValue *tv = map_get(&proc->module->info->types, hash_pointer(expr));
|
TypeAndValue *tv = map_get(&proc->module->info->types, hash_pointer(expr));
|
||||||
// GB_ASSERT(tv == NULL || tv->mode == Addressing_Variable);
|
|
||||||
|
|
||||||
|
|
||||||
if (e->kind == Entity_Constant) {
|
if (e->kind == Entity_Constant) {
|
||||||
if (base_type(e->type) == t_string) {
|
if (base_type(e->type) == t_string) {
|
||||||
@@ -3148,10 +3144,8 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
|
|||||||
} else if (e->kind == Entity_Variable && e->Variable.anonymous) {
|
} else if (e->kind == Entity_Variable && e->Variable.anonymous) {
|
||||||
v = ssa_add_using_variable(proc, e);
|
v = ssa_add_using_variable(proc, e);
|
||||||
} else if (e->kind == Entity_ImplicitValue) {
|
} else if (e->kind == Entity_ImplicitValue) {
|
||||||
ssaValue *g = ssa_emit_implicit_value(proc, e);
|
// TODO(bill): Should a copy be made?
|
||||||
// NOTE(bill): Create a copy as it's by value
|
v = ssa_find_implicit_value_backing(proc, e->ImplicitValue.id);
|
||||||
v = ssa_add_local_generated(proc, ssa_type(g));
|
|
||||||
ssa_emit_store(proc, v, g);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v == NULL) {
|
if (v == NULL) {
|
||||||
@@ -4210,7 +4204,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
|
|||||||
ssa_open_scope(proc);
|
ssa_open_scope(proc);
|
||||||
defer (ssa_close_scope(proc, ssaDeferExit_Default, NULL));
|
defer (ssa_close_scope(proc, ssaDeferExit_Default, NULL));
|
||||||
|
|
||||||
ssaValue *context_ptr = ssa_find_global_variable(proc, make_string("__context"));
|
ssaValue *context_ptr = ssa_find_implicit_value_backing(proc, ImplicitValue_context);
|
||||||
ssaValue *prev_context = ssa_add_local_generated(proc, t_context);
|
ssaValue *prev_context = ssa_add_local_generated(proc, t_context);
|
||||||
ssa_emit_store(proc, prev_context, ssa_emit_load(proc, context_ptr));
|
ssa_emit_store(proc, prev_context, ssa_emit_load(proc, context_ptr));
|
||||||
|
|
||||||
@@ -4229,7 +4223,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
|
|||||||
ssa_open_scope(proc);
|
ssa_open_scope(proc);
|
||||||
defer (ssa_close_scope(proc, ssaDeferExit_Default, NULL));
|
defer (ssa_close_scope(proc, ssaDeferExit_Default, NULL));
|
||||||
|
|
||||||
ssaValue *context_ptr = ssa_find_global_variable(proc, make_string("__context"));
|
ssaValue *context_ptr = ssa_find_implicit_value_backing(proc, ImplicitValue_context);
|
||||||
ssaValue *prev_context = ssa_add_local_generated(proc, t_context);
|
ssaValue *prev_context = ssa_add_local_generated(proc, t_context);
|
||||||
ssa_emit_store(proc, prev_context, ssa_emit_load(proc, context_ptr));
|
ssa_emit_store(proc, prev_context, ssa_emit_load(proc, context_ptr));
|
||||||
|
|
||||||
|
|||||||
+26
-26
@@ -1928,7 +1928,7 @@ typedef union gbFileDescriptor {
|
|||||||
|
|
||||||
typedef struct gbFileOperations gbFileOperations;
|
typedef struct gbFileOperations gbFileOperations;
|
||||||
|
|
||||||
#define GB_FILE_OPEN_PROC(name) gbFileError name(gbFileDescriptor *fd, gbFileOperations const **ops, gbFileMode mode, char const *filename)
|
#define GB_FILE_OPEN_PROC(name) gbFileError name(gbFileDescriptor *fd, gbFileOperations *ops, gbFileMode mode, char const *filename)
|
||||||
#define GB_FILE_READ_AT_PROC(name) b32 name(gbFileDescriptor fd, void *buffer, isize size, i64 offset, isize *bytes_read)
|
#define GB_FILE_READ_AT_PROC(name) b32 name(gbFileDescriptor fd, void *buffer, isize size, i64 offset, isize *bytes_read)
|
||||||
#define GB_FILE_WRITE_AT_PROC(name) b32 name(gbFileDescriptor fd, void const *buffer, isize size, i64 offset, isize *bytes_written)
|
#define GB_FILE_WRITE_AT_PROC(name) b32 name(gbFileDescriptor fd, void const *buffer, isize size, i64 offset, isize *bytes_written)
|
||||||
#define GB_FILE_SEEK_PROC(name) b32 name(gbFileDescriptor fd, i64 offset, gbSeekWhenceType whence, i64 *new_offset)
|
#define GB_FILE_SEEK_PROC(name) b32 name(gbFileDescriptor fd, i64 offset, gbSeekWhenceType whence, i64 *new_offset)
|
||||||
@@ -1958,11 +1958,11 @@ extern gbFileOperations const gbDefaultFileOperations;
|
|||||||
typedef u64 gbFileTime;
|
typedef u64 gbFileTime;
|
||||||
|
|
||||||
typedef struct gbFile {
|
typedef struct gbFile {
|
||||||
gbFileOperations const *ops;
|
gbFileOperations ops;
|
||||||
gbFileDescriptor fd;
|
gbFileDescriptor fd;
|
||||||
char const * filename;
|
char const * filename;
|
||||||
gbFileTime last_write_time;
|
gbFileTime last_write_time;
|
||||||
// gbDirInfo * dir_info; // TODO(bill): Get directory info
|
// gbDirInfo * dir_info; // TODO(bill): Get directory info
|
||||||
} gbFile;
|
} gbFile;
|
||||||
|
|
||||||
// TODO(bill): gbAsyncFile
|
// TODO(bill): gbAsyncFile
|
||||||
@@ -1980,7 +1980,7 @@ GB_DEF gbFile *const gb_file_get_standard(gbFileStandardType std);
|
|||||||
GB_DEF gbFileError gb_file_create (gbFile *file, char const *filename);
|
GB_DEF gbFileError gb_file_create (gbFile *file, char const *filename);
|
||||||
GB_DEF gbFileError gb_file_open (gbFile *file, char const *filename);
|
GB_DEF gbFileError gb_file_open (gbFile *file, char const *filename);
|
||||||
GB_DEF gbFileError gb_file_open_mode (gbFile *file, gbFileMode mode, char const *filename);
|
GB_DEF gbFileError gb_file_open_mode (gbFile *file, gbFileMode mode, char const *filename);
|
||||||
GB_DEF gbFileError gb_file_new (gbFile *file, gbFileDescriptor fd, gbFileOperations const *ops, char const *filename);
|
GB_DEF gbFileError gb_file_new (gbFile *file, gbFileDescriptor fd, gbFileOperations ops, char const *filename);
|
||||||
GB_DEF b32 gb_file_read_at_check (gbFile *file, void *buffer, isize size, i64 offset, isize *bytes_read);
|
GB_DEF b32 gb_file_read_at_check (gbFile *file, void *buffer, isize size, i64 offset, isize *bytes_read);
|
||||||
GB_DEF b32 gb_file_write_at_check(gbFile *file, void const *buffer, isize size, i64 offset, isize *bytes_written);
|
GB_DEF b32 gb_file_write_at_check(gbFile *file, void const *buffer, isize size, i64 offset, isize *bytes_written);
|
||||||
GB_DEF b32 gb_file_read_at (gbFile *file, void *buffer, isize size, i64 offset);
|
GB_DEF b32 gb_file_read_at (gbFile *file, void *buffer, isize size, i64 offset);
|
||||||
@@ -7299,7 +7299,7 @@ u64 gb_murmur64_seed(void const *data_, isize len, u64 seed) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fd->p = handle;
|
fd->p = handle;
|
||||||
*ops = &gbDefaultFileOperations;
|
*ops = gbDefaultFileOperations;
|
||||||
return gbFileError_None;
|
return gbFileError_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7381,7 +7381,7 @@ u64 gb_murmur64_seed(void const *data_, isize len, u64 seed) {
|
|||||||
return gbFileError_Invalid;
|
return gbFileError_Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
*ops = &gbDefaultFileOperations;
|
*ops = gbDefaultFileOperations;
|
||||||
return gbFileError_None;
|
return gbFileError_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7389,7 +7389,7 @@ u64 gb_murmur64_seed(void const *data_, isize len, u64 seed) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
gbFileError gb_file_new(gbFile *f, gbFileDescriptor fd, gbFileOperations const *ops, char const *filename) {
|
gbFileError gb_file_new(gbFile *f, gbFileDescriptor fd, gbFileOperations ops, char const *filename) {
|
||||||
gbFileError err = gbFileError_None;
|
gbFileError err = gbFileError_None;
|
||||||
|
|
||||||
f->ops = ops;
|
f->ops = ops;
|
||||||
@@ -7428,20 +7428,20 @@ gbFileError gb_file_close(gbFile *f) {
|
|||||||
return gbFileError_Invalid;
|
return gbFileError_Invalid;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!f->ops) f->ops = &gbDefaultFileOperations;
|
if (!f->ops.read_at) f->ops = gbDefaultFileOperations;
|
||||||
f->ops->close(f->fd);
|
f->ops.close(f->fd);
|
||||||
|
|
||||||
return gbFileError_None;
|
return gbFileError_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_inline b32 gb_file_read_at_check(gbFile *f, void *buffer, isize size, i64 offset, isize *bytes_read) {
|
gb_inline b32 gb_file_read_at_check(gbFile *f, void *buffer, isize size, i64 offset, isize *bytes_read) {
|
||||||
if (!f->ops) f->ops = &gbDefaultFileOperations;
|
if (!f->ops.read_at) f->ops = gbDefaultFileOperations;
|
||||||
return f->ops->read_at(f->fd, buffer, size, offset, bytes_read);
|
return f->ops.read_at(f->fd, buffer, size, offset, bytes_read);
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_inline b32 gb_file_write_at_check(gbFile *f, void const *buffer, isize size, i64 offset, isize *bytes_written) {
|
gb_inline b32 gb_file_write_at_check(gbFile *f, void const *buffer, isize size, i64 offset, isize *bytes_written) {
|
||||||
if (!f->ops) f->ops = &gbDefaultFileOperations;
|
if (!f->ops.read_at) f->ops = gbDefaultFileOperations;
|
||||||
return f->ops->write_at(f->fd, buffer, size, offset, bytes_written);
|
return f->ops.write_at(f->fd, buffer, size, offset, bytes_written);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -7455,30 +7455,30 @@ gb_inline b32 gb_file_write_at(gbFile *f, void const *buffer, isize size, i64 of
|
|||||||
|
|
||||||
gb_inline i64 gb_file_seek(gbFile *f, i64 offset) {
|
gb_inline i64 gb_file_seek(gbFile *f, i64 offset) {
|
||||||
i64 new_offset = 0;
|
i64 new_offset = 0;
|
||||||
if (!f->ops) f->ops = &gbDefaultFileOperations;
|
if (!f->ops.read_at) f->ops = gbDefaultFileOperations;
|
||||||
f->ops->seek(f->fd, offset, gbSeekWhence_Begin, &new_offset);
|
f->ops.seek(f->fd, offset, gbSeekWhence_Begin, &new_offset);
|
||||||
return new_offset;
|
return new_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_inline i64 gb_file_seek_to_end(gbFile *f) {
|
gb_inline i64 gb_file_seek_to_end(gbFile *f) {
|
||||||
i64 new_offset = 0;
|
i64 new_offset = 0;
|
||||||
if (!f->ops) f->ops = &gbDefaultFileOperations;
|
if (!f->ops.read_at) f->ops = gbDefaultFileOperations;
|
||||||
f->ops->seek(f->fd, 0, gbSeekWhence_End, &new_offset);
|
f->ops.seek(f->fd, 0, gbSeekWhence_End, &new_offset);
|
||||||
return new_offset;
|
return new_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE(bill): Skips a certain amount of bytes
|
// NOTE(bill): Skips a certain amount of bytes
|
||||||
gb_inline i64 gb_file_skip(gbFile *f, i64 bytes) {
|
gb_inline i64 gb_file_skip(gbFile *f, i64 bytes) {
|
||||||
i64 new_offset = 0;
|
i64 new_offset = 0;
|
||||||
if (!f->ops) f->ops = &gbDefaultFileOperations;
|
if (!f->ops.read_at) f->ops = gbDefaultFileOperations;
|
||||||
f->ops->seek(f->fd, bytes, gbSeekWhence_Current, &new_offset);
|
f->ops.seek(f->fd, bytes, gbSeekWhence_Current, &new_offset);
|
||||||
return new_offset;
|
return new_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_inline i64 gb_file_tell(gbFile *f) {
|
gb_inline i64 gb_file_tell(gbFile *f) {
|
||||||
i64 new_offset = 0;
|
i64 new_offset = 0;
|
||||||
if (!f->ops) f->ops = &gbDefaultFileOperations;
|
if (!f->ops.read_at) f->ops = gbDefaultFileOperations;
|
||||||
f->ops->seek(f->fd, 0, gbSeekWhence_Current, &new_offset);
|
f->ops.seek(f->fd, 0, gbSeekWhence_Current, &new_offset);
|
||||||
return new_offset;
|
return new_offset;
|
||||||
}
|
}
|
||||||
gb_inline b32 gb_file_read (gbFile *f, void *buffer, isize size) { return gb_file_read_at(f, buffer, size, gb_file_tell(f)); }
|
gb_inline b32 gb_file_read (gbFile *f, void *buffer, isize size) { return gb_file_read_at(f, buffer, size, gb_file_tell(f)); }
|
||||||
@@ -7516,7 +7516,7 @@ gb_global gbFile gb__std_files[gbFileStandard_Count] = {{0}};
|
|||||||
|
|
||||||
gb_inline gbFile *const gb_file_get_standard(gbFileStandardType std) {
|
gb_inline gbFile *const gb_file_get_standard(gbFileStandardType std) {
|
||||||
if (!gb__std_file_set) {
|
if (!gb__std_file_set) {
|
||||||
#define GB__SET_STD_FILE(type, v) gb__std_files[type].fd.p = v; gb__std_files[type].ops = &gbDefaultFileOperations
|
#define GB__SET_STD_FILE(type, v) gb__std_files[type].fd.p = v; gb__std_files[type].ops = gbDefaultFileOperations
|
||||||
GB__SET_STD_FILE(gbFileStandard_Input, GetStdHandle(STD_INPUT_HANDLE));
|
GB__SET_STD_FILE(gbFileStandard_Input, GetStdHandle(STD_INPUT_HANDLE));
|
||||||
GB__SET_STD_FILE(gbFileStandard_Output, GetStdHandle(STD_OUTPUT_HANDLE));
|
GB__SET_STD_FILE(gbFileStandard_Output, GetStdHandle(STD_OUTPUT_HANDLE));
|
||||||
GB__SET_STD_FILE(gbFileStandard_Error, GetStdHandle(STD_ERROR_HANDLE));
|
GB__SET_STD_FILE(gbFileStandard_Error, GetStdHandle(STD_ERROR_HANDLE));
|
||||||
@@ -7555,7 +7555,7 @@ b32 gb_file_exists(char const *name) {
|
|||||||
|
|
||||||
gb_inline gbFile *const gb_file_get_standard(gbFileStandardType std) {
|
gb_inline gbFile *const gb_file_get_standard(gbFileStandardType std) {
|
||||||
if (!gb__std_file_set) {
|
if (!gb__std_file_set) {
|
||||||
#define GB__SET_STD_FILE(type, v) gb__std_files[type].fd.i = v; gb__std_files[type].ops = &gbDefaultFileOperations
|
#define GB__SET_STD_FILE(type, v) gb__std_files[type].fd.i = v; gb__std_files[type].ops = gbDefaultFileOperations
|
||||||
GB__SET_STD_FILE(gbFileStandard_Input, 0);
|
GB__SET_STD_FILE(gbFileStandard_Input, 0);
|
||||||
GB__SET_STD_FILE(gbFileStandard_Output, 1);
|
GB__SET_STD_FILE(gbFileStandard_Output, 1);
|
||||||
GB__SET_STD_FILE(gbFileStandard_Error, 2);
|
GB__SET_STD_FILE(gbFileStandard_Error, 2);
|
||||||
|
|||||||
+10
-10
@@ -115,17 +115,17 @@ GB_COMPARE_PROC(string_cmp_proc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool operator ==(String a, String b) { return are_strings_equal(a, b) != 0; }
|
gb_inline bool operator ==(String a, String b) { return are_strings_equal(a, b) != 0; }
|
||||||
bool operator !=(String a, String b) { return !operator==(a, b); }
|
gb_inline bool operator !=(String a, String b) { return !operator==(a, b); }
|
||||||
bool operator < (String a, String b) { return string_compare(a, b) < 0; }
|
gb_inline bool operator < (String a, String b) { return string_compare(a, b) < 0; }
|
||||||
bool operator > (String a, String b) { return string_compare(a, b) > 0; }
|
gb_inline bool operator > (String a, String b) { return string_compare(a, b) > 0; }
|
||||||
bool operator <=(String a, String b) { return string_compare(a, b) <= 0; }
|
gb_inline bool operator <=(String a, String b) { return string_compare(a, b) <= 0; }
|
||||||
bool operator >=(String a, String b) { return string_compare(a, b) >= 0; }
|
gb_inline bool operator >=(String a, String b) { return string_compare(a, b) >= 0; }
|
||||||
|
|
||||||
template <size_t N> bool operator ==(String a, char const (&b)[N]) { return a == make_string(b); }
|
template <size_t N> gb_inline bool operator ==(String a, char const (&b)[N]) { return a == make_string(cast(u8 *)b, N-1); }
|
||||||
template <size_t N> bool operator !=(String a, char const (&b)[N]) { return a != make_string(b); }
|
template <size_t N> gb_inline bool operator !=(String a, char const (&b)[N]) { return a != make_string(cast(u8 *)b, N-1); }
|
||||||
template <size_t N> bool operator ==(char const (&a)[N], String b) { return make_string(a) == b; }
|
template <size_t N> gb_inline bool operator ==(char const (&a)[N], String b) { return make_string(cast(u8 *)a, N-1) == b; }
|
||||||
template <size_t N> bool operator !=(char const (&a)[N], String b) { return make_string(a) != b; }
|
template <size_t N> gb_inline bool operator !=(char const (&a)[N], String b) { return make_string(cast(u8 *)a, N-1) != b; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user