mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
This commit is contained in:
@@ -45,6 +45,7 @@ del *.ilk > NUL 2> NUL
|
|||||||
cl %compiler_settings% "src\main.c" ^
|
cl %compiler_settings% "src\main.c" ^
|
||||||
/link %linker_settings% -OUT:%exe_name% ^
|
/link %linker_settings% -OUT:%exe_name% ^
|
||||||
&& odin run code/demo.odin
|
&& odin run code/demo.odin
|
||||||
|
rem && odin run code/Jaze/src/main.odin
|
||||||
rem && odin build_dll code/example.odin ^
|
rem && odin build_dll code/example.odin ^
|
||||||
rem odin run code/demo.odin
|
rem odin run code/demo.odin
|
||||||
|
|
||||||
|
|||||||
+12
-100
@@ -5,107 +5,8 @@
|
|||||||
#import "mem.odin";
|
#import "mem.odin";
|
||||||
#import "opengl.odin";
|
#import "opengl.odin";
|
||||||
#import "os.odin";
|
#import "os.odin";
|
||||||
// #import "halloc.odin";
|
|
||||||
|
|
||||||
Token_Kind :: enum {
|
|
||||||
}
|
|
||||||
Token_Pos :: struct {
|
|
||||||
file: string,
|
|
||||||
line: int,
|
|
||||||
column: int,
|
|
||||||
}
|
|
||||||
Token :: struct {
|
|
||||||
kind: Token_Kind,
|
|
||||||
name: string,
|
|
||||||
using pos: Token_Pos,
|
|
||||||
}
|
|
||||||
|
|
||||||
Exact_Value :: union {
|
|
||||||
Boolean {b: bool},
|
|
||||||
String {s: string},
|
|
||||||
Integer {i: i64},
|
|
||||||
Float {f: f64},
|
|
||||||
Pointer {p: i64},
|
|
||||||
Compound{c: rawptr},
|
|
||||||
}
|
|
||||||
Overload_Kind :: enum {
|
|
||||||
UNKNOWN,
|
|
||||||
NO,
|
|
||||||
YES,
|
|
||||||
}
|
|
||||||
Scope :: struct {
|
|
||||||
parent: ^Scope,
|
|
||||||
prev, next: ^Scope,
|
|
||||||
first_child, last_child: ^Scope,
|
|
||||||
elements: map[string]^Entity,
|
|
||||||
implicit: map[^Entity]bool,
|
|
||||||
|
|
||||||
shared: [dynamic]^Scope,
|
|
||||||
imported: [dynamic]^Scope,
|
|
||||||
is_proc: bool,
|
|
||||||
is_global: bool,
|
|
||||||
is_file: bool,
|
|
||||||
is_init: bool,
|
|
||||||
has_been_imported: bool, // This is only applicable to file scopes
|
|
||||||
file: rawptr,
|
|
||||||
}
|
|
||||||
|
|
||||||
Type :: struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
Entity :: union {
|
|
||||||
// Common Fields
|
|
||||||
flags: u32,
|
|
||||||
using token: Token,
|
|
||||||
scope: ^Scope, // Parent's scope
|
|
||||||
type: ^Type,
|
|
||||||
// identifier: ^ast.Node,
|
|
||||||
|
|
||||||
using_parent: ^Entity,
|
|
||||||
// using_expr: ^ast.Node,
|
|
||||||
|
|
||||||
// Variants
|
|
||||||
Constant{value: Exact_Value},
|
|
||||||
Variable{
|
|
||||||
field_index, field_src_index: int,
|
|
||||||
is_immutable, is_thread_local: bool,
|
|
||||||
},
|
|
||||||
Type_Name{},
|
|
||||||
Procedure{
|
|
||||||
is_foreign: bool,
|
|
||||||
foreign_name: string,
|
|
||||||
foreign_library: ^Entity,
|
|
||||||
link_name: string,
|
|
||||||
tags: u64,
|
|
||||||
overload_kind: Overload_Kind,
|
|
||||||
},
|
|
||||||
Builtin{id: int},
|
|
||||||
Import_Name{
|
|
||||||
import_path: string,
|
|
||||||
import_name: string,
|
|
||||||
import_scope: ^Scope,
|
|
||||||
used: bool,
|
|
||||||
},
|
|
||||||
Library_Name{
|
|
||||||
library_path: string,
|
|
||||||
library_name: string,
|
|
||||||
used: bool,
|
|
||||||
},
|
|
||||||
Nil{},
|
|
||||||
}
|
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
e: Entity;
|
|
||||||
u := union_cast(^Type_Info.Union)type_info_base(type_info_of_val(e));
|
|
||||||
|
|
||||||
|
|
||||||
fmt.println(type_info_base(type_info(Entity)));
|
|
||||||
|
|
||||||
|
|
||||||
// e.flags = 123;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
/*
|
/*
|
||||||
Version 0.1.1
|
Version 0.1.1
|
||||||
|
|
||||||
@@ -123,7 +24,14 @@ main :: proc() {
|
|||||||
* immutable variables are "completely immutable" - rules need a full explanation
|
* immutable variables are "completely immutable" - rules need a full explanation
|
||||||
* `slice_to_bytes` - convert any slice to a slice of bytes
|
* `slice_to_bytes` - convert any slice to a slice of bytes
|
||||||
* `union_cast` allows for optional ok check
|
* `union_cast` allows for optional ok check
|
||||||
|
* Record type field `names` (struct/raw_union/enum)
|
||||||
* ?: ternary operator
|
* ?: ternary operator
|
||||||
|
* Unions with variants and common fields
|
||||||
|
* New built-in procedures
|
||||||
|
- `delete` to delete map entries `delete(m, key)`
|
||||||
|
- `clear` to clear dynamic maps and arrays `clear(map_or_array)`
|
||||||
|
- `reserve` to reserve space for the dynamic maps and arrays `reserve(map_or_array)`
|
||||||
|
* Unexported entities and fields using an underscore prefix
|
||||||
|
|
||||||
Removed:
|
Removed:
|
||||||
* Maybe/option types
|
* Maybe/option types
|
||||||
@@ -137,9 +45,14 @@ main :: proc() {
|
|||||||
* match x in y {} // For type match statements
|
* match x in y {} // For type match statements
|
||||||
* Version numbering now starts from 0.1.0 and uses the convention:
|
* Version numbering now starts from 0.1.0 and uses the convention:
|
||||||
- major.minor.patch
|
- major.minor.patch
|
||||||
|
* Core library additions to Windows specific stuff
|
||||||
|
|
||||||
Fixes:
|
Fixes:
|
||||||
* Many fmt.* fixes
|
* Many fmt.* fixes
|
||||||
|
* Overloading bug due to comparison of named types
|
||||||
|
* Overloading bug due to `#import .` collision
|
||||||
|
* disallow a `cast` from pointers of unions
|
||||||
|
* Minor bugs in generated IR code for slices
|
||||||
|
|
||||||
To come very Soon™:
|
To come very Soon™:
|
||||||
* Linux and OS X builds (unofficial ones do exist already)
|
* Linux and OS X builds (unofficial ones do exist already)
|
||||||
@@ -231,6 +144,5 @@ main :: proc() {
|
|||||||
compile_assert(size_of([vector 7]i32) == size_of([7]i32));
|
compile_assert(size_of([vector 7]i32) == size_of([7]i32));
|
||||||
// align_of([vector 7]i32) != align_of([7]i32) // this may be the case
|
// align_of([vector 7]i32) != align_of([7]i32) // this may be the case
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -89,9 +89,9 @@ Type_Info :: union {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// // NOTE(bill): only the ones that are needed (not all types)
|
// NOTE(bill): only the ones that are needed (not all types)
|
||||||
// // This will be set by the compiler
|
// This will be set by the compiler
|
||||||
__type_infos: []Type_Info;
|
__type_table: []Type_Info;
|
||||||
|
|
||||||
type_info_base :: proc(info: ^Type_Info) -> ^Type_Info {
|
type_info_base :: proc(info: ^Type_Info) -> ^Type_Info {
|
||||||
if info == nil {
|
if info == nil {
|
||||||
|
|||||||
+27
-14
@@ -206,10 +206,12 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
|
|||||||
}
|
}
|
||||||
buffer_write_byte(buf, '{');
|
buffer_write_byte(buf, '{');
|
||||||
for name, i in info.names {
|
for name, i in info.names {
|
||||||
|
if i > 0 {
|
||||||
|
buffer_write_string(buf, ", ");
|
||||||
|
}
|
||||||
buffer_write_string(buf, name);
|
buffer_write_string(buf, name);
|
||||||
buffer_write_string(buf, ": ");
|
buffer_write_string(buf, ": ");
|
||||||
buffer_write_type(buf, info.types[i]);
|
buffer_write_type(buf, info.types[i]);
|
||||||
buffer_write_byte(buf, ',');
|
|
||||||
}
|
}
|
||||||
buffer_write_byte(buf, '}');
|
buffer_write_byte(buf, '}');
|
||||||
|
|
||||||
@@ -227,7 +229,7 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
|
|||||||
total_count += 1;
|
total_count += 1;
|
||||||
}
|
}
|
||||||
for name, i in info.variant_names {
|
for name, i in info.variant_names {
|
||||||
if i > 0 || total_count > 0 {
|
if total_count > 0 || i > 0 {
|
||||||
buffer_write_string(buf, ", ");
|
buffer_write_string(buf, ", ");
|
||||||
}
|
}
|
||||||
buffer_write_string(buf, name);
|
buffer_write_string(buf, name);
|
||||||
@@ -237,13 +239,15 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
|
|||||||
variant_type := type_info_base(info.variant_types[i]);
|
variant_type := type_info_base(info.variant_types[i]);
|
||||||
variant := union_cast(^Struct)variant_type;
|
variant := union_cast(^Struct)variant_type;
|
||||||
|
|
||||||
for j in cf.names.count..<variant.names.count {
|
vc := variant.names.count-cf.names.count;
|
||||||
|
for j in 0..<vc {
|
||||||
if j > 0 {
|
if j > 0 {
|
||||||
buffer_write_byte(buf, ',');
|
buffer_write_string(buf, ", ");
|
||||||
}
|
}
|
||||||
buffer_write_string(buf, variant.names[j]);
|
index := j + cf.names.count;
|
||||||
|
buffer_write_string(buf, variant.names[index]);
|
||||||
buffer_write_string(buf, ": ");
|
buffer_write_string(buf, ": ");
|
||||||
buffer_write_type(buf, variant.types[j]);
|
buffer_write_type(buf, variant.types[index]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buffer_write_string(buf, "}");
|
buffer_write_string(buf, "}");
|
||||||
@@ -251,17 +255,26 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
|
|||||||
case Raw_Union:
|
case Raw_Union:
|
||||||
buffer_write_string(buf, "raw_union {");
|
buffer_write_string(buf, "raw_union {");
|
||||||
for name, i in info.names {
|
for name, i in info.names {
|
||||||
|
if i > 0 {
|
||||||
|
buffer_write_string(buf, ", ");
|
||||||
|
}
|
||||||
buffer_write_string(buf, name);
|
buffer_write_string(buf, name);
|
||||||
buffer_write_string(buf, ": ");
|
buffer_write_string(buf, ": ");
|
||||||
buffer_write_type(buf, info.types[i]);
|
buffer_write_type(buf, info.types[i]);
|
||||||
buffer_write_byte(buf, ',');
|
|
||||||
}
|
}
|
||||||
buffer_write_string(buf, "}");
|
buffer_write_string(buf, "}");
|
||||||
|
|
||||||
case Enum:
|
case Enum:
|
||||||
buffer_write_string(buf, "enum ");
|
buffer_write_string(buf, "enum ");
|
||||||
buffer_write_type(buf, info.base);
|
buffer_write_type(buf, info.base);
|
||||||
buffer_write_string(buf, " {}");
|
buffer_write_string(buf, " {");
|
||||||
|
for name, i in info.names {
|
||||||
|
if i > 0 {
|
||||||
|
buffer_write_string(buf, ", ");
|
||||||
|
}
|
||||||
|
buffer_write_string(buf, name);
|
||||||
|
}
|
||||||
|
buffer_write_string(buf, "}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -700,13 +713,13 @@ fmt_enum :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
|||||||
case u32: i = cast(i64)v;
|
case u32: i = cast(i64)v;
|
||||||
case u64: i = cast(i64)v;
|
case u64: i = cast(i64)v;
|
||||||
case uint: i = cast(i64)v;
|
case uint: i = cast(i64)v;
|
||||||
case f32: f = cast(f64)v;
|
case f32: f = cast(f64)v; i = transmute(i64)f;
|
||||||
case f64: f = cast(f64)v;
|
case f64: f = cast(f64)v; i = transmute(i64)f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if types.is_string(e.base) {
|
if types.is_string(e.base) {
|
||||||
for it, idx in e.values {
|
for val, idx in e.values {
|
||||||
if it.i == i {
|
if val.i == i {
|
||||||
buffer_write_string(fi.buf, e.names[idx]);
|
buffer_write_string(fi.buf, e.names[idx]);
|
||||||
ok = true;
|
ok = true;
|
||||||
break;
|
break;
|
||||||
@@ -716,8 +729,8 @@ fmt_enum :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
|||||||
buffer_write_string(fi.buf, "");
|
buffer_write_string(fi.buf, "");
|
||||||
ok = true;
|
ok = true;
|
||||||
} else {
|
} else {
|
||||||
for it, idx in e.values {
|
for val, idx in e.values {
|
||||||
if it.f == f {
|
if val.i == i {
|
||||||
buffer_write_string(fi.buf, e.names[idx]);
|
buffer_write_string(fi.buf, e.names[idx]);
|
||||||
ok = true;
|
ok = true;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
new_c_string :: proc(s: string) -> ^byte {
|
||||||
|
c := new_c_string(byte, s.count+1);
|
||||||
|
copy(c, cast([]byte)s);
|
||||||
|
c[s.count] = 0;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
to_odin_string :: proc(c: ^byte) -> string {
|
||||||
|
s: string;
|
||||||
|
s.data = c;
|
||||||
|
for (c+s.count)^ != 0 {
|
||||||
|
s.count += 1;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
+4
-4
@@ -490,8 +490,8 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node) {
|
|||||||
|
|
||||||
field_count = check_fields(c, node, st->fields, fields, field_count, str_lit("struct"));
|
field_count = check_fields(c, node, st->fields, fields, field_count, str_lit("struct"));
|
||||||
|
|
||||||
struct_type->Record.struct_is_packed = st->is_packed;
|
struct_type->Record.is_packed = st->is_packed;
|
||||||
struct_type->Record.struct_is_ordered = st->is_ordered;
|
struct_type->Record.is_ordered = st->is_ordered;
|
||||||
struct_type->Record.fields = fields;
|
struct_type->Record.fields = fields;
|
||||||
struct_type->Record.fields_in_src_order = fields;
|
struct_type->Record.fields_in_src_order = fields;
|
||||||
struct_type->Record.field_count = field_count;
|
struct_type->Record.field_count = field_count;
|
||||||
@@ -629,8 +629,8 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node) {
|
|||||||
check_open_scope(c, dummy_struct);
|
check_open_scope(c, dummy_struct);
|
||||||
Entity **fields = gb_alloc_array(c->allocator, Entity *, list_count);
|
Entity **fields = gb_alloc_array(c->allocator, Entity *, list_count);
|
||||||
isize field_count = check_fields(c, dummy_struct, list, fields, list_count, str_lit("variant"));
|
isize field_count = check_fields(c, dummy_struct, list, fields, list_count, str_lit("variant"));
|
||||||
base_type->Record.struct_is_packed = false;
|
base_type->Record.is_packed = false;
|
||||||
base_type->Record.struct_is_ordered = true;
|
base_type->Record.is_ordered = true;
|
||||||
base_type->Record.fields = fields;
|
base_type->Record.fields = fields;
|
||||||
base_type->Record.fields_in_src_order = fields;
|
base_type->Record.fields_in_src_order = fields;
|
||||||
base_type->Record.field_count = field_count;
|
base_type->Record.field_count = field_count;
|
||||||
|
|||||||
@@ -1832,7 +1832,7 @@ irValue *ir_emit_struct_ep(irProcedure *proc, irValue *s, i32 index) {
|
|||||||
GB_ASSERT(t->Record.field_count > 0);
|
GB_ASSERT(t->Record.field_count > 0);
|
||||||
GB_ASSERT(gb_is_between(index, 0, t->Record.field_count-1));
|
GB_ASSERT(gb_is_between(index, 0, t->Record.field_count-1));
|
||||||
result_type = make_type_pointer(a, t->Record.fields[index]->type);
|
result_type = make_type_pointer(a, t->Record.fields[index]->type);
|
||||||
i64 offset = t->Record.struct_offsets[index];
|
i64 offset = t->Record.offsets[index];
|
||||||
irValue *ptr = ir_emit_conv(proc, s, t_u8_ptr);
|
irValue *ptr = ir_emit_conv(proc, s, t_u8_ptr);
|
||||||
ptr = ir_emit_ptr_offset(proc, ptr, ir_make_const_int(a, offset));
|
ptr = ir_emit_ptr_offset(proc, ptr, ir_make_const_int(a, offset));
|
||||||
return ir_emit_conv(proc, ptr, result_type);
|
return ir_emit_conv(proc, ptr, result_type);
|
||||||
@@ -1895,7 +1895,7 @@ irValue *ir_emit_struct_ev(irProcedure *proc, irValue *s, i32 index) {
|
|||||||
GB_ASSERT(t->Record.field_count > 0);
|
GB_ASSERT(t->Record.field_count > 0);
|
||||||
GB_ASSERT(gb_is_between(index, 0, t->Record.field_count-1));
|
GB_ASSERT(gb_is_between(index, 0, t->Record.field_count-1));
|
||||||
Type *ptr_type = make_type_pointer(a, t->Record.fields[index]->type);
|
Type *ptr_type = make_type_pointer(a, t->Record.fields[index]->type);
|
||||||
i64 offset = t->Record.struct_offsets[index];
|
i64 offset = t->Record.offsets[index];
|
||||||
irValue *ptr = ir_address_from_load_or_generate_local(proc, s);
|
irValue *ptr = ir_address_from_load_or_generate_local(proc, s);
|
||||||
ptr = ir_emit_conv(proc, s, t_u8_ptr);
|
ptr = ir_emit_conv(proc, s, t_u8_ptr);
|
||||||
ptr = ir_emit_ptr_offset(proc, ptr, ir_make_const_int(a, offset));
|
ptr = ir_emit_ptr_offset(proc, ptr, ir_make_const_int(a, offset));
|
||||||
@@ -6353,14 +6353,12 @@ void ir_gen_tree(irGen *s) {
|
|||||||
CheckerInfo *info = proc->module->info;
|
CheckerInfo *info = proc->module->info;
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
irValue *global_type_infos = ir_find_global_variable(proc, str_lit("__type_infos"));
|
irValue *global_type_table = ir_find_global_variable(proc, str_lit("__type_table"));
|
||||||
Type *type = base_type(type_deref(ir_type(ir_global_type_info_data)));
|
Type *type = base_type(type_deref(ir_type(ir_global_type_info_data)));
|
||||||
GB_ASSERT(is_type_array(type));
|
GB_ASSERT(is_type_array(type));
|
||||||
irValue *array_data = ir_emit_array_epi(proc, ir_global_type_info_data, 0);
|
ir_fill_slice(proc, global_type_table,
|
||||||
irValue *array_count = ir_make_const_int(proc->module->allocator, type->Array.count);
|
ir_emit_array_epi(proc, ir_global_type_info_data, 0),
|
||||||
|
ir_make_const_int(proc->module->allocator, type->Array.count));
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, global_type_infos, 0), array_data);
|
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, global_type_infos, 1), array_count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -6557,8 +6555,8 @@ void ir_gen_tree(irGen *s) {
|
|||||||
{
|
{
|
||||||
irValue *size = ir_make_const_int(a, type_size_of(a, t));
|
irValue *size = ir_make_const_int(a, type_size_of(a, t));
|
||||||
irValue *align = ir_make_const_int(a, type_align_of(a, t));
|
irValue *align = ir_make_const_int(a, type_align_of(a, t));
|
||||||
irValue *packed = ir_make_const_bool(a, t->Record.struct_is_packed);
|
irValue *packed = ir_make_const_bool(a, t->Record.is_packed);
|
||||||
irValue *ordered = ir_make_const_bool(a, t->Record.struct_is_ordered);
|
irValue *ordered = ir_make_const_bool(a, t->Record.is_ordered);
|
||||||
irValue *custom_align = ir_make_const_bool(a, t->Record.custom_align);
|
irValue *custom_align = ir_make_const_bool(a, t->Record.custom_align);
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, record, 3), size);
|
ir_emit_store(proc, ir_emit_struct_ep(proc, record, 3), size);
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, record, 4), align);
|
ir_emit_store(proc, ir_emit_struct_ep(proc, record, 4), align);
|
||||||
@@ -6576,7 +6574,7 @@ void ir_gen_tree(irGen *s) {
|
|||||||
// TODO(bill): Order fields in source order not layout order
|
// TODO(bill): Order fields in source order not layout order
|
||||||
Entity *f = t->Record.fields_in_src_order[source_index];
|
Entity *f = t->Record.fields_in_src_order[source_index];
|
||||||
irValue *tip = ir_get_type_info_ptr(proc, f->type);
|
irValue *tip = ir_get_type_info_ptr(proc, f->type);
|
||||||
i64 foffset = t->Record.struct_offsets[f->Variable.field_index];
|
i64 foffset = t->Record.offsets[f->Variable.field_index];
|
||||||
GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
|
GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
|
||||||
|
|
||||||
irValue *index = ir_make_const_int(a, source_index);
|
irValue *index = ir_make_const_int(a, source_index);
|
||||||
@@ -6618,7 +6616,7 @@ void ir_gen_tree(irGen *s) {
|
|||||||
// TODO(bill): Order fields in source order not layout order
|
// TODO(bill): Order fields in source order not layout order
|
||||||
Entity *f = t->Record.fields[field_index];
|
Entity *f = t->Record.fields[field_index];
|
||||||
irValue *tip = ir_get_type_info_ptr(proc, f->type);
|
irValue *tip = ir_get_type_info_ptr(proc, f->type);
|
||||||
i64 foffset = t->Record.struct_offsets[f->Variable.field_index];
|
i64 foffset = t->Record.offsets[f->Variable.field_index];
|
||||||
GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
|
GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
|
||||||
|
|
||||||
irValue *index = ir_make_const_int(a, field_index);
|
irValue *index = ir_make_const_int(a, field_index);
|
||||||
|
|||||||
+5
-7
@@ -195,7 +195,7 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
|
|||||||
return;
|
return;
|
||||||
case Type_DynamicArray:
|
case Type_DynamicArray:
|
||||||
ir_fprintf(f, "{");
|
ir_fprintf(f, "{");
|
||||||
ir_print_type(f, m, t->Slice.elem);
|
ir_print_type(f, m, t->DynamicArray.elem);
|
||||||
ir_fprintf(f, "*, i%lld, i%lld,", word_bits, word_bits);
|
ir_fprintf(f, "*, i%lld, i%lld,", word_bits, word_bits);
|
||||||
ir_print_type(f, m, t_allocator);
|
ir_print_type(f, m, t_allocator);
|
||||||
ir_fprintf(f, "}");
|
ir_fprintf(f, "}");
|
||||||
@@ -203,7 +203,7 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
|
|||||||
case Type_Record: {
|
case Type_Record: {
|
||||||
switch (t->Record.kind) {
|
switch (t->Record.kind) {
|
||||||
case TypeRecord_Struct:
|
case TypeRecord_Struct:
|
||||||
if (t->Record.struct_is_packed) {
|
if (t->Record.is_packed) {
|
||||||
ir_fprintf(f, "<");
|
ir_fprintf(f, "<");
|
||||||
}
|
}
|
||||||
ir_fprintf(f, "{");
|
ir_fprintf(f, "{");
|
||||||
@@ -220,7 +220,7 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
|
|||||||
ir_print_type(f, m, t->Record.fields[i]->type);
|
ir_print_type(f, m, t->Record.fields[i]->type);
|
||||||
}
|
}
|
||||||
ir_fprintf(f, "}");
|
ir_fprintf(f, "}");
|
||||||
if (t->Record.struct_is_packed) {
|
if (t->Record.is_packed) {
|
||||||
ir_fprintf(f, ">");
|
ir_fprintf(f, ">");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -526,7 +526,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (type->Record.struct_is_packed) {
|
if (type->Record.is_packed) {
|
||||||
ir_fprintf(f, "<");
|
ir_fprintf(f, "<");
|
||||||
}
|
}
|
||||||
ir_fprintf(f, "{");
|
ir_fprintf(f, "{");
|
||||||
@@ -543,7 +543,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
|||||||
|
|
||||||
|
|
||||||
ir_fprintf(f, "}");
|
ir_fprintf(f, "}");
|
||||||
if (type->Record.struct_is_packed) {
|
if (type->Record.is_packed) {
|
||||||
ir_fprintf(f, ">");
|
ir_fprintf(f, ">");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -616,8 +616,6 @@ void ir_print_value(irFileBuffer *f, irModule *m, irValue *value, Type *type_hin
|
|||||||
ir_print_type(f, m, t_int);
|
ir_print_type(f, m, t_int);
|
||||||
ir_fprintf(f, " 0, i32 0), ");
|
ir_fprintf(f, " 0, i32 0), ");
|
||||||
ir_print_type(f, m, t_int);
|
ir_print_type(f, m, t_int);
|
||||||
ir_fprintf(f, " %lld, ", cs->count);
|
|
||||||
ir_print_type(f, m, t_int);
|
|
||||||
ir_fprintf(f, " %lld}", cs->count);
|
ir_fprintf(f, " %lld}", cs->count);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|||||||
+1
-1
@@ -3475,7 +3475,7 @@ AstNode *parse_stmt(AstFile *f) {
|
|||||||
syntax_error(token, "#include is not a valid import declaration kind. Use #load instead");
|
syntax_error(token, "#include is not a valid import declaration kind. Use #load instead");
|
||||||
s = ast_bad_stmt(f, token, f->curr_token);
|
s = ast_bad_stmt(f, token, f->curr_token);
|
||||||
} else {
|
} else {
|
||||||
syntax_error(token, "Unknown tag used: `%.*s`", LIT(tag));
|
syntax_error(token, "Unknown tag directive used: `%.*s`", LIT(tag));
|
||||||
s = ast_bad_stmt(f, token, f->curr_token);
|
s = ast_bad_stmt(f, token, f->curr_token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-19
@@ -88,21 +88,21 @@ typedef struct TypeRecord {
|
|||||||
|
|
||||||
// All record types
|
// All record types
|
||||||
// Theses are arrays
|
// Theses are arrays
|
||||||
// Entity_Variable - struct/raw_union
|
// Entity_Variable - struct/raw_union/union (for common fields)
|
||||||
// Entity_Constant - enum
|
// Entity_Constant - enum
|
||||||
Entity **fields;
|
Entity **fields;
|
||||||
i32 field_count; // == struct_offsets count
|
i32 field_count; // == struct_offsets count
|
||||||
|
Entity **fields_in_src_order; // Entity_Variable
|
||||||
AstNode *node;
|
AstNode *node;
|
||||||
|
|
||||||
// Entity_TypeName - union
|
// Entity_TypeName - union
|
||||||
Entity **variants;
|
Entity **variants;
|
||||||
i32 variant_count;
|
i32 variant_count;
|
||||||
|
|
||||||
i64 * struct_offsets;
|
i64 * offsets;
|
||||||
bool struct_are_offsets_set;
|
bool are_offsets_set;
|
||||||
bool struct_is_packed;
|
bool is_packed;
|
||||||
bool struct_is_ordered;
|
bool is_ordered;
|
||||||
Entity **fields_in_src_order; // Entity_Variable
|
|
||||||
|
|
||||||
i64 custom_align; // NOTE(bill): Only used in structs at the moment
|
i64 custom_align; // NOTE(bill): Only used in structs at the moment
|
||||||
Entity * names;
|
Entity * names;
|
||||||
@@ -862,8 +862,8 @@ bool are_types_identical(Type *x, Type *y) {
|
|||||||
case TypeRecord_Union:
|
case TypeRecord_Union:
|
||||||
if (x->Record.field_count == y->Record.field_count &&
|
if (x->Record.field_count == y->Record.field_count &&
|
||||||
x->Record.variant_count == y->Record.variant_count &&
|
x->Record.variant_count == y->Record.variant_count &&
|
||||||
x->Record.struct_is_packed == y->Record.struct_is_packed &&
|
x->Record.is_packed == y->Record.is_packed &&
|
||||||
x->Record.struct_is_ordered == y->Record.struct_is_ordered &&
|
x->Record.is_ordered == y->Record.is_ordered &&
|
||||||
x->Record.custom_align == y->Record.custom_align) {
|
x->Record.custom_align == y->Record.custom_align) {
|
||||||
// TODO(bill); Fix the custom alignment rule
|
// TODO(bill); Fix the custom alignment rule
|
||||||
for (isize i = 0; i < x->Record.field_count; i++) {
|
for (isize i = 0; i < x->Record.field_count; i++) {
|
||||||
@@ -1587,7 +1587,7 @@ i64 type_align_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
|
|||||||
}
|
}
|
||||||
if (t->Record.field_count > 0) {
|
if (t->Record.field_count > 0) {
|
||||||
// TODO(bill): What is this supposed to be?
|
// TODO(bill): What is this supposed to be?
|
||||||
if (t->Record.struct_is_packed) {
|
if (t->Record.is_packed) {
|
||||||
i64 max = build_context.word_size;
|
i64 max = build_context.word_size;
|
||||||
for (isize i = 0; i < t->Record.field_count; i++) {
|
for (isize i = 0; i < t->Record.field_count; i++) {
|
||||||
Type *field_type = t->Record.fields[i]->type;
|
Type *field_type = t->Record.fields[i]->type;
|
||||||
@@ -1678,15 +1678,15 @@ i64 *type_set_offsets_of(gbAllocator allocator, Entity **fields, isize field_cou
|
|||||||
bool type_set_offsets(gbAllocator allocator, Type *t) {
|
bool type_set_offsets(gbAllocator allocator, Type *t) {
|
||||||
t = base_type(t);
|
t = base_type(t);
|
||||||
if (is_type_struct(t)) {
|
if (is_type_struct(t)) {
|
||||||
if (!t->Record.struct_are_offsets_set) {
|
if (!t->Record.are_offsets_set) {
|
||||||
t->Record.struct_offsets = type_set_offsets_of(allocator, t->Record.fields, t->Record.field_count, t->Record.struct_is_packed);
|
t->Record.offsets = type_set_offsets_of(allocator, t->Record.fields, t->Record.field_count, t->Record.is_packed);
|
||||||
t->Record.struct_are_offsets_set = true;
|
t->Record.are_offsets_set = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (is_type_union(t)) {
|
} else if (is_type_union(t)) {
|
||||||
if (!t->Record.struct_are_offsets_set) {
|
if (!t->Record.are_offsets_set) {
|
||||||
t->Record.struct_offsets = type_set_offsets_of(allocator, t->Record.fields, t->Record.field_count, false);
|
t->Record.offsets = type_set_offsets_of(allocator, t->Record.fields, t->Record.field_count, false);
|
||||||
t->Record.struct_are_offsets_set = true;
|
t->Record.are_offsets_set = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (is_type_tuple(t)) {
|
} else if (is_type_tuple(t)) {
|
||||||
@@ -1812,7 +1812,7 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
|
|||||||
return FAILURE_SIZE;
|
return FAILURE_SIZE;
|
||||||
}
|
}
|
||||||
type_set_offsets(allocator, t);
|
type_set_offsets(allocator, t);
|
||||||
i64 size = t->Record.struct_offsets[count-1] + type_size_of_internal(allocator, t->Record.fields[count-1]->type, path);
|
i64 size = t->Record.offsets[count-1] + type_size_of_internal(allocator, t->Record.fields[count-1]->type, path);
|
||||||
return align_formula(size, align);
|
return align_formula(size, align);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@@ -1865,7 +1865,7 @@ i64 type_offset_of(gbAllocator allocator, Type *t, i32 index) {
|
|||||||
if (t->kind == Type_Record && t->Record.kind == TypeRecord_Struct) {
|
if (t->kind == Type_Record && t->Record.kind == TypeRecord_Struct) {
|
||||||
type_set_offsets(allocator, t);
|
type_set_offsets(allocator, t);
|
||||||
if (gb_is_between(index, 0, t->Record.field_count-1)) {
|
if (gb_is_between(index, 0, t->Record.field_count-1)) {
|
||||||
return t->Record.struct_offsets[index];
|
return t->Record.offsets[index];
|
||||||
}
|
}
|
||||||
} else if (t->kind == Type_Tuple) {
|
} else if (t->kind == Type_Tuple) {
|
||||||
type_set_offsets(allocator, t);
|
type_set_offsets(allocator, t);
|
||||||
@@ -1989,10 +1989,10 @@ gbString write_type_to_string(gbString str, Type *type) {
|
|||||||
switch (type->Record.kind) {
|
switch (type->Record.kind) {
|
||||||
case TypeRecord_Struct:
|
case TypeRecord_Struct:
|
||||||
str = gb_string_appendc(str, "struct");
|
str = gb_string_appendc(str, "struct");
|
||||||
if (type->Record.struct_is_packed) {
|
if (type->Record.is_packed) {
|
||||||
str = gb_string_appendc(str, " #packed");
|
str = gb_string_appendc(str, " #packed");
|
||||||
}
|
}
|
||||||
if (type->Record.struct_is_ordered) {
|
if (type->Record.is_ordered) {
|
||||||
str = gb_string_appendc(str, " #ordered");
|
str = gb_string_appendc(str, " #ordered");
|
||||||
}
|
}
|
||||||
str = gb_string_appendc(str, " {");
|
str = gb_string_appendc(str, " {");
|
||||||
|
|||||||
Reference in New Issue
Block a user