Browse Source

implement arithmetic operations asm generation

Arnaud Vergnet 3 months ago
parent
commit
74e97fe963
11 changed files with 152 additions and 69 deletions
  1. 3
    3
      Makefile
  2. 18
    4
      al.lex
  3. 25
    9
      as.y
  4. 16
    1
      asm_instructions.c
  5. 2
    15
      asm_instructions.h
  6. 18
    16
      symbol_table.c
  7. 12
    4
      symbol_table.h
  8. 10
    15
      symbol_table.test.c
  9. 2
    2
      test.c
  10. 30
    0
      yacc_util.c
  11. 16
    0
      yacc_util.h

+ 3
- 3
Makefile View File

@@ -5,10 +5,10 @@ CC = gcc
5 5
 all: compilateur test
6 6
 
7 7
 test: symbol_table.test.c symbol_table.c symbol_table.h
8
-	$(CC) -o test symbol_table.test.c symbol_table.c
8
+	$(CC) -g -o test symbol_table.test.c symbol_table.c
9 9
 
10
-compilateur: as.tab.c lex.yy.c symbol_table.c symbol_table.h asm_instructions.c asm_instructions.h
11
-	$(CC) -o compilateur as.tab.c lex.yy.c symbol_table.c asm_instructions.c
10
+compilateur: as.tab.c lex.yy.c symbol_table.c symbol_table.h asm_instructions.c asm_instructions.h yacc_util.c yacc_util.h
11
+	$(CC) -o compilateur as.tab.c lex.yy.c symbol_table.c asm_instructions.c yacc_util.c
12 12
 
13 13
 as.tab.c: as.y
14 14
 	$(YACC) as.y

+ 18
- 4
al.lex View File

@@ -1,4 +1,6 @@
1 1
 %{
2
+#include "asm_instructions.h"
3
+#include "symbol_table.h"
2 4
 #include "as.tab.h"
3 5
 %}
4 6
 
@@ -11,10 +13,22 @@ D           [0-9]
11 13
                 return tNB;
12 14
             }
13 15
 
14
-"+"			{ return tADD; }
15
-"-"			{ return tSUB; }
16
-"*"			{ return tMUL; }
17
-"/"			{ return tDIV; }
16
+"+"			{ 
17
+                yylval.instruction = ADD;
18
+                return tADD; 
19
+            }
20
+"-"			{ 
21
+                yylval.instruction = SOU;
22
+                return tSUB;
23
+            }
24
+"*"			{ 
25
+                yylval.instruction = MUL;
26
+                return tMUL;
27
+            }
28
+"/"			{ 
29
+                yylval.instruction = DIV;
30
+                return tDIV;
31
+            }
18 32
 "="			{ return tEQ; }
19 33
 "("			{ return tPO; }
20 34
 ")"			{ return tPF; }

+ 25
- 9
as.y View File

@@ -2,23 +2,28 @@
2 2
 #include "stdio.h"
3 3
 #include "stdlib.h"
4 4
 #include "symbol_table.h"
5
+#include "asm_instructions.h"
6
+#include "yacc_util.h"
5 7
 
6 8
 enum Type current_type = TYPE_INT;
7 9
 
8 10
 SymbolTable symbol_table;
11
+InstructionTable instruction_table;
9 12
 
10 13
 %}
11 14
 
12 15
 %union {
13 16
     char* symbol_name;
17
+    SymbolItem* symbol;
14 18
 	int nombre;
19
+	Instruction instruction;
15 20
 }
16 21
 
17 22
 %token<nombre> tNB
18
-%token tADD
19
-%token tSUB
20
-%token tMUL
21
-%token tDIV
23
+%token<instruction> tADD
24
+%token<instruction> tSUB
25
+%token<instruction> tMUL
26
+%token<instruction> tDIV
22 27
 %token tPO
23 28
 %token tPF
24 29
 %token tPV
@@ -50,7 +55,7 @@ SymbolTable symbol_table;
50 55
 %left tSUB
51 56
 %left tMUL
52 57
 %left tDIV
53
-// %type<nombre> E
58
+%type<symbol> E
54 59
 
55 60
 %%
56 61
 
@@ -71,13 +76,20 @@ Instructions : Instruction Instructions |  { printf("Instructions\n"); } ;
71 76
 
72 77
 Instruction : Aff | Printf { printf("Instruction\n"); } ;
73 78
 
74
-Aff : tID tEQ E tPV { mark_symbol_initialized(&symbol_table, $1); } ;
79
+Aff : tID tEQ E tPV { write_affectation(&symbol_table, &instruction_table, $1, $3); } ;
75 80
 
76
-E : tNB { printf("%d\n", $1); } | tID | E tADD E | E tMUL E | E tSUB E | E tDIV E | tPO E tPF | tSUB E ;
81
+E : tNB { $$ = init_temp_symbol(&symbol_table, &instruction_table, $1); } 
82
+    | tID { $$ = get_symbol_item(&symbol_table, $1); } 
83
+    | E tADD E {$$ = write_op(&symbol_table, &instruction_table, $2, $1, $3); } 
84
+    | E tMUL E { $$ = write_op(&symbol_table, &instruction_table, $2, $1, $3); } 
85
+    | E tSUB E { $$ = write_op(&symbol_table, &instruction_table, $2, $1, $3); } 
86
+    | E tDIV E { $$ = write_op(&symbol_table, &instruction_table, $2, $1, $3); } 
87
+    | tPO E tPF { $$ = $2; } 
88
+    | tSUB E  { $$ = write_negation(&symbol_table, &instruction_table, $2); } ;
77 89
 
78
-Declarations : | Declaration Declarations { printf("Declarations\n"); } ;
90
+Declarations : | Declaration Declarations ;
79 91
 
80
-Declaration : DeclarationInt | DeclarationConst { printf("Declaration\n"); } ;
92
+Declaration : DeclarationInt | DeclarationConst ;
81 93
 
82 94
 DeclarationInt : tINT { current_type = TYPE_INT; } DeclarationBody tPV ;
83 95
 
@@ -162,6 +174,7 @@ On suppose que E est tout le temps une vt, donc on génère tout le temps le mê
162 174
 
163 175
 void init() {
164 176
     init_table(&symbol_table);
177
+    init_instruction_table(&instruction_table);
165 178
 }
166 179
 
167 180
 void yyerror(char const* err) {
@@ -173,4 +186,7 @@ void main(void) {
173 186
     init();
174 187
 	yyparse();
175 188
 	print_table(&symbol_table);
189
+    FILE *f = fopen("instruction_table.txt", "w+");
190
+	write_instruction_table(&instruction_table, f);
191
+    fclose(f);
176 192
 }

+ 16
- 1
asm_instructions.c View File

@@ -1,5 +1,20 @@
1 1
 #include "asm_instructions.h"
2 2
 
3
+char* instructions_labels[12] = {
4
+        "ADD",
5
+        "MUL",
6
+        "SOU",
7
+        "DIV",
8
+        "COP",
9
+        "AFC",
10
+        "JMP",
11
+        "JMF",
12
+        "INF",
13
+        "SUP",
14
+        "EQU",
15
+        "PRI"
16
+};
17
+
3 18
 void init_instruction_table(InstructionTable *table) {
4 19
     table->index = 0;
5 20
 }
@@ -26,5 +41,5 @@ void write_instruction_table(InstructionTable *table, FILE *file) {
26 41
 }
27 42
 
28 43
 void write_instruction(InstructionItem *item, FILE *file) {
29
-    fprintf(file, "%s %d %d %d", instructions_labels[item->instruction], item->arg1, item->arg2, item->arg3);
44
+    fprintf(file, "%s %d %d %d\n", instructions_labels[item->instruction], item->arg1, item->arg2, item->arg3);
30 45
 }

+ 2
- 15
asm_instructions.h View File

@@ -8,7 +8,7 @@
8 8
 typedef enum Instruction {
9 9
         ADD,
10 10
         MUL,
11
-        SUO,
11
+        SOU,
12 12
         DIV,
13 13
         COP,
14 14
         AFC,
@@ -20,20 +20,7 @@ typedef enum Instruction {
20 20
         PRI
21 21
 } Instruction;
22 22
 
23
-char* instructions_labels[12] = {
24
-        "ADD",
25
-        "MUL",
26
-        "SUO",
27
-        "DIV",
28
-        "COP",
29
-        "AFC",
30
-        "JMP",
31
-        "JMF",
32
-        "INF",
33
-        "SUP",
34
-        "EQU",
35
-        "PRI"
36
-};
23
+char* instructions_labels[12];
37 24
 
38 25
 
39 26
 typedef struct InstructionItem {

+ 18
- 16
symbol_table.c View File

@@ -8,6 +8,13 @@ void init_table(SymbolTable *table) {
8 8
     table->temp_index = SYMBOL_TABLE_SIZE - 1;
9 9
 }
10 10
 
11
+void init_symbol_item(SymbolItem *symbol_item, size_t name_size) {
12
+    symbol_item->type = 0;
13
+    symbol_item->name = malloc(name_size);
14
+    symbol_item->address = 0;
15
+    symbol_item->init = 0;
16
+}
17
+
11 18
 int has_symbol(SymbolTable* table, char *name) {
12 19
     for (int i = 0; i < table->index; i++) {
13 20
         if (strcmp(table->table[i].name, name) == 0) {
@@ -30,6 +37,7 @@ int add_symbol(SymbolTable *table, enum Type type, char *name) {
30 37
         return -1;
31 38
     }
32 39
     SymbolItem newItem;
40
+    init_symbol_item(&newItem, strlen(name));
33 41
     newItem.type = type;
34 42
     newItem.name = name;
35 43
     newItem.address = table->index;
@@ -40,26 +48,20 @@ int add_symbol(SymbolTable *table, enum Type type, char *name) {
40 48
     return 0;
41 49
 }
42 50
 
43
-int add_temp_symbol(SymbolTable* table, enum Type type, char *name) {
51
+const SymbolItem* add_temp_symbol(SymbolTable* table, enum Type type) {
44 52
     if (table->temp_index < table->index) {
45
-        return -2;
46
-    }
47
-    if (has_symbol(table, name)) {
48
-        return -1;
49
-    }
50
-    if (name[0] != '_') {
51
-        return -3;
53
+        return NULL;
52 54
     }
53 55
 
54
-    SymbolItem newItem;
55
-    newItem.type = type;
56
-    newItem.name = name;
57
-    newItem.address = table->temp_index;
58
-    newItem.init = 0;
56
+    SymbolItem *newItem = &table->table[table->temp_index];
57
+    init_symbol_item(newItem, 10);
58
+    newItem->type = type;
59
+    sprintf(newItem->name, "_temp%d", table->temp_index);
60
+    newItem->address = table->temp_index;
61
+    newItem->init = 0;
59 62
 
60
-    table->table[table->temp_index] = newItem;
61 63
     table->temp_index--;
62
-    return 0;
64
+    return newItem;
63 65
 }
64 66
 
65 67
 int mark_symbol_initialized(SymbolTable *table, char *name) {
@@ -107,7 +109,7 @@ void print_item(struct SymbolItem *item) {
107 109
     }
108 110
 }
109 111
 
110
-SymbolItem *get_symbol_item(SymbolTable *table, char *name) {
112
+SymbolItem *get_symbol_item(SymbolTable *table, const char *name) {
111 113
     for (int i = 0; i < table->index; i++) {
112 114
         if (strcmp(table->table[i].name, name) == 0) {
113 115
             return &table->table[i];

+ 12
- 4
symbol_table.h View File

@@ -1,6 +1,8 @@
1 1
 #ifndef SYMBOL_TABLE_H_INCLUDED
2 2
 #define SYMBOL_TABLE_H_INCLUDED
3 3
 
4
+#include <stddef.h>
5
+
4 6
 #define SYMBOL_TABLE_SIZE 100
5 7
 
6 8
 enum Type {
@@ -32,6 +34,13 @@ typedef struct SymbolTable {
32 34
 void init_table(SymbolTable *table);
33 35
 
34 36
 /**
37
+ * Initializes the symbol
38
+ *
39
+ * @param table
40
+ */
41
+void init_symbol_item(SymbolItem *symbol_item, size_t name_size);
42
+
43
+/**
35 44
  * Checks if the given symbol is in the table
36 45
  *
37 46
  * @param table
@@ -57,10 +66,9 @@ int add_symbol(SymbolTable* table, enum Type type, char *name);
57 66
  * @param table
58 67
  * @param type
59 68
  * @param name
60
- * @return 0 on success, -1 if the symbol already exists, -2 if the table is full
61
- *          -3 if the name doesn't start by _
69
+ * @return 0 on success, -1 if the table is full
62 70
  */
63
-int add_temp_symbol(SymbolTable* table, enum Type type, char *name);
71
+const SymbolItem* add_temp_symbol(SymbolTable* table, enum Type type);
64 72
 
65 73
 /**
66 74
  * Marks the given symbol as initialized
@@ -100,6 +108,6 @@ char* type_to_string(enum Type type);
100 108
  * @param name
101 109
  * @return the item if found, NULL otherwise
102 110
  */
103
-SymbolItem *get_symbol_item(SymbolTable* table, char *name);
111
+SymbolItem *get_symbol_item(SymbolTable* table, const char *name);
104 112
 
105 113
 #endif /* !SYMBOL_TABLE_H_INCLUDED  */

+ 10
- 15
symbol_table.test.c View File

@@ -1,6 +1,7 @@
1 1
 #include "symbol_table.h"
2 2
 #include <stdio.h>
3 3
 #include <assert.h>
4
+#include <string.h>
4 5
 
5 6
 int main() {
6 7
     int err;
@@ -33,23 +34,17 @@ int main() {
33 34
     printf("Mark b initialized\n");
34 35
     assert(err == -1);
35 36
 
36
-    err = add_temp_symbol(&table, TYPE_INT, "_temp1");
37
-    printf("Add _temp1 temporary variable\n");
38
-    assert(err == 0);
39
-    err = add_temp_symbol(&table, TYPE_INT, "_temp2");
40
-    printf("Add _temp2 temporary variable\n");
41
-    assert(err == 0);
42
-    err = add_temp_symbol(&table, TYPE_INT, "_temp1");
43
-    printf("Add _temp1 temporary variable\n");
44
-    assert(err == -1);
45
-    err = add_temp_symbol(&table, TYPE_INT, "temp1");
46
-    printf("Add temp1 temporary variable\n");
47
-    assert(err == -3);
37
+    const SymbolItem* var1 = add_temp_symbol(&table, TYPE_INT);
38
+    printf("Add _temp99 temporary variable\n");
39
+    assert(strcmp(var1->name, "_temp99") == 0);
40
+    const SymbolItem* var2 = add_temp_symbol(&table, TYPE_INT);
41
+    printf("Add _temp98 temporary variable\n");
42
+    assert(strcmp(var2->name, "_temp98") == 0);
48 43
 
49
-    item = get_symbol_item(&table, "_temp1");
50
-    printf("_temp1:\n");
44
+    item = get_symbol_item(&table, "_temp98");
45
+    printf("_temp98:\n");
51 46
     print_item(item);
52
-    item = get_symbol_item(&table, "_temp5");
47
+    item = get_symbol_item(&table, "_temp0");
53 48
     printf("_temp5:\n");
54 49
     print_item(item);
55 50
 

+ 2
- 2
test.c View File

@@ -2,6 +2,6 @@ int main(){
2 2
     int x, y, z;
3 3
     const PL5_op, b, c;
4 4
     printf(x);
5
-    x = 3 + 2;
6
-    y = 3;
5
+    x = 2;
6
+    y = 3 + 3 + x;
7 7
 }

+ 30
- 0
yacc_util.c View File

@@ -0,0 +1,30 @@
1
+#include "yacc_util.h"
2
+
3
+void write_affectation(SymbolTable* symbol_table, InstructionTable *instruction_table, char* symbol_dest, SymbolItem* src) {
4
+    mark_symbol_initialized(symbol_table, symbol_dest);
5
+    SymbolItem *dest = get_symbol_item(symbol_table, symbol_dest);
6
+    add_instruction(instruction_table, COP, src->address, dest->address, 0);
7
+}
8
+
9
+const SymbolItem* write_op(SymbolTable* symbol_table, InstructionTable *instruction_table, Instruction instruction, SymbolItem *op1, SymbolItem *op2) {
10
+    const SymbolItem* dest = add_temp_symbol(symbol_table, TYPE_INT);
11
+    add_instruction(instruction_table, instruction, dest->address, op1->address, op2->address);
12
+    return dest;
13
+}
14
+
15
+const SymbolItem* write_negation(SymbolTable* symbol_table, InstructionTable *instruction_table, SymbolItem *op2) {
16
+//    Create temp variable with 0
17
+    const SymbolItem* op1 = init_temp_symbol(symbol_table, instruction_table, 0);
18
+    const SymbolItem* dest = add_temp_symbol(symbol_table, TYPE_INT);
19
+//    Make the 0 - variable operation
20
+    add_instruction(instruction_table, SOU, dest->address, op1->address, op2->address);
21
+    return dest;
22
+}
23
+
24
+
25
+const SymbolItem* init_temp_symbol(SymbolTable* symbol_table, InstructionTable *instruction_table, int constant) {
26
+    const SymbolItem* dest = add_temp_symbol(symbol_table, TYPE_INT);
27
+    add_instruction(instruction_table, AFC, dest->address, constant, 0);
28
+    return dest;
29
+}
30
+

+ 16
- 0
yacc_util.h View File

@@ -0,0 +1,16 @@
1
+#include "symbol_table.h"
2
+#include "asm_instructions.h"
3
+
4
+#ifndef COMPILATOR_2000_YACC_UTIL_H
5
+#define COMPILATOR_2000_YACC_UTIL_H
6
+
7
+
8
+void write_affectation(SymbolTable* symbolTable, InstructionTable *instructionTable, char* symbol_dest, SymbolItem* src);
9
+
10
+const SymbolItem* write_op(SymbolTable* symbol_table, InstructionTable *instruction_table, Instruction instruction, SymbolItem *op1, SymbolItem *op2);
11
+
12
+const SymbolItem* write_negation(SymbolTable* symbol_table, InstructionTable *instruction_table, SymbolItem *op2);
13
+
14
+const SymbolItem* init_temp_symbol(SymbolTable* symbol_table, InstructionTable *instruction_table, int constant);
15
+
16
+#endif //COMPILATOR_2000_YACC_UTIL_H

Loading…
Cancel
Save