New approach, new lexer

This commit is contained in:
Krzosa Karol
2022-05-06 10:13:16 +02:00
parent 557dde1936
commit e3b5e9b33a
33 changed files with 3331 additions and 784 deletions

View File

@@ -1,126 +1,475 @@
function void gen_decl(Parser *p, Decl *node);
function void gen_decl(Decl *node);
function void gen_cdecl(Typespec *type, String str);
function void gen_stmt_list(Stmt *stmt);
global String_List *glist;
global Arena *gscratch;
global Parser *genp;
#define strf(...) string_listf(gscratch, glist, __VA_ARGS__)
//-----------------------------------------------------------------------------
// String replacing util
//-----------------------------------------------------------------------------
typedef struct String_Map String_Map;
struct String_Map{
String replace;
String with;
};
function void
gen_typespec(Parser *p, Typespec *spec, B32 is_left){
switch(spec->kind) {
case TS_Name: {
if(is_left) lex_print("%s", spec->name.s.str);
} break;
case TS_Pointer: {
gen_typespec(p, spec->base,is_left);
if(is_left) lex_print("*");
} break;
case TS_Array: {
gen_typespec(p, spec->array_spec.base,is_left);
if(!is_left){
lex_print("[");
expr_print(p, spec->array_spec.size);
lex_print("]");
string_mapped_print(String string, String_Map *map, SizeU count){
Tokens tokens = lex_stream(string, lit("string_mapped_print"));
for(Token *t = tokens.tokens; t != tokens.tokens + tokens.len; t++){
String string = t->string;
for(SizeU i = 0; i < count; i++){
if(string_compare(string, map[i].replace)){
string = map[i].with;
break;
}
} break;
}
case TS_Function: {
invalid_codepath;
} break;
default: {invalid_codepath;} break;
if(t->kind == TK_At) continue;
if(string_compare(t->string,keyword_function.s)) strf("\n");
strf("%.*s", (int)string.len, string.str);
if(string_compare(t->string,keyword_function.s)) strf("\n");
if(t->kind == TK_OpenBrace) strf("\n");
if(t->kind == TK_CloseBrace && t[1].kind != TK_Semicolon) strf("\n");
if(t->kind == TK_Semicolon) strf("\n");
if(t->kind == TK_Identifier && (t[1].kind == TK_Keyword || t[1].kind == TK_Identifier)) strf(" ");
if(t->kind == TK_Keyword) strf(" ");
if(t->kind == TK_Comma) strf(" ");
}
free(tokens.tokens);
}
#define STR(X) lit(#X)
function Typespec *
typespec_get_func(Typespec *type){
switch(type->kind){
case TS_Name:{return 0;} break;
case TS_Pointer:{return typespec_get_func(type->base);} break;
case TS_Array:{return typespec_get_func(type->array_spec.base);} break;
case TS_Function:{return type;} break;
default: {invalid_codepath;} break;
}
return 0;
//-----------------------------------------------------------------------------
// Codegen
//-----------------------------------------------------------------------------
function void
token_strf(Token *token){
strf("%.*s", (S32)token->len, token->str);
}
function void
gen_decl(Parser *p, Decl *node){
gen_expr(Expr *expr){
switch(expr->kind) {
case EK_Atom: {
token_strf(expr->token);
} break;
case EK_Sizeof:{
strf("sizeof(");
if(expr->size_of.kind == SIZEOF_Expr){
gen_expr(expr->size_of.expr);
}
else{
assert(expr->size_of.kind == SIZEOF_Type);
gen_cdecl(expr->size_of.type, string_empty);
}
strf(")");
}break;
case EK_Binary:{
strf("(");
gen_expr(expr->binary.left);
token_strf(expr->token);
gen_expr(expr->binary.right);
strf(")");
} break;
case EK_Unary:{
strf("(");
token_strf(expr->token);
gen_expr(expr->unary.expr);
strf(")");
} break;
case EK_Ternary:{
strf("(");
gen_expr(expr->ternary.cond);
strf("?");
gen_expr(expr->ternary.on_true);
strf(":");
gen_expr(expr->ternary.on_false);
strf(")");
} break;
case EK_List:{
strf("(");
for(Expr *n = expr->list.first; n; n=n->next){
gen_expr(n);
if(n!=expr->list.last) strf(",");
}
strf(")");
}break;
case EK_Cast:{
strf("(");
strf("(");
gen_cdecl(expr->cast.type, string_empty);
strf(")");
gen_expr(expr->cast.expr);
strf(")");
} break;
case EK_Index:{
gen_expr(expr->index.atom);
strf("[");
gen_expr(expr->index.index);
strf("]");
}break;
case EK_Call:{
gen_expr(expr->call.atom);
strf("(");
gen_expr(expr->call.list);
strf(")");
}break;
default: {invalid_codepath;} break;
}
}
function String
gen_cdecl_paren(String str, String original){
if(string_is_empty(original) || original.str[0] == '['){
return str;
}
else{
String result = string_fmt(gscratch, "(%.*s)", (int)str.len, str.str);
return result;
}
}
function String
gen__cdecl(Typespec *type, String str){
switch(type->kind) {
case TS_Name: {
String space = string_is_empty(str) ? lit(""):lit(" ");
String result = string_fmt(gscratch, "%s%s%.*s", type->name.s.str, space.str, (int)str.len, str.str);
return result;
} break;
case TS_Pointer: {
String pointer = string_fmt(gscratch, "*%.*s", (int)str.len, str.str);
String add_paren = gen_cdecl_paren(pointer, str);
String result = gen__cdecl(type->base, add_paren);
return result;
} break;
case TS_Array: {
String left = string_fmt(gscratch, "%s[", str.str);
String_List *save = glist;
String_List list = {0};
glist = &list;
gen_expr(type->array_spec.size);
String expr_string = string_list_flatten(gscratch, glist);
glist = save;
String right = string_fmt(gscratch, "%s%s]", left.str, expr_string.str);
String paren = gen_cdecl_paren(right, str);
String result = gen__cdecl(type->array_spec.base, paren);
return result;
} break;
case TS_Function: {
String result = string_fmt(gscratch, "(*%s)(", str.str);
if (type->function_spec.first == 0) {
result= string_fmt(gscratch, "%svoid", result.str);
}
else {
for(Typespec *n = type->function_spec.first; n; n=n->next){
String arg = gen__cdecl(n, string_empty);
result = string_fmt(gscratch, "%s%s", result.str, arg.str);
if(n != type->function_spec.last)
result = string_fmt(gscratch, "%s, ", result.str);
}
}
result = string_fmt(gscratch, "%s)", result.str);
result = gen__cdecl(type->function_spec.ret, result);
return result;
} break;
default: {invalid_codepath;} break;
}
return string_empty;
}
function void
gen_cdecl(Typespec *type, String str){
String string = gen__cdecl(type, str);
strf("%.*s", (int)string.len, string.str);
}
function void
gen_assign_expr(Expr *expr){
if(expr){
strf(" = ");
gen_expr(expr);
}
}
function void
gen_function_decl(Decl *node){
strf("function ");
gen_cdecl(node->function_decl.ret, string_empty);
strf(" %s(", node->name.s.str);
for(Decl_Function_Arg *arg = node->function_decl.first; arg; arg=arg->next){
gen_cdecl(arg->typespec, arg->name.s);
if(arg!=node->function_decl.last) strf(", ");
}
strf(")");
}
typedef struct Macro{
Intern_String name;
Note *param_type;
Note *param_expr;
Decl *decl;
}Macro;
global Macro macros[32];
global S32 macros_i;
function void
gen_forward_decl(Decl *node){
U8 *name = node->name.s.str;
switch(node->kind) {
case DECL_List: {
for(Decl *n = node->list.first; n; n=n->next){
gen_decl(p,n);
lex_new_line();
gen_forward_decl(n);
}
} break;
case DECL_Variable:{
Typespec *func = typespec_get_func(node->variable_decl.type);
if(!func){
gen_typespec(p, node->variable_decl.type, true);
lex_print(" %s", node->name.s.str);
gen_typespec(p, node->variable_decl.type, false);
}
else{
gen_typespec(p, func->function_spec.ret, true);
lex_print("(*");
lex_print("%s", node->name.s.str);
lex_print(")");
lex_print("(");
for(Typespec *t = func->function_spec.first; t; t=t->next){
gen_typespec(p, t, true);
gen_typespec(p, t, false);
if(t != func->function_spec.last) lex_print(", ");
}
lex_print(")");
}
print_assign_expr(p,node->variable_decl.expr);
lex_print(";");
} break;
case DECL_Typedef:{
lex_print("typedef %s ", node->name.s.str);
gen_typespec(p, node->typedef_decl.type, true);
gen_typespec(p, node->typedef_decl.type, false);
lex_print(";");
} break;
case DECL_Function:{
gen_function_decl(node);
strf(";\n");
}break;
case DECL_Struct:
case DECL_Union :{
U8 *struct_name = node->kind==DECL_Struct ? (U8*)"struct" : (U8*)"union";
U8 *name = node->name.s.str;
if(node->struct_decl.kind == STRUCT_Base)
lex_print("typedef %s %s %s;\n", struct_name, name, name);
lex_print("%s %s{\n", struct_name, name?name:(U8*)"");
for(Decl *n = node->struct_decl.first; n; n=n->next){
gen_decl(p, n);
lex_print("\n");
Note *note = decl_find_note(node, lit("register"));
if(note){
Note *param_expr = decl_find_note(node, lit("param_expr"));
Note *param_type = decl_find_note(node, lit("param_type"));
macros[macros_i++] = (Macro){
.name=node->name,
.param_type=param_type,
.param_expr=param_expr,
.decl=node
};
}
else{
U8 *struct_name = node->kind==DECL_Struct ? (U8*)"struct" : (U8*)"union";
if(node->struct_decl.kind == STRUCT_Base)
strf("typedef %s %s %s;\n", struct_name, name, name);
}
lex_print("};");
if(node->struct_decl.kind == STRUCT_Base)
lex_print("\n");
} break;
case DECL_Enum:{
lex_print("enum %s", node->name.s.str);
if(!intern_compare(node->enum_decl.typespec->name, intern_s64)){
lex_print(" : ");
lex_print("%s", node->enum_decl.typespec->name.s.str);
}
lex_print("{\n");
String prefix = decl_find_string_note(node, lit("prefix"), string_empty);
for(Decl_Enum_Child *n = node->enum_decl.first; n; n=n->next){
lex_print("%.*s%s", (int)prefix.len, prefix.str, n->name.s.str);
print_assign_expr(p, n->expr);
lex_print(",\n");
}
lex_print("};\n");
} break;
default: {invalid_codepath;} break;
}
}
function void
gen_decl(Decl *node){
U8 *name = node->name.s.str;
switch(node->kind) {
case DECL_List: {
for(Decl *n = node->list.first; n; n=n->next){
gen_decl(n);
strf("\n");
}
} break;
case DECL_Variable:{
gen_cdecl(node->variable_decl.type, node->name.s);
gen_assign_expr(node->variable_decl.expr);
strf(";");
} break;
case DECL_Typedef:{
strf("typedef ");
gen_cdecl(node->typedef_decl.type, node->name.s);
strf(";");
} break;
case DECL_Struct:
case DECL_Union :{
Note *note = decl_find_note(node, lit("register"));
if(note){
Arena_Checkpoint checkpoint = arena_checkpoint(gscratch);
Pointer_Array array = gather(checkpoint.arena, node, GATHER_Decl|GATHER_Typespec, TRAVERS_All);
Intern_String based = intern_string(genp, lit("Based_Type_Represent"));
Intern_String type = intern_string(genp, lit("Type"));
for(Pointer it = pointer_array_iter_begin(&array); it.typespec; it = pointer_array_iter_next(&array)){
if(it.kind == PK_Typespec){
Typespec *typespec = it.typespec;
assert(typespec->kind == TS_Name || typespec->kind == TS_Pointer || typespec->kind == TS_Array || typespec->kind == TS_Function);
if(typespec->kind == TS_Name){
if(intern_compare(typespec->name, type)){
typespec->name = based;
}
}
}
else if(it.kind == PK_Decl){
Decl *decl = it.decl;
if(decl->kind == DECL_Struct || decl->kind == DECL_Function){
if(intern_compare(decl->name, type)){
decl->name = based;
}
}
}
}
arena_restore(checkpoint);
}
U8 *struct_name = node->kind==DECL_Struct ? (U8*)"struct" : (U8*)"union";
strf("%s", struct_name);
if(node->struct_decl.kind == STRUCT_Base)
strf(" %s", node->name.s.str);
strf("{\n");
for(Decl *n = node->struct_decl.first; n; n=n->next){
gen_decl(n);
strf("\n");
}
strf("}");
if(node->struct_decl.kind == STRUCT_Nested)
strf("%.*s", (int)node->name.s.len, node->name.s.str);
strf(";");
if(node->struct_decl.kind == STRUCT_Base)
strf("\n");
} break;
case DECL_Enum:{
strf("typedef enum %s", name);
if(!intern_compare(node->enum_decl.typespec->name, intern_s64)){
strf(" : ");
strf("%s", node->enum_decl.typespec->name.s.str);
}
strf("{\n");
String prefix = decl_find_string_note(node, lit("prefix"), string_empty);
for(Decl_Enum_Child *n = node->enum_decl.first; n; n=n->next){
strf("%.*s%s", (int)prefix.len, prefix.str, n->name.s.str);
gen_assign_expr(n->expr);
strf(",\n");
}
strf("}%s;\n", name);
} break;
case DECL_Function:{
gen_function_decl(node);
gen_stmt_list(node->function_decl.body);
} break;
default: {invalid_codepath;} break;
}
}
function void
gen_stmt_list(Stmt *stmt){
strf("{\n");
for(Stmt *s = stmt->list.first; s; s=s->next){
gen_stmt(s);
strf("\n");
}
strf("}");
}
function void
gen_stmt(Stmt *stmt){
switch(stmt->kind) {
case STMT_List: {
gen_stmt_list(stmt);
} break;
case STMT_Return:{
strf("return ");
gen_expr(stmt->ret.expr);
strf(";");
} break;
case STMT_If:{
strf("if ");
gen_expr(stmt->stmt_if.cond);
gen_stmt_list(stmt->stmt_if.body);
for(Stmt_If *s = stmt->stmt_if.next; s; s=s->next){
if(s->next){
strf("else if ");
gen_expr(s->cond);
gen_stmt_list(s->body);
}
else{
strf("else");
gen_stmt_list(s->body);
}
}
} break;
case STMT_Expr: {
gen_expr(stmt->expr);
strf(";");
} break;
case STMT_Decl: {
gen_decl(stmt->decl);
} break;
default: {invalid_codepath;} break;
}
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
global Decl *gen_parent;
function void
gen_code(Decl *node){
U8 *name = node->name.s.str;
switch(node->kind) {
case DECL_List: {
for(Decl *n = node->list.first; n; n=n->next){
gen_code(n);
}
} break;
case DECL_Variable:{
} break;
case DECL_Typedef:{
} break;
case DECL_Struct:
case DECL_Union :{
gen_parent = node;
for(Decl *n = node->struct_decl.first; n; n=n->next){
gen_code(n);
}
} break;
case DECL_Enum:{
} break;
default: {invalid_codepath;} break;
}
}
String_List list;
function void
gen_begin(Arena *scratch, Parser *p){
list = (String_List){0};
gscratch = scratch;
glist = &list;
genp = p;
}
function void
gen_end(){
String result = string_list_flatten(gscratch, glist);
lex_print("%s", result.str);
}