From f040360f3fe05ba8b9d9bc50c16a2dda585a81df Mon Sep 17 00:00:00 2001 From: David Gonzalez Martin Date: Thu, 5 Jun 2025 04:42:39 -0600 Subject: [PATCH] wip --- src/compiler.bbb | 1 + src/compiler.cpp | 14 ++++++++++-- src/compiler.hpp | 11 +++++++++- src/emitter.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ src/parser.cpp | 11 ++++++++-- 5 files changed, 89 insertions(+), 5 deletions(-) diff --git a/src/compiler.bbb b/src/compiler.bbb index b6dda3d..b4b6854 100644 --- a/src/compiler.bbb +++ b/src/compiler.bbb @@ -5451,6 +5451,7 @@ compile_file = fn (arena: &Arena, compile_options: CompileFile) void >is_compiler = string_equal(relative_file_path, "src/compiler.bbb"); >outputh_path_dir = arena_join_string(arena, [ base_cache_dir, + #enum_name(#build_mode), #select(is_compiler, "/compiler/", "/"), #enum_name(compile_options.build_mode), "_", diff --git a/src/compiler.cpp b/src/compiler.cpp index 625dc05..107b7d8 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -605,7 +605,7 @@ void entry_point(Slice arguments, Slice envp) bool has_debug_info = true; String relative_file_path_parts[] = { string_literal("tests/"), name, string_literal(".bbb") }; auto relative_file_path = arena_join_string(arena, array_to_slice(relative_file_path_parts)); - char* const arguments[] = + char* const compiler_arguments[] = { (char*)compiler.pointer, (char*)"compile", @@ -614,7 +614,7 @@ void entry_point(Slice arguments, Slice envp) (char*)(has_debug_info ? "true" : "false"), 0, }; - Slice arg_slice = array_to_slice(arguments); + Slice arg_slice = array_to_slice(compiler_arguments); arg_slice.length -= 1; auto execution = os_execute(arena, arg_slice, environment, {}); auto success = execution.termination_kind == TerminationKind::exit && execution.termination_code == 0; @@ -625,6 +625,16 @@ void entry_point(Slice arguments, Slice envp) print(string_literal("\n")); bb_fail(); } + + char* const run_arguments[] = + { + (char*)compiler.pointer, + (char*)"compile", + (char*)relative_file_path.pointer, + (char*)build_mode_to_string(build_mode).pointer, + (char*)(has_debug_info ? "true" : "false"), + 0, + }; break; } } diff --git a/src/compiler.hpp b/src/compiler.hpp index 6c6fe86..c4d7216 100644 --- a/src/compiler.hpp +++ b/src/compiler.hpp @@ -336,7 +336,7 @@ enum class TypeId struct TypeInteger { - u32 bit_count; + u64 bit_count; bool is_signed; }; @@ -840,6 +840,7 @@ enum class ValueId string_to_enum, local, argument, + build_mode, }; struct ValueConstantInteger @@ -1293,6 +1294,7 @@ struct Module Type* first_function_type; Type* va_list_type; + Type* build_mode_enum; Value* void_value; Global* first_global; @@ -2037,6 +2039,13 @@ fn Type* resolve_alias(Module* module, Type* type) } +fn u64 enum_bit_count(u64 highest_value) +{ + auto needed_bit_count = 64 - (u64)clz(highest_value); + needed_bit_count = needed_bit_count ? needed_bit_count : 1; + return needed_bit_count; +} + struct ArgBuilder { char* args[128]; diff --git a/src/emitter.cpp b/src/emitter.cpp index 4061b6e..817c5ca 100644 --- a/src/emitter.cpp +++ b/src/emitter.cpp @@ -2609,6 +2609,52 @@ fn void copy_block(Module* module, Scope* parent_scope, BlockCopy copy) } } +fn Type* get_build_mode_enum(Module* module) +{ + auto result = module->build_mode_enum; + + if (!result) + { + String enum_names[] = { + string_literal("debug_none"), + string_literal("debug"), + string_literal("soft_optimize"), + string_literal("optimize_for_speed"), + string_literal("optimize_for_size"), + string_literal("aggressively_optimize_for_speed"), + string_literal("aggressively_optimize_for_size"), + }; + + auto enum_fields = arena_allocate(module->arena, array_length(enum_names)); + + u64 field_value = 0; + for (String enum_name : enum_names) + { + enum_fields[field_value] = { + .name = enum_name, + .value = field_value, + }; + + field_value += 1; + } + + auto backing_type = integer_type(module, { .bit_count = array_length(enum_names) - 1, .is_signed = false }); + + result = type_allocate_init(module, { + .enumerator = { + .fields = enum_fields, + .backing_type = backing_type, + }, + .id = TypeId::enumerator, + .name = string_literal("BuildMode"), + .scope = &module->scope, + }); + } + + assert(result); + return result; +} + fn void analyze_type(Module* module, Value* value, Type* expected_type, TypeAnalysis analysis) { assert(!value->type); @@ -4341,6 +4387,17 @@ fn void analyze_type(Module* module, Value* value, Type* expected_type, TypeAnal module->current_macro_instantiation = current_macro_instantiation; module->current_function = current_function; } break; + case ValueId::build_mode: + { + value_type = get_build_mode_enum(module); + if (expected_type) + { + // typecheck(module, expected_type); + trap(); + } + + typecheck(module, expected_type, value_type); + } break; default: unreachable(); } diff --git a/src/parser.cpp b/src/parser.cpp index 9f97707..74d9ec1 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -3,6 +3,7 @@ enum class ValueIntrinsic { align_of, + build_mode, byte_size, enum_from_int, enum_name, @@ -1153,6 +1154,7 @@ fn Token tokenize(Module* module) String value_intrinsics[] = { string_literal("align_of"), + string_literal("build_mode"), string_literal("byte_size"), string_literal("enum_from_int"), string_literal("enum_name"), @@ -1862,6 +1864,12 @@ fn Value* parse_left(Module* module, Scope* scope, ValueBuilder builder) .id = ValueId::binary, }; } break; + case ValueIntrinsic::build_mode: + { + *result = { + .id = ValueId::build_mode, + }; + } break; case ValueIntrinsic::count: unreachable(); } } break; @@ -3477,8 +3485,7 @@ void parse(Module* module) }; } - auto needed_bit_count = 64 - (u32)clz(highest_value); - needed_bit_count = needed_bit_count ? needed_bit_count : 1; + auto needed_bit_count = enum_bit_count(highest_value); if (!backing_type) {