diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/generator.c | 135 | ||||
-rw-r--r-- | src/generator.h | 4 | ||||
-rw-r--r-- | src/symbol_table.c | 28 | ||||
-rw-r--r-- | src/symbol_table.h | 4 | ||||
-rw-r--r-- | src/tpc.y | 20 |
5 files changed, 116 insertions, 75 deletions
diff --git a/src/generator.c b/src/generator.c index 0a40570..3ecfe0d 100644 --- a/src/generator.c +++ b/src/generator.c | |||
@@ -10,71 +10,74 @@ | |||
10 | void gen_prologue() { | 10 | void gen_prologue() { |
11 | fprintf(output, "extern printf\nextern scanf\n"); | 11 | fprintf(output, "extern printf\nextern scanf\n"); |
12 | fprintf(output, "section .data\n"); | 12 | fprintf(output, "section .data\n"); |
13 | } | ||
14 | |||
15 | void gen_prologue_continue(int *bss_done) { | ||
16 | if (*bss_done != 0) return; | ||
17 | |||
13 | fprintf(output, "format_int db \"%%d\",10,0\n"); | 18 | fprintf(output, "format_int db \"%%d\",10,0\n"); |
14 | fprintf(output, "format_char db \"%%c\",10,0\n"); | 19 | fprintf(output, "format_char db \"%%c\",10,0\n"); |
15 | fprintf(output, "format_int_in: db \"%%d\", 0\n"); | 20 | fprintf(output, "format_int_in: db \"%%d\", 0\n"); |
16 | fprintf(output, "format_char_in: db \"%%c\", 0\n\n"); | 21 | fprintf(output, "format_char_in: db \"%%c\", 0\n\n"); |
17 | fprintf(output, "section .bss\n"); | 22 | fprintf(output, "section .bss\n"); |
23 | |||
24 | fprintf(output, "globals: resq %d\n", nb_globals); | ||
25 | fprintf(output, "section .text\n\nglobal _start\n"); | ||
26 | fprintf(output, "\nprinte: ;print needs an argument in rax\n"); | ||
27 | fprintf(output, "push rbp\n"); | ||
28 | fprintf(output, "mov rbp, rsp\n"); | ||
29 | fprintf(output, "push rsi\n"); | ||
30 | fprintf(output, "push rdi\n"); | ||
31 | fprintf(output, "mov rsi, rax\n"); | ||
32 | fprintf(output, "mov rdi, format_int\n"); | ||
33 | fprintf(output, "mov rax, 0\n"); | ||
34 | fprintf(output, "call printf WRT ..plt\n"); | ||
35 | fprintf(output, "pop rdi\n"); | ||
36 | fprintf(output, "pop rsi\n"); | ||
37 | fprintf(output, "pop rbp\n"); | ||
38 | fprintf(output, "ret\n"); | ||
39 | fprintf(output, "\nprintc: ;print needs an argument in rax\n"); | ||
40 | fprintf(output, "push rbp\n"); | ||
41 | fprintf(output, "mov rbp, rsp\n"); | ||
42 | fprintf(output, "push rsi\n"); | ||
43 | fprintf(output, "push rdi\n"); | ||
44 | fprintf(output, "mov rsi, rax\n"); | ||
45 | fprintf(output, "mov rdi, format_char\n"); | ||
46 | fprintf(output, "mov rax, 0\n"); | ||
47 | fprintf(output, "call printf WRT ..plt\n"); | ||
48 | fprintf(output, "pop rdi\n"); | ||
49 | fprintf(output, "pop rsi\n"); | ||
50 | fprintf(output, "pop rbp\n"); | ||
51 | fprintf(output, "ret\n"); | ||
52 | fprintf(output, "\nreade: ;read needs an adress in rax\n"); | ||
53 | fprintf(output, "push rbp\n"); | ||
54 | fprintf(output, "mov rbp, rsp\n"); | ||
55 | fprintf(output, "push rsi\n"); | ||
56 | fprintf(output, "push rdi\n"); | ||
57 | fprintf(output, "mov rsi, rax\n"); | ||
58 | fprintf(output, "mov rdi, format_int_in\n"); | ||
59 | fprintf(output, "mov rax, 0\n"); | ||
60 | fprintf(output, "call scanf\n"); | ||
61 | fprintf(output, "pop rdi\n"); | ||
62 | fprintf(output, "pop rsi\n"); | ||
63 | fprintf(output, "pop rbp\n"); | ||
64 | fprintf(output, "ret\n"); | ||
65 | fprintf(output, "\nreadc: ;read needs an adress in rax\n"); | ||
66 | fprintf(output, "push rbp\n"); | ||
67 | fprintf(output, "mov rbp, rsp\n"); | ||
68 | fprintf(output, "push rsi\n"); | ||
69 | fprintf(output, "push rdi\n"); | ||
70 | fprintf(output, "mov rsi, rax\n"); | ||
71 | fprintf(output, "mov rdi, format_char_in\n"); | ||
72 | fprintf(output, "mov rax, 0\n"); | ||
73 | fprintf(output, "call scanf\n"); | ||
74 | fprintf(output, "pop rdi\n"); | ||
75 | fprintf(output, "pop rsi\n"); | ||
76 | fprintf(output, "pop rbp\n"); | ||
77 | fprintf(output, "ret\n"); | ||
78 | *bss_done = 1; | ||
18 | } | 79 | } |
19 | void gen_prologue_continue(int *bss_done) { | 80 | |
20 | if (*bss_done == 0) { | ||
21 | fprintf(output, "globals: resq %d\n", nb_globals); | ||
22 | fprintf(output, "section .text\n\nglobal _start\n"); | ||
23 | fprintf(output, "\nprinte: ;print needs an argument in rax\n"); | ||
24 | fprintf(output, "push rbp\n"); | ||
25 | fprintf(output, "mov rbp, rsp\n"); | ||
26 | fprintf(output, "push rsi\n"); | ||
27 | fprintf(output, "push rdi\n"); | ||
28 | fprintf(output, "mov rsi, rax\n"); | ||
29 | fprintf(output, "mov rdi, format_int\n"); | ||
30 | fprintf(output, "mov rax, 0\n"); | ||
31 | fprintf(output, "call printf WRT ..plt\n"); | ||
32 | fprintf(output, "pop rdi\n"); | ||
33 | fprintf(output, "pop rsi\n"); | ||
34 | fprintf(output, "pop rbp\n"); | ||
35 | fprintf(output, "ret\n"); | ||
36 | fprintf(output, "\nprintc: ;print needs an argument in rax\n"); | ||
37 | fprintf(output, "push rbp\n"); | ||
38 | fprintf(output, "mov rbp, rsp\n"); | ||
39 | fprintf(output, "push rsi\n"); | ||
40 | fprintf(output, "push rdi\n"); | ||
41 | fprintf(output, "mov rsi, rax\n"); | ||
42 | fprintf(output, "mov rdi, format_char\n"); | ||
43 | fprintf(output, "mov rax, 0\n"); | ||
44 | fprintf(output, "call printf WRT ..plt\n"); | ||
45 | fprintf(output, "pop rdi\n"); | ||
46 | fprintf(output, "pop rsi\n"); | ||
47 | fprintf(output, "pop rbp\n"); | ||
48 | fprintf(output, "ret\n"); | ||
49 | fprintf(output, "\nreade: ;read needs an adress in rax\n"); | ||
50 | fprintf(output, "push rbp\n"); | ||
51 | fprintf(output, "mov rbp, rsp\n"); | ||
52 | fprintf(output, "push rsi\n"); | ||
53 | fprintf(output, "push rdi\n"); | ||
54 | fprintf(output, "mov rsi, rax\n"); | ||
55 | fprintf(output, "mov rdi, format_int_in\n"); | ||
56 | fprintf(output, "mov rax, 0\n"); | ||
57 | fprintf(output, "call scanf\n"); | ||
58 | fprintf(output, "pop rdi\n"); | ||
59 | fprintf(output, "pop rsi\n"); | ||
60 | fprintf(output, "pop rbp\n"); | ||
61 | fprintf(output, "ret\n"); | ||
62 | fprintf(output, "\nreadc: ;read needs an adress in rax\n"); | ||
63 | fprintf(output, "push rbp\n"); | ||
64 | fprintf(output, "mov rbp, rsp\n"); | ||
65 | fprintf(output, "push rsi\n"); | ||
66 | fprintf(output, "push rdi\n"); | ||
67 | fprintf(output, "mov rsi, rax\n"); | ||
68 | fprintf(output, "mov rdi, format_char_in\n"); | ||
69 | fprintf(output, "mov rax, 0\n"); | ||
70 | fprintf(output, "call scanf\n"); | ||
71 | fprintf(output, "pop rdi\n"); | ||
72 | fprintf(output, "pop rsi\n"); | ||
73 | fprintf(output, "pop rbp\n"); | ||
74 | fprintf(output, "ret\n"); | ||
75 | *bss_done = 1; | ||
76 | } | ||
77 | } | ||
78 | void gen_const_declaration() { | 81 | void gen_const_declaration() { |
79 | fprintf(output, "\n_start:\n"); | 82 | fprintf(output, "\n_start:\n"); |
80 | fprintf(output, "push rbp\nmov rbp, rsp\n\n"); | 83 | fprintf(output, "push rbp\nmov rbp, rsp\n\n"); |
@@ -90,6 +93,20 @@ void gen_const_declaration() { | |||
90 | fun_display_table(); | 93 | fun_display_table(); |
91 | } | 94 | } |
92 | 95 | ||
96 | void gen_const(const char name[], int value, Scope scope) { | ||
97 | switch (scope) { | ||
98 | case LOCAL: | ||
99 | loc_addConst(name); | ||
100 | fprintf(output, "push %d\n", value); | ||
101 | return; | ||
102 | |||
103 | case GLOBAL: | ||
104 | glo_addConst(name); | ||
105 | fprintf(output, "%s: db QWORD %d\n", name, value); | ||
106 | return; | ||
107 | } | ||
108 | } | ||
109 | |||
93 | Type gen_function_declaration(const char name[], int return_type) { | 110 | Type gen_function_declaration(const char name[], int return_type) { |
94 | fprintf(output, "\n%s:\npush rbp\nmov rbp,rsp\n", name); | 111 | fprintf(output, "\n%s:\npush rbp\nmov rbp,rsp\n", name); |
95 | return return_type; | 112 | return return_type; |
diff --git a/src/generator.h b/src/generator.h index 41a769a..6c132fd 100644 --- a/src/generator.h +++ b/src/generator.h | |||
@@ -7,6 +7,7 @@ | |||
7 | #define __GENERATOR_H__ | 7 | #define __GENERATOR_H__ |
8 | 8 | ||
9 | #include <stdio.h> | 9 | #include <stdio.h> |
10 | #include <stdbool.h> | ||
10 | #include "symbol_table.h" | 11 | #include "symbol_table.h" |
11 | 12 | ||
12 | typedef enum scope { | 13 | typedef enum scope { |
@@ -21,10 +22,13 @@ FILE *output; | |||
21 | void gen_prologue(); | 22 | void gen_prologue(); |
22 | void gen_prologue_continue(int *bss_done); | 23 | void gen_prologue_continue(int *bss_done); |
23 | void gen_const_declaration(); | 24 | void gen_const_declaration(); |
25 | void gen_const(const char name[], int value, Scope scope); | ||
26 | |||
24 | Type gen_function_declaration(const char name[], int return_type); | 27 | Type gen_function_declaration(const char name[], int return_type); |
25 | void gen_function_end_declaration(const char name[], int return_type, int nb_param); | 28 | void gen_function_end_declaration(const char name[], int return_type, int nb_param); |
26 | void gen_function_return(Type expect, Type actual); | 29 | void gen_function_return(Type expect, Type actual); |
27 | Type gen_function_call(const char name[], int nb_param); | 30 | Type gen_function_call(const char name[], int nb_param); |
31 | |||
28 | void gen_declaration(const char name[], int type, Scope scope); | 32 | void gen_declaration(const char name[], int type, Scope scope); |
29 | void gen_check(const char name[], Scope scope); | 33 | void gen_check(const char name[], Scope scope); |
30 | 34 | ||
diff --git a/src/symbol_table.c b/src/symbol_table.c index 483de4c..08124ac 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c | |||
@@ -66,7 +66,7 @@ int fun_lookup(const char name[], int nb_param) { | |||
66 | return -1; | 66 | return -1; |
67 | } | 67 | } |
68 | 68 | ||
69 | void glo_addVar(const char name[], int type) { | 69 | static void glo_add(const char name[], int type, bool read_only) { |
70 | int count; | 70 | int count; |
71 | for (count = 0; count < glo_symbol_table.size; count++) { | 71 | for (count = 0; count < glo_symbol_table.size; count++) { |
72 | if (!strcmp(glo_symbol_table.entries[count].name, name)) { | 72 | if (!strcmp(glo_symbol_table.entries[count].name, name)) { |
@@ -82,8 +82,16 @@ void glo_addVar(const char name[], int type) { | |||
82 | } | 82 | } |
83 | strcpy(glo_symbol_table.entries[glo_symbol_table.size - 1].name, name); | 83 | strcpy(glo_symbol_table.entries[glo_symbol_table.size - 1].name, name); |
84 | glo_symbol_table.entries[glo_symbol_table.size - 1].type = type; | 84 | glo_symbol_table.entries[glo_symbol_table.size - 1].type = type; |
85 | glo_symbol_table.entries[glo_symbol_table.size - 1].addr = | 85 | glo_symbol_table.entries[glo_symbol_table.size - 1].addr = (glo_symbol_table.size - 1) * 8; |
86 | (glo_symbol_table.size - 1) * 8; | 86 | glo_symbol_table.entries[glo_symbol_table.size - 1].read_only = read_only; |
87 | } | ||
88 | |||
89 | void glo_addVar(const char name[], int type) { | ||
90 | glo_add(name, type, false); | ||
91 | } | ||
92 | |||
93 | void glo_addConst(const char name[]) { | ||
94 | glo_add(name, INT, true); | ||
87 | } | 95 | } |
88 | 96 | ||
89 | // Verifies that the variable exists and returns the type | 97 | // Verifies that the variable exists and returns the type |
@@ -125,7 +133,7 @@ void glo_display_table() { | |||
125 | fprintf(output, "\n"); | 133 | fprintf(output, "\n"); |
126 | } | 134 | } |
127 | 135 | ||
128 | void loc_addVar(const char name[], int type) { | 136 | static void loc_add(const char name[], int type, bool read_only) { |
129 | int count; | 137 | int count; |
130 | for (count = 0; count < loc_symbol_table.size; count++) { | 138 | for (count = 0; count < loc_symbol_table.size; count++) { |
131 | if (!strcmp(loc_symbol_table.entries[count].name, name)) { | 139 | if (!strcmp(loc_symbol_table.entries[count].name, name)) { |
@@ -141,8 +149,16 @@ void loc_addVar(const char name[], int type) { | |||
141 | } |