mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-28 10:20:05 +00:00
File Library and TypeDecl syntax change
This commit is contained in:
@@ -343,6 +343,10 @@ void init_universal_scope(void) {
|
||||
entity->Builtin.id = id;
|
||||
add_global_entity(entity);
|
||||
}
|
||||
|
||||
// Custom Runtime Types
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+19
-1
@@ -288,21 +288,25 @@ b32 is_type_named(Type *t) {
|
||||
return t->kind == Type_Named;
|
||||
}
|
||||
b32 is_type_boolean(Type *t) {
|
||||
t = get_base_type(t);
|
||||
if (t->kind == Type_Basic)
|
||||
return (t->basic.flags & BasicFlag_Boolean) != 0;
|
||||
return false;
|
||||
}
|
||||
b32 is_type_integer(Type *t) {
|
||||
t = get_base_type(t);
|
||||
if (t->kind == Type_Basic)
|
||||
return (t->basic.flags & BasicFlag_Integer) != 0;
|
||||
return false;
|
||||
}
|
||||
b32 is_type_unsigned(Type *t) {
|
||||
t = get_base_type(t);
|
||||
if (t->kind == Type_Basic)
|
||||
return (t->basic.flags & BasicFlag_Unsigned) != 0;
|
||||
return false;
|
||||
}
|
||||
b32 is_type_numeric(Type *t) {
|
||||
t = get_base_type(t);
|
||||
if (t->kind == Type_Basic)
|
||||
return (t->basic.flags & BasicFlag_Numeric) != 0;
|
||||
if (t->kind == Type_Vector)
|
||||
@@ -310,36 +314,45 @@ b32 is_type_numeric(Type *t) {
|
||||
return false;
|
||||
}
|
||||
b32 is_type_string(Type *t) {
|
||||
t = get_base_type(t);
|
||||
if (t->kind == Type_Basic)
|
||||
return (t->basic.flags & BasicFlag_String) != 0;
|
||||
return false;
|
||||
}
|
||||
b32 is_type_typed(Type *t) {
|
||||
t = get_base_type(t);
|
||||
if (t->kind == Type_Basic)
|
||||
return (t->basic.flags & BasicFlag_Untyped) == 0;
|
||||
return true;
|
||||
}
|
||||
b32 is_type_untyped(Type *t) {
|
||||
t = get_base_type(t);
|
||||
if (t->kind == Type_Basic)
|
||||
return (t->basic.flags & BasicFlag_Untyped) != 0;
|
||||
return false;
|
||||
}
|
||||
b32 is_type_ordered(Type *t) {
|
||||
t = get_base_type(t);
|
||||
if (t->kind == Type_Basic)
|
||||
return (t->basic.flags & BasicFlag_Ordered) != 0;
|
||||
if (t->kind == Type_Pointer)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
b32 is_type_constant_type(Type *t) {
|
||||
t = get_base_type(t);
|
||||
if (t->kind == Type_Basic)
|
||||
return (t->basic.flags & BasicFlag_ConstantType) != 0;
|
||||
return false;
|
||||
}
|
||||
b32 is_type_float(Type *t) {
|
||||
t = get_base_type(t);
|
||||
if (t->kind == Type_Basic)
|
||||
return (t->basic.flags & BasicFlag_Float) != 0;
|
||||
return false;
|
||||
}
|
||||
b32 is_type_pointer(Type *t) {
|
||||
t = get_base_type(t);
|
||||
if (t->kind == Type_Basic)
|
||||
return (t->basic.flags & BasicFlag_Pointer) != 0;
|
||||
return t->kind == Type_Pointer;
|
||||
@@ -361,9 +374,11 @@ b32 is_type_u8(Type *t) {
|
||||
return false;
|
||||
}
|
||||
b32 is_type_slice(Type *t) {
|
||||
t = get_base_type(t);
|
||||
return t->kind == Type_Slice;
|
||||
}
|
||||
b32 is_type_u8_slice(Type *t) {
|
||||
t = get_base_type(t);
|
||||
if (t->kind == Type_Slice)
|
||||
return is_type_u8(t->slice.elem);
|
||||
return false;
|
||||
@@ -372,6 +387,7 @@ b32 is_type_vector(Type *t) {
|
||||
return t->kind == Type_Vector;
|
||||
}
|
||||
b32 is_type_proc(Type *t) {
|
||||
t = get_base_type(t);
|
||||
return t->kind == Type_Proc;
|
||||
}
|
||||
Type *base_vector_type(Type *t) {
|
||||
@@ -548,8 +564,10 @@ i64 type_align_of(BaseTypeSizes s, gbAllocator allocator, Type *t) {
|
||||
return type_align_of(s, allocator, t->array.elem);
|
||||
case Type_Vector: {
|
||||
i64 size = type_size_of(s, allocator, t->vector.elem);
|
||||
size *= t->vector.count;
|
||||
size = next_pow2(size);
|
||||
// TODO(bill): Type_Vector type_align_of
|
||||
return gb_clamp(size, s.max_align, 2*s.max_align);
|
||||
return gb_clamp(size, s.max_align, 4*s.max_align);
|
||||
} break;
|
||||
|
||||
case Type_Structure: {
|
||||
|
||||
+13
-18
@@ -219,7 +219,11 @@ void ssa_print_exact_value(gbFile *f, ssaModule *m, ExactValue value, Type *type
|
||||
if (value.value_integer == 0) {
|
||||
ssa_fprintf(f, "null");
|
||||
} else {
|
||||
GB_PANIC("TODO(bill): Pointer constant");
|
||||
ssa_fprintf(f, "inttoptr (");
|
||||
ssa_print_type(f, m->sizes, t_int);
|
||||
ssa_fprintf(f, " %llu to ", value.value_integer);
|
||||
ssa_print_type(f, m->sizes, t_rawptr);
|
||||
ssa_fprintf(f, ")");
|
||||
}
|
||||
} else {
|
||||
ssa_fprintf(f, "%lld", value.value_integer);
|
||||
@@ -241,7 +245,11 @@ void ssa_print_exact_value(gbFile *f, ssaModule *m, ExactValue value, Type *type
|
||||
if (value.value_pointer == NULL) {
|
||||
ssa_fprintf(f, "null");
|
||||
} else {
|
||||
GB_PANIC("TODO(bill): ExactValue_Pointer");
|
||||
ssa_fprintf(f, "inttoptr (");
|
||||
ssa_print_type(f, m->sizes, t_int);
|
||||
ssa_fprintf(f, " %llu to ", cast(u64)cast(uintptr)value.value_pointer);
|
||||
ssa_print_type(f, m->sizes, t_rawptr);
|
||||
ssa_fprintf(f, ")");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -580,8 +588,7 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
|
||||
} break;
|
||||
|
||||
case ssaInstr_MemCopy: {
|
||||
ssa_fprintf(f, "call void @llvm.memmove.p0i8.p0i8.");
|
||||
ssa_print_type(f, m->sizes, t_int);
|
||||
ssa_fprintf(f, "call void @memory_move");
|
||||
ssa_fprintf(f, "(i8* ");
|
||||
ssa_print_value(f, m, instr->CopyMemory.dst, t_rawptr);
|
||||
ssa_fprintf(f, ", i8* ");
|
||||
@@ -590,11 +597,7 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
|
||||
ssa_print_type(f, m->sizes, t_int);
|
||||
ssa_fprintf(f, " ");
|
||||
ssa_print_value(f, m, instr->CopyMemory.len, t_int);
|
||||
char *vol_str = "false";
|
||||
if (instr->CopyMemory.is_volatile) {
|
||||
vol_str = "true";
|
||||
}
|
||||
ssa_fprintf(f, ", i32 %d, i1 %s)\n", instr->CopyMemory.align, vol_str);
|
||||
ssa_fprintf(f, ")\n");
|
||||
} break;
|
||||
|
||||
|
||||
@@ -671,7 +674,7 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
|
||||
|
||||
void ssa_print_proc(gbFile *f, ssaModule *m, ssaProcedure *proc) {
|
||||
if (proc->body == NULL) {
|
||||
ssa_fprintf(f, "declare ");
|
||||
ssa_fprintf(f, "\ndeclare ");
|
||||
} else {
|
||||
ssa_fprintf(f, "\ndefine ");
|
||||
}
|
||||
@@ -777,14 +780,6 @@ void ssa_print_llvm_ir(gbFile *f, ssaModule *m) {
|
||||
}
|
||||
|
||||
|
||||
ssa_fprintf(f, "declare void @llvm.memmove.p0i8.p0i8.");
|
||||
ssa_print_type(f, m->sizes, t_int);
|
||||
ssa_fprintf(f, "(i8*, i8*, ");
|
||||
ssa_print_type(f, m->sizes, t_int);
|
||||
ssa_fprintf(f, ", i32, i1) argmemonly nounwind \n\n");
|
||||
|
||||
|
||||
|
||||
gb_for_array(member_index, m->members.entries) {
|
||||
auto *entry = &m->members.entries[member_index];
|
||||
ssaValue *v = entry->value;
|
||||
|
||||
+3
-2
@@ -811,9 +811,10 @@ void ssa_emit_defer_stmts(ssaProcedure *proc, ssaDeferKind kind, ssaBlock *block
|
||||
while (i --> 0) {
|
||||
ssaDefer d = proc->defer_stmts[i];
|
||||
if (kind == ssaDefer_Return) {
|
||||
ssa_build_defer_stmt(proc, d);
|
||||
ssa_build_defer_stmt(proc, d);
|
||||
} else if (kind == ssaDefer_Default) {
|
||||
if (proc->scope_index == d.scope_index) {
|
||||
if (proc->scope_index == d.scope_index &&
|
||||
d.scope_index > 1) {
|
||||
ssa_build_defer_stmt(proc, d);
|
||||
gb_array_pop(proc->defer_stmts);
|
||||
continue;
|
||||
|
||||
+3
-3
@@ -3616,9 +3616,9 @@ gb_inline void gb_zero_size(void *ptr, isize size) { gb_memset(ptr, 0, size); }
|
||||
gb_inline void *gb_memcopy(void *dest, void const *source, isize n) {
|
||||
#if defined(_MSC_VER)
|
||||
// TODO(bill): Is this good enough?
|
||||
__movsb(cast(u8 *gb_restrict)dest, cast(u8 *gb_restrict)source, n);
|
||||
__movsb(cast(u8 *)dest, cast(u8 *)source, n);
|
||||
#elif defined(GB_CPU_X86)
|
||||
__asm__ __volatile__("rep movsb" : "+D"(cast(u8 *gb_restrict)dest), "+S"(cast(u8 *gb_restrict)source), "+c"(n) : : "memory");
|
||||
__asm__ __volatile__("rep movsb" : "+D"(cast(u8 *)dest), "+S"(cast(u8 *)source), "+c"(n) : : "memory");
|
||||
#else
|
||||
u8 *d = cast(u8 *)dest;
|
||||
u8 const *s = cast(u8 const *)source;
|
||||
@@ -5753,7 +5753,7 @@ void gb_sort(void *base_, isize count, isize size, gbCompareProc cmp) {
|
||||
Type radix_piece = (radix_value >> byte_index) & 0xff; \
|
||||
dest[offsets[radix_piece]++] = source[i]; \
|
||||
} \
|
||||
gb_swap(Type *gb_restrict, source, dest); \
|
||||
gb_swap(Type *, source, dest); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
+16
-12
@@ -80,19 +80,23 @@ int main(int argc, char **argv) {
|
||||
i32 exit_code = win32_exec_command_line_app(
|
||||
"../misc/llvm-bin/opt -mem2reg %s -o %.*s.bc",
|
||||
output_name, cast(int)base_name_len, output_name);
|
||||
if (exit_code == 0) {
|
||||
win32_exec_command_line_app(
|
||||
"clang -o %.*s.exe %.*s.bc -Wno-override-module "
|
||||
"-lKernel32.lib -lUser32.lib -lGdi32.lib -lOpengl32.lib "
|
||||
,
|
||||
cast(int)base_name_len, output_name,
|
||||
cast(int)base_name_len, output_name);
|
||||
if (run_output) {
|
||||
win32_exec_command_line_app("%.*s.exe", cast(int)base_name_len, output_name);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
if (exit_code != 0)
|
||||
return exit_code;
|
||||
|
||||
exit_code = win32_exec_command_line_app(
|
||||
"clang -o %.*s.exe %.*s.bc "
|
||||
"-Wno-override-module "
|
||||
// "-nostartfiles "
|
||||
"-lKernel32.lib -lUser32.lib -lGdi32.lib -lOpengl32.lib "
|
||||
,
|
||||
cast(int)base_name_len, output_name,
|
||||
cast(int)base_name_len, output_name);
|
||||
if (exit_code != 0)
|
||||
return exit_code;
|
||||
|
||||
if (run_output) {
|
||||
win32_exec_command_line_app("%.*s.exe", cast(int)base_name_len, output_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
+28
-13
@@ -441,7 +441,7 @@ void ast_file_err_(AstFile *file, char *function, Token token, char *fmt, ...) {
|
||||
// NOTE(bill): And this below is why is I/we need a new language! Discriminated unions are a pain in C/C++
|
||||
gb_inline AstNode *make_node(AstFile *f, AstNodeKind kind) {
|
||||
gbArena *arena = &f->arena;
|
||||
if (gb_arena_size_remaining(arena, GB_DEFAULT_MEMORY_ALIGNMENT) < gb_size_of(AstNode)) {
|
||||
if (gb_arena_size_remaining(arena, GB_DEFAULT_MEMORY_ALIGNMENT) <= gb_size_of(AstNode)) {
|
||||
// NOTE(bill): If a syntax error is so bad, just quit!
|
||||
gb_exit(1);
|
||||
}
|
||||
@@ -1735,7 +1735,9 @@ AstNode *parse_decl(AstFile *f, AstNode *name_list, isize name_count) {
|
||||
AstNode *type = NULL;
|
||||
isize value_count = 0;
|
||||
if (allow_token(f, Token_Colon)) {
|
||||
type = parse_identifier_or_type(f);
|
||||
if (!allow_token(f, Token_type)) {
|
||||
type = parse_identifier_or_type(f);
|
||||
}
|
||||
} else if (f->cursor[0].kind != Token_Eq && f->cursor[0].kind != Token_Semicolon) {
|
||||
ast_file_err(f, f->cursor[0], "Expected type separator `:` or `=`");
|
||||
}
|
||||
@@ -1748,13 +1750,30 @@ AstNode *parse_decl(AstFile *f, AstNode *name_list, isize name_count) {
|
||||
declaration_kind = Declaration_Immutable;
|
||||
next_token(f);
|
||||
|
||||
if (f->cursor[0].kind == Token_proc &&
|
||||
if (f->cursor[0].kind == Token_type) {
|
||||
Token token = expect_token(f, Token_type);
|
||||
if (name_count != 1) {
|
||||
ast_file_err(f, ast_node_token(name_list), "You can only declare one type at a time");
|
||||
return make_bad_decl(f, name_list->Ident.token, token);
|
||||
}
|
||||
|
||||
if (type != NULL) {
|
||||
ast_file_err(f, f->cursor[-1], "Expected either `type` or nothing between : and :");
|
||||
// NOTE(bill): Do not fail though
|
||||
}
|
||||
|
||||
AstNode *type = parse_type(f);
|
||||
// if (type->kind != AstNode_StructType) {
|
||||
// expect_token(f, Token_Semicolon);
|
||||
// }
|
||||
return make_type_decl(f, token, name_list, type);
|
||||
} else if (f->cursor[0].kind == Token_proc &&
|
||||
declaration_kind == Declaration_Immutable) {
|
||||
// NOTE(bill): Procedure declarations
|
||||
Token proc_token = f->cursor[0];
|
||||
AstNode *name = name_list;
|
||||
if (name_count != 1) {
|
||||
ast_file_err(f, proc_token, "You can only declare one procedure at a time (at the moment)");
|
||||
ast_file_err(f, proc_token, "You can only declare one procedure at a time");
|
||||
return make_bad_decl(f, name->Ident.token, proc_token);
|
||||
}
|
||||
|
||||
@@ -1945,14 +1964,6 @@ AstNode *parse_stmt(AstFile *f) {
|
||||
AstNode *s = NULL;
|
||||
Token token = f->cursor[0];
|
||||
switch (token.kind) {
|
||||
case Token_type: {
|
||||
Token token = expect_token(f, Token_type);
|
||||
AstNode *name = parse_identifier(f);
|
||||
expect_token(f, Token_Colon);
|
||||
AstNode *type = parse_type(f);
|
||||
return make_type_decl(f, token, name, type);
|
||||
} break;
|
||||
|
||||
// Operands
|
||||
case Token_Identifier:
|
||||
case Token_Integer:
|
||||
@@ -1966,7 +1977,11 @@ AstNode *parse_stmt(AstFile *f) {
|
||||
case Token_Xor:
|
||||
case Token_Not:
|
||||
s = parse_simple_stmt(f);
|
||||
if (s->kind != AstNode_ProcDecl && !allow_token(f, Token_Semicolon)) {
|
||||
if (s->kind != AstNode_ProcDecl &&
|
||||
(s->kind == AstNode_TypeDecl &&
|
||||
s->TypeDecl.type->kind != AstNode_StructType &&
|
||||
s->TypeDecl.type->kind != AstNode_ProcType) &&
|
||||
!allow_token(f, Token_Semicolon)) {
|
||||
// CLEANUP(bill): Semicolon handling in parser
|
||||
ast_file_err(f, f->cursor[0],
|
||||
"Expected `;` after statement, got `%.*s`",
|
||||
|
||||
Reference in New Issue
Block a user