Codegen change, remove typedefs, use standard
This commit is contained in:
@@ -58,6 +58,31 @@ unique_name(Allocator *allocator, Ast *ast){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 "String";
|
||||||
|
case TYPE_CHAR: return "char";
|
||||||
|
case TYPE_F32: return "float";
|
||||||
|
case TYPE_F64: return "double";
|
||||||
|
case TYPE_INT: return "int";
|
||||||
|
case TYPE_S8: return "int8_t";
|
||||||
|
case TYPE_S16: return "int16_t";
|
||||||
|
case TYPE_S32: return "int32_t";
|
||||||
|
case TYPE_S64: return "int64_t";
|
||||||
|
case TYPE_U8: return "uint8_t";
|
||||||
|
case TYPE_U16: return "uint16_t";
|
||||||
|
case TYPE_U32: return "uint32_t";
|
||||||
|
case TYPE_U64: return "uint64_t";
|
||||||
|
case TYPE_TUPLE: return "Tuple";
|
||||||
|
case TYPE_TYPE: return "int64_t";
|
||||||
|
invalid_default_case;
|
||||||
|
}
|
||||||
|
return "<unknown_type>";
|
||||||
|
}
|
||||||
|
|
||||||
function String
|
function String
|
||||||
string_simple_decl_prefix(Allocator *a, Ast_Type *ast){
|
string_simple_decl_prefix(Allocator *a, Ast_Type *ast){
|
||||||
switch(ast->kind){
|
switch(ast->kind){
|
||||||
@@ -88,7 +113,7 @@ string_simple_decl_prefix(Allocator *a, Ast_Type *ast){
|
|||||||
return string_fmt(a, "%Q%Q", sc, string);
|
return string_fmt(a, "%Q%Q", sc, string);
|
||||||
}break;
|
}break;
|
||||||
default: {
|
default: {
|
||||||
String string = string_fmt(a, "%s ", name(ast));
|
String string = string_fmt(a, "%s ", get_ctype_name_for_type(ast));
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,7 +224,7 @@ gen_value(Token *pos, Value a){
|
|||||||
}break;
|
}break;
|
||||||
case TYPE_STRING:{
|
case TYPE_STRING:{
|
||||||
int length = 0;
|
int length = 0;
|
||||||
gen("(String){(U8 *)\"");
|
gen("(String){(uint8_t *)\"");
|
||||||
for(int i = 0; i < a.intern_val.len; i++){
|
for(int i = 0; i < a.intern_val.len; i++){
|
||||||
if(a.intern_val.str[i] == '\n'){length += 2; gen("\\n");}
|
if(a.intern_val.str[i] == '\n'){length += 2; gen("\\n");}
|
||||||
else if(a.intern_val.str[i] == '\r'){length += 2; gen("\\r");}
|
else if(a.intern_val.str[i] == '\r'){length += 2; gen("\\r");}
|
||||||
@@ -500,8 +525,8 @@ gen_ast(Ast *ast){
|
|||||||
switch(ast->kind){
|
switch(ast->kind){
|
||||||
|
|
||||||
CASE(RUNTIME_ASSERT, Builtin){
|
CASE(RUNTIME_ASSERT, Builtin){
|
||||||
if(node->assert_message.len == 0) gen("assert");
|
if(node->assert_message.len == 0) gen("CORE_Assert");
|
||||||
else gen("assert_msg");
|
else gen("CORE_AssertMessage");
|
||||||
gen("(");
|
gen("(");
|
||||||
gen_expr(node->expr);
|
gen_expr(node->expr);
|
||||||
if(node->assert_message.len){
|
if(node->assert_message.len){
|
||||||
@@ -597,9 +622,9 @@ gen_ast(Ast *ast){
|
|||||||
|
|
||||||
// Array iter
|
// Array iter
|
||||||
if(node->is_array_traversal){
|
if(node->is_array_traversal){
|
||||||
gen("for(S64 _i%d = 0; _i%d < ", node->pos->line, node->pos->line);
|
gen("for(int64_t _i%d = 0; _i%d < ", node->pos->line, node->pos->line);
|
||||||
if(is_array(node->cond->resolved_type)){
|
if(is_array(node->cond->resolved_type)){
|
||||||
gen("_buff_cap(");
|
gen("CORE_BufferSize(");
|
||||||
gen_expr(node->cond);
|
gen_expr(node->cond);
|
||||||
gen(")");
|
gen(")");
|
||||||
} else{
|
} else{
|
||||||
@@ -759,34 +784,14 @@ compile_to_c_code(){
|
|||||||
|
|
||||||
gen(R"==(
|
gen(R"==(
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <math.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
typedef int8_t S8;
|
#define CORE_Assert(x) do{if(!(x))__debugbreak();}while(0)
|
||||||
typedef int16_t S16;
|
#define CORE_AssertMessage(x,...) CORE_Assert(x)
|
||||||
typedef int32_t S32;
|
#define CORE_BufferSize(x) (sizeof(x)/sizeof((x)[0]))
|
||||||
typedef int64_t S64;
|
|
||||||
typedef uint8_t U8;
|
|
||||||
typedef uint16_t U16;
|
|
||||||
typedef uint32_t U32;
|
|
||||||
typedef uint64_t U64;
|
|
||||||
typedef S8 B8;
|
|
||||||
typedef S16 B16;
|
|
||||||
typedef S32 B32;
|
|
||||||
typedef S64 B64;
|
|
||||||
typedef U64 SizeU;
|
|
||||||
typedef S64 SizeS;
|
|
||||||
typedef float F32;
|
|
||||||
typedef double F64;
|
|
||||||
typedef S32 Bool;
|
|
||||||
typedef S64 Type;
|
|
||||||
#define true 1
|
|
||||||
#define false 0
|
|
||||||
#define assert(x) do{if(!(x))__debugbreak();}while(0)
|
|
||||||
#define assert_msg(x,...) assert(x)
|
|
||||||
#define _buff_cap(x) (sizeof(x)/sizeof((x)[0]))
|
|
||||||
typedef struct String{
|
typedef struct String{
|
||||||
U8 *str;
|
uint8_t *str;
|
||||||
S64 len;
|
int64_t len;
|
||||||
}String;
|
}String;
|
||||||
)==");
|
)==");
|
||||||
|
|
||||||
@@ -806,7 +811,7 @@ typedef struct String{
|
|||||||
if(type->kind == TYPE_SLICE){
|
if(type->kind == TYPE_SLICE){
|
||||||
genln("typedef struct Slice%llu{", type->type_id);
|
genln("typedef struct Slice%llu{", type->type_id);
|
||||||
global_indent++;
|
global_indent++;
|
||||||
genln("S64 len;");
|
genln("int64_t len;");
|
||||||
genln("");
|
genln("");
|
||||||
gen_simple_decl(type_pointer(type->base), pctx->intern("data"_s));
|
gen_simple_decl(type_pointer(type->base), pctx->intern("data"_s));
|
||||||
gen(";");
|
gen(";");
|
||||||
@@ -865,7 +870,7 @@ typedef struct String{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate type info
|
// Generate type info
|
||||||
genln("S64 type_infos_len = %d;", length(&pctx->all_types));
|
genln("int64_t type_infos_len = %d;", length(&pctx->all_types));
|
||||||
genln("Type_Info *type_infos = (Type_Info[]){");
|
genln("Type_Info *type_infos = (Type_Info[]){");
|
||||||
global_indent++;
|
global_indent++;
|
||||||
Iter(&pctx->all_types){
|
Iter(&pctx->all_types){
|
||||||
@@ -894,7 +899,7 @@ typedef struct String{
|
|||||||
gen(".struct_member_count = %d, ", t->agg.members.len);
|
gen(".struct_member_count = %d, ", t->agg.members.len);
|
||||||
gen(".struct_members = (Type_Info_Struct_Member[]){");
|
gen(".struct_members = (Type_Info_Struct_Member[]){");
|
||||||
For_Named(t->agg.members, m){
|
For_Named(t->agg.members, m){
|
||||||
gen("{.name = (String){(U8 *)\"%Q\", %d}, .type = %d, .offset = %d}, ", m.name, m.name.len, m.type->type_id, m.offset);
|
gen("{.name = (String){(uint8_t *)\"%Q\", %d}, .type = %d, .offset = %d}, ", m.name, m.name.len, m.type->type_id, m.offset);
|
||||||
|
|
||||||
}
|
}
|
||||||
gen("}");
|
gen("}");
|
||||||
|
|||||||
@@ -9,15 +9,10 @@ In the future
|
|||||||
|
|
||||||
- [ ] Cleanup
|
- [ ] Cleanup
|
||||||
- [ ] Remove tuple stuff or cleanup, in the future might replace it with a better implementation
|
- [ ] Remove tuple stuff or cleanup, in the future might replace it with a better implementation
|
||||||
- [ ] Add ability to do i: int = 0 inside for loops
|
- [ ] Add ability to do i: int = 0 inside for loops for i: int = 0, i < 10, i+=1
|
||||||
|
- [ ] Complicated c declaration generation
|
||||||
- [ ] The fact that symbols from main file get introduced to the loaded files
|
- [ ] The fact that symbols from main file get introduced to the loaded files
|
||||||
might be kind of confusing, need to watch out for that
|
might be kind of confusing, need to watch out for that
|
||||||
- [ ] You can't alias Lambdas because they are not evaluated as constant.
|
|
||||||
I used a little simplification where lambdas and structs were marked as such
|
|
||||||
in parsing I think. BUT Structs work so it's maybe just a little fix of constant
|
|
||||||
propagation using Operands, where I will need to modify Operand of lambda to
|
|
||||||
be constant AND rewrite_const to not rewrite a lambda OR SOMETHING, maybe it's cool
|
|
||||||
dont know. BUT not sure if we wont need to rewrite the idea that Lambdas can be Decls.
|
|
||||||
|
|
||||||
- [ ] Conditional compilation
|
- [ ] Conditional compilation
|
||||||
- [ ] Expand macros
|
- [ ] Expand macros
|
||||||
@@ -157,6 +152,12 @@ For modules it's a bit different cause they should be distributed as valid.
|
|||||||
|
|
||||||
## Done
|
## Done
|
||||||
|
|
||||||
|
- [x] You can't alias Lambdas because they are not evaluated as constant.
|
||||||
|
I used a little simplification where lambdas and structs were marked as such
|
||||||
|
in parsing I think. BUT Structs work so it's maybe just a little fix of constant
|
||||||
|
propagation using Operands, where I will need to modify Operand of lambda to
|
||||||
|
be constant AND rewrite_const to not rewrite a lambda OR SOMETHING, maybe it's cool
|
||||||
|
dont know. BUT not sure if we wont need to rewrite the idea that Lambdas can be Decls.
|
||||||
- [x] Operator Overloading
|
- [x] Operator Overloading
|
||||||
- [x] '.' Operator doesn't handle expressions inside the dot chain, no good, so casts don't work
|
- [x] '.' Operator doesn't handle expressions inside the dot chain, no good, so casts don't work
|
||||||
- [x] Introduce List to reduce heap allocations and make it more arena friendly, can we get rid of heap completly?
|
- [x] Introduce List to reduce heap allocations and make it more arena friendly, can we get rid of heap completly?
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
function const char *
|
function const char *
|
||||||
name(Ast_Type *type){
|
get_name_of_type(Ast_Type *type){
|
||||||
switch(type->kind){
|
switch(type->kind){
|
||||||
case TYPE_VOID: return "void";
|
case TYPE_VOID: return "void";
|
||||||
case TYPE_BOOL: return "Bool";
|
case TYPE_BOOL: return "Bool";
|
||||||
@@ -400,7 +400,7 @@ typename_base(String_Builder *sb, Ast_Type *type){
|
|||||||
case TYPE_UNTYPED_FLOAT: sb->addf("Untyped_Float"); break;
|
case TYPE_UNTYPED_FLOAT: sb->addf("Untyped_Float"); break;
|
||||||
case TYPE_UNTYPED_STRING: sb->addf("Untyped_String"); break;
|
case TYPE_UNTYPED_STRING: sb->addf("Untyped_String"); break;
|
||||||
default: {
|
default: {
|
||||||
sb->addf("%s", name(type));
|
sb->addf("%s", get_name_of_type(type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user