aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-01-15 17:34:35 +0000
committergingerBill <bill@gingerbill.org>2022-01-15 17:34:35 +0000
commit6c4867081985a8dd1cccb3e5c503d72807e4ee87 (patch)
treead05274b4f59af1fd043917553894d7879141057 /src
parent51dcbc80c3f0ef8755a0dc07b257ca93b264c2cc (diff)
Make `ODIN_BUILD_MODE` a enum type
Diffstat (limited to 'src')
-rw-r--r--src/build_settings.cpp23
-rw-r--r--src/check_expr.cpp112
-rw-r--r--src/checker.cpp64
3 files changed, 128 insertions, 71 deletions
diff --git a/src/build_settings.cpp b/src/build_settings.cpp
index ccae0fcf0..bafa93042 100644
--- a/src/build_settings.cpp
+++ b/src/build_settings.cpp
@@ -119,6 +119,8 @@ enum BuildModeKind {
BuildMode_Object,
BuildMode_Assembly,
BuildMode_LLVM_IR,
+
+ BuildMode_COUNT,
};
enum CommandKind : u32 {
@@ -172,10 +174,9 @@ struct BuildContext {
String ODIN_VENDOR; // compiler vendor
String ODIN_VERSION; // compiler version
String ODIN_ROOT; // Odin ROOT
- String ODIN_BUILD_MODE;
bool ODIN_DEBUG; // Odin in debug mode
bool ODIN_DISABLE_ASSERT; // Whether the default 'assert' et al is disabled in code or not
- bool ODIN_DEFAULT_TO_NIL_ALLOCATOR; // Whether the default allocator is a "nil" allocator or not (i.e. it does nothing)
+bool ODIN_DEFAULT_TO_NIL_ALLOCATOR; // Whether the default allocator is a "nil" allocator or not (i.e. it does nothing)
TargetEndianKind endian_kind;
@@ -855,24 +856,6 @@ void init_build_context(TargetMetrics *cross_target) {
bc->ODIN_VENDOR = str_lit("odin");
bc->ODIN_VERSION = ODIN_VERSION;
bc->ODIN_ROOT = odin_root_dir();
- switch (bc->build_mode) {
- default:
- case BuildMode_Executable:
- bc->ODIN_BUILD_MODE = str_lit("executable");
- break;
- case BuildMode_DynamicLibrary:
- bc->ODIN_BUILD_MODE = str_lit("dynamic");
- break;
- case BuildMode_Object:
- bc->ODIN_BUILD_MODE = str_lit("object");
- break;
- case BuildMode_Assembly:
- bc->ODIN_BUILD_MODE = str_lit("assembly");
- break;
- case BuildMode_LLVM_IR:
- bc->ODIN_BUILD_MODE = str_lit("llvm-ir");
- break;
- }
bc->copy_file_contents = true;
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index 1162cefee..8667d8734 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -119,6 +119,58 @@ void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name
void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Operand const &x, Type *type_hint);
void check_or_return_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_);
+
+void check_did_you_mean_print(DidYouMeanAnswers *d, char const *prefix = "") {
+ auto results = did_you_mean_results(d);
+ if (results.count != 0) {
+ error_line("\tSuggestion: Did you mean?\n");
+ for_array(i, results) {
+ String const &target = results[i].target;
+ error_line("\t\t%s%.*s\n", prefix, LIT(target));
+ // error_line("\t\t%.*s %td\n", LIT(target), results[i].distance);
+ }
+ }
+}
+
+void check_did_you_mean_type(String const &name, Array<Entity *> const &fields, char const *prefix = "") {
+ ERROR_BLOCK();
+
+ DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name);
+ defer (did_you_mean_destroy(&d));
+
+ for_array(i, fields) {
+ did_you_mean_append(&d, fields[i]->token.string);
+ }
+ check_did_you_mean_print(&d, prefix);
+}
+
+void check_did_you_mean_type(String const &name, Slice<Entity *> const &fields, char const *prefix = "") {
+ ERROR_BLOCK();
+
+ DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name);
+ defer (did_you_mean_destroy(&d));
+
+ for_array(i, fields) {
+ did_you_mean_append(&d, fields[i]->token.string);
+ }
+ check_did_you_mean_print(&d, prefix);
+}
+
+void check_did_you_mean_scope(String const &name, Scope *scope, char const *prefix = "") {
+ ERROR_BLOCK();
+
+ DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.entries.count, name);
+ defer (did_you_mean_destroy(&d));
+
+ mutex_lock(&scope->mutex);
+ for_array(i, scope->elements.entries) {
+ Entity *e = scope->elements.entries[i].value;
+ did_you_mean_append(&d, e->token.string);
+ }
+ mutex_unlock(&scope->mutex);
+ check_did_you_mean_print(&d, prefix);
+}
+
Entity *entity_from_expr(Ast *expr) {
expr = unparen_expr(expr);
switch (expr->kind) {
@@ -3361,7 +3413,17 @@ void convert_untyped_error(CheckerContext *c, Operand *operand, Type *target_typ
}
}
}
+ ERROR_BLOCK();
+
error(operand->expr, "Cannot convert untyped value '%s' to '%s' from '%s'%s", expr_str, type_str, from_type_str, extra_text);
+ if (operand->value.kind == ExactValue_String) {
+ String key = operand->value.value_string;
+ if (is_type_string(operand->type) && is_type_enum(target_type)) {
+ gb_printf_err("HERE!\n");
+ Type *et = base_type(target_type);
+ check_did_you_mean_type(key, et->Enum.fields, ".");
+ }
+ }
gb_string_free(from_type_str);
gb_string_free(type_str);
@@ -3979,56 +4041,6 @@ ExactValue get_constant_field(CheckerContext *c, Operand const *operand, Selecti
if (success_) *success_ = true;
return empty_exact_value;
}
-void check_did_you_mean_print(DidYouMeanAnswers *d) {
- auto results = did_you_mean_results(d);
- if (results.count != 0) {
- error_line("\tSuggestion: Did you mean?\n");
- for_array(i, results) {
- String const &target = results[i].target;
- error_line("\t\t%.*s\n", LIT(target));
- // error_line("\t\t%.*s %td\n", LIT(target), results[i].distance);
- }
- }
-}
-
-void check_did_you_mean_type(String const &name, Array<Entity *> const &fields) {
- ERROR_BLOCK();
-
- DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name);
- defer (did_you_mean_destroy(&d));
-
- for_array(i, fields) {
- did_you_mean_append(&d, fields[i]->token.string);
- }
- check_did_you_mean_print(&d);
-}
-
-void check_did_you_mean_type(String const &name, Slice<Entity *> const &fields) {
- ERROR_BLOCK();
-
- DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name);
- defer (did_you_mean_destroy(&d));
-
- for_array(i, fields) {
- did_you_mean_append(&d, fields[i]->token.string);
- }
- check_did_you_mean_print(&d);
-}
-
-void check_did_you_mean_scope(String const &name, Scope *scope) {
- ERROR_BLOCK();
-
- DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.entries.count, name);
- defer (did_you_mean_destroy(&d));
-
- mutex_lock(&scope->mutex);
- for_array(i, scope->elements.entries) {
- Entity *e = scope->elements.entries[i].value;
- did_you_mean_append(&d, e->token.string);
- }
- mutex_unlock(&scope->mutex);
- check_did_you_mean_print(&d);
-}
Type *determine_swizzle_array_type(Type *original_type, Type *type_hint, isize new_count) {
Type *array_type = base_type(type_deref(original_type));
diff --git a/src/checker.cpp b/src/checker.cpp
index f261c8f4a..c3dcd1d11 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -780,6 +780,54 @@ AstPackage *create_builtin_package(char const *name) {
return pkg;
}
+struct GlobalEnumValue {
+ char const *name;
+ i64 value;
+};
+
+Slice<Entity *> add_global_enum_type(String const &type_name, GlobalEnumValue *values, isize value_count) {
+ Scope *scope = create_scope(nullptr, builtin_pkg->scope);
+ Entity *e = alloc_entity_type_name(scope, make_token_ident(type_name), nullptr, EntityState_Resolved);
+
+ Type *enum_type = alloc_type_enum();
+ Type *named_type = alloc_type_named(type_name, enum_type, e);
+ set_base_type(named_type, enum_type);
+ enum_type->Enum.base_type = t_int;
+ enum_type->Enum.scope = scope;
+
+ auto fields = array_make<Entity *>(permanent_allocator(), value_count);
+ for (isize i = 0; i < value_count; i++) {
+ i64 value = values[i].value;
+ Entity *e = alloc_entity_constant(scope, make_token_ident(values[i].name), named_type, exact_value_i64(value));
+ e->flags |= EntityFlag_Visited;
+ e->state = EntityState_Resolved;
+ fields[i] = e;
+
+ Entity *ie = scope_insert(scope, e);
+ GB_ASSERT(ie == nullptr);
+ }
+
+
+ enum_type->Enum.fields = fields;
+ enum_type->Enum.min_value_index = 0;
+ enum_type->Enum.max_value_index = value_count-1;
+ enum_type->Enum.min_value = &enum_type->Enum.fields[enum_type->Enum.min_value_index]->Constant.value;
+ enum_type->Enum.max_value = &enum_type->Enum.fields[enum_type->Enum.max_value_index]->Constant.value;
+
+ return slice_from_array(fields);
+}
+void add_global_enum_constant(Slice<Entity *> const &fields, char const *name, i64 value) {
+ for (Entity *field : fields) {
+ GB_ASSERT(field->kind == Entity_Constant);
+ if (value == exact_value_to_i64(field->Constant.value)) {
+ add_global_constant(name, field->type, field->Constant.value);
+ return;
+ }
+ }
+ GB_PANIC("Unfound enum value for global constant: %s %lld", name, cast(long long)value);
+}
+
+
void init_universal(void) {
BuildContext *bc = &build_context;
@@ -815,7 +863,21 @@ void init_universal(void) {
add_global_string_constant("ODIN_VERSION", bc->ODIN_VERSION);
add_global_string_constant("ODIN_ROOT", bc->ODIN_ROOT);
- add_global_string_constant("ODIN_BUILD_MODE", bc->ODIN_BUILD_MODE);
+ {
+ GlobalEnumValue values[BuildMode_COUNT] = {
+ {"Executable", BuildMode_Executable},
+ {"Dynamic", BuildMode_DynamicLibrary},
+ {"Object", BuildMode_Object},
+ {"Assembly", BuildMode_Assembly},
+ {"LLVM_IR", BuildMode_LLVM_IR},
+ };
+
+ auto fields = add_global_enum_type(str_lit("Odin_Build_Mode_Type"), values, gb_count_of(values));
+ add_global_enum_constant(fields, "ODIN_BUILD_MODE", bc->build_mode);
+ }
+
+ // add_global_string_constant("ODIN_BUILD_MODE", bc->ODIN_BUILD_MODE);
+
add_global_bool_constant("ODIN_DEBUG", bc->ODIN_DEBUG);
add_global_bool_constant("ODIN_DISABLE_ASSERT", bc->ODIN_DISABLE_ASSERT);
add_global_bool_constant("ODIN_DEFAULT_TO_NIL_ALLOCATOR", bc->ODIN_DEFAULT_TO_NIL_ALLOCATOR);