Change entity collection strategy

This commit is contained in:
Ginger Bill
2016-12-03 00:16:51 +00:00
parent 4bb45700a5
commit 0b87313f08
13 changed files with 368 additions and 325 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
#import "fmt.odin";
#import "game.odin";
main :: proc() {
fmt.println("Hellope");
game.run();
}
+161 -162
View File
@@ -43,7 +43,7 @@ printf :: proc(fmt: string, args: ..any) -> int {
fprint_type :: proc(f: ^os.File, info: ^Type_Info) {
data: [PRINT_BUF_SIZE]byte;
buf := data[:0];
print_type_to_buffer(^buf, info);
bprint_type(^buf, info);
os.write(f, buf);
}
@@ -59,7 +59,7 @@ print_byte_buffer :: proc(buf: ^[]byte, b: []byte) {
}
}
print_string_to_buffer :: proc(buf: ^[]byte, s: string) {
bprint_string :: proc(buf: ^[]byte, s: string) {
print_byte_buffer(buf, s as []byte);
}
@@ -71,30 +71,30 @@ byte_reverse :: proc(b: []byte) {
}
}
print_rune_to_buffer :: proc(buf: ^[]byte, r: rune) {
bprint_rune :: proc(buf: ^[]byte, r: rune) {
b, n := utf8.encode_rune(r);
print_string_to_buffer(buf, b[:n] as string);
bprint_string(buf, b[:n] as string);
}
print_space_to_buffer :: proc(buf: ^[]byte) { print_rune_to_buffer(buf, ' '); }
print_nl_to_buffer :: proc(buf: ^[]byte) { print_rune_to_buffer(buf, '\n'); }
bprint_space :: proc(buf: ^[]byte) { bprint_rune(buf, ' '); }
bprint_nl :: proc(buf: ^[]byte) { bprint_rune(buf, '\n'); }
__NUM_TO_CHAR_TABLE := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@$";
print_bool_to_buffer :: proc(buffer: ^[]byte, b : bool) {
if b { print_string_to_buffer(buffer, "true"); }
else { print_string_to_buffer(buffer, "false"); }
bprint_bool :: proc(buffer: ^[]byte, b : bool) {
if b { bprint_string(buffer, "true"); }
else { bprint_string(buffer, "false"); }
}
print_pointer_to_buffer :: proc(buffer: ^[]byte, p: rawptr) #inline {
print_string_to_buffer(buffer, "0x");
print_u64_to_buffer(buffer, p as uint as u64);
bprint_pointer :: proc(buffer: ^[]byte, p: rawptr) #inline {
bprint_string(buffer, "0x");
bprint_u64(buffer, p as uint as u64);
}
print_f16_to_buffer :: proc(buffer: ^[]byte, f: f32) #inline { print__f64(buffer, f as f64, 4); }
print_f32_to_buffer :: proc(buffer: ^[]byte, f: f32) #inline { print__f64(buffer, f as f64, 7); }
print_f64_to_buffer :: proc(buffer: ^[]byte, f: f64) #inline { print__f64(buffer, f as f64, 16); }
print_u64_to_buffer :: proc(buffer: ^[]byte, value: u64) {
bprint_f16 :: proc(buffer: ^[]byte, f: f32) #inline { print__f64(buffer, f as f64, 4); }
bprint_f32 :: proc(buffer: ^[]byte, f: f32) #inline { print__f64(buffer, f as f64, 7); }
bprint_f64 :: proc(buffer: ^[]byte, f: f64) #inline { print__f64(buffer, f as f64, 16); }
bprint_u64 :: proc(buffer: ^[]byte, value: u64) {
i := value;
buf: [20]byte;
len := 0;
@@ -108,33 +108,32 @@ print_u64_to_buffer :: proc(buffer: ^[]byte, value: u64) {
i /= 10;
}
byte_reverse(buf[:len]);
print_string_to_buffer(buffer, buf[:len] as string);
bprint_string(buffer, buf[:len] as string);
}
print_i64_to_buffer :: proc(buffer: ^[]byte, value: i64) {
bprint_i64 :: proc(buffer: ^[]byte, value: i64) {
// TODO(bill): Cleanup printing
i := value;
neg := i < 0;
if neg {
if i < 0 {
i = -i;
print_rune_to_buffer(buffer, '-');
bprint_rune(buffer, '-');
}
print_u64_to_buffer(buffer, i as u64);
bprint_u64(buffer, i as u64);
}
print_u128_to_buffer :: proc(buffer: ^[]byte, value: u128) {
bprint_u128 :: proc(buffer: ^[]byte, value: u128) {
a := value transmute [2]u64;
if a[1] != 0 {
print_u64_to_buffer(buffer, a[1]);
bprint_u64(buffer, a[1]);
}
print_u64_to_buffer(buffer, a[0]);
bprint_u64(buffer, a[0]);
}
print_i128_to_buffer :: proc(buffer: ^[]byte, value: i128) {
bprint_i128 :: proc(buffer: ^[]byte, value: i128) {
i := value;
neg := i < 0;
if neg {
if i < 0 {
i = -i;
print_rune_to_buffer(buffer, '-');
bprint_rune(buffer, '-');
}
print_u128_to_buffer(buffer, i as u128);
bprint_u128(buffer, i as u128);
}
@@ -142,30 +141,30 @@ print_i128_to_buffer :: proc(buffer: ^[]byte, value: i128) {
print__f64 :: proc(buffer: ^[]byte, value: f64, decimal_places: int) {
f := value;
if f == 0 {
print_rune_to_buffer(buffer, '0');
bprint_rune(buffer, '0');
return;
}
if f < 0 {
print_rune_to_buffer(buffer, '-');
bprint_rune(buffer, '-');
f = -f;
}
i := f as u64;
print_u64_to_buffer(buffer, i);
bprint_u64(buffer, i);
f -= i as f64;
print_rune_to_buffer(buffer, '.');
bprint_rune(buffer, '.');
mult: f64 = 10.0;
for ; decimal_places >= 0; decimal_places-- {
i = (f * mult) as u64;
print_u64_to_buffer(buffer, i as u64);
bprint_u64(buffer, i as u64);
f -= i as f64 / mult;
mult *= 10;
}
}
print_type_to_buffer :: proc(buf: ^[]byte, ti: ^Type_Info) {
bprint_type :: proc(buf: ^[]byte, ti: ^Type_Info) {
if ti == nil {
return;
}
@@ -173,127 +172,127 @@ print_type_to_buffer :: proc(buf: ^[]byte, ti: ^Type_Info) {
using Type_Info;
match type info : ti {
case Named:
print_string_to_buffer(buf, info.name);
bprint_string(buf, info.name);
case Integer:
match {
case ti == type_info(int):
print_string_to_buffer(buf, "int");
bprint_string(buf, "int");
case ti == type_info(uint):
print_string_to_buffer(buf, "uint");
bprint_string(buf, "uint");
default:
if info.signed {
print_string_to_buffer(buf, "i");
bprint_string(buf, "i");
} else {
print_string_to_buffer(buf, "u");
bprint_string(buf, "u");
}
print_u64_to_buffer(buf, 8*info.size as u64);
bprint_u64(buf, 8*info.size as u64);
}
case Float:
match info.size {
case 4: print_string_to_buffer(buf, "f32");
case 8: print_string_to_buffer(buf, "f64");
case 4: bprint_string(buf, "f32");
case 8: bprint_string(buf, "f64");
}
case String: print_string_to_buffer(buf, "string");
case Boolean: print_string_to_buffer(buf, "bool");
case String: bprint_string(buf, "string");
case Boolean: bprint_string(buf, "bool");
case Pointer:
if info.elem == nil {
print_string_to_buffer(buf, "rawptr");
bprint_string(buf, "rawptr");
} else {
print_string_to_buffer(buf, "^");
print_type_to_buffer(buf, info.elem);
bprint_string(buf, "^");
bprint_type(buf, info.elem);
}
case Maybe:
print_string_to_buffer(buf, "?");
print_type_to_buffer(buf, info.elem);
bprint_string(buf, "?");
bprint_type(buf, info.elem);
case Procedure:
print_string_to_buffer(buf, "proc");
bprint_string(buf, "proc");
if info.params == nil {
print_string_to_buffer(buf, "()");
bprint_string(buf, "()");
} else {
count := (info.params as ^Tuple).fields.count;
if count == 1 { print_string_to_buffer(buf, "("); }
print_type_to_buffer(buf, info.params);
if count == 1 { print_string_to_buffer(buf, ")"); }
if count == 1 { bprint_string(buf, "("); }
bprint_type(buf, info.params);
if count == 1 { bprint_string(buf, ")"); }
}
if info.results != nil {
print_string_to_buffer(buf, " -> ");
print_type_to_buffer(buf, info.results);
bprint_string(buf, " -> ");
bprint_type(buf, info.results);
}
case Tuple:
count := info.fields.count;
if count != 1 { print_string_to_buffer(buf, "("); }
if count != 1 { bprint_string(buf, "("); }
for i := 0; i < count; i++ {
if i > 0 { print_string_to_buffer(buf, ", "); }
if i > 0 { bprint_string(buf, ", "); }
f := info.fields[i];
if f.name.count > 0 {
print_string_to_buffer(buf, f.name);
print_string_to_buffer(buf, ": ");
bprint_string(buf, f.name);
bprint_string(buf, ": ");
}
print_type_to_buffer(buf, f.type_info);
bprint_type(buf, f.type_info);
}
if count != 1 { print_string_to_buffer(buf, ")"); }
if count != 1 { bprint_string(buf, ")"); }
case Array:
print_string_to_buffer(buf, "[");
print_i64_to_buffer(buf, info.count as i64);
print_string_to_buffer(buf, "]");
print_type_to_buffer(buf, info.elem);
bprint_string(buf, "[");
bprint_i64(buf, info.count as i64);
bprint_string(buf, "]");
bprint_type(buf, info.elem);
case Slice:
print_string_to_buffer(buf, "[");
print_string_to_buffer(buf, "]");
print_type_to_buffer(buf, info.elem);
bprint_string(buf, "[");
bprint_string(buf, "]");
bprint_type(buf, info.elem);
case Vector:
print_string_to_buffer(buf, "[vector ");
print_i64_to_buffer(buf, info.count as i64);
print_string_to_buffer(buf, "]");
print_type_to_buffer(buf, info.elem);
bprint_string(buf, "[vector ");
bprint_i64(buf, info.count as i64);
bprint_string(buf, "]");
bprint_type(buf, info.elem);
case Struct:
print_string_to_buffer(buf, "struct ");
if info.packed { print_string_to_buffer(buf, "#packed "); }
if info.ordered { print_string_to_buffer(buf, "#ordered "); }
print_string_to_buffer(buf, "{");
bprint_string(buf, "struct ");
if info.packed { bprint_string(buf, "#packed "); }
if info.ordered { bprint_string(buf, "#ordered "); }
bprint_string(buf, "{");
for i := 0; i < info.fields.count; i++ {
if i > 0 {
print_string_to_buffer(buf, ", ");
bprint_string(buf, ", ");
}
print_any_to_buffer(buf, info.fields[i].name);
print_string_to_buffer(buf, ": ");
print_type_to_buffer(buf, info.fields[i].type_info);
bprint_any(buf, info.fields[i].name);
bprint_string(buf, ": ");
bprint_type(buf, info.fields[i].type_info);
}
print_string_to_buffer(buf, "}");
bprint_string(buf, "}");
case Union:
print_string_to_buffer(buf, "union {");
bprint_string(buf, "union {");
for i := 0; i < info.fields.count; i++ {
if i > 0 {
print_string_to_buffer(buf, ", ");
bprint_string(buf, ", ");
}
print_any_to_buffer(buf, info.fields[i].name);
print_string_to_buffer(buf, ": ");
print_type_to_buffer(buf, info.fields[i].type_info);
bprint_any(buf, info.fields[i].name);
bprint_string(buf, ": ");
bprint_type(buf, info.fields[i].type_info);
}
print_string_to_buffer(buf, "}");
bprint_string(buf, "}");
case Raw_Union:
print_string_to_buffer(buf, "raw_union {");
bprint_string(buf, "raw_union {");
for i := 0; i < info.fields.count; i++ {
if i > 0 {
print_string_to_buffer(buf, ", ");
bprint_string(buf, ", ");
}
print_any_to_buffer(buf, info.fields[i].name);
print_string_to_buffer(buf, ": ");
print_type_to_buffer(buf, info.fields[i].type_info);
bprint_any(buf, info.fields[i].name);
bprint_string(buf, ": ");
bprint_type(buf, info.fields[i].type_info);
}
print_string_to_buffer(buf, "}");
bprint_string(buf, "}");
case Enum:
print_string_to_buffer(buf, "enum ");
print_type_to_buffer(buf, info.base);
print_string_to_buffer(buf, "{}");
bprint_string(buf, "enum ");
bprint_type(buf, info.base);
bprint_string(buf, "{}");
}
}
@@ -305,14 +304,14 @@ make_any :: proc(type_info: ^Type_Info, data: rawptr) -> any {
return a;
}
print_any_to_buffer :: proc(buf: ^[]byte, arg: any) {
bprint_any :: proc(buf: ^[]byte, arg: any) {
if arg.type_info == nil {
print_string_to_buffer(buf, "<nil>");
bprint_string(buf, "<nil>");
return;
}
if arg.data == nil {
print_string_to_buffer(buf, "<nil>");
bprint_string(buf, "<nil>");
return;
}
@@ -322,73 +321,73 @@ print_any_to_buffer :: proc(buf: ^[]byte, arg: any) {
a := make_any(info.base, arg.data);
match type b : info.base {
case Struct:
print_string_to_buffer(buf, info.name);
print_string_to_buffer(buf, "{");
bprint_string(buf, info.name);
bprint_string(buf, "{");
for i := 0; i < b.fields.count; i++ {
f := b.fields[i];
if i > 0 {
print_string_to_buffer(buf, ", ");
bprint_string(buf, ", ");
}
print_string_to_buffer(buf, f.name);
// print_any_to_buffer(buf, f.offset);
print_string_to_buffer(buf, " = ");
bprint_string(buf, f.name);
// bprint_any(buf, f.offset);
bprint_string(buf, " = ");
data := arg.data as ^byte + f.offset;
print_any_to_buffer(buf, make_any(f.type_info, data));
bprint_any(buf, make_any(f.type_info, data));
}
print_string_to_buffer(buf, "}");
bprint_string(buf, "}");
default:
print_any_to_buffer(buf, a);
bprint_any(buf, a);
}
case Integer:
match type i : arg {
case i8: print_i64_to_buffer(buf, i as i64);
case u8: print_u64_to_buffer(buf, i as u64);
case i16: print_i64_to_buffer(buf, i as i64);
case u16: print_u64_to_buffer(buf, i as u64);
case i32: print_i64_to_buffer(buf, i as i64);
case u32: print_u64_to_buffer(buf, i as u64);
case i64: print_i64_to_buffer(buf, i as i64);
case u64: print_u64_to_buffer(buf, i as u64);
case i128: print_i128_to_buffer(buf, i);
case u128: print_u128_to_buffer(buf, i);
case i8: bprint_i64(buf, i as i64);
case u8: bprint_u64(buf, i as u64);
case i16: bprint_i64(buf, i as i64);
case u16: bprint_u64(buf, i as u64);
case i32: bprint_i64(buf, i as i64);
case u32: bprint_u64(buf, i as u64);
case i64: bprint_i64(buf, i);
case u64: bprint_u64(buf, i);
case i128: bprint_i128(buf, i);
case u128: bprint_u128(buf, i);
case int: print_u64_to_buffer(buf, i as u64);
case uint: print_u64_to_buffer(buf, i as u64);
case int: bprint_i64(buf, i as i64);
case uint: bprint_u64(buf, i as u64);
}
case Float:
match type f : arg {
// case f16: print_f64_to_buffer(buf, f as f64);
case f32: print_f32_to_buffer(buf, f);
case f64: print_f64_to_buffer(buf, f);
// case f128: print_f64_to_buffer(buf, f as f64);
// case f16: bprint_f64(buf, f as f64);
case f32: bprint_f32(buf, f);
case f64: bprint_f64(buf, f);
// case f128: bprint_f64(buf, f as f64);
}
case String:
match type s : arg {
case string: print_string_to_buffer(buf, s);
case string: bprint_string(buf, s);
}
case Boolean:
match type b : arg {
case bool: print_bool_to_buffer(buf, b);
case bool: bprint_bool(buf, b);
}
case Pointer:
match type p : arg {
case ^Type_Info: print_type_to_buffer(buf, p);
default: print_pointer_to_buffer(buf, (arg.data as ^rawptr)^);
case ^Type_Info: bprint_type(buf, p);
default: bprint_pointer(buf, (arg.data as ^rawptr)^);
}
case Maybe:
size := mem.size_of_type_info(info.elem);
data := slice_ptr(arg.data as ^byte, size+1);
if data[size] != 0 {
print_any_to_buffer(buf, make_any(info.elem, arg.data));
bprint_any(buf, make_any(info.elem, arg.data));
} else {
print_string_to_buffer(buf, "nil");
bprint_string(buf, "nil");
}
case Enum:
@@ -404,33 +403,33 @@ print_any_to_buffer :: proc(buf: ^[]byte, arg: any) {
case u32: value = i as i64;
case u64: value = i as i64;
}
print_string_to_buffer(buf, __enum_to_string(arg.type_info, value));
bprint_string(buf, __enum_to_string(arg.type_info, value));
case Array:
bprintf(buf, "[%]%{", info.count, info.elem);
defer print_string_to_buffer(buf, "}");
defer bprint_string(buf, "}");
for i := 0; i < info.count; i++ {
if i > 0 {
print_string_to_buffer(buf, ", ");
bprint_string(buf, ", ");
}
data := arg.data as ^byte + i*info.elem_size;
print_any_to_buffer(buf, make_any(info.elem, data));
bprint_any(buf, make_any(info.elem, data));
}
case Slice:
slice := arg.data as ^[]byte;
bprintf(buf, "[]%{", info.elem);
defer print_string_to_buffer(buf, "}");
defer bprint_string(buf, "}");
for i := 0; i < slice.count; i++ {
if i > 0 {
print_string_to_buffer(buf, ", ");
bprint_string(buf, ", ");
}
data := slice.data + i*info.elem_size;
print_any_to_buffer(buf, make_any(info.elem, data));
bprint_any(buf, make_any(info.elem, data));
}
case Vector:
@@ -445,7 +444,7 @@ print_any_to_buffer :: proc(buf: ^[]byte, arg: any) {
}
bprintf(buf, "[vector %]%{", info.count, info.elem);
defer print_string_to_buffer(buf, "}");
defer bprint_string(buf, "}");
if is_bool(info.elem) {
return;
@@ -453,37 +452,37 @@ print_any_to_buffer :: proc(buf: ^[]byte, arg: any) {
for i := 0; i < info.count; i++ {
if i > 0 {
print_string_to_buffer(buf, ", ");
bprint_string(buf, ", ");
}
data := arg.data as ^byte + i*info.elem_size;
print_any_to_buffer(buf, make_any(info.elem, data));
bprint_any(buf, make_any(info.elem, data));
}
case Struct:
bprintf(buf, "%{", arg.type_info);
defer print_string_to_buffer(buf, "}");
defer bprint_string(buf, "}");
for i := 0; i < info.fields.count; i++ {
if i > 0 {
print_string_to_buffer(buf, ", ");
bprint_string(buf, ", ");
}
print_string_to_buffer(buf, info.fields[i].name);
print_string_to_buffer(buf, " = ");
bprint_string(buf, info.fields[i].name);
bprint_string(buf, " = ");
data := arg.data as ^byte + info.fields[i].offset;
ti := info.fields[i].type_info;
print_any_to_buffer(buf, make_any(ti, data));
bprint_any(buf, make_any(ti, data));
}
case Union:
print_string_to_buffer(buf, "(union)");
bprint_string(buf, "(union)");
case Raw_Union:
print_string_to_buffer(buf, "(raw_union)");
bprint_string(buf, "(raw_union)");
case Procedure:
print_type_to_buffer(buf, arg.type_info);
print_string_to_buffer(buf, " @ 0x");
print_pointer_to_buffer(buf, (arg.data as ^rawptr)^);
bprint_type(buf, arg.type_info);
bprint_string(buf, " @ 0x");
bprint_pointer(buf, (arg.data as ^rawptr)^);
}
}
@@ -520,13 +519,13 @@ bprintf :: proc(buf: ^[]byte, fmt: string, args: ..any) -> int {
continue;
}
print_string_to_buffer(buf, fmt[prev:i]);
bprint_string(buf, fmt[prev:i]);
i++; // Skip %
if i < fmt.count {
next := fmt[i] as rune;
if next == '%' {
print_string_to_buffer(buf, "%");
bprint_string(buf, "%");
i++;
prev = i;
continue;
@@ -538,17 +537,17 @@ bprintf :: proc(buf: ^[]byte, fmt: string, args: ..any) -> int {
}
if 0 <= index && index < args.count {
print_any_to_buffer(buf, args[index]);
bprint_any(buf, args[index]);
implicit_index = index+1;
} else {
// TODO(bill): Error check index out bounds
print_string_to_buffer(buf, "<invalid>");
bprint_string(buf, "<invalid>");
}
prev = i;
}
print_string_to_buffer(buf, fmt[prev:]);
bprint_string(buf, fmt[prev:]);
return buf.count;
}
@@ -573,9 +572,9 @@ bprint :: proc(buf: ^[]byte, args: ..any) -> int {
arg := args[i];
is_string := arg.data != nil && is_type_string(arg.type_info);
if i > 0 && !is_string && !prev_string {
print_space_to_buffer(buf);
bprint_space(buf);
}
print_any_to_buffer(buf, arg);
bprint_any(buf, arg);
prev_string = is_string;
}
return buf.count;
@@ -586,8 +585,8 @@ bprintln :: proc(buf: ^[]byte, args: ..any) -> int {
if i > 0 {
append(buf, ' ');
}
print_any_to_buffer(buf, args[i]);
bprint_any(buf, args[i]);
}
print_nl_to_buffer(buf);
bprint_nl(buf);
return buf.count;
}
+83
View File
@@ -0,0 +1,83 @@
typedef struct BuildContext {
String ODIN_OS; // target operating system
String ODIN_ARCH; // target architecture
String ODIN_VENDOR; // compiler vendor
String ODIN_VERSION; // compiler version
String ODIN_ROOT; // Odin ROOT
i64 word_size;
i64 max_align;
String llc_flags;
String link_flags;
} BuildContext;
String odin_root_dir(void) {
String path = global_module_path;
Array(wchar_t) path_buf;
isize len, i;
gbTempArenaMemory tmp;
wchar_t *text;
if (global_module_path_set) {
return global_module_path;
}
array_init_count(&path_buf, heap_allocator(), 300);
len = 0;
for (;;) {
len = GetModuleFileNameW(NULL, &path_buf.e[0], path_buf.count);
if (len == 0) {
return make_string(NULL, 0);
}
if (len < path_buf.count) {
break;
}
array_resize(&path_buf, 2*path_buf.count + 300);
}
tmp = gb_temp_arena_memory_begin(&string_buffer_arena);
text = gb_alloc_array(string_buffer_allocator, wchar_t, len+1);
GetModuleFileNameW(NULL, text, len);
path = string16_to_string(heap_allocator(), make_string16(text, len));
for (i = path.len-1; i >= 0; i--) {
u8 c = path.text[i];
if (c == '/' || c == '\\') {
break;
}
path.len--;
}
global_module_path = path;
global_module_path_set = true;
gb_temp_arena_memory_end(tmp);
array_free(&path_buf);
return path;
}
void init_build_context(BuildContext *bc) {
bc->ODIN_OS = str_lit("windows");
bc->ODIN_ARCH = str_lit("amd64");
bc->ODIN_VENDOR = str_lit("odin");
bc->ODIN_VERSION = str_lit("0.0.3d");
bc->ODIN_ROOT = odin_root_dir();
if (str_eq(bc->ODIN_ARCH, str_lit("amd64"))) {
bc->word_size = 8;
bc->max_align = 16;
bc->llc_flags = str_lit("-march=x86-64 ");
bc->link_flags = str_lit("/machine:x64 ");
} else if (str_eq(bc->ODIN_ARCH, str_lit("x86"))) {
bc->word_size = 4;
bc->max_align = 8;
bc->llc_flags = str_lit("-march=x86 ");
bc->link_flags = str_lit("/machine:x86 ");
}
}
+55 -11
View File
@@ -535,7 +535,7 @@ void add_global_string_constant(gbAllocator a, String name, String value) {
}
void init_universal_scope(void) {
void init_universal_scope(BuildContext *bc) {
// NOTE(bill): No need to free these
gbAllocator a = heap_allocator();
universal_scope = make_scope(NULL, a);
@@ -555,11 +555,11 @@ void init_universal_scope(void) {
add_global_entity(make_entity_nil(a, str_lit("nil"), t_untyped_nil));
// TODO(bill): Set through flags in the compiler
add_global_string_constant(a, str_lit("ODIN_OS"), str_lit("windows"));
add_global_string_constant(a, str_lit("ODIN_ARCH"), str_lit("amd64"));
add_global_string_constant(a, str_lit("ODIN_VENDOR"), str_lit("odin"));
add_global_string_constant(a, str_lit("ODIN_VERSION"), str_lit(VERSION_STRING));
add_global_string_constant(a, str_lit("ODIN_ENDIAN"), str_lit("little"));
add_global_string_constant(a, str_lit("ODIN_OS"), bc->ODIN_OS);
add_global_string_constant(a, str_lit("ODIN_ARCH"), bc->ODIN_ARCH);
add_global_string_constant(a, str_lit("ODIN_VENDOR"), bc->ODIN_VENDOR);
add_global_string_constant(a, str_lit("ODIN_VERSION"), bc->ODIN_VERSION);
add_global_string_constant(a, str_lit("ODIN_ROOT"), bc->ODIN_ROOT);
// Builtin Procedures
@@ -607,12 +607,13 @@ void destroy_checker_info(CheckerInfo *i) {
}
void init_checker(Checker *c, Parser *parser, BaseTypeSizes sizes) {
void init_checker(Checker *c, Parser *parser, BuildContext *bc) {
gbAllocator a = heap_allocator();
c->parser = parser;
init_checker_info(&c->info);
c->sizes = sizes;
c->sizes.word_size = bc->word_size;
c->sizes.max_align = bc->max_align;
array_init(&c->proc_stack, a);
array_init(&c->procs, a);
@@ -698,7 +699,10 @@ void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode
if (mode == Addressing_Constant) {
if (is_type_constant_type(type)) {
GB_ASSERT(value.kind != ExactValue_Invalid);
// if (value.kind == ExactValue_Invalid) {
// TODO(bill): Is this correct?
// return;
// }
if (!(type != t_invalid || is_type_constant_type(type))) {
compiler_error("add_type_and_value - invalid type: %s", type_to_string(type));
}
@@ -1086,6 +1090,35 @@ void check_global_entities_by_kind(Checker *c, EntityKind kind) {
}
}
void check_all_global_entities(Checker *c) {
for_array(i, c->info.entities.entries) {
MapDeclInfoEntry *entry = &c->info.entities.entries.e[i];
Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
DeclInfo *d = entry->value;
if (d->scope != e->scope) {
continue;
}
add_curr_ast_file(c, d->scope->file);
if (e->kind != Entity_Procedure && str_eq(e->token.string, str_lit("main"))) {
if (e->scope->is_init) {
error(e->token, "`main` is reserved as the entry point procedure in the initial scope");
continue;
}
} else if (e->scope->is_global && str_eq(e->token.string, str_lit("main"))) {
error(e->token, "`main` is reserved as the entry point procedure in the initial scope");
continue;
}
Scope *prev_scope = c->context.scope;
c->context.scope = d->scope;
check_entity_decl(c, e, d, NULL, NULL);
}
}
void check_global_collect_entities(Checker *c, Scope *parent_scope, AstNodeArray nodes, MapScope *file_scopes) {
for_array(decl_index, nodes) {
AstNode *decl = nodes.e[decl_index];
@@ -1120,6 +1153,9 @@ void check_global_collect_entities(Checker *c, Scope *parent_scope, AstNodeArray
AstNode *name = cd->names.e[i];
AstNode *value = cd->values.e[i];
ExactValue v = {ExactValue_Invalid};
if (name->kind != AstNode_Ident) {
error_node(name, "A declaration's name but be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
}
Entity *e = make_entity_constant(c->allocator, parent_scope, name->Ident, NULL, v);
e->identifier = name;
DeclInfo *di = make_declaration_info(c->allocator, parent_scope);
@@ -1161,6 +1197,9 @@ void check_global_collect_entities(Checker *c, Scope *parent_scope, AstNodeArray
if (i < vd->values.count) {
value = vd->values.e[i];
}
if (name->kind != AstNode_Ident) {
error_node(name, "A declaration's name but be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
}
Entity *e = make_entity_variable(c->allocator, parent_scope, name->Ident, NULL);
e->identifier = name;
entities[entity_index++] = e;
@@ -1386,13 +1425,18 @@ void check_parsed_files(Checker *c) {
check_import_entities(c, &file_scopes);
#if 0
check_global_entities_by_kind(c, Entity_TypeName);
check_global_entities_by_kind(c, Entity_Constant);
init_preload_types(c);
add_implicit_value(c, ImplicitValue_context, str_lit("context"), str_lit("__context"), t_context);
check_global_entities_by_kind(c, Entity_Constant);
check_global_entities_by_kind(c, Entity_Procedure);
check_global_entities_by_kind(c, Entity_Variable);
#else
check_all_global_entities(c);
init_preload_types(c);
add_implicit_value(c, ImplicitValue_context, str_lit("context"), str_lit("__context"), t_context);
#endif
for (isize i = 1; i < ImplicitValue_Count; i++) {
// NOTE(bill): First is invalid
+8
View File
@@ -121,10 +121,12 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type, Cyc
}
}
#if 0
if (e->kind == Entity_Procedure) {
check_proc_decl(c, e, d);
return;
}
#endif
CheckerContext prev = c->context;
c->context.scope = d->scope;
c->context.decl = d;
@@ -139,6 +141,11 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type, Cyc
case Entity_TypeName:
check_type_decl(c, e, d->type_expr, named_type, cycle_checker);
break;
#if 1
case Entity_Procedure:
check_proc_decl(c, e, d);
break;
#endif
}
c->context = prev;
@@ -279,6 +286,7 @@ void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init_e
Operand operand = {0};
if (init_expr) {
// check_expr_or_type(c, &operand, init_expr);
check_expr(c, &operand, init_expr);
}
check_init_constant(c, e, &operand);
+3 -1
View File
@@ -1060,7 +1060,9 @@ void check_identifier(Checker *c, Operand *o, AstNode *n, Type *named_type, Cycl
return;
}
o->value = e->Constant.value;
GB_ASSERT(o->value.kind != ExactValue_Invalid);
if (o->value.kind == ExactValue_Invalid) {
return;
}
o->mode = Addressing_Constant;
break;
-49
View File
@@ -13,55 +13,6 @@ gb_global String global_module_path = {0};
gb_global bool global_module_path_set = false;
String get_module_dir() {
String path = global_module_path;
Array(wchar_t) path_buf;
isize len, i;
gbTempArenaMemory tmp;
wchar_t *text;
if (global_module_path_set) {
return global_module_path;
}
array_init_count(&path_buf, heap_allocator(), 300);
len = 0;
for (;;) {
len = GetModuleFileNameW(NULL, &path_buf.e[0], path_buf.count);
if (len == 0) {
return make_string(NULL, 0);
}
if (len < path_buf.count) {
break;
}
array_resize(&path_buf, 2*path_buf.count + 300);
}
tmp = gb_temp_arena_memory_begin(&string_buffer_arena);
text = gb_alloc_array(string_buffer_allocator, wchar_t, len+1);
GetModuleFileNameW(NULL, text, len);
path = string16_to_string(heap_allocator(), make_string16(text, len));
for (i = path.len-1; i >= 0; i--) {
u8 c = path.text[i];
if (c == '/' || c == '\\') {
break;
}
path.len--;
}
global_module_path = path;
global_module_path_set = true;
gb_temp_arena_memory_end(tmp);
array_free(&path_buf);
return path;
}
String path_to_fullpath(gbAllocator a, String s) {
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&string_buffer_arena);
String16 string16 = string_to_string16(string_buffer_allocator, s);
+1
View File
@@ -306,6 +306,7 @@ ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, ExactValue y)
case Token_Shr: c = a >> b; break;
default: goto error;
}
return make_exact_value_integer(c);
} break;
+10 -43
View File
@@ -1,11 +1,11 @@
#if defined(__cplusplus)
extern "C" {
#endif
#define VERSION_STRING "v0.0.3d"
#include "common.c"
#include "timings.c"
#include "unicode.c"
#include "build.c"
#include "tokenizer.c"
#include "parser.c"
// #include "printer.c"
@@ -59,39 +59,6 @@ i32 win32_exec_command_line_app(char *name, char *fmt, ...) {
return exit_code;
}
typedef enum ArchKind {
ArchKind_x64,
ArchKind_x86,
} ArchKind;
typedef struct ArchData {
BaseTypeSizes sizes;
String llc_flags;
String link_flags;
} ArchData;
ArchData make_arch_data(ArchKind kind) {
ArchData data = {0};
switch (kind) {
case ArchKind_x64:
default:
data.sizes.word_size = 8;
data.sizes.max_align = 16;
data.llc_flags = str_lit("-march=x86-64 ");
data.link_flags = str_lit("/machine:x64 ");
break;
case ArchKind_x86:
data.sizes.word_size = 4;
data.sizes.max_align = 8;
data.llc_flags = str_lit("-march=x86 ");
data.link_flags = str_lit("/machine:x86 ");
break;
}
return data;
}
void usage(char *argv0) {
gb_printf_err("%s is a tool for managing Odin source code\n", argv0);
@@ -118,9 +85,10 @@ int main(int argc, char **argv) {
init_string_buffer_memory();
init_global_error_collector();
String module_dir = get_module_dir();
BuildContext build_context = {0};
init_build_context(&build_context);
init_universal_scope();
init_universal_scope(&build_context);
char *init_filename = NULL;
bool run_output = false;
@@ -131,7 +99,7 @@ int main(int argc, char **argv) {
} else if (str_eq(arg1, str_lit("build"))) {
init_filename = argv[2];
} else if (str_eq(arg1, str_lit("version"))) {
gb_printf("%s version %s", argv[0], VERSION_STRING);
gb_printf("%s version %.*s", argv[0], LIT(build_context.ODIN_VERSION));
return 0;
} else {
usage(argv[0]);
@@ -157,9 +125,8 @@ int main(int argc, char **argv) {
timings_start_section(&timings, str_lit("type check"));
Checker checker = {0};
ArchData arch_data = make_arch_data(ArchKind_x64);
init_checker(&checker, &parser, arch_data.sizes);
init_checker(&checker, &parser, &build_context);
// defer (destroy_checker(&checker));
check_parsed_files(&checker);
@@ -206,7 +173,7 @@ int main(int argc, char **argv) {
// "-dce "
// "-S "
"",
LIT(module_dir),
LIT(build_context.ODIN_ROOT),
output_name, LIT(output));
if (exit_code != 0) {
return exit_code;
@@ -220,10 +187,10 @@ int main(int argc, char **argv) {
"%.*s "
// "-debug-pass=Arguments "
"",
LIT(module_dir),
LIT(build_context.ODIN_ROOT),
LIT(output),
optimization_level,
LIT(arch_data.llc_flags));
LIT(build_context.llc_flags));
if (exit_code != 0) {
return exit_code;
}
@@ -247,7 +214,7 @@ int main(int argc, char **argv) {
" %.*s "
"",
LIT(output), LIT(output),
lib_str, LIT(arch_data.link_flags));
lib_str, LIT(build_context.link_flags));
if (exit_code != 0) {
return exit_code;
}
+32 -48
View File
@@ -1169,11 +1169,13 @@ bool expect_semicolon_after_stmt(AstFile *f, AstNode *s) {
// return true;
// }
// switch (f->curr_token.kind) {
// case Token_EOF:
// case Token_CloseBrace:
// return true;
// }
if (f->curr_token.pos.line == f->prev_token.pos.line) {
switch (f->curr_token.kind) {
case Token_EOF:
case Token_CloseBrace:
return true;
}
}
if (s != NULL) {
syntax_error(f->prev_token, "Expected `;` after %.*s, got `%.*s`",
@@ -1194,18 +1196,18 @@ AstNode * parse_body(AstFile *f);
AstNode *parse_identifier(AstFile *f) {
Token token = f->curr_token;
if (token.kind == Token_Identifier) {
if (token.kind == Token_Ident) {
next_token(f);
} else {
token.string = str_lit("_");
expect_token(f, Token_Identifier);
expect_token(f, Token_Ident);
}
return make_ident(f, token);
}
AstNode *parse_tag_expr(AstFile *f, AstNode *expression) {
Token token = expect_token(f, Token_Hash);
Token name = expect_token(f, Token_Identifier);
Token name = expect_token(f, Token_Ident);
return make_tag_expr(f, token, name, expression);
}
@@ -1401,7 +1403,7 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name, String *link_n
AstNode *parse_operand(AstFile *f, bool lhs) {
AstNode *operand = NULL; // Operand
switch (f->curr_token.kind) {
case Token_Identifier:
case Token_Ident:
operand = parse_identifier(f);
if (!lhs) {
// TODO(bill): Handle?
@@ -1456,7 +1458,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
case Token_Hash: {
Token token = expect_token(f, Token_Hash);
Token name = expect_token(f, Token_Identifier);
Token name = expect_token(f, Token_Ident);
if (str_eq(name.string, str_lit("file"))) {
Token token = name;
token.kind = Token_String;
@@ -1584,21 +1586,15 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) {
bool loop = true;
while (loop) {
switch (f->curr_token.kind) {
case Token_OpenParen: {
if (lhs) {
// TODO(bill): Handle this shit! Is this even allowed in this language?!
}
case Token_OpenParen:
operand = parse_call_expr(f, operand);
} break;
break;
case Token_Period: {
Token token = f->curr_token;
next_token(f);
if (lhs) {
// TODO(bill): handle this
}
switch (f->curr_token.kind) {
case Token_Identifier:
case Token_Ident:
operand = make_selector_expr(f, token, operand, parse_identifier(f));
break;
default: {
@@ -1664,20 +1660,13 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) {
operand = make_demaybe_expr(f, operand, expect_token(f, Token_Maybe));
break;
case Token_OpenBrace: {
case Token_OpenBrace:
if (!lhs && is_literal_type(operand) && f->expr_level >= 0) {
if (f->curr_token.pos.line == f->prev_token.pos.line) {
// TODO(bill): This is a hack due to optional semicolons
// TODO(bill): It's probably much better to solve this by changing
// the syntax for struct literals and array literals
operand = parse_literal_value(f, operand);
} else {
loop = false;
}
operand = parse_literal_value(f, operand);
} else {
loop = false;
}
} break;
break;
default:
loop = false;
@@ -1933,14 +1922,13 @@ AstNode *parse_type(AstFile *f) {
}
Token parse_procedure_signature(AstFile *f,
AstNodeArray *params, AstNodeArray *results);
Token parse_proc_signature(AstFile *f, AstNodeArray *params, AstNodeArray *results);
AstNode *parse_proc_type(AstFile *f) {
AstNodeArray params = {0};
AstNodeArray results = {0};
Token proc_token = parse_procedure_signature(f, &params, &results);
Token proc_token = parse_proc_signature(f, &params, &results);
return make_proc_type(f, proc_token, params, results);
}
@@ -1949,7 +1937,7 @@ AstNode *parse_proc_type(AstFile *f) {
AstNodeArray parse_parameter_list(AstFile *f) {
AstNodeArray params = make_ast_node_array(f);
while (f->curr_token.kind == Token_Identifier ||
while (f->curr_token.kind == Token_Ident ||
f->curr_token.kind == Token_using) {
bool is_using = false;
if (allow_token(f, Token_using)) {
@@ -2068,7 +2056,7 @@ AstNodeArray parse_record_params(AstFile *f, isize *decl_count_, bool using_allo
AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
switch (f->curr_token.kind) {
case Token_Identifier: {
case Token_Ident: {
AstNode *e = parse_identifier(f);
while (f->curr_token.kind == Token_Period) {
Token token = f->curr_token;
@@ -2128,7 +2116,7 @@ AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
bool is_packed = false;
bool is_ordered = false;
while (allow_token(f, Token_Hash)) {
Token tag = expect_token_after(f, Token_Identifier, "`#`");
Token tag = expect_token_after(f, Token_Ident, "`#`");
if (str_eq(tag.string, str_lit("packed"))) {
if (is_packed) {
syntax_error(tag, "Duplicate struct tag `#%.*s`", LIT(tag.string));
@@ -2268,9 +2256,9 @@ AstNodeArray parse_results(AstFile *f) {
return results;
}
Token parse_procedure_signature(AstFile *f,
AstNodeArray *params,
AstNodeArray *results) {
Token parse_proc_signature(AstFile *f,
AstNodeArray *params,
AstNodeArray *results) {
Token proc_token = expect_token(f, Token_proc);
expect_token(f, Token_OpenParen);
*params = parse_parameter_list(f);
@@ -2292,11 +2280,7 @@ AstNode *parse_body(AstFile *f) {
AstNode *parse_proc_decl(AstFile *f, Token proc_token, AstNode *name) {
AstNodeArray params = {0};
AstNodeArray results = {0};
parse_procedure_signature(f, &params, &results);
AstNode *proc_type = make_proc_type(f, proc_token, params, results);
AstNode *proc_type = parse_proc_type(f);
AstNode *body = NULL;
u64 tags = 0;
@@ -2736,7 +2720,7 @@ AstNode *parse_stmt(AstFile *f) {
Token token = f->curr_token;
switch (token.kind) {
// Operands
case Token_Identifier:
case Token_Ident:
case Token_Integer:
case Token_Float:
case Token_Rune:
@@ -2827,7 +2811,7 @@ AstNode *parse_stmt(AstFile *f) {
case Token_Hash: {
AstNode *s = NULL;
Token hash_token = expect_token(f, Token_Hash);
Token name = expect_token(f, Token_Identifier);
Token name = expect_token(f, Token_Ident);
String tag = name.string;
if (str_eq(tag, str_lit("shared_global_scope"))) {
if (f->curr_proc == NULL) {
@@ -2878,10 +2862,10 @@ AstNode *parse_stmt(AstFile *f) {
switch (f->curr_token.kind) {
case Token_Period:
import_name = f->curr_token;
import_name.kind = Token_Identifier;
import_name.kind = Token_Ident;
next_token(f);
break;
case Token_Identifier:
case Token_Ident:
import_name = f->curr_token;
next_token(f);
break;
@@ -3100,7 +3084,7 @@ String get_fullpath_relative(gbAllocator a, String base_dir, String path) {
}
String get_fullpath_core(gbAllocator a, String path) {
String module_dir = get_module_dir();
String module_dir = odin_root_dir();
String res = {0};
char core[] = "core/";
+2 -2
View File
@@ -5300,7 +5300,7 @@ void ssa_gen_tree(ssaGen *s) {
{
Token token = {Token_Identifier};
Token token = {Token_Ident};
i32 id = cast(i32)entry_index;
char name_base[] = "__$enum_values";
isize name_len = gb_size_of(name_base) + 10;
@@ -5314,7 +5314,7 @@ void ssa_gen_tree(ssaGen *s) {
map_ssa_value_set(&m->members, hash_string(token.string), value_array);
}
{
Token token = {Token_Identifier};
Token token = {Token_Ident};
i32 id = cast(i32)entry_index;
char name_base[] = "__$enum_names";
isize name_len = gb_size_of(name_base) + 10;
+5 -2
View File
@@ -1001,8 +1001,11 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
default: {
if (!is_type_float(elem_type)) {
if (is_type_unsigned(elem_type)) ssa_fprintf(f, "u");
else ssa_fprintf(f, "s");
if (is_type_unsigned(elem_type)) {
ssa_fprintf(f, "u");
} else {
ssa_fprintf(f, "s");
}
}
switch (bo->op) {
+6 -5
View File
@@ -4,7 +4,7 @@
TOKEN_KIND(Token_Comment, "Comment"), \
\
TOKEN_KIND(Token__LiteralBegin, "_LiteralBegin"), \
TOKEN_KIND(Token_Identifier, "Identifier"), \
TOKEN_KIND(Token_Ident, "Identifier"), \
TOKEN_KIND(Token_Integer, "Integer"), \
TOKEN_KIND(Token_Float, "Float"), \
TOKEN_KIND(Token_Rune, "Rune"), \
@@ -157,10 +157,10 @@ typedef struct Token {
} Token;
Token empty_token = {Token_Invalid};
Token blank_token = {Token_Identifier, {cast(u8 *)"_", 1}};
Token blank_token = {Token_Ident, {cast(u8 *)"_", 1}};
Token make_token_ident(String s) {
Token t = {Token_Identifier, s};
Token t = {Token_Ident, s};
return t;
}
@@ -311,8 +311,9 @@ typedef struct Tokenizer {
void tokenizer_err(Tokenizer *t, char *msg, ...) {
va_list va;
isize column = t->read_curr - t->line+1;
if (column < 1)
if (column < 1) {
column = 1;
}
gb_printf_err("%.*s(%td:%td) Syntax error: ", LIT(t->fullpath), t->line_count, column);
@@ -628,7 +629,7 @@ Token tokenizer_get_token(Tokenizer *t) {
curr_rune = t->curr_rune;
if (rune_is_letter(curr_rune)) {
token.kind = Token_Identifier;
token.kind = Token_Ident;
while (rune_is_letter(t->curr_rune) || rune_is_digit(t->curr_rune)) {
advance_to_next_rune(t);
}