Browse Source

New build flag: -define:foo=123

gingerBill 6 years ago
parent
commit
2878cd8241
4 changed files with 119 additions and 34 deletions
  1. 2 0
      src/build_settings.cpp
  2. 38 0
      src/checker.cpp
  3. 79 33
      src/main.cpp
  4. 0 1
      src/string.cpp

+ 2 - 0
src/build_settings.cpp

@@ -110,6 +110,8 @@ struct BuildContext {
 
 
 	gbAffinity affinity;
 	gbAffinity affinity;
 	isize      thread_count;
 	isize      thread_count;
+
+	Map<ExactValue> defined_values; // Key:
 };
 };
 
 
 
 

+ 38 - 0
src/checker.cpp

@@ -721,6 +721,44 @@ void init_universal(void) {
 		add_global_entity(entity, intrinsics_pkg->scope);
 		add_global_entity(entity, intrinsics_pkg->scope);
 	}
 	}
 
 
+	bool defined_values_double_declaration = true;
+	for_array(i, bc->defined_values.entries) {
+		String name = bc->defined_values.entries[i].key.string;
+		ExactValue value = bc->defined_values.entries[i].value;
+		GB_ASSERT(value.kind != ExactValue_Invalid);
+
+		Type *type = nullptr;
+		switch (value.kind) {
+		case ExactValue_Bool:
+			type = t_untyped_bool;
+			break;
+		case ExactValue_String:
+			type = t_untyped_string;
+			break;
+		case ExactValue_Integer:
+			type = t_untyped_integer;
+			break;
+		case ExactValue_Float:
+			type = t_untyped_float;
+			break;
+		}
+		GB_ASSERT(type != nullptr);
+
+
+
+		Entity *entity = alloc_entity_constant(nullptr, make_token_ident(name), type, value);
+		entity->state = EntityState_Resolved;
+		if (scope_insert(builtin_pkg->scope, entity)) {
+			error(entity->token, "'%.*s' defined as an argument is already declared at the global scope", LIT(name));
+			defined_values_double_declaration = true;
+			// NOTE(bill): Just exit early before anything, even though the compiler will do that anyway
+		}
+	}
+
+	if (defined_values_double_declaration) {
+		gb_exit(1);
+	}
+
 
 
 	t_u8_ptr       = alloc_type_pointer(t_u8);
 	t_u8_ptr       = alloc_type_pointer(t_u8);
 	t_int_ptr      = alloc_type_pointer(t_int);
 	t_int_ptr      = alloc_type_pointer(t_int);

+ 79 - 33
src/main.cpp

@@ -2,10 +2,10 @@
 
 
 #include "common.cpp"
 #include "common.cpp"
 #include "timings.cpp"
 #include "timings.cpp"
-#include "build_settings.cpp"
 #include "tokenizer.cpp"
 #include "tokenizer.cpp"
 #include "big_int.cpp"
 #include "big_int.cpp"
 #include "exact_value.cpp"
 #include "exact_value.cpp"
+#include "build_settings.cpp"
 
 
 #include "parser.hpp"
 #include "parser.hpp"
 #include "checker.hpp"
 #include "checker.hpp"
@@ -207,6 +207,7 @@ enum BuildFlagKind {
 	BuildFlag_ThreadCount,
 	BuildFlag_ThreadCount,
 	BuildFlag_KeepTempFiles,
 	BuildFlag_KeepTempFiles,
 	BuildFlag_Collection,
 	BuildFlag_Collection,
+	BuildFlag_Define,
 	BuildFlag_BuildMode,
 	BuildFlag_BuildMode,
 	BuildFlag_Debug,
 	BuildFlag_Debug,
 	BuildFlag_CrossCompile,
 	BuildFlag_CrossCompile,
@@ -242,6 +243,41 @@ void add_flag(Array<BuildFlag> *build_flags, BuildFlagKind kind, String name, Bu
 	array_add(build_flags, flag);
 	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<String> args) {
 bool parse_build_flags(Array<String> args) {
 	auto build_flags = array_make<BuildFlag>(heap_allocator(), 0, BuildFlag_COUNT);
 	auto build_flags = array_make<BuildFlag>(heap_allocator(), 0, BuildFlag_COUNT);
 	add_flag(&build_flags, BuildFlag_OutFile,           str_lit("out"),             BuildFlagParam_String);
 	add_flag(&build_flags, BuildFlag_OutFile,           str_lit("out"),             BuildFlagParam_String);
@@ -251,6 +287,7 @@ bool parse_build_flags(Array<String> args) {
 	add_flag(&build_flags, BuildFlag_ThreadCount,       str_lit("thread-count"),    BuildFlagParam_Integer);
 	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_KeepTempFiles,     str_lit("keep-temp-files"), BuildFlagParam_None);
 	add_flag(&build_flags, BuildFlag_Collection,        str_lit("collection"),      BuildFlagParam_String);
 	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_BuildMode,         str_lit("build-mode"),      BuildFlagParam_String);
 	add_flag(&build_flags, BuildFlag_Debug,             str_lit("debug"),           BuildFlagParam_None);
 	add_flag(&build_flags, BuildFlag_Debug,             str_lit("debug"),           BuildFlagParam_None);
 	add_flag(&build_flags, BuildFlag_CrossCompile,      str_lit("cross-compile"),   BuildFlagParam_String);
 	add_flag(&build_flags, BuildFlag_CrossCompile,      str_lit("cross-compile"),   BuildFlagParam_String);
@@ -276,7 +313,8 @@ bool parse_build_flags(Array<String> args) {
 		String name = substring(flag, 1, flag.len);
 		String name = substring(flag, 1, flag.len);
 		isize end = 0;
 		isize end = 0;
 		for (; end < name.len; end++) {
 		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);
 		name = substring(name, 0, end);
 		String param = {};
 		String param = {};
@@ -306,7 +344,9 @@ bool parse_build_flags(Array<String> args) {
 					} else {
 					} else {
 						ok = true;
 						ok = true;
 						switch (bf.param_kind) {
 						switch (bf.param_kind) {
-						default: ok = false; break;
+						default:
+							ok = false;
+							break;
 						case BuildFlagParam_Boolean: {
 						case BuildFlagParam_Boolean: {
 							if (str_eq_ignore_case(param, str_lit("t")) ||
 							if (str_eq_ignore_case(param, str_lit("t")) ||
 							    str_eq_ignore_case(param, str_lit("true")) ||
 							    str_eq_ignore_case(param, str_lit("true")) ||
@@ -465,7 +505,7 @@ bool parse_build_flags(Array<String> args) {
 							break;
 							break;
 						}
 						}
 
 
-						case BuildFlag_Collection: {
+						case BuildFlag_Define: {
 							GB_ASSERT(value.kind == ExactValue_String);
 							GB_ASSERT(value.kind == ExactValue_String);
 							String str = value.value_string;
 							String str = value.value_string;
 							isize eq_pos = -1;
 							isize eq_pos = -1;
@@ -476,59 +516,50 @@ bool parse_build_flags(Array<String> args) {
 								}
 								}
 							}
 							}
 							if (eq_pos < 0) {
 							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;
 								bad_flags = true;
 								break;
 								break;
 							}
 							}
 							String name = substring(str, 0, eq_pos);
 							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;
 								bad_flags = true;
 								break;
 								break;
 							}
 							}
 
 
 							if (!string_is_valid_identifier(name)) {
 							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;
 								bad_flags = true;
 								break;
 								break;
 							}
 							}
 
 
 							if (name == "_") {
 							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;
 								bad_flags = true;
 								break;
 								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;
 								bad_flags = true;
 								break;
 								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;
 								bad_flags = true;
-								break;
 							}
 							}
 
 
-							add_library_collection(name, path);
-
-							// NOTE(bill): Allow for multiple library collections
-							continue;
+							break;
 						}
 						}
 
 
+
+
 						case BuildFlag_BuildMode: {
 						case BuildFlag_BuildMode: {
 							GB_ASSERT(value.kind == ExactValue_String);
 							GB_ASSERT(value.kind == ExactValue_String);
 							String str = value.value_string;
 							String str = value.value_string;
@@ -599,8 +630,13 @@ void show_timings(Checker *c, Timings *t) {
 	isize tokens   = p->total_token_count;
 	isize tokens   = p->total_token_count;
 	isize files    = 0;
 	isize files    = 0;
 	isize packages = p->packages.count;
 	isize packages = p->packages.count;
+	isize total_file_size = 0;
 	for_array(i, p->packages) {
 	for_array(i, p->packages) {
 		files += p->packages[i]->files.count;
 		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
 #if 1
 	timings_print_all(t);
 	timings_print_all(t);
@@ -608,10 +644,11 @@ void show_timings(Checker *c, Timings *t) {
 	{
 	{
 		timings_print_all(t);
 		timings_print_all(t);
 		gb_printf("\n");
 		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");
 		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("us/LOC       - %.3f\n", 1.0e6*parse_time/cast(f64)lines);
 		gb_printf("Tokens/s     - %.3f\n", cast(f64)tokens/parse_time);
 		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("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");
 		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("us/LOC       - %.3f\n", 1.0e6*parse_time/cast(f64)lines);
 		gb_printf("Tokens/s     - %.3f\n", cast(f64)tokens/parse_time);
 		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("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");
 		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("us/LOC       - %.3f\n", 1.0e6*total_time/cast(f64)lines);
 		gb_printf("Tokens/s     - %.3f\n", cast(f64)tokens/total_time);
 		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("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");
 		gb_printf("\n");
 	}
 	}
 #endif
 #endif
@@ -741,6 +785,8 @@ int main(int arg_count, char **arg_ptr) {
 	// NOTE(bill): 'core' cannot be (re)defined by the user
 	// 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")));
 	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<String> args = setup_args(arg_count, arg_ptr);
 	Array<String> args = setup_args(arg_count, arg_ptr);
 
 
 	String command = args[1];
 	String command = args[1];

+ 0 - 1
src/string.cpp

@@ -308,7 +308,6 @@ String directory_from_path(String const &s) {
 	return substring(s, 0, i);
 	return substring(s, 0, i);
 }
 }
 
 
-
 String concatenate_strings(gbAllocator a, String const &x, String const &y) {
 String concatenate_strings(gbAllocator a, String const &x, String const &y) {
 	isize len = x.len+y.len;
 	isize len = x.len+y.len;
 	u8 *data = gb_alloc_array(a, u8, len+1);
 	u8 *data = gb_alloc_array(a, u8, len+1);