This commit is contained in:
Ginger Bill
2017-02-24 19:48:18 +00:00
parent a982c51c30
commit 9b2f5c359a
5 changed files with 45 additions and 133 deletions
+12 -100
View File
@@ -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
} }
*/
} }
+4 -4
View File
@@ -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;
+6 -6
View File
@@ -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));
@@ -6555,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);
@@ -6574,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);
@@ -6616,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);
+4 -4
View File
@@ -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, ">");
} }
+19 -19
View File
@@ -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, " {");