From 2ab0d9757388d1ec84db56b6ebb49a2ffff34d62 Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Mon, 12 Jun 2017 14:19:12 +0100 Subject: [PATCH] `import` and `import_load` as keywords; Fix procedure literal call trick --- code/demo.odin | 31 +++++----- core/_preload.odin | 8 +-- core/atomics.odin | 2 +- core/fmt.odin | 12 ++-- core/mem.odin | 4 +- core/opengl.odin | 6 +- core/os.odin | 6 +- core/os_linux.odin | 3 +- core/os_windows.odin | 2 +- core/os_x.odin | 4 +- core/strconv.odin | 2 +- core/sync.odin | 4 +- core/sync_linux.odin | 4 +- core/sync_windows.odin | 4 +- core/sys/wgl.odin | 2 +- src/check_expr.cpp | 2 +- src/parser.cpp | 132 ++++++++++++++++++++++------------------- src/tokenizer.cpp | 72 +++++++++++----------- 18 files changed, 156 insertions(+), 144 deletions(-) diff --git a/code/demo.odin b/code/demo.odin index 69323f95d..3a4893934 100644 --- a/code/demo.odin +++ b/code/demo.odin @@ -1,19 +1,18 @@ -#import "fmt.odin"; -#import "atomics.odin"; -#import "bits.odin"; -#import "math.odin"; -#import "mem.odin"; -#import "opengl.odin"; -#import "strconv.odin"; -#import "strings.odin"; -#import "sync.odin"; -#import "types.odin"; -#import "utf8.odin"; -#import "utf16.odin"; +import "fmt.odin"; +import "atomics.odin"; +import "bits.odin"; +import "math.odin"; +import "mem.odin"; +import "opengl.odin"; +import "strconv.odin"; +import "strings.odin"; +import "sync.odin"; +import "types.odin"; +import "utf8.odin"; +import "utf16.odin"; proc main() { - var x = proc() { - fmt.println("Hello"); - }; - x(); + proc(s: string){ + fmt.println(s, "world!"); + }("Hellope"); } diff --git a/core/_preload.odin b/core/_preload.odin index c37601bb7..2fd021be9 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -1,9 +1,9 @@ #shared_global_scope; -#import "os.odin"; -#import "fmt.odin"; -#import "utf8.odin"; -#import "raw.odin"; +import "os.odin"; +import "fmt.odin"; +import "utf8.odin"; +import "raw.odin"; // Naming Conventions: // In general, PascalCase for types and snake_case for values diff --git a/core/atomics.odin b/core/atomics.odin index 785f10db8..09f144edd 100644 --- a/core/atomics.odin +++ b/core/atomics.odin @@ -1,7 +1,7 @@ // TODO(bill): Use assembly instead here to implement atomics // Inline vs external file? -#import win32 "sys/windows.odin" when ODIN_OS == "windows"; +import win32 "sys/windows.odin" when ODIN_OS == "windows"; var _ = compile_assert(ODIN_ARCH == "amd64"); // TODO(bill): x86 version diff --git a/core/fmt.odin b/core/fmt.odin index ce56ec0f5..24920d349 100644 --- a/core/fmt.odin +++ b/core/fmt.odin @@ -1,9 +1,9 @@ -#import "os.odin"; -#import "mem.odin"; -#import "utf8.odin"; -#import "types.odin"; -#import "strconv.odin"; -#import "raw.odin"; +import "os.odin"; +import "mem.odin"; +import "utf8.odin"; +import "types.odin"; +import "strconv.odin"; +import "raw.odin"; const _BUFFER_SIZE = 1<<12; diff --git a/core/mem.odin b/core/mem.odin index 90b9a26e5..6f55f48f5 100644 --- a/core/mem.odin +++ b/core/mem.odin @@ -1,5 +1,5 @@ -#import "fmt.odin"; -#import "os.odin"; +import "fmt.odin"; +import "os.odin"; proc swap(b: u16) -> u16 #foreign __llvm_core "llvm.bswap.i16"; proc swap(b: u32) -> u32 #foreign __llvm_core "llvm.bswap.i32"; diff --git a/core/opengl.odin b/core/opengl.odin index 73a179742..fe78ba6c5 100644 --- a/core/opengl.odin +++ b/core/opengl.odin @@ -1,8 +1,8 @@ #foreign_system_library lib "opengl32.lib" when ODIN_OS == "windows"; #foreign_system_library lib "gl" when ODIN_OS == "linux"; -#import win32 "sys/windows.odin" when ODIN_OS == "windows"; -#import "sys/wgl.odin" when ODIN_OS == "windows"; -#load "opengl_constants.odin"; +import win32 "sys/windows.odin" when ODIN_OS == "windows"; +import "sys/wgl.odin" when ODIN_OS == "windows"; +import_load "opengl_constants.odin"; proc Clear (mask: u32) #foreign lib "glClear"; proc ClearColor (r, g, b, a: f32) #foreign lib "glClearColor"; diff --git a/core/os.odin b/core/os.odin index 4d67679c6..35daa13ad 100644 --- a/core/os.odin +++ b/core/os.odin @@ -1,6 +1,6 @@ -#load "os_windows.odin" when ODIN_OS == "windows"; -#load "os_x.odin" when ODIN_OS == "osx"; -#load "os_linux.odin" when ODIN_OS == "linux"; +import_load "os_windows.odin" when ODIN_OS == "windows"; +import_load "os_x.odin" when ODIN_OS == "osx"; +import_load "os_linux.odin" when ODIN_OS == "linux"; proc write_string(fd: Handle, str: string) -> (int, Errno) { return write(fd, []u8(str)); diff --git a/core/os_linux.odin b/core/os_linux.odin index 8d9405ecd..1a3e82bbf 100644 --- a/core/os_linux.odin +++ b/core/os_linux.odin @@ -1,5 +1,4 @@ -// #import "fmt.odin"; -#import "strings.odin"; +import "strings.odin"; type Handle i32; type FileTime u64; diff --git a/core/os_windows.odin b/core/os_windows.odin index c1a31ff50..68e657fd1 100644 --- a/core/os_windows.odin +++ b/core/os_windows.odin @@ -1,4 +1,4 @@ -#import win32 "sys/windows.odin"; +import win32 "sys/windows.odin"; type Handle int; type FileTime u64; diff --git a/core/os_x.odin b/core/os_x.odin index 3b591e19c..c75da9836 100644 --- a/core/os_x.odin +++ b/core/os_x.odin @@ -1,5 +1,5 @@ -#import "fmt.odin"; -#import "strings.odin"; +import "fmt.odin"; +import "strings.odin"; type Handle i32; type FileTime u64; diff --git a/core/strconv.odin b/core/strconv.odin index e129241a3..557429656 100644 --- a/core/strconv.odin +++ b/core/strconv.odin @@ -1,4 +1,4 @@ -#import . "decimal.odin"; +import . "decimal.odin"; type IntFlag enum { Prefix = 1<<0, diff --git a/core/sync.odin b/core/sync.odin index 485df759a..9c3fc3188 100644 --- a/core/sync.odin +++ b/core/sync.odin @@ -1,2 +1,2 @@ -#load "sync_windows.odin" when ODIN_OS == "windows"; -#load "sync_linux.odin" when ODIN_OS == "linux"; +import_load "sync_windows.odin" when ODIN_OS == "windows"; +import_load "sync_linux.odin" when ODIN_OS == "linux"; diff --git a/core/sync_linux.odin b/core/sync_linux.odin index 228fb16b3..cee68f420 100644 --- a/core/sync_linux.odin +++ b/core/sync_linux.odin @@ -1,5 +1,5 @@ -#import "atomics.odin"; -#import "os.odin"; +import "atomics.odin"; +import "os.odin"; type Semaphore struct { // _handle: win32.Handle, diff --git a/core/sync_windows.odin b/core/sync_windows.odin index e0ede4943..1f9410202 100644 --- a/core/sync_windows.odin +++ b/core/sync_windows.odin @@ -1,5 +1,5 @@ -#import win32 "sys/windows.odin" when ODIN_OS == "windows"; -#import "atomics.odin"; +import win32 "sys/windows.odin" when ODIN_OS == "windows"; +import "atomics.odin"; type Semaphore struct { _handle: win32.Handle, diff --git a/core/sys/wgl.odin b/core/sys/wgl.odin index 5d373578a..c2594d475 100644 --- a/core/sys/wgl.odin +++ b/core/sys/wgl.odin @@ -1,5 +1,5 @@ #foreign_system_library "opengl32.lib" when ODIN_OS == "windows"; -#import . "windows.odin"; +import . "windows.odin"; const CONTEXT_MAJOR_VERSION_ARB = 0x2091; const CONTEXT_MINOR_VERSION_ARB = 0x2092; diff --git a/src/check_expr.cpp b/src/check_expr.cpp index aac533b17..cf35c30b3 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -5510,7 +5510,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t check_open_scope(c, pl->type); { decl = make_declaration_info(c->allocator, c->context.scope, c->context.decl); - decl->proc_decl = pl->type; + decl->proc_decl = node; c->context.decl = decl; if (pl->tags != 0) { diff --git a/src/parser.cpp b/src/parser.cpp index 09dbc77d7..d3347bbef 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -48,7 +48,7 @@ struct AstFile { struct ImportedFile { String path; String rel_path; - TokenPos pos; // #import + TokenPos pos; // import }; struct Parser { @@ -2098,7 +2098,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) { // Parse Procedure Type or Literal case Token_proc: { - Token token = f->curr_token; next_token(f); + Token token = expect_token(f, Token_proc); AstNode *foreign_library = NULL; String foreign_name = {}; String link_name = {}; @@ -2582,12 +2582,18 @@ AstNode *parse_value_decl(AstFile *f, Token token) { } AstNode *parse_proc_decl(AstFile *f) { + TokenKind look_ahead = look_ahead_token_kind(f, 1); + if (look_ahead != Token_Ident) { + return ast_expr_stmt(f, parse_expr(f, true)); + } + Token token = expect_token(f, Token_proc); AstNode *body = NULL; AstNode *foreign_library = NULL; String foreign_name = {}; String link_name = {}; + AstNode *name = parse_ident(f); AstNode *type = parse_proc_type(f, token, &foreign_library, &foreign_name, &link_name); u64 tags = type->ProcType.tags; @@ -3840,69 +3846,75 @@ AstNode *parse_stmt(AstFile *f) { return ast_push_context(f, token, expr, body); } break; + case Token_import: { + Token token = expect_token(f, Token_import); + AstNode *cond = NULL; + Token import_name = {}; + + switch (f->curr_token.kind) { + case Token_Period: + import_name = f->curr_token; + import_name.kind = Token_Ident; + next_token(f); + break; + case Token_Ident: + import_name = f->curr_token; + next_token(f); + break; + default: + import_name.pos = f->curr_token.pos; + break; + } + + if (import_name.string == "_") { + syntax_error(import_name, "Illegal import name: `_`"); + } + + Token file_path = expect_token_after(f, Token_String, "import"); + if (allow_token(f, Token_when)) { + cond = parse_expr(f, false); + } + + AstNode *decl = NULL; + if (f->curr_proc != NULL) { + syntax_error(import_name, "You cannot use `import` within a procedure. This must be done at the file scope"); + decl = ast_bad_decl(f, import_name, file_path); + } else { + decl = ast_import_decl(f, token, true, file_path, import_name, cond); + } + expect_semicolon(f, decl); + return decl; + } + + case Token_import_load: { + Token token = expect_token(f, Token_import_load); + AstNode *cond = NULL; + Token file_path = expect_token_after(f, Token_String, "import_load"); + Token import_name = file_path; + import_name.string = str_lit("."); + + if (allow_token(f, Token_when)) { + cond = parse_expr(f, false); + } + + AstNode *decl = NULL; + if (f->curr_proc != NULL) { + syntax_error(import_name, "You cannot use `import_load` within a procedure. This must be done at the file scope"); + decl = ast_bad_decl(f, import_name, file_path); + } else { + decl = ast_import_decl(f, token, false, file_path, import_name, cond); + } + expect_semicolon(f, decl); + return decl; + } + case Token_Hash: { AstNode *s = NULL; Token hash_token = expect_token(f, Token_Hash); Token name = expect_token(f, Token_Ident); String tag = name.string; - if (tag == "import") { - AstNode *cond = NULL; - Token import_name = {}; - - switch (f->curr_token.kind) { - case Token_Period: - import_name = f->curr_token; - import_name.kind = Token_Ident; - next_token(f); - break; - case Token_Ident: - import_name = f->curr_token; - next_token(f); - break; - default: - import_name.pos = f->curr_token.pos; - break; - } - - if (import_name.string == "_") { - syntax_error(import_name, "Illegal #import name: `_`"); - } - - Token file_path = expect_token_after(f, Token_String, "#import"); - if (allow_token(f, Token_when)) { - cond = parse_expr(f, false); - } - - AstNode *decl = NULL; - if (f->curr_proc != NULL) { - syntax_error(import_name, "You cannot use `#import` within a procedure. This must be done at the file scope"); - decl = ast_bad_decl(f, import_name, file_path); - } else { - decl = ast_import_decl(f, hash_token, true, file_path, import_name, cond); - } - expect_semicolon(f, decl); - return decl; - } else if (tag == "load") { - AstNode *cond = NULL; - Token file_path = expect_token_after(f, Token_String, "#load"); - Token import_name = file_path; - import_name.string = str_lit("."); - - if (allow_token(f, Token_when)) { - cond = parse_expr(f, false); - } - - AstNode *decl = NULL; - if (f->curr_proc != NULL) { - syntax_error(import_name, "You cannot use `#load` within a procedure. This must be done at the file scope"); - decl = ast_bad_decl(f, import_name, file_path); - } else { - decl = ast_import_decl(f, hash_token, false, file_path, import_name, cond); - } - expect_semicolon(f, decl); - return decl; - } else if (tag == "shared_global_scope") { + if (tag == "shared_global_scope") { if (f->curr_proc == NULL) { f->is_global_scope = true; s = ast_empty_stmt(f, f->curr_token); @@ -4007,7 +4019,7 @@ AstNode *parse_stmt(AstFile *f) { } if (tag == "include") { - syntax_error(token, "#include is not a valid import declaration kind. Use #load instead"); + syntax_error(token, "#include is not a valid import declaration kind. Use import_load instead"); s = ast_bad_stmt(f, token, f->curr_token); } else { syntax_error(token, "Unknown tag directive used: `%.*s`", LIT(tag)); diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index d1ea26da7..1bdeb2f10 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -82,41 +82,43 @@ TOKEN_KIND(Token__ComparisonEnd, "_ComparisonEnd"), \ TOKEN_KIND(Token__OperatorEnd, "_OperatorEnd"), \ \ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \ - TOKEN_KIND(Token_var, "var"), \ - TOKEN_KIND(Token_let, "let"), \ - TOKEN_KIND(Token_const, "const"), \ - TOKEN_KIND(Token_type, "type"), \ - TOKEN_KIND(Token_when, "when"), \ - TOKEN_KIND(Token_if, "if"), \ - TOKEN_KIND(Token_else, "else"), \ - TOKEN_KIND(Token_for, "for"), \ - TOKEN_KIND(Token_in, "in"), \ - TOKEN_KIND(Token_match, "match"), \ - TOKEN_KIND(Token_case, "case"), \ - TOKEN_KIND(Token_break, "break"), \ - TOKEN_KIND(Token_continue, "continue"), \ - TOKEN_KIND(Token_fallthrough, "fallthrough"), \ - TOKEN_KIND(Token_defer, "defer"), \ - TOKEN_KIND(Token_return, "return"), \ - TOKEN_KIND(Token_proc, "proc"), \ - TOKEN_KIND(Token_macro, "macro"), \ - TOKEN_KIND(Token_struct, "struct"), \ - TOKEN_KIND(Token_union, "union"), \ - TOKEN_KIND(Token_raw_union, "raw_union"), \ - TOKEN_KIND(Token_enum, "enum"), \ - TOKEN_KIND(Token_bit_field, "bit_field"), \ - TOKEN_KIND(Token_vector, "vector"), \ - TOKEN_KIND(Token_static, "static"), \ - TOKEN_KIND(Token_dynamic, "dynamic"), \ - TOKEN_KIND(Token_map, "map"), \ - TOKEN_KIND(Token_using, "using"), \ - TOKEN_KIND(Token_context, "context"), \ - TOKEN_KIND(Token_push_context, "push_context"), \ - TOKEN_KIND(Token_push_allocator, "push_allocator"), \ - TOKEN_KIND(Token_asm, "asm"), \ - TOKEN_KIND(Token_yield, "yield"), \ - TOKEN_KIND(Token_await, "await"), \ - TOKEN_KIND(Token_atomic, "atomic"), \ + TOKEN_KIND(Token_var, "var"), \ + TOKEN_KIND(Token_let, "let"), \ + TOKEN_KIND(Token_const, "const"), \ + TOKEN_KIND(Token_type, "type"), \ + TOKEN_KIND(Token_import, "import"), \ + TOKEN_KIND(Token_import_load, "import_load"), \ + TOKEN_KIND(Token_when, "when"), \ + TOKEN_KIND(Token_if, "if"), \ + TOKEN_KIND(Token_else, "else"), \ + TOKEN_KIND(Token_for, "for"), \ + TOKEN_KIND(Token_in, "in"), \ + TOKEN_KIND(Token_match, "match"), \ + TOKEN_KIND(Token_case, "case"), \ + TOKEN_KIND(Token_break, "break"), \ + TOKEN_KIND(Token_continue, "continue"), \ + TOKEN_KIND(Token_fallthrough, "fallthrough"), \ + TOKEN_KIND(Token_defer, "defer"), \ + TOKEN_KIND(Token_return, "return"), \ + TOKEN_KIND(Token_proc, "proc"), \ + TOKEN_KIND(Token_macro, "macro"), \ + TOKEN_KIND(Token_struct, "struct"), \ + TOKEN_KIND(Token_union, "union"), \ + TOKEN_KIND(Token_raw_union, "raw_union"), \ + TOKEN_KIND(Token_enum, "enum"), \ + TOKEN_KIND(Token_bit_field, "bit_field"), \ + TOKEN_KIND(Token_vector, "vector"), \ + TOKEN_KIND(Token_static, "static"), \ + TOKEN_KIND(Token_dynamic, "dynamic"), \ + TOKEN_KIND(Token_map, "map"), \ + TOKEN_KIND(Token_using, "using"), \ + TOKEN_KIND(Token_context, "context"), \ + TOKEN_KIND(Token_push_context, "push_context"), \ + TOKEN_KIND(Token_push_allocator, "push_allocator"), \ + TOKEN_KIND(Token_asm, "asm"), \ + TOKEN_KIND(Token_yield, "yield"), \ + TOKEN_KIND(Token_await, "await"), \ + TOKEN_KIND(Token_atomic, "atomic"), \ TOKEN_KIND(Token__KeywordEnd, "_KeywordEnd"), \ TOKEN_KIND(Token_Count, "")