bloat-buster/src/compiler.h
2025-05-01 20:00:04 -06:00

188 lines
3.2 KiB
C++

#pragma once
#include <lib.h>
#define CommandF(F) \
F(compile),\
F(test),
ENUM(Command, u8, CommandF);
#define BuildModeF(F) \
F(debug_none),\
F(debug),\
F(soft_optimize),\
F(optimize_for_speed),\
F(optimize_for_size),\
F(aggressively_optimize_for_speed),\
F(aggressively_optimize_for_size),
ENUM(BuildMode, u8, BuildModeF);
fn String build_mode_to_string(BuildMode build_mode)
{
switch (build_mode)
{
case_to_name(BuildMode, debug_none);
case_to_name(BuildMode, debug);
case_to_name(BuildMode, soft_optimize);
case_to_name(BuildMode, optimize_for_speed);
case_to_name(BuildMode, optimize_for_size);
case_to_name(BuildMode, aggressively_optimize_for_speed);
case_to_name(BuildMode, aggressively_optimize_for_size);
}
}
#define CPUArchitectureF(F) \
F(x86_64)
ENUM(CPUArchitecture, u8, CPUArchitectureF);
#define OperatingSystemF(F) \
F(linux_)
ENUM(OperatingSystem, u8, OperatingSystemF);
struct Target
{
CPUArchitecture cpu;
OperatingSystem os;
};
struct Compile
{
String relative_file_path;
BuildMode build_mode;
bool has_debug_info;
bool silent;
};
#define base_cache_dir "bb-cache"
enum class TypeId
{
};
struct TypeInteger
{
u32 bit_count;
bool is_signed;
};
struct Type
{
};
struct Value
{
};
struct Scope
{
};
struct Variable
{
};
struct Global
{
Variable variable;
};
struct Local
{
Variable variable;
};
struct MacroDeclaration
{
};
struct MacroInstantiation
{
};
struct Module
{
Arena& arena;
String content;
u64 offset;
u64 line_offset;
u64 line_character_offset;
Type* first_pointer_type;
Type* first_slice_type;
Type* first_pair_struct_type;
Type* first_array_type;
Type* base_type_allocation;
Type* va_list_type;
Value* void_value;
Global* first_global;
Global* current_function;
MacroDeclaration* current_macro_declaration;
MacroInstantiation* current_macro_instantiation;
Scope scope;
String name;
String path;
String executable;
Slice<String>objects;
Target target;
BuildMode build_mode;
bool has_debug_info;
bool silent;
};
constexpr u64 i128_offset = 64 * 2;
constexpr u64 void_offset = i128_offset + 2;
fn Type* integer_type(Module& module, TypeInteger integer)
{
assert(integer.bit_count);
assert(integer.bit_count <= 64 || integer.bit_count == 128);
auto index = integer.bit_count ? (i128_offset + integer.is_signed) : (integer.bit_count - 1 + (64 * integer.is_signed));
return module.base_type_allocation + index;
}
fn Type* void_type(Module& module)
{
return module.base_type_allocation + void_offset;
}
fn Type* noreturn_type(Module& module)
{
return void_type(module) + 1;
}
struct Options
{
String content;
String path;
String executable;
String name;
Slice<String> objects;
Target target;
BuildMode build_mode;
bool has_debug_info;
bool silent;
};
fn Type* new_type(Module& module)
{
auto* result = &arena_allocate<Type>(module.arena, 1)[0];
return result;
}
fn Value* new_value(Module& module)
{
auto* result = &arena_allocate<Value>(module.arena, 1)[0];
return result;
}
void parse(Module& module);
void emit(Module& module);