Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Start codegen #30

Merged
merged 5 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/codegen/RISCV/codegen.c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// Possibility later
3 changes: 3 additions & 0 deletions src/codegen/RISCV/codegen.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Possibility later

#pragma once
80 changes: 80 additions & 0 deletions src/codegen/x86/codegen.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "codegen.h"

#include <testing/tassert.h> // tassert

struct GenState {
// Each bit corresponds with a registers 0-31 where the LSB is 0
uint32_t registers_in_use;

unsigned int rsp_offset;
} GEN_STATE;

void code_gen_init() {
GEN_STATE.registers_in_use = 0;
GEN_STATE.rsp_offset = 0;
}

char *start_main() {
static char start[256] = "\
global _start\
section .text\
\
_start:";

return start;
}

char *end_main() {
static char end[256] = "\
mov rax, 60\
mov rdi, 0\
syscall";

return end;
}

char *start_func() {
static char start[256] = "\
sub rsp, 32\
mov [rsp], r12\
mov [rsp+8], r13\
mov [rsp+16], r14\
mov [rsp+24], r15";

return start;
}

char *end_func() {
static char end[256] = "\
mov r12, [rsp]\
mov r13, [rsp+8]\
mov r14, [rsp+16]\
mov r15, [rsp+24]\
add rsp, 32";

return end;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is perhaps silly, but are all of these no-input functions not behaving as immutable global variables you are asking for copies of?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the conversation above, it will make sense once we reorganize this to write into files instead


char *init_int_literal(int val) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For my understanding, what exactly does this do? Does it just push a new int with the specified value to the stack? Still getting there with the assembly.

Also, this is all fine for now, but in the future maybe we should have all of these functions also accept a FILE* fp and print into there instead. What do you think?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup

GEN_STATE.rsp_offset += 8;

char *init;
init = (char *)malloc(256 * sizeof(char));
sprintf(init, "mov [rsp+%d], %d", GEN_STATE.rsp_offset, val);

return init;
}

int test_init_int_literal() {
testing_func_setup();
code_gen_init();

tassert(strcmp(init_int_literal(100), "mov [rsp+8], 100") == 0);

return 0;
}
15 changes: 15 additions & 0 deletions src/codegen/x86/codegen.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include <testing/test_utils.h>

char *start_main();

char *end_main();

char *start_func();

char *end_func();

char *init_int_literal(int val);

int test_init_int_literal();
15 changes: 15 additions & 0 deletions src/codegen/x86/test_x86.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Run all of the tests at the end of each C file in the lexer module
*/

#include "codegen.h"
#include <testing/test_utils.h>

int test_x86() {
testing_module_setup();

test_init_int_literal();

testing_module_cleanup();
return 0;
}
10 changes: 10 additions & 0 deletions src/codegen/x86/test_x86.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Run all of the tests at the end of each C file in the lexer module
*/

#pragma once

#include "codegen.h"
#include <testing/test_utils.h>

int test_x86();
3 changes: 3 additions & 0 deletions src/lexer/lex.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "lex.h"
#include <testing/tassert.h> // tassert
#include <testing/test_utils.h>

#include <ctype.h>
#include <string.h> // memcpy
Expand Down Expand Up @@ -502,6 +503,8 @@ static const char *ttype_names[] = {
const char *ttype_name(TokenType tt) { return ttype_names[tt]; }

int test_ttype_from_string() {
testing_func_setup();

tassert(ttype_from_string("1") == TT_LITERAL);
tassert(ttype_from_string("1.2") == TT_LITERAL);

Expand Down
4 changes: 2 additions & 2 deletions src/lexer/test_lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
#include <testing/test_utils.h>

int test_lexer() {
testing_setup();
testing_module_setup();

test_ttype_from_string();

testing_cleanup();
testing_module_cleanup();
return 0;
}
2 changes: 2 additions & 0 deletions src/lexer/test_lexer.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/*
* Run all of the tests at the end of each C file in the lexer module */

#pragma once

#include "lex.h"

int test_lexer();
2 changes: 2 additions & 0 deletions src/testing/main.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#include "lexer/test_lexer.h"
#include "codegen/x86/test_x86.h"

int main() {
test_lexer();
test_x86();

return 0;
}
2 changes: 2 additions & 0 deletions src/testing/tassert.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#pragma once

#include <assert.h>

#define tassert(e) ((void)((e) ? 0 : __assert(#e, __FILE__, __LINE__)))
Expand Down
11 changes: 9 additions & 2 deletions src/testing/test_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@
#include <util/out.h>

void testing_setup_internal(const char *func_name) {
printf("Running test ");
printf("Running tests from ");
fflush(stdout);
PRINT_WITH_COLOR(CODE_GREEN, "\"%s\"", func_name);
printf(" ...\n");
}

void testing_cleanup_internal(const char *func_name) {
printf("Concluded test ");
printf("Concluded tests from ");
fflush(stdout);
PRINT_WITH_COLOR(CODE_GREEN, "\"%s\"", func_name);
printf("\n");
}

void testing_single_test_internal(const char *func_name) {
printf("Running ");
fflush(stdout);
PRINT_WITH_COLOR(CODE_GREEN, "\"%s\"", func_name);
printf("\n");
Expand Down
35 changes: 28 additions & 7 deletions src/testing/test_utils.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#pragma once

/* Testing utility
* Here is an example usage of the testing
*
Expand All @@ -11,30 +13,49 @@
#include <testing/test_utils.h>

int test_lexer() {
testing_setup();
testing_module_setup();

test_ttype_from_string();

testing_cleanup();
testing_module_cleanup();
return 0;
}

* After this, include a call to this function in the "testing/main.c" file like how it's done for test_lexer.
* After this, include a call to this function in the "testing/main.c" file like
how it's done for test_lexer.

#include "lexer/test_lexer.h"

int main() {
test_lexer();
test_lexer();

return 0;
return 0;
}

* Finally, here is what a test might look like. Make sure to include a call to testing_func_setup at the start.

int test_ttype_from_string() {
testing_func_setup();

tassert(ttype_from_string("1") == TT_LITERAL);
tassert(ttype_from_string("1.2") == TT_LITERAL);

// ...

tassert(ttype_from_string(";") == TT_SEMI);

return 0;
}
*/

#define testing_setup() testing_setup_internal(__func__)
#define testing_module_setup() testing_setup_internal(__func__)

#define testing_cleanup() testing_cleanup_internal(__func__)
#define testing_module_cleanup() testing_cleanup_internal(__func__)

#define testing_func_setup() testing_single_test_internal(__func__)

void testing_setup_internal(const char *func_name);

void testing_cleanup_internal(const char *func_name);

void testing_single_test_internal(const char *func_name);
Loading