188 lines
3.2 KiB
C++
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);
|