mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
v0.0.4 - odin build_dll, atomic.odin, sync.odin
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
set exe_name=odin.exe
|
set exe_name=odin.exe
|
||||||
|
|
||||||
:: Debug = 0, Release = 1
|
:: Debug = 0, Release = 1
|
||||||
set release_mode=0
|
set release_mode=1
|
||||||
|
|
||||||
set compiler_flags= -nologo -Oi -TC -W4 -fp:fast -fp:except- -Gm- -MP -FC -GS- -EHsc- -GR-
|
set compiler_flags= -nologo -Oi -TC -W4 -fp:fast -fp:except- -Gm- -MP -FC -GS- -EHsc- -GR-
|
||||||
|
|
||||||
@@ -48,8 +48,8 @@ rem pushd %build_dir%
|
|||||||
|
|
||||||
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 build_dll code/example.odin ^
|
|
||||||
&& odin run code/demo.odin
|
&& odin run code/demo.odin
|
||||||
|
rem && odin build_dll code/example.odin ^
|
||||||
rem && odin run code/demo.odin
|
rem && odin run code/demo.odin
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,6 @@
|
|||||||
#import "win32.odin"
|
#import "win32.odin"
|
||||||
#import "fmt.odin"
|
#import "fmt.odin"
|
||||||
|
#import "sync.odin"
|
||||||
|
|
||||||
Dll :: struct {
|
Dll :: struct {
|
||||||
Handle :: type rawptr
|
Handle :: type rawptr
|
||||||
@@ -50,6 +51,5 @@ main :: proc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
some_thing := (proc_addr as proc())
|
some_thing := (proc_addr as proc())
|
||||||
fmt.println(some_thing)
|
|
||||||
some_thing()
|
some_thing()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -205,6 +205,37 @@ GetProcessHeap :: proc() -> HANDLE #foreign #dll_import
|
|||||||
|
|
||||||
HEAP_ZERO_MEMORY :: 0x00000008
|
HEAP_ZERO_MEMORY :: 0x00000008
|
||||||
|
|
||||||
|
// Synchronization
|
||||||
|
|
||||||
|
SECURITY_ATTRIBUTES :: struct #ordered {
|
||||||
|
length: u32
|
||||||
|
security_descriptor: rawptr
|
||||||
|
inherit_handle: BOOL
|
||||||
|
}
|
||||||
|
|
||||||
|
INFINITE :: 0xffffffff
|
||||||
|
|
||||||
|
CreateSemaphoreA :: proc(attributes: ^SECURITY_ATTRIBUTES, initial_count, maximum_count: i32, name: ^byte) -> HANDLE #foreign #dll_import
|
||||||
|
ReleaseSemaphore :: proc(semaphore: HANDLE, release_count: i32, previous_count: ^i32) -> BOOL #foreign #dll_import
|
||||||
|
WaitForSingleObject :: proc(handle: HANDLE, milliseconds: u32) -> u32 #foreign #dll_import
|
||||||
|
|
||||||
|
|
||||||
|
InterlockedCompareExchange :: proc(dst: ^i32, exchange, comparand: i32) -> i32 #foreign
|
||||||
|
InterlockedExchange :: proc(dst: ^i32, desired: i32) -> i32 #foreign
|
||||||
|
InterlockedExchangeAdd :: proc(dst: ^i32, desired: i32) -> i32 #foreign
|
||||||
|
InterlockedAnd :: proc(dst: ^i32, desired: i32) -> i32 #foreign
|
||||||
|
InterlockedOr :: proc(dst: ^i32, desired: i32) -> i32 #foreign
|
||||||
|
|
||||||
|
InterlockedCompareExchange64 :: proc(dst: ^i64, exchange, comparand: i64) -> i64 #foreign
|
||||||
|
InterlockedExchange64 :: proc(dst: ^i64, desired: i64) -> i64 #foreign
|
||||||
|
InterlockedExchangeAdd64 :: proc(dst: ^i64, desired: i64) -> i64 #foreign
|
||||||
|
InterlockedAnd64 :: proc(dst: ^i64, desired: i64) -> i64 #foreign
|
||||||
|
InterlockedOr64 :: proc(dst: ^i64, desired: i64) -> i64 #foreign
|
||||||
|
|
||||||
|
_mm_pause :: proc() #foreign
|
||||||
|
ReadWriteBarrier :: proc() #foreign
|
||||||
|
WriteBarrier :: proc() #foreign
|
||||||
|
ReadBarrier :: proc() #foreign
|
||||||
|
|
||||||
|
|
||||||
// GDI
|
// GDI
|
||||||
|
|||||||
+1
-1
@@ -149,7 +149,7 @@ String get_filepath_extension(String path) {
|
|||||||
|
|
||||||
void init_build_context(BuildContext *bc) {
|
void init_build_context(BuildContext *bc) {
|
||||||
bc->ODIN_VENDOR = str_lit("odin");
|
bc->ODIN_VENDOR = str_lit("odin");
|
||||||
bc->ODIN_VERSION = str_lit("0.0.3d");
|
bc->ODIN_VERSION = str_lit("0.0.4");
|
||||||
bc->ODIN_ROOT = odin_root_dir();
|
bc->ODIN_ROOT = odin_root_dir();
|
||||||
|
|
||||||
#if defined(GB_SYSTEM_WINDOWS)
|
#if defined(GB_SYSTEM_WINDOWS)
|
||||||
|
|||||||
+40
-30
@@ -1120,31 +1120,6 @@ void check_global_collect_entities_from_file(Checker *c, Scope *parent_scope, As
|
|||||||
DelayedDecl di = {parent_scope, decl};
|
DelayedDecl di = {parent_scope, decl};
|
||||||
array_add(&c->delayed_foreign_libraries, di);
|
array_add(&c->delayed_foreign_libraries, di);
|
||||||
case_end;
|
case_end;
|
||||||
case_ast_node(cd, ConstDecl, decl);
|
|
||||||
for_array(i, cd->values) {
|
|
||||||
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);
|
|
||||||
di->type_expr = cd->type;
|
|
||||||
di->init_expr = value;
|
|
||||||
add_entity_and_decl_info(c, name, e, di);
|
|
||||||
}
|
|
||||||
|
|
||||||
isize lhs_count = cd->names.count;
|
|
||||||
isize rhs_count = cd->values.count;
|
|
||||||
|
|
||||||
if (rhs_count == 0 && cd->type == NULL) {
|
|
||||||
error_node(decl, "Missing type or initial expression");
|
|
||||||
} else if (lhs_count < rhs_count) {
|
|
||||||
error_node(decl, "Extra initial expression");
|
|
||||||
}
|
|
||||||
case_end;
|
|
||||||
case_ast_node(vd, VarDecl, decl);
|
case_ast_node(vd, VarDecl, decl);
|
||||||
if (!parent_scope->is_file) {
|
if (!parent_scope->is_file) {
|
||||||
// NOTE(bill): Within a procedure, variables must be in order
|
// NOTE(bill): Within a procedure, variables must be in order
|
||||||
@@ -1171,7 +1146,8 @@ void check_global_collect_entities_from_file(Checker *c, Scope *parent_scope, As
|
|||||||
value = vd->values.e[i];
|
value = vd->values.e[i];
|
||||||
}
|
}
|
||||||
if (name->kind != AstNode_Ident) {
|
if (name->kind != AstNode_Ident) {
|
||||||
error_node(name, "A declaration's name but be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
|
error_node(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
Entity *e = make_entity_variable(c->allocator, parent_scope, name->Ident, NULL);
|
Entity *e = make_entity_variable(c->allocator, parent_scope, name->Ident, NULL);
|
||||||
e->identifier = name;
|
e->identifier = name;
|
||||||
@@ -1180,7 +1156,7 @@ void check_global_collect_entities_from_file(Checker *c, Scope *parent_scope, As
|
|||||||
DeclInfo *d = di;
|
DeclInfo *d = di;
|
||||||
if (d == NULL) {
|
if (d == NULL) {
|
||||||
AstNode *init_expr = value;
|
AstNode *init_expr = value;
|
||||||
d = make_declaration_info(heap_allocator(), parent_scope);
|
d = make_declaration_info(heap_allocator(), e->scope);
|
||||||
d->type_expr = vd->type;
|
d->type_expr = vd->type;
|
||||||
d->init_expr = init_expr;
|
d->init_expr = init_expr;
|
||||||
d->var_decl_tags = vd->tags;
|
d->var_decl_tags = vd->tags;
|
||||||
@@ -1189,15 +1165,52 @@ void check_global_collect_entities_from_file(Checker *c, Scope *parent_scope, As
|
|||||||
add_entity_and_decl_info(c, name, e, d);
|
add_entity_and_decl_info(c, name, e, d);
|
||||||
}
|
}
|
||||||
case_end;
|
case_end;
|
||||||
|
case_ast_node(cd, ConstDecl, decl);
|
||||||
|
for_array(i, cd->values) {
|
||||||
|
AstNode *name = cd->names.e[i];
|
||||||
|
AstNode *value = unparen_expr(cd->values.e[i]);
|
||||||
|
if (name->kind != AstNode_Ident) {
|
||||||
|
error_node(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExactValue v = {ExactValue_Invalid};
|
||||||
|
Entity *e = make_entity_constant(c->allocator, parent_scope, name->Ident, NULL, v);
|
||||||
|
e->identifier = name;
|
||||||
|
DeclInfo *di = make_declaration_info(c->allocator, e->scope);
|
||||||
|
di->type_expr = cd->type;
|
||||||
|
di->init_expr = value;
|
||||||
|
add_entity_and_decl_info(c, name, e, di);
|
||||||
|
}
|
||||||
|
|
||||||
|
isize lhs_count = cd->names.count;
|
||||||
|
isize rhs_count = cd->values.count;
|
||||||
|
|
||||||
|
if (rhs_count == 0 && cd->type == NULL) {
|
||||||
|
error_node(decl, "Missing type or initial expression");
|
||||||
|
} else if (lhs_count < rhs_count) {
|
||||||
|
error_node(decl, "Extra initial expression");
|
||||||
|
}
|
||||||
|
case_end;
|
||||||
case_ast_node(td, TypeDecl, decl);
|
case_ast_node(td, TypeDecl, decl);
|
||||||
|
if (td->name->kind != AstNode_Ident) {
|
||||||
|
error_node(td->name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[td->name->kind]));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
ast_node(n, Ident, td->name);
|
ast_node(n, Ident, td->name);
|
||||||
|
|
||||||
Entity *e = make_entity_type_name(c->allocator, parent_scope, *n, NULL);
|
Entity *e = make_entity_type_name(c->allocator, parent_scope, *n, NULL);
|
||||||
e->identifier = td->name;
|
e->identifier = td->name;
|
||||||
DeclInfo *d = make_declaration_info(c->allocator, e->scope);
|
DeclInfo *d = make_declaration_info(c->allocator, e->scope);
|
||||||
d->type_expr = td->type;
|
d->type_expr = td->type;
|
||||||
|
d->init_expr = td->type;
|
||||||
add_entity_and_decl_info(c, td->name, e, d);
|
add_entity_and_decl_info(c, td->name, e, d);
|
||||||
case_end;
|
case_end;
|
||||||
case_ast_node(pd, ProcDecl, decl);
|
case_ast_node(pd, ProcDecl, decl);
|
||||||
|
if (pd->name->kind != AstNode_Ident) {
|
||||||
|
error_node(pd->name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[pd->name->kind]));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
ast_node(n, Ident, pd->name);
|
ast_node(n, Ident, pd->name);
|
||||||
Token token = *n;
|
Token token = *n;
|
||||||
Entity *e = make_entity_procedure(c->allocator, parent_scope, token, NULL, pd->tags);
|
Entity *e = make_entity_procedure(c->allocator, parent_scope, token, NULL, pd->tags);
|
||||||
@@ -1275,9 +1288,6 @@ void check_import_entities(Checker *c, MapScope *file_scopes) {
|
|||||||
if (e->scope == parent_scope) {
|
if (e->scope == parent_scope) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// NOTE(bill): Do not add other imported entities
|
// NOTE(bill): Do not add other imported entities
|
||||||
add_entity(c, parent_scope, NULL, e);
|
add_entity(c, parent_scope, NULL, e);
|
||||||
if (!id->is_load) { // `#import`ed entities don't get exported
|
if (!id->is_load) { // `#import`ed entities don't get exported
|
||||||
|
|||||||
+21
-19
@@ -211,8 +211,25 @@ void check_init_constant(Checker *c, Entity *e, Operand *operand) {
|
|||||||
e->Constant.value = operand->value;
|
e->Constant.value = operand->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def) {
|
||||||
|
GB_ASSERT(e->type == NULL);
|
||||||
|
Type *named = make_type_named(c->allocator, e->token.string, NULL, e);
|
||||||
|
named->Named.type_name = e;
|
||||||
|
if (def != NULL && def->kind == Type_Named) {
|
||||||
|
def->Named.base = named;
|
||||||
|
}
|
||||||
|
e->type = named;
|
||||||
|
|
||||||
void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init_expr) {
|
// gb_printf_err("%.*s %p\n", LIT(e->token.string), e);
|
||||||
|
|
||||||
|
Type *bt = check_type_extra(c, type_expr, named);
|
||||||
|
named->Named.base = base_type(bt);
|
||||||
|
if (named->Named.base == t_invalid) {
|
||||||
|
// gb_printf("check_type_decl: %s\n", type_to_string(named));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init_expr, Type *named_type) {
|
||||||
GB_ASSERT(e->type == NULL);
|
GB_ASSERT(e->type == NULL);
|
||||||
|
|
||||||
if (e->flags & EntityFlag_Visited) {
|
if (e->flags & EntityFlag_Visited) {
|
||||||
@@ -238,26 +255,10 @@ void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init_e
|
|||||||
// check_expr_or_type(c, &operand, init_expr);
|
// check_expr_or_type(c, &operand, init_expr);
|
||||||
check_expr(c, &operand, init_expr);
|
check_expr(c, &operand, init_expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
check_init_constant(c, e, &operand);
|
check_init_constant(c, e, &operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def) {
|
|
||||||
GB_ASSERT(e->type == NULL);
|
|
||||||
Type *named = make_type_named(c->allocator, e->token.string, NULL, e);
|
|
||||||
named->Named.type_name = e;
|
|
||||||
if (def != NULL && def->kind == Type_Named) {
|
|
||||||
def->Named.base = named;
|
|
||||||
}
|
|
||||||
e->type = named;
|
|
||||||
|
|
||||||
// gb_printf_err("%.*s %p\n", LIT(e->token.string), e);
|
|
||||||
|
|
||||||
Type *bt = check_type_extra(c, type_expr, named);
|
|
||||||
named->Named.base = base_type(bt);
|
|
||||||
if (named->Named.base == t_invalid) {
|
|
||||||
// gb_printf("check_type_decl: %s\n", type_to_string(named));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool are_signatures_similar_enough(Type *a_, Type *b_) {
|
bool are_signatures_similar_enough(Type *a_, Type *b_) {
|
||||||
@@ -458,6 +459,7 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
|
|||||||
if (found) {
|
if (found) {
|
||||||
d = *found;
|
d = *found;
|
||||||
} else {
|
} else {
|
||||||
|
// TODO(bill): Err here?
|
||||||
e->type = t_invalid;
|
e->type = t_invalid;
|
||||||
set_base_type(named_type, t_invalid);
|
set_base_type(named_type, t_invalid);
|
||||||
return;
|
return;
|
||||||
@@ -471,7 +473,7 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
|
|||||||
|
|
||||||
switch (e->kind) {
|
switch (e->kind) {
|
||||||
case Entity_Constant:
|
case Entity_Constant:
|
||||||
check_const_decl(c, e, d->type_expr, d->init_expr);
|
check_const_decl(c, e, d->type_expr, d->init_expr, named_type);
|
||||||
break;
|
break;
|
||||||
case Entity_Variable:
|
case Entity_Variable:
|
||||||
check_var_decl(c, e, d->entities, d->entity_count, d->type_expr, d->init_expr);
|
check_var_decl(c, e, d->entities, d->entity_count, d->type_expr, d->init_expr);
|
||||||
|
|||||||
+21
-7
@@ -11,9 +11,11 @@ bool check_value_is_expressible(Checker *c, ExactValue in_value, Type *type,
|
|||||||
void convert_to_typed (Checker *c, Operand *operand, Type *target_type, i32 level);
|
void convert_to_typed (Checker *c, Operand *operand, Type *target_type, i32 level);
|
||||||
gbString expr_to_string (AstNode *expression);
|
gbString expr_to_string (AstNode *expression);
|
||||||
void check_entity_decl (Checker *c, Entity *e, DeclInfo *decl, Type *named_type);
|
void check_entity_decl (Checker *c, Entity *e, DeclInfo *decl, Type *named_type);
|
||||||
|
void check_const_decl (Checker *c, Entity *e, AstNode *type_expr, AstNode *init_expr, Type *named_type);
|
||||||
void check_proc_body (Checker *c, Token token, DeclInfo *decl, Type *type, AstNode *body);
|
void check_proc_body (Checker *c, Token token, DeclInfo *decl, Type *type, AstNode *body);
|
||||||
void update_expr_type (Checker *c, AstNode *e, Type *type, bool final);
|
void update_expr_type (Checker *c, AstNode *e, Type *type, bool final);
|
||||||
|
|
||||||
|
|
||||||
gb_inline Type *check_type(Checker *c, AstNode *expression) {
|
gb_inline Type *check_type(Checker *c, AstNode *expression) {
|
||||||
return check_type_extra(c, expression, NULL);
|
return check_type_extra(c, expression, NULL);
|
||||||
}
|
}
|
||||||
@@ -87,22 +89,20 @@ void check_local_collect_entities(Checker *c, AstNodeArray nodes, DelayedEntitie
|
|||||||
|
|
||||||
for_array(i, cd->values) {
|
for_array(i, cd->values) {
|
||||||
AstNode *name = cd->names.e[i];
|
AstNode *name = cd->names.e[i];
|
||||||
AstNode *value = cd->values.e[i];
|
AstNode *value = unparen_expr(cd->values.e[i]);
|
||||||
ExactValue v = {ExactValue_Invalid};
|
if (name->kind != AstNode_Ident) {
|
||||||
|
error_node(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
|
||||||
if (!ast_node_expect(name, AstNode_Ident)) {
|
|
||||||
entities[entity_index++] = NULL;
|
entities[entity_index++] = NULL;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExactValue v = {ExactValue_Invalid};
|
||||||
Entity *e = make_entity_constant(c->allocator, c->context.scope, name->Ident, NULL, v);
|
Entity *e = make_entity_constant(c->allocator, c->context.scope, name->Ident, NULL, v);
|
||||||
e->identifier = name;
|
e->identifier = name;
|
||||||
entities[entity_index++] = e;
|
entities[entity_index++] = e;
|
||||||
|
|
||||||
DeclInfo *d = make_declaration_info(c->allocator, e->scope);
|
DeclInfo *d = make_declaration_info(c->allocator, e->scope);
|
||||||
d->type_expr = cd->type;
|
d->type_expr = cd->type;
|
||||||
d->init_expr = value;
|
d->init_expr = value;
|
||||||
|
|
||||||
add_entity_and_decl_info(c, name, e, d);
|
add_entity_and_decl_info(c, name, e, d);
|
||||||
|
|
||||||
DelayedEntity delay = {name, e, d};
|
DelayedEntity delay = {name, e, d};
|
||||||
@@ -171,6 +171,10 @@ void check_local_collect_entities(Checker *c, AstNodeArray nodes, DelayedEntitie
|
|||||||
if (!ast_node_expect(td->name, AstNode_Ident)) {
|
if (!ast_node_expect(td->name, AstNode_Ident)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (td->name->kind != AstNode_Ident) {
|
||||||
|
error_node(td->name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[td->name->kind]));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Token name_token = td->name->Ident;
|
Token name_token = td->name->Ident;
|
||||||
|
|
||||||
@@ -457,7 +461,6 @@ void populate_using_entity_map(Checker *c, AstNode *node, Type *t, MapEntity *en
|
|||||||
gb_string_free(str);
|
gb_string_free(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init_expr);
|
|
||||||
|
|
||||||
void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
|
void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
|
||||||
Entity **fields, isize field_count,
|
Entity **fields, isize field_count,
|
||||||
@@ -1581,6 +1584,11 @@ bool check_is_vector_elem(Checker *c, AstNode *expr) {
|
|||||||
void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
|
void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
|
||||||
switch (op.kind) {
|
switch (op.kind) {
|
||||||
case Token_Pointer: { // Pointer address
|
case Token_Pointer: { // Pointer address
|
||||||
|
if (o->mode == Addressing_Type) {
|
||||||
|
o->type = make_type_pointer(c->allocator, o->type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (o->mode != Addressing_Variable ||
|
if (o->mode != Addressing_Variable ||
|
||||||
check_is_expr_vector_index(c, o->expr) ||
|
check_is_expr_vector_index(c, o->expr) ||
|
||||||
check_is_vector_elem(c, o->expr)) {
|
check_is_vector_elem(c, o->expr)) {
|
||||||
@@ -1600,6 +1608,12 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
|
|||||||
|
|
||||||
case Token_Maybe: { // Make maybe
|
case Token_Maybe: { // Make maybe
|
||||||
Type *t = default_type(o->type);
|
Type *t = default_type(o->type);
|
||||||
|
|
||||||
|
if (o->mode == Addressing_Type) {
|
||||||
|
o->type = make_type_pointer(c->allocator, t);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool is_value =
|
bool is_value =
|
||||||
o->mode == Addressing_Variable ||
|
o->mode == Addressing_Variable ||
|
||||||
o->mode == Addressing_Value ||
|
o->mode == Addressing_Value ||
|
||||||
|
|||||||
@@ -1095,6 +1095,11 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
|||||||
#if 1
|
#if 1
|
||||||
// NOTE(bill): This must be handled here so it has access to the parent scope stuff
|
// NOTE(bill): This must be handled here so it has access to the parent scope stuff
|
||||||
// e.g. using
|
// e.g. using
|
||||||
|
if (pd->name->kind != AstNode_Ident) {
|
||||||
|
error_node(pd->name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[pd->name->kind]));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
Entity *e = make_entity_procedure(c->allocator, c->context.scope, pd->name->Ident, NULL, pd->tags);
|
Entity *e = make_entity_procedure(c->allocator, c->context.scope, pd->name->Ident, NULL, pd->tags);
|
||||||
e->identifier = pd->name;
|
e->identifier = pd->name;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -4112,7 +4112,7 @@ gb_inline i64 gb_atomic64_fetch_and(gbAtomic64 volatile *a, i64 operand) {
|
|||||||
|
|
||||||
gb_inline i64 gb_atomic64_fetch_or(gbAtomic64 volatile *a, i64 operand) {
|
gb_inline i64 gb_atomic64_fetch_or(gbAtomic64 volatile *a, i64 operand) {
|
||||||
#if defined(GB_ARCH_64_BIT)
|
#if defined(GB_ARCH_64_BIT)
|
||||||
return _InterlockedAnd64(cast(i64 volatile *)a, operand);
|
return _InterlockedOr64(cast(i64 volatile *)a, operand);
|
||||||
#elif GB_CPU_X86
|
#elif GB_CPU_X86
|
||||||
i64 expected = a->value;
|
i64 expected = a->value;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|||||||
@@ -1936,6 +1936,7 @@ AstNode *parse_simple_stmt(AstFile *f) {
|
|||||||
f->curr_token.kind == Token_enum ||
|
f->curr_token.kind == Token_enum ||
|
||||||
f->curr_token.kind == Token_union ||
|
f->curr_token.kind == Token_union ||
|
||||||
f->curr_token.kind == Token_raw_union) {
|
f->curr_token.kind == Token_raw_union) {
|
||||||
|
// if (f->curr_token.kind == Token_type) {
|
||||||
Token token = f->curr_token;
|
Token token = f->curr_token;
|
||||||
if (token.kind == Token_type) {
|
if (token.kind == Token_type) {
|
||||||
next_token(f);
|
next_token(f);
|
||||||
|
|||||||
+1
-1
@@ -109,7 +109,7 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
|
|||||||
TOKEN_KIND(Token_using, "using"), \
|
TOKEN_KIND(Token_using, "using"), \
|
||||||
TOKEN_KIND(Token_asm, "asm"), \
|
TOKEN_KIND(Token_asm, "asm"), \
|
||||||
TOKEN_KIND(Token_volatile, "volatile"), \
|
TOKEN_KIND(Token_volatile, "volatile"), \
|
||||||
TOKEN_KIND(Token_atomic, "atomic"), \
|
/* TOKEN_KIND(Token_atomic, "atomic"), */\
|
||||||
TOKEN_KIND(Token_push_allocator, "push_allocator"), \
|
TOKEN_KIND(Token_push_allocator, "push_allocator"), \
|
||||||
TOKEN_KIND(Token_push_context, "push_context"), \
|
TOKEN_KIND(Token_push_context, "push_context"), \
|
||||||
TOKEN_KIND(Token__KeywordEnd, "_KeywordEnd"), \
|
TOKEN_KIND(Token__KeywordEnd, "_KeywordEnd"), \
|
||||||
|
|||||||
Reference in New Issue
Block a user