Skip to content

Commit

Permalink
feat: 30cc can now compile itself
Browse files Browse the repository at this point in the history
  • Loading branch information
keyvank committed Dec 3, 2024
1 parent 68b8b0f commit a92f0aa
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 35 deletions.
12 changes: 10 additions & 2 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,21 @@ def compile(path):
os.makedirs(pathlib.Path(obj_filename).parent, exist_ok=True)
with io.open(asm_filename, "w") as f:
f.write(asm)
subprocess.run(["nasm", "-f", "elf64", asm_filename, "-o", obj_filename])
subprocess.run(
["nasm", "-f", "elf64", asm_filename, "-o", obj_filename], check=True
)
except Exception as e:
has_error = True
print("Error compiling:", f, e)


objs = list(glob.glob("target/obj/**/*.o", recursive=True))
objs = list(
[
p
for p in glob.glob("target/obj/**/*.o", recursive=True)
if not p.startswith("target/obj/examples")
]
)

if not has_error:
subprocess.run(
Expand Down
101 changes: 76 additions & 25 deletions codegen/codegen.c
Original file line number Diff line number Diff line change
@@ -1,24 +1,9 @@
#include "../libc.h"
#include "codegen.h"
#include "../linked_list.h"
#include "stdarg.h"
#define UNUSED(x) (void)(x)

context new_context()
{
context ctx;
ctx.data = new_linked_list();
ctx.text = new_linked_list();
ctx.global_table = new_linked_list();
ctx.symbol_table = new_linked_list();
ctx.structs = new_linked_list();
ctx.label_counter = 0;
ctx.loop_end_labels = new_linked_list();
ctx.loop_start_labels = new_linked_list();
ctx.stack_size = 0;
return ctx;
}

#ifndef _30CC
#include <stdarg.h>
char *cc_asprintf(char *fmt, ...)
{
char *txt = (char *)malloc(128);
Expand Down Expand Up @@ -48,6 +33,72 @@ void add_text(context *ctx, char *fmt, ...)
va_end(args);
add_to_list(ctx->text, txt);
}
#endif

#ifdef _30CC
#define PUSHARGS() __asm__("push rdi" \
"push rsi" \
"push rdx" \
"push rcx" \
"push r8" \
"push r9")
#define SRARGS() __asm__("mov r9, r8" \
"mov r8, rcx" \
"mov rcx, rdx" \
"mov rdx, rsi" \
"mov rsi, rdi" \
"mov rdi, 0")
#define POPARGS() __asm__("pop r9" \
"pop r8" \
"pop rcx" \
"pop rdx" \
"pop rsi" \
"pop rdi")
char *cc_asprintf(char *fmt, ...)
{
SRARGS();
PUSHARGS();
char *txt = (char *)malloc(128);
POPARGS();
sprintf(txt, fmt);
return txt;
}

void add_data(context *ctx, char *fmt, ...)
{
PUSHARGS();
char *txt = (char *)malloc(128);
POPARGS();
sprintf(txt, fmt);
add_to_list(ctx->data, txt);
}

void add_text(context *ctx, char *fmt, ...)
{
PUSHARGS();
char *txt = (char *)malloc(128);
POPARGS();
sprintf(txt, fmt);
add_to_list(ctx->text, txt);
}
#endif

#define UNUSED(x) x

context *new_context()
{
context *ctx = (context *)malloc(sizeof(context));
ctx->data = new_linked_list();
ctx->text = new_linked_list();
ctx->global_table = new_linked_list();
ctx->symbol_table = new_linked_list();
ctx->structs = new_linked_list();
ctx->label_counter = 0;
ctx->loop_end_labels = new_linked_list();
ctx->loop_start_labels = new_linked_list();
ctx->stack_size = 0;
return ctx;
}

void replace_text(context *ctx, char *a, char *b)
{
Expand All @@ -56,7 +107,7 @@ void replace_text(context *ctx, char *a, char *b)
{
if (strcmp(curr->value, a) == 0)
{
curr->value = b;
curr->value = (void *)b;
}
curr = curr->next;
}
Expand Down Expand Up @@ -100,7 +151,7 @@ char *new_label(context *ctx)
char *new_loop_end_label(context *ctx)
{
char *name = new_label(ctx);
int *label_id = malloc(sizeof(int));
int *label_id = (int *)malloc(sizeof(int));
*label_id = ctx->label_counter - 1;
add_to_list(ctx->loop_end_labels, label_id);
return name;
Expand All @@ -121,7 +172,7 @@ char *get_current_loop_end_label_counter(context *ctx, char *name)
char *new_loop_start_label(context *ctx)
{
char *name = new_label(ctx);
int *label_id = malloc(sizeof(int));
int *label_id = (int *)malloc(sizeof(int));
*label_id = ctx->label_counter - 1;
add_to_list(ctx->loop_start_labels, label_id);

Expand Down Expand Up @@ -306,7 +357,7 @@ general_type *new_primitive_type(char *type_name)
primitive_type *data = (primitive_type *)malloc(sizeof(primitive_type));
data->type_name = type_name;
ret->kind = TYPE_PRIMITIVE;
ret->data = data;
ret->data = (void *)data;
ret->debug = primitive_type_debug;
ret->size = primitive_type_size;
return ret;
Expand All @@ -318,7 +369,7 @@ general_type *new_pointer_type(general_type *of)
pointer_type *data = (pointer_type *)malloc(sizeof(pointer_type));
data->of = of;
ret->kind = TYPE_POINTER;
ret->data = data;
ret->data = (void *)data;
ret->debug = pointer_type_debug;
ret->size = pointer_type_size;
return ret;
Expand All @@ -331,7 +382,7 @@ general_type *new_func_type(general_type *return_type, linked_list *arg_types)
data->return_type = return_type;
data->arg_types = arg_types;
ret->kind = TYPE_FUNC;
ret->data = data;
ret->data = (void *)data;
ret->debug = func_type_debug;
ret->size = func_type_size;
return ret;
Expand All @@ -343,7 +394,7 @@ general_type *new_struct_type(char *struct_name)
struct_type *data = (struct_type *)malloc(sizeof(struct_type));
data->struct_name = struct_name;
ret->kind = TYPE_STRUCT;
ret->data = data;
ret->data = (void *)data;
ret->debug = struct_type_debug;
ret->size = struct_type_size;
return ret;
Expand Down Expand Up @@ -513,4 +564,4 @@ char *reg_typed(char *reg, general_type *tp, context *ctx)
fprintf(stderr, "Unknown size %u!\n", sz);
exit(1);
return "";
}
}
6 changes: 3 additions & 3 deletions codegen/codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ general_type *new_pointer_type(general_type *of);
general_type *new_func_type(general_type *return_type, linked_list *arg_types);
int types_equal(general_type *a, general_type *b, context *ctx);

context new_context();
context *new_context();
void add_text(context *ctx, char *fmt, ...);
void add_data(context *ctx, char *fmt, ...);
void replace_text(context *ctx, char *a, char *b);
Expand All @@ -86,9 +86,9 @@ symbol *new_global_symbol(context *ctx, char *name, char *repl, general_type *ty
symbol *new_temp_symbol(context *ctx, general_type *type);
char *new_label(context *ctx);
char *new_loop_end_label(context *ctx);
char *get_current_loop_end_label_counter(context *ctx, char* name);
char *get_current_loop_end_label_counter(context *ctx, char *name);
char *new_loop_start_label(context *ctx);
char *get_current_loop_start_label_counter(context *ctx, char* name);
char *get_current_loop_start_label_counter(context *ctx, char *name);
void exit_loop(context *ctx);

context_struct *find_struct(context *ctx, char *name);
Expand Down
10 changes: 5 additions & 5 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ typed_token *process(char *filename, int log_lex, int log_prep)
ctx->defs = new_linked_list();

seg_define *_30cc_define = (seg_define *)malloc(sizeof(seg_define));
_30cc_define->arg_names=new_linked_list();
_30cc_define->arg_names = new_linked_list();
_30cc_define->id = "_30CC";
_30cc_define->replace = new_linked_list();
add_to_list(ctx->defs, _30cc_define);
Expand Down Expand Up @@ -82,17 +82,17 @@ int main(int argc, char **argv)

if (strcmp(argv[2], "--asm") == 0)
{
context ctx = new_context();
prog->apply(prog, &ctx);
list_node *curr = ctx.data->first;
context *ctx = new_context();
prog->apply(prog, ctx);
list_node *curr = ctx->data->first;
printf("section .data\n");
while (curr)
{
printf("%s\n", (char *)curr->value);
curr = curr->next;
}
printf("section .text\n");
curr = ctx.text->first;
curr = ctx->text->first;
while (curr)
{
printf("%s\n", (char *)curr->value);
Expand Down

0 comments on commit a92f0aa

Please sign in to comment.