Skip to content

Commit

Permalink
v0.0.4 - odin build_dll, atomic.odin, sync.odin
Browse files Browse the repository at this point in the history
  • Loading branch information
gingerBill committed Dec 9, 2016
1 parent de9016b commit a6f8c9d
Show file tree
Hide file tree
Showing 11 changed files with 125 additions and 62 deletions.
4 changes: 2 additions & 2 deletions build.bat
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
set exe_name=odin.exe

:: 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-

Expand Down Expand Up @@ -48,8 +48,8 @@ rem pushd %build_dir%

cl %compiler_settings% "src\main.c" ^
/link %linker_settings% -OUT:%exe_name% ^
&& odin build_dll code/example.odin ^
&& odin run code/demo.odin
rem && odin build_dll code/example.odin ^
rem && odin run code/demo.odin


Expand Down
2 changes: 1 addition & 1 deletion code/demo.odin
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#import "win32.odin"
#import "fmt.odin"
#import "sync.odin"

Dll :: struct {
Handle :: type rawptr
Expand Down Expand Up @@ -50,6 +51,5 @@ main :: proc() {
}

some_thing := (proc_addr as proc())
fmt.println(some_thing)
some_thing()
}
31 changes: 31 additions & 0 deletions core/win32.odin
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,37 @@ GetProcessHeap :: proc() -> HANDLE #foreign #dll_import

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
Expand Down
2 changes: 1 addition & 1 deletion src/build.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ String get_filepath_extension(String path) {

void init_build_context(BuildContext *bc) {
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();

#if defined(GB_SYSTEM_WINDOWS)
Expand Down
70 changes: 40 additions & 30 deletions src/checker/checker.c
Original file line number Diff line number Diff line change
Expand Up @@ -1120,31 +1120,6 @@ void check_global_collect_entities_from_file(Checker *c, Scope *parent_scope, As
DelayedDecl di = {parent_scope, decl};
array_add(&c->delayed_foreign_libraries, di);
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);
if (!parent_scope->is_file) {
// NOTE(bill): Within a procedure, variables must be in order
Expand All @@ -1171,7 +1146,8 @@ void check_global_collect_entities_from_file(Checker *c, Scope *parent_scope, As
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]));
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);
e->identifier = name;
Expand All @@ -1180,7 +1156,7 @@ void check_global_collect_entities_from_file(Checker *c, Scope *parent_scope, As
DeclInfo *d = di;
if (d == NULL) {
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->init_expr = init_expr;
d->var_decl_tags = vd->tags;
Expand All @@ -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);
}
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);
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);

Entity *e = make_entity_type_name(c->allocator, parent_scope, *n, NULL);
e->identifier = td->name;
DeclInfo *d = make_declaration_info(c->allocator, e->scope);
d->type_expr = td->type;
d->init_expr = td->type;
add_entity_and_decl_info(c, td->name, e, d);
case_end;
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);
Token token = *n;
Entity *e = make_entity_procedure(c->allocator, parent_scope, token, NULL, pd->tags);
Expand Down Expand Up @@ -1275,9 +1288,6 @@ void check_import_entities(Checker *c, MapScope *file_scopes) {
if (e->scope == parent_scope) {
continue;
}



// NOTE(bill): Do not add other imported entities
add_entity(c, parent_scope, NULL, e);
if (!id->is_load) { // `#import`ed entities don't get exported
Expand Down
40 changes: 21 additions & 19 deletions src/checker/decl.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,25 @@ void check_init_constant(Checker *c, Entity *e, Operand *operand) {
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;

// gb_printf_err("%.*s %p\n", LIT(e->token.string), e);

void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init_expr) {
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);

if (e->flags & EntityFlag_Visited) {
Expand All @@ -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(c, &operand, init_expr);
}

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_) {
Expand Down Expand Up @@ -458,6 +459,7 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
if (found) {
d = *found;
} else {
// TODO(bill): Err here?
e->type = t_invalid;
set_base_type(named_type, t_invalid);
return;
Expand All @@ -471,7 +473,7 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {

switch (e->kind) {
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;
case Entity_Variable:
check_var_decl(c, e, d->entities, d->entity_count, d->type_expr, d->init_expr);
Expand Down
28 changes: 21 additions & 7 deletions src/checker/expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
gbString expr_to_string (AstNode *expression);
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 update_expr_type (Checker *c, AstNode *e, Type *type, bool final);


gb_inline Type *check_type(Checker *c, AstNode *expression) {
return check_type_extra(c, expression, NULL);
}
Expand Down Expand Up @@ -87,22 +89,20 @@ void check_local_collect_entities(Checker *c, AstNodeArray nodes, DelayedEntitie

for_array(i, cd->values) {
AstNode *name = cd->names.e[i];
AstNode *value = cd->values.e[i];
ExactValue v = {ExactValue_Invalid};

if (!ast_node_expect(name, AstNode_Ident)) {
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]));
entities[entity_index++] = NULL;
continue;
}

ExactValue v = {ExactValue_Invalid};
Entity *e = make_entity_constant(c->allocator, c->context.scope, name->Ident, NULL, v);
e->identifier = name;
entities[entity_index++] = e;

DeclInfo *d = make_declaration_info(c->allocator, e->scope);
d->type_expr = cd->type;
d->init_expr = value;

add_entity_and_decl_info(c, name, e, d);

DelayedEntity delay = {name, e, d};
Expand Down Expand Up @@ -171,6 +171,10 @@ void check_local_collect_entities(Checker *c, AstNodeArray nodes, DelayedEntitie
if (!ast_node_expect(td->name, AstNode_Ident)) {
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;

Expand Down Expand Up @@ -457,7 +461,6 @@ void populate_using_entity_map(Checker *c, AstNode *node, Type *t, MapEntity *en
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,
Entity **fields, isize field_count,
Expand Down Expand Up @@ -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) {
switch (op.kind) {
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 ||
check_is_expr_vector_index(c, o->expr) ||
check_is_vector_elem(c, o->expr)) {
Expand All @@ -1600,6 +1608,12 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {

case Token_Maybe: { // Make maybe
Type *t = default_type(o->type);

if (o->mode == Addressing_Type) {
o->type = make_type_pointer(c->allocator, t);
return;
}

bool is_value =
o->mode == Addressing_Variable ||
o->mode == Addressing_Value ||
Expand Down
5 changes: 5 additions & 0 deletions src/checker/stmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1095,6 +1095,11 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
#if 1
// NOTE(bill): This must be handled here so it has access to the parent scope stuff
// 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);
e->identifier = pd->name;

Expand Down
2 changes: 1 addition & 1 deletion src/gb/gb.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
#if defined(GB_ARCH_64_BIT)
return _InterlockedAnd64(cast(i64 volatile *)a, operand);
return _InterlockedOr64(cast(i64 volatile *)a, operand);
#elif GB_CPU_X86
i64 expected = a->value;
for (;;) {
Expand Down
1 change: 1 addition & 0 deletions src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -1936,6 +1936,7 @@ AstNode *parse_simple_stmt(AstFile *f) {
f->curr_token.kind == Token_enum ||
f->curr_token.kind == Token_union ||
f->curr_token.kind == Token_raw_union) {
// if (f->curr_token.kind == Token_type) {
Token token = f->curr_token;
if (token.kind == Token_type) {
next_token(f);
Expand Down
2 changes: 1 addition & 1 deletion src/tokenizer.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
TOKEN_KIND(Token_using, "using"), \
TOKEN_KIND(Token_asm, "asm"), \
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_context, "push_context"), \
TOKEN_KIND(Token__KeywordEnd, "_KeywordEnd"), \
Expand Down

0 comments on commit a6f8c9d

Please sign in to comment.