diff --git a/build.bat b/build.bat index ce58a8839..2fe7a1cbd 100644 --- a/build.bat +++ b/build.bat @@ -23,12 +23,18 @@ set compiler_warnings= ^ -wd4505 -wd4512 -wd4550 set compiler_includes= -set libs= kernel32.lib user32.lib gdi32.lib opengl32.lib ..\src\utf8proc\utf8proc.lib +set libs= kernel32.lib user32.lib gdi32.lib opengl32.lib set linker_flags= -incremental:no -opt:ref -subsystem:console -rem Debug -if %release_mode% EQU 0 (set linker_flags=%linker_flags% -debug) + +if %release_mode% EQU 0 ( rem Debug + set linker_flags=%linker_flags% -debug + set libs=%libs% ..\src\utf8proc\utf8proc_debug.lib +) else ( rem Release + set linker_flags=%linker_flags% + set libs=%libs% ..\src\utf8proc\utf8proc.lib +) set compiler_settings=%compiler_includes% %compiler_flags% %compiler_warnings% set linker_settings=%libs% %linker_flags% diff --git a/examples/basic.odin b/examples/basic.odin index e9ffe5591..42d7404c2 100644 --- a/examples/basic.odin +++ b/examples/basic.odin @@ -53,8 +53,8 @@ print_rune :: proc(r: rune) { print_string(str); } -print_space :: proc() { print_rune($ $); } -print_nl :: proc() { print_rune($\n$); } +print_space :: proc() { print_rune(#rune " "); } +print_nl :: proc() { print_rune(#rune "\n"); } print_int :: proc(i: int) { print_int_base(i, 10); @@ -70,7 +70,7 @@ print_int_base :: proc(i, base: int) { i = -i; } if i == 0 { - buf[len] = $0$; + buf[len] = #rune "0"; len++; } for i > 0 { @@ -80,7 +80,7 @@ print_int_base :: proc(i, base: int) { } if negative { - buf[len] = $-$; + buf[len] = #rune "-"; len++; } @@ -89,7 +89,7 @@ print_int_base :: proc(i, base: int) { } print_uint :: proc(i: uint) { - print__uint(i, 10, 0, $ $); + print__uint(i, 10, 0, #rune " "); } print__uint :: proc(i, base: uint, min_width: int, pad_char: byte) { NUM_TO_CHAR_TABLE :: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@$"; @@ -97,7 +97,7 @@ print__uint :: proc(i, base: uint, min_width: int, pad_char: byte) { buf: [65]byte; len := 0; if i == 0 { - buf[len] = $0$; + buf[len] = #rune "0"; len++; } for i > 0 { @@ -119,18 +119,18 @@ print_bool :: proc(b : bool) { else { print_string("false"); } } -print_pointer :: proc(p: rawptr) #inline { print__uint(p as uint, 16, 0, $ $); } +print_pointer :: proc(p: rawptr) #inline { print__uint(p as uint, 16, 0, #rune " "); } print_f32 :: proc(f: f32) #inline { print__f64(f as f64, 7); } print_f64 :: proc(f: f64) #inline { print__f64(f, 10); } print__f64 :: proc(f: f64, decimal_places: int) { if f == 0 { - print_rune($0$); + print_rune(#rune "0"); return; } if f < 0 { - print_rune($-$); + print_rune(#rune "-"); f = -f; } @@ -140,7 +140,7 @@ print__f64 :: proc(f: f64, decimal_places: int) { buf: [22]byte; len := 0; if i == 0 { - buf[len] = $0$; + buf[len] = #rune "0"; len++; } for i > 0 { @@ -156,7 +156,7 @@ print__f64 :: proc(f: f64, decimal_places: int) { print_u64(i); f -= i as f64; - print_rune($.$); + print_rune(#rune "."); mult := 10.0; for decimal_places := 6; decimal_places >= 0; decimal_places-- { diff --git a/examples/demo.odin b/examples/demo.odin index 491a79900..ce6ed4346 100644 --- a/examples/demo.odin +++ b/examples/demo.odin @@ -3,16 +3,16 @@ #load "game.odin" main :: proc() { - _ = hellope(); - procedures(); - variables(); - constants(); - types(); - data_control(); - using_fields(); + // _ = hellope(); + // procedures(); + // variables(); + // constants(); + // types(); + // data_control(); + // using_fields(); - // run_game(); + run_game(); } hellope :: proc() -> int { @@ -440,7 +440,7 @@ types :: proc() { // FORENOTE: 5 * h was originally allowed but it was an edge case in the // compiler I didn't think it was enough to justify have it it. - print_f32(i[0]); print_rune($,$); + print_f32(i[0]); print_rune(#rune ","); print_f32(i[1]); print_nl(); } @@ -502,12 +502,12 @@ void main() { }`; - hearts1 := $💕$; - hearts2 := $\U0001f495$; // 32 bit - hearts3 := "\xf0\x9f\x92\x95"; // Note it's a string, should I allow untyped string -> untyped rune casts? + hearts1 := #rune "💕"; + hearts2 := #rune "\U0001f495"; // 32 bit + hearts3 := #rune "\xf0\x9f\x92\x95"; - 㐒 := $㐒$; - 㐒16 := $\u4db5$; // 16 bit + 㐒 := #rune "㐒"; + 㐒16 := #rune "\u4db5"; // 16 bit but will be `rune` // String ideas "nicked" from Go, so far. I think I might change how some of it works later. } diff --git a/examples/game.odin b/examples/game.odin index f6afb92bf..b4e97a2ce 100644 --- a/examples/game.odin +++ b/examples/game.odin @@ -2,7 +2,7 @@ #load "opengl.odin" #load "math.odin" -TWO_HEARTS :: $💕$; +TWO_HEARTS :: #rune "💕"; win32_perf_count_freq := GetQueryPerformanceFrequency(); time_now :: proc() -> f64 { diff --git a/examples/win32.odin b/examples/win32.odin index ee58367f7..b262cbca3 100644 --- a/examples/win32.odin +++ b/examples/win32.odin @@ -291,43 +291,43 @@ VK_INSERT :: 0x2D; VK_DELETE :: 0x2E; VK_HELP :: 0x2F; -VK_0 :: $0$; -VK_1 :: $1$; -VK_2 :: $2$; -VK_3 :: $3$; -VK_4 :: $4$; -VK_5 :: $5$; -VK_6 :: $6$; -VK_7 :: $7$; -VK_8 :: $8$; -VK_9 :: $9$; +VK_0 :: #rune "0"; +VK_1 :: #rune "1"; +VK_2 :: #rune "2"; +VK_3 :: #rune "3"; +VK_4 :: #rune "4"; +VK_5 :: #rune "5"; +VK_6 :: #rune "6"; +VK_7 :: #rune "7"; +VK_8 :: #rune "8"; +VK_9 :: #rune "9"; -VK_A :: $A$; -VK_B :: $B$; -VK_C :: $C$; -VK_D :: $D$; -VK_E :: $E$; -VK_F :: $F$; -VK_G :: $G$; -VK_H :: $H$; -VK_I :: $I$; -VK_J :: $J$; -VK_K :: $K$; -VK_L :: $L$; -VK_M :: $M$; -VK_N :: $N$; -VK_O :: $O$; -VK_P :: $P$; -VK_Q :: $Q$; -VK_R :: $R$; -VK_S :: $S$; -VK_T :: $T$; -VK_U :: $U$; -VK_V :: $V$; -VK_W :: $W$; -VK_X :: $X$; -VK_Y :: $Y$; -VK_Z :: $Z$; +VK_A :: #rune "A"; +VK_B :: #rune "B"; +VK_C :: #rune "C"; +VK_D :: #rune "D"; +VK_E :: #rune "E"; +VK_F :: #rune "F"; +VK_G :: #rune "G"; +VK_H :: #rune "H"; +VK_I :: #rune "I"; +VK_J :: #rune "J"; +VK_K :: #rune "K"; +VK_L :: #rune "L"; +VK_M :: #rune "M"; +VK_N :: #rune "N"; +VK_O :: #rune "O"; +VK_P :: #rune "P"; +VK_Q :: #rune "Q"; +VK_R :: #rune "R"; +VK_S :: #rune "S"; +VK_T :: #rune "T"; +VK_U :: #rune "U"; +VK_V :: #rune "V"; +VK_W :: #rune "W"; +VK_X :: #rune "X"; +VK_Y :: #rune "Y"; +VK_Z :: #rune "Z"; VK_LWIN :: 0x5B; VK_RWIN :: 0x5C; diff --git a/misc/lib_maker.bat b/misc/lib_maker.bat index 5f6f323ff..ca49f9400 100644 --- a/misc/lib_maker.bat +++ b/misc/lib_maker.bat @@ -7,6 +7,6 @@ FOR %%f IN (name) do ( FOR %%g in (!%%f!) do set "%%f=%%~ng" ) -cl -nologo -O2 -MDd -TP -c %file_input% ^ +cl -nologo -O2 -MT -TP -c %file_input% ^ && lib -nologo %name%.obj -out:%name%.lib ^ && del *.obj diff --git a/src/checker/checker.cpp b/src/checker/checker.cpp index 458ce0dce..fb2b9139e 100644 --- a/src/checker/checker.cpp +++ b/src/checker/checker.cpp @@ -251,7 +251,7 @@ void scope_lookup_parent_entity(Checker *c, Scope *s, String name, Scope **scope if (found) { Entity *e = *found; if (gone_thru_proc) { - if (e->kind == Entity_Variable && e->parent != c->global_scope) { + if (e->kind == Entity_Variable && e->scope != c->global_scope) { continue; } } @@ -292,8 +292,8 @@ Entity *scope_insert_entity(Scope *s, Entity *entity) { if (found) return *found; map_set(&s->elements, key, entity); - if (entity->parent == NULL) - entity->parent = s; + if (entity->scope == NULL) + entity->scope = s; return NULL; } @@ -640,7 +640,7 @@ void check_parsed_files(Checker *c) { case_ast_node(td, TypeDecl, decl); ast_node(n, Ident, td->name); Entity *e = make_entity_type_name(c->allocator, c->global_scope, n->token, NULL); - DeclInfo *d = make_declaration_info(c->allocator, e->parent); + DeclInfo *d = make_declaration_info(c->allocator, e->scope); d->type_expr = td->type; add_file_entity(c, td->name, e, d); case_end; @@ -650,7 +650,7 @@ void check_parsed_files(Checker *c) { Token token = n->token; Entity *e = make_entity_procedure(c->allocator, c->global_scope, token, NULL); add_entity(c, c->global_scope, pd->name, e); - DeclInfo *d = make_declaration_info(c->allocator, e->parent); + DeclInfo *d = make_declaration_info(c->allocator, e->scope); d->proc_decl = decl; map_set(&c->info.entities, hash_pointer(e), d); case_end; diff --git a/src/checker/entity.cpp b/src/checker/entity.cpp index b59481319..90c4f3198 100644 --- a/src/checker/entity.cpp +++ b/src/checker/entity.cpp @@ -31,7 +31,7 @@ struct Entity { EntityKind kind; EntityGuid guid; - Scope *parent; + Scope *scope; Token token; Type *type; @@ -54,52 +54,52 @@ EntityGuid next_entity_guid(void) { return cast(EntityGuid)gb_atomic64_fetch_add(&entity_guid_counter, 1); } -Entity *alloc_entity(gbAllocator a, EntityKind kind, Scope *parent, Token token, Type *type) { +Entity *alloc_entity(gbAllocator a, EntityKind kind, Scope *scope, Token token, Type *type) { Entity *entity = gb_alloc_item(a, Entity); entity->kind = kind; entity->guid = next_entity_guid(); - entity->parent = parent; + entity->scope = scope; entity->token = token; entity->type = type; return entity; } -Entity *make_entity_variable(gbAllocator a, Scope *parent, Token token, Type *type) { - Entity *entity = alloc_entity(a, Entity_Variable, parent, token, type); +Entity *make_entity_variable(gbAllocator a, Scope *scope, Token token, Type *type) { + Entity *entity = alloc_entity(a, Entity_Variable, scope, token, type); return entity; } -Entity *make_entity_constant(gbAllocator a, Scope *parent, Token token, Type *type, ExactValue value) { - Entity *entity = alloc_entity(a, Entity_Constant, parent, token, type); +Entity *make_entity_constant(gbAllocator a, Scope *scope, Token token, Type *type, ExactValue value) { + Entity *entity = alloc_entity(a, Entity_Constant, scope, token, type); entity->Constant.value = value; return entity; } -Entity *make_entity_type_name(gbAllocator a, Scope *parent, Token token, Type *type) { - Entity *entity = alloc_entity(a, Entity_TypeName, parent, token, type); +Entity *make_entity_type_name(gbAllocator a, Scope *scope, Token token, Type *type) { + Entity *entity = alloc_entity(a, Entity_TypeName, scope, token, type); return entity; } -Entity *make_entity_param(gbAllocator a, Scope *parent, Token token, Type *type) { - Entity *entity = make_entity_variable(a, parent, token, type); +Entity *make_entity_param(gbAllocator a, Scope *scope, Token token, Type *type) { + Entity *entity = make_entity_variable(a, scope, token, type); entity->Variable.used = true; return entity; } -Entity *make_entity_field(gbAllocator a, Scope *parent, Token token, Type *type, b32 is_anonymous) { - Entity *entity = make_entity_variable(a, parent, token, type); +Entity *make_entity_field(gbAllocator a, Scope *scope, Token token, Type *type, b32 is_anonymous) { + Entity *entity = make_entity_variable(a, scope, token, type); entity->Variable.is_field = true; entity->Variable.anonymous = cast(b8)is_anonymous; return entity; } -Entity *make_entity_procedure(gbAllocator a, Scope *parent, Token token, Type *signature_type) { - Entity *entity = alloc_entity(a, Entity_Procedure, parent, token, signature_type); +Entity *make_entity_procedure(gbAllocator a, Scope *scope, Token token, Type *signature_type) { + Entity *entity = alloc_entity(a, Entity_Procedure, scope, token, signature_type); return entity; } -Entity *make_entity_builtin(gbAllocator a, Scope *parent, Token token, Type *type, BuiltinProcId id) { - Entity *entity = alloc_entity(a, Entity_Builtin, parent, token, type); +Entity *make_entity_builtin(gbAllocator a, Scope *scope, Token token, Type *type, BuiltinProcId id) { + Entity *entity = alloc_entity(a, Entity_Builtin, scope, token, type); entity->Builtin.id = id; return entity; } diff --git a/src/checker/stmt.cpp b/src/checker/stmt.cpp index e120a467f..e4dc5f7f3 100644 --- a/src/checker/stmt.cpp +++ b/src/checker/stmt.cpp @@ -380,6 +380,7 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod push_procedure(c, type); ast_node(bs, BlockStmt, body); + // TODO(bill): Check declarations first (except mutable variable declarations) check_stmt_list(c, bs->list, 0); if (type->Proc.result_count > 0) { if (!check_is_terminating(c, body)) { @@ -394,7 +395,7 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod void check_proc_decl(Checker *c, Entity *e, DeclInfo *d, b32 check_body_later) { GB_ASSERT(e->type == NULL); - Type *proc_type = make_type_proc(c->allocator, e->parent, NULL, 0, NULL, 0); + Type *proc_type = make_type_proc(c->allocator, e->scope, NULL, 0, NULL, 0); e->type = proc_type; ast_node(pd, ProcDecl, d->proc_decl); @@ -864,7 +865,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { add_entity(c, c->context.scope, pd->name, e); DeclInfo decl = {}; - init_declaration_info(&decl, e->parent); + init_declaration_info(&decl, e->scope); decl.proc_decl = node; check_proc_decl(c, e, &decl, false); destroy_declaration_info(&decl); diff --git a/src/main.cpp b/src/main.cpp index c2cbb124b..26ef255ce 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -82,11 +82,16 @@ int main(int argc, char **argv) { char const *output_name = ssa.output_file.filename; isize base_name_len = gb_path_extension(output_name)-1 - output_name; - i32 exit_code = win32_exec_command_line_app( + + + i32 exit_code = 0; + 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) return exit_code; +#if 1 +#endif exit_code = win32_exec_command_line_app( "clang -o %.*s.exe %.*s.bc " diff --git a/src/parser.cpp b/src/parser.cpp index ca090a9c7..1691e76de 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1144,7 +1144,22 @@ AstNode *parse_operand(AstFile *f, b32 lhs) { case Token_Hash: { operand = parse_tag_expr(f, NULL); - operand->TagExpr.expr = parse_expr(f, false); + String name = operand->TagExpr.name.string; + if (are_strings_equal(name, make_string("rune"))) { + if (f->cursor[0].kind == Token_String) { + Token *s = &f->cursor[0]; + + if (gb_utf8_strnlen(s->string.text, s->string.len) != 1) { + ast_file_err(f, *s, "Invalid rune literal %.*s", LIT(s->string)); + } + s->kind = Token_Rune; // NOTE(bill): Change it + } else { + expect_token(f, Token_String); + } + operand = parse_operand(f, lhs); + } else { + operand->TagExpr.expr = parse_expr(f, false); + } return operand; } diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index c931a7eb0..a5d8c8c82 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -698,43 +698,6 @@ Token tokenizer_get_token(Tokenizer *t) { } } break; - case '$': { // Rune Literal - b32 valid = true; - isize len = 0; - token.kind = Token_Rune; - for (;;) { - Rune r = t->curr_rune; - if (r == '\n' || r < 0) { - if (valid) - tokenizer_err(t, "Rune literal not terminated"); - break; - } - advance_to_next_rune(t); - if (r == '$') - break; - len++; - if (r == '\\') { - if (!scan_escape(t, '$')) - valid = false; - } - } - - token.string.len = t->curr - token.string.text; - if (valid && len != 1) { - tokenizer_err(t, "Invalid rune literal %.*s", LIT(token.string)); - } else { - i32 success = unquote_string(gb_heap_allocator(), &token.string); - if (success > 0) { - if (success == 2) { - gb_array_append(t->allocated_strings, token.string); - } - return token; - } else { - tokenizer_err(t, "Invalid rune literal %.*s", LIT(token.string)); - } - } - } break; - case '.': token.kind = Token_Period; // Default if (gb_is_between(t->curr_rune, '0', '9')) { // Might be a number