Single header mode sort of working
This commit is contained in:
@@ -58,12 +58,13 @@ unique_name(Allocator *allocator, Ast *ast){
|
||||
return result;
|
||||
}
|
||||
|
||||
global String prefixed_string_type;
|
||||
function const char *
|
||||
get_ctype_name_for_type(Ast_Type *type){
|
||||
switch(type->kind){
|
||||
case TYPE_VOID: return "void";
|
||||
case TYPE_BOOL: return "bool";
|
||||
case TYPE_STRING: return "CORE_String";
|
||||
case TYPE_STRING: return (char *)prefixed_string_type.str;
|
||||
case TYPE_CHAR: return "char";
|
||||
case TYPE_F32: return "float";
|
||||
case TYPE_F64: return "double";
|
||||
@@ -107,7 +108,7 @@ string_simple_decl_prefix(Allocator *a, Ast_Type *ast){
|
||||
}break;
|
||||
case TYPE_STRUCT: {
|
||||
auto constant = (Ast_Decl *)ast->ast;
|
||||
auto name = constant->name;
|
||||
auto name = constant->unique_name;
|
||||
String string = string_fmt(a, "%Q ", name);
|
||||
String sc = {};
|
||||
return string_fmt(a, "%Q%Q", sc, string);
|
||||
@@ -224,7 +225,7 @@ gen_value(Token *pos, Value a){
|
||||
}break;
|
||||
case TYPE_STRING:{
|
||||
int length = 0;
|
||||
gen("(CORE_String){(uint8_t *)\"");
|
||||
gen("(%QString){(uint8_t *)\"", symbol_prefix);
|
||||
for(int i = 0; i < a.intern_val.len; i++){
|
||||
if(a.intern_val.str[i] == '\n'){length += 2; gen("\\n");}
|
||||
else if(a.intern_val.str[i] == '\r'){length += 2; gen("\\r");}
|
||||
@@ -525,8 +526,8 @@ gen_ast(Ast *ast){
|
||||
switch(ast->kind){
|
||||
|
||||
CASE(RUNTIME_ASSERT, Builtin){
|
||||
if(node->assert_message.len == 0) gen("CORE_Assert");
|
||||
else gen("CORE_AssertMessage");
|
||||
if(node->assert_message.len == 0) gen("%QAssert", symbol_prefix);
|
||||
else gen("%QAssertMessage", symbol_prefix);
|
||||
gen("(");
|
||||
gen_expr(node->expr);
|
||||
if(node->assert_message.len){
|
||||
@@ -545,7 +546,7 @@ gen_ast(Ast *ast){
|
||||
|
||||
int i = 0;
|
||||
For(node->expr){
|
||||
genln("CORE_MemoryCopy(&%Q.m%d, ", var_name, i);
|
||||
genln("%QMemoryCopy(&%Q.m%d, ", symbol_prefix, var_name, i);
|
||||
if(!is_array(it->resolved_type)) gen("&");
|
||||
gen("(");
|
||||
gen_expr(it);
|
||||
@@ -624,7 +625,7 @@ gen_ast(Ast *ast){
|
||||
if(node->is_array_traversal){
|
||||
gen("for(int64_t _i%d = 0; _i%d < ", node->pos->line, node->pos->line);
|
||||
if(is_array(node->cond->resolved_type)){
|
||||
gen("CORE_BufferSize(");
|
||||
gen("%QBufferSize(", symbol_prefix);
|
||||
gen_expr(node->cond);
|
||||
gen(")");
|
||||
} else{
|
||||
@@ -681,7 +682,7 @@ gen_ast(Ast *ast){
|
||||
|
||||
CASE(STRUCT, Decl){
|
||||
gen("struct ");
|
||||
gen("%Q{", node->name);
|
||||
gen("%Q{", node->unique_name);
|
||||
global_indent++;
|
||||
is_inside_struct++;
|
||||
For(node->scope->decls){
|
||||
@@ -695,12 +696,6 @@ gen_ast(Ast *ast){
|
||||
BREAK();
|
||||
}
|
||||
|
||||
CASE(TYPE, Decl){
|
||||
gen("// Type %Q = ", node->name);
|
||||
gen_simple_decl(node->type_val);
|
||||
BREAK();
|
||||
}
|
||||
|
||||
CASE(ENUM, Decl){
|
||||
gen("/*enum %Q{", node->name);
|
||||
// @todo add typespec
|
||||
@@ -716,6 +711,7 @@ gen_ast(Ast *ast){
|
||||
BREAK();
|
||||
}
|
||||
|
||||
case AST_TYPE:
|
||||
CASE(CONST, Decl){unused(node);BREAK();}
|
||||
|
||||
CASE(SWITCH, Switch){
|
||||
@@ -761,7 +757,7 @@ gen_ast(Ast *ast){
|
||||
|
||||
int i = 0;
|
||||
For(node->vars){
|
||||
gen("CORE_MemoryCopy((void *)&%Q, (void *)&%Q.m%d, sizeof(%Q));", it->name, var_name, i++, it->name);
|
||||
gen("%QMemoryCopy((void *)&%Q, (void *)&%Q.m%d, sizeof(%Q));", symbol_prefix, it->name, var_name, i++, it->name);
|
||||
}
|
||||
BREAK();
|
||||
}
|
||||
@@ -782,26 +778,64 @@ function String
|
||||
compile_to_c_code(){
|
||||
generating_time_begin = os_time();
|
||||
|
||||
prefixed_string_type = string_fmt(pctx->perm, "%QString", symbol_prefix);
|
||||
if(single_header_library_mode){
|
||||
gen(R"==(
|
||||
/*
|
||||
Do this:
|
||||
#define %Q_IMPLEMENTATION
|
||||
before you include this file in *one* C or C++ file to create the implementation.
|
||||
|
||||
// i.e. it should look like this:
|
||||
#include ...
|
||||
#include ...
|
||||
#include ...
|
||||
#define %Q_IMPLEMENTATION
|
||||
#include "%Q.h"
|
||||
|
||||
You can #define %QAssert(x) to avoid using default assert
|
||||
You can #define %QAssertMessage(x) to get more comprehensive error info
|
||||
You can #define %QMemoryCopy(x) to avoid using default memory copy
|
||||
*/
|
||||
)==", single_header_library_name, single_header_library_name, single_header_library_name,
|
||||
symbol_prefix, symbol_prefix, symbol_prefix);
|
||||
genln("#ifndef %Q_LIBRARY_HEADER ", single_header_library_name);
|
||||
genln("#define %Q_LIBRARY_HEADER ", single_header_library_name);
|
||||
}
|
||||
|
||||
gen(R"==(
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#define CORE_Assert(x) do{if(!(x))__debugbreak();}while(0)
|
||||
#define CORE_AssertMessage(x,...) CORE_Assert(x)
|
||||
#define CORE_BufferSize(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
||||
typedef struct CORE_String{
|
||||
uint8_t *str;
|
||||
int64_t len;
|
||||
}CORE_String;
|
||||
#ifndef Assert
|
||||
#define Assert(x) do{if(!(x))__debugbreak();}while(0)
|
||||
#endif
|
||||
|
||||
#ifndef AssertMessage
|
||||
#define AssertMessage(x,...) Assert(x)
|
||||
#endif
|
||||
|
||||
#ifndef MemoryCopy
|
||||
#define MemoryCopy MemoryCopy_
|
||||
|
||||
static void
|
||||
CORE_MemoryCopy(void *dst, void *src, size_t size){
|
||||
MemoryCopy_(void *dst, void *src, size_t size){
|
||||
uint8_t *d = (uint8_t*)dst;
|
||||
uint8_t *s = (uint8_t*)src;
|
||||
for(size_t i = 0; i < size; i++){
|
||||
d[i] = s[i];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#define BufferSize(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
||||
typedef struct String{
|
||||
uint8_t *str;
|
||||
int64_t len;
|
||||
}String;
|
||||
|
||||
|
||||
)==");
|
||||
|
||||
@@ -809,7 +843,7 @@ CORE_MemoryCopy(void *dst, void *src, size_t size){
|
||||
Iter(&pctx->ordered_decls){
|
||||
auto i = it.item[0];
|
||||
if(i->kind == AST_STRUCT){
|
||||
genln("typedef struct %Q %Q;", i->name, i->name);
|
||||
genln("typedef struct %Q %Q;", i->unique_name, i->unique_name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -912,7 +946,7 @@ CORE_MemoryCopy(void *dst, void *src, size_t size){
|
||||
gen(".struct_member_count = %d, ", t->agg.members.len);
|
||||
gen(".struct_members = (Type_Info_Struct_Member[]){");
|
||||
For_Named(t->agg.members, m){
|
||||
gen("{.name = (CORE_String){(uint8_t *)\"%Q\", %d}, .type = %d, .offset = %d}, ", m.name, m.name.len, m.type->type_id, m.offset);
|
||||
gen("{.name = (%Q){(uint8_t *)\"%Q\", %d}, .type = %d, .offset = %d}, ", prefixed_string_type, m.name, m.name.len, m.type->type_id, m.offset);
|
||||
|
||||
}
|
||||
gen("}");
|
||||
@@ -927,6 +961,11 @@ CORE_MemoryCopy(void *dst, void *src, size_t size){
|
||||
|
||||
}
|
||||
|
||||
if(single_header_library_mode){
|
||||
genln("#endif");
|
||||
genln("#ifdef %Q_IMPLEMENTATION ", single_header_library_name);
|
||||
}
|
||||
|
||||
// Generate actual code
|
||||
Iter(&pctx->ordered_decls){
|
||||
if(it.index >= pctx->base_language_ordered_decl_len){
|
||||
@@ -935,6 +974,12 @@ CORE_MemoryCopy(void *dst, void *src, size_t size){
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(single_header_library_mode){
|
||||
genln("#endif");
|
||||
}
|
||||
|
||||
|
||||
String string_result = string_flatten(pctx->perm, &pctx->gen);
|
||||
generating_time_end = os_time();
|
||||
return string_result;
|
||||
|
||||
Reference in New Issue
Block a user