From 2878cd8241d6cbb57a7a2f927be7407d11ad80d8 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 23 Feb 2019 23:21:27 +0000 Subject: New build flag: -define:foo=123 --- src/main.cpp | 112 +++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 79 insertions(+), 33 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 51a6856d1..fb88e9c34 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,10 +2,10 @@ #include "common.cpp" #include "timings.cpp" -#include "build_settings.cpp" #include "tokenizer.cpp" #include "big_int.cpp" #include "exact_value.cpp" +#include "build_settings.cpp" #include "parser.hpp" #include "checker.hpp" @@ -207,6 +207,7 @@ enum BuildFlagKind { BuildFlag_ThreadCount, BuildFlag_KeepTempFiles, BuildFlag_Collection, + BuildFlag_Define, BuildFlag_BuildMode, BuildFlag_Debug, BuildFlag_CrossCompile, @@ -242,6 +243,41 @@ void add_flag(Array *build_flags, BuildFlagKind kind, String name, Bu array_add(build_flags, flag); } +ExactValue build_param_to_exact_value(String name, String param) { + ExactValue value = {}; + if (str_eq_ignore_case(param, str_lit("t")) || + str_eq_ignore_case(param, str_lit("true"))) { + value = exact_value_bool(true); + } else if (str_eq_ignore_case(param, str_lit("f")) || + str_eq_ignore_case(param, str_lit("false"))) { + value = exact_value_bool(false); + } else if (param.len > 0) { + if (param[0] == '"') { + value = exact_value_string(param); + if (value.kind == ExactValue_String) { + String s = value.value_string; + if (s.len > 1 && s[0] == '"' && s[s.len-1] == '"') { + value.value_string = substring(s, 1, s.len-1); + } + } + } else if (param[0] == '-' || param[0] == '+' || gb_is_between(param[0], '0', '9')) { + if (string_contains_char(param, '.')) { + value = exact_value_float_from_string(param); + } else { + value = exact_value_integer_from_string(param); + } + if (value.kind == ExactValue_Invalid) { + gb_printf_err("Invalid flag parameter for '%.*s' = '%.*s'\n", LIT(name), LIT(param)); + } + } + } else { + gb_printf_err("Invalid flag parameter for '%.*s' = '%.*s'\n", LIT(name), LIT(param)); + } + + return value; +} + + bool parse_build_flags(Array args) { auto build_flags = array_make(heap_allocator(), 0, BuildFlag_COUNT); add_flag(&build_flags, BuildFlag_OutFile, str_lit("out"), BuildFlagParam_String); @@ -251,6 +287,7 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_ThreadCount, str_lit("thread-count"), BuildFlagParam_Integer); add_flag(&build_flags, BuildFlag_KeepTempFiles, str_lit("keep-temp-files"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_Collection, str_lit("collection"), BuildFlagParam_String); + add_flag(&build_flags, BuildFlag_Define, str_lit("define"), BuildFlagParam_String); add_flag(&build_flags, BuildFlag_BuildMode, str_lit("build-mode"), BuildFlagParam_String); add_flag(&build_flags, BuildFlag_Debug, str_lit("debug"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_CrossCompile, str_lit("cross-compile"), BuildFlagParam_String); @@ -276,7 +313,8 @@ bool parse_build_flags(Array args) { String name = substring(flag, 1, flag.len); isize end = 0; for (; end < name.len; end++) { - if (name[end] == '=') break; + if (name[end] == ':') break; + if (name[end] == '=') break; // IMPORTANT TODO(bill): DEPRECATE THIS!!!! } name = substring(name, 0, end); String param = {}; @@ -306,7 +344,9 @@ bool parse_build_flags(Array args) { } else { ok = true; switch (bf.param_kind) { - default: ok = false; break; + default: + ok = false; + break; case BuildFlagParam_Boolean: { if (str_eq_ignore_case(param, str_lit("t")) || str_eq_ignore_case(param, str_lit("true")) || @@ -465,7 +505,7 @@ bool parse_build_flags(Array args) { break; } - case BuildFlag_Collection: { + case BuildFlag_Define: { GB_ASSERT(value.kind == ExactValue_String); String str = value.value_string; isize eq_pos = -1; @@ -476,59 +516,50 @@ bool parse_build_flags(Array args) { } } if (eq_pos < 0) { - gb_printf_err("Expected 'name=path', got '%.*s'\n", LIT(param)); + gb_printf_err("Expected 'name=value', got '%.*s'\n", LIT(param)); bad_flags = true; break; } String name = substring(str, 0, eq_pos); - String path = substring(str, eq_pos+1, str.len); - if (name.len == 0 || path.len == 0) { - gb_printf_err("Expected 'name=path', got '%.*s'\n", LIT(param)); + String value = substring(str, eq_pos+1, str.len); + if (name.len == 0 || value.len == 0) { + gb_printf_err("Expected 'name=value', got '%.*s'\n", LIT(param)); bad_flags = true; break; } if (!string_is_valid_identifier(name)) { - gb_printf_err("Library collection name '%.*s' must be a valid identifier\n", LIT(name)); + gb_printf_err("Defined constant name '%.*s' must be a valid identifier\n", LIT(name)); bad_flags = true; break; } if (name == "_") { - gb_printf_err("Library collection name cannot be an underscore\n"); + gb_printf_err("Defined constant name cannot be an underscore\n"); bad_flags = true; break; } - if (name == "system") { - gb_printf_err("Library collection name 'system' is reserved\n"); - bad_flags = true; - break; - } + HashKey key = hash_string(name); - String prev_path = {}; - bool found = find_library_collection_path(name, &prev_path); - if (found) { - gb_printf_err("Library collection '%.*s' already exists with path '%.*s'\n", LIT(name), LIT(prev_path)); + if (map_get(&build_context.defined_values, key) != nullptr) { + gb_printf_err("Defined constant '%.*s' already exists\n", LIT(name)); bad_flags = true; break; } - gbAllocator a = heap_allocator(); - String fullpath = path_to_fullpath(a, path); - if (!path_is_directory(fullpath)) { - gb_printf_err("Library collection '%.*s' path must be a directory, got '%.*s'\n", LIT(name), LIT(fullpath)); - gb_free(a, fullpath.text); + ExactValue v = build_param_to_exact_value(name, value); + if (v.kind != ExactValue_Invalid) { + map_set(&build_context.defined_values, key, v); + } else { bad_flags = true; - break; } - add_library_collection(name, path); - - // NOTE(bill): Allow for multiple library collections - continue; + break; } + + case BuildFlag_BuildMode: { GB_ASSERT(value.kind == ExactValue_String); String str = value.value_string; @@ -599,8 +630,13 @@ void show_timings(Checker *c, Timings *t) { isize tokens = p->total_token_count; isize files = 0; isize packages = p->packages.count; + isize total_file_size = 0; for_array(i, p->packages) { files += p->packages[i]->files.count; + for_array(j, p->packages[i]->files) { + AstFile *file = p->packages[i]->files[j]; + total_file_size += file->tokenizer.end - file->tokenizer.start; + } } #if 1 timings_print_all(t); @@ -608,10 +644,11 @@ void show_timings(Checker *c, Timings *t) { { timings_print_all(t); gb_printf("\n"); - gb_printf("Total Lines - %td\n", lines); - gb_printf("Total Tokens - %td\n", tokens); - gb_printf("Total Files - %td\n", files); - gb_printf("Total Packages - %td\n", packages); + gb_printf("Total Lines - %td\n", lines); + gb_printf("Total Tokens - %td\n", tokens); + gb_printf("Total Files - %td\n", files); + gb_printf("Total Packages - %td\n", packages); + gb_printf("Total File Size - %td\n", total_file_size); gb_printf("\n"); } { @@ -623,6 +660,9 @@ void show_timings(Checker *c, Timings *t) { gb_printf("us/LOC - %.3f\n", 1.0e6*parse_time/cast(f64)lines); gb_printf("Tokens/s - %.3f\n", cast(f64)tokens/parse_time); gb_printf("us/Token - %.3f\n", 1.0e6*parse_time/cast(f64)tokens); + gb_printf("bytes/s - %.3f\n", cast(f64)total_file_size/parse_time); + gb_printf("us/bytes - %.3f\n", 1.0e6*parse_time/cast(f64)total_file_size); + gb_printf("\n"); } { @@ -634,6 +674,8 @@ void show_timings(Checker *c, Timings *t) { gb_printf("us/LOC - %.3f\n", 1.0e6*parse_time/cast(f64)lines); gb_printf("Tokens/s - %.3f\n", cast(f64)tokens/parse_time); gb_printf("us/Token - %.3f\n", 1.0e6*parse_time/cast(f64)tokens); + gb_printf("bytes/s - %.3f\n", cast(f64)total_file_size/parse_time); + gb_printf("us/bytes - %.3f\n", 1.0e6*parse_time/cast(f64)total_file_size); gb_printf("\n"); } { @@ -643,6 +685,8 @@ void show_timings(Checker *c, Timings *t) { gb_printf("us/LOC - %.3f\n", 1.0e6*total_time/cast(f64)lines); gb_printf("Tokens/s - %.3f\n", cast(f64)tokens/total_time); gb_printf("us/Token - %.3f\n", 1.0e6*total_time/cast(f64)tokens); + gb_printf("bytes/s - %.3f\n", cast(f64)total_file_size/total_time); + gb_printf("us/bytes - %.3f\n", 1.0e6*total_time/cast(f64)total_file_size); gb_printf("\n"); } #endif @@ -741,6 +785,8 @@ int main(int arg_count, char **arg_ptr) { // NOTE(bill): 'core' cannot be (re)defined by the user add_library_collection(str_lit("core"), get_fullpath_relative(heap_allocator(), odin_root_dir(), str_lit("core"))); + map_init(&build_context.defined_values, heap_allocator()); + Array args = setup_args(arg_count, arg_ptr); String command = args[1]; -- cgit v1.2.3 From cdfaa643ccdc54e0fba3bc43536f33e5ae8debac Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 23 Feb 2019 23:30:03 +0000 Subject: Reimplement -collection; remove `static` from Odin tokenizer/parser in core library --- build.bat | 4 +-- core/odin/ast/ast.odin | 1 - core/odin/parser/parser.odin | 31 --------------------- core/odin/token/token.odin | 2 -- src/main.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 67 insertions(+), 36 deletions(-) (limited to 'src/main.cpp') diff --git a/build.bat b/build.bat index 402d8842c..58ae69f93 100644 --- a/build.bat +++ b/build.bat @@ -42,8 +42,8 @@ del *.ilk > NUL 2> NUL cl %compiler_settings% "src\main.cpp" ^ /link %linker_settings% -OUT:%exe_name% ^ - && odin run examples/demo/demo.odin + && odin run examples/demo/demo.odin -keep-temp-files del *.obj > NUL 2> NUL -:end_of_build \ No newline at end of file +:end_of_build diff --git a/core/odin/ast/ast.odin b/core/odin/ast/ast.odin index 784c89e6a..8c43ee8e3 100644 --- a/core/odin/ast/ast.odin +++ b/core/odin/ast/ast.odin @@ -365,7 +365,6 @@ Value_Decl :: struct { type: ^Expr, values: []^Expr, comment: ^Comment_Group, - is_static: bool, is_using: bool, is_mutable: bool, } diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index 7c7a816c9..4c43a20e5 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -1033,37 +1033,6 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt { expect_semicolon(p, s); return s; - case token.Static: - docs := p.lead_comment; - tok := expect_token(p, token.Static); - - list := parse_lhs_expr_list(p); - if len(list) == 0 { - error(p, tok.pos, "illegal use of 'static' statement"); - expect_semicolon(p, nil); - return ast.new(ast.Bad_Stmt, tok.pos, end_pos(p.prev_tok)); - } - - expect_token_after(p, token.Colon, "identifier list"); - decl := parse_value_decl(p, list, docs); - if decl != nil do switch d in &decl.derived { - case ast.Value_Decl: - if d.is_mutable { - d.is_static = true; - } else { - error(p, tok.pos, "'static' may only be currently used with variable declarations"); - } - case: - error(p, tok.pos, "illegal use of 'static' statement"); - } - - error(p, tok.pos, "illegal use of 'static' statement"); - if decl != nil { - return decl; - } - - return ast.new(ast.Bad_Stmt, tok.pos, end_pos(p.prev_tok)); - case token.Using: docs := p.lead_comment; tok := expect_token(p, token.Using); diff --git a/core/odin/token/token.odin b/core/odin/token/token.odin index 46b3fc846..f52f6301e 100644 --- a/core/odin/token/token.odin +++ b/core/odin/token/token.odin @@ -139,7 +139,6 @@ using Kind :: enum u16 { Bit_Field, Bit_Set, Map, - Static, Dynamic, Auto_Cast, Cast, @@ -274,7 +273,6 @@ tokens := [Kind.COUNT]string { "bit_field", "bit_set", "map", - "static", "dynamic", "auto_cast", "cast", diff --git a/src/main.cpp b/src/main.cpp index fb88e9c34..beda80cad 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -505,6 +505,71 @@ bool parse_build_flags(Array args) { break; } + case BuildFlag_Collection: { + GB_ASSERT(value.kind == ExactValue_String); + String str = value.value_string; + isize eq_pos = -1; + for (isize i = 0; i < str.len; i++) { + if (str[i] == '=') { + eq_pos = i; + break; + } + } + if (eq_pos < 0) { + gb_printf_err("Expected 'name=path', got '%.*s'\n", LIT(param)); + bad_flags = true; + break; + } + String name = substring(str, 0, eq_pos); + String path = substring(str, eq_pos+1, str.len); + if (name.len == 0 || path.len == 0) { + gb_printf_err("Expected 'name=path', got '%.*s'\n", LIT(param)); + bad_flags = true; + break; + } + + if (!string_is_valid_identifier(name)) { + gb_printf_err("Library collection name '%.*s' must be a valid identifier\n", LIT(name)); + bad_flags = true; + break; + } + + if (name == "_") { + gb_printf_err("Library collection name cannot be an underscore\n"); + bad_flags = true; + break; + } + + if (name == "system") { + gb_printf_err("Library collection name 'system' is reserved\n"); + bad_flags = true; + break; + } + + String prev_path = {}; + bool found = find_library_collection_path(name, &prev_path); + if (found) { + gb_printf_err("Library collection '%.*s' already exists with path '%.*s'\n", LIT(name), LIT(prev_path)); + bad_flags = true; + break; + } + + gbAllocator a = heap_allocator(); + String fullpath = path_to_fullpath(a, path); + if (!path_is_directory(fullpath)) { + gb_printf_err("Library collection '%.*s' path must be a directory, got '%.*s'\n", LIT(name), LIT(fullpath)); + gb_free(a, fullpath.text); + bad_flags = true; + break; + } + + add_library_collection(name, path); + + // NOTE(bill): Allow for multiple library collections + continue; + } + + case BuildFlag_Define: { GB_ASSERT(value.kind == ExactValue_String); String str = value.value_string; -- cgit v1.2.3