Browse Source

add interpreter

Arnaud Vergnet 3 months ago
parent
commit
e3ea8ee709

+ 6
- 3
.gitignore View File

@@ -1,6 +1,9 @@
1
-/as.tab.c
2
-/as.tab.h
3 1
 /compilateur
4
-/lex.yy.c
5 2
 
6 3
 /as.output
4
+/instruction_table.txt
5
+/test
6
+/interpreter/interpreter
7
+*.tab.c
8
+*.tab.h
9
+*.yy.c

+ 8
- 0
interpreter/input.txt View File

@@ -0,0 +1,8 @@
1
+AFC 0 1
2
+AFC 10 20
3
+ADD 0 0 10
4
+AFC 1 8888
5
+SUP 2 0 1
6
+JMF 2 7
7
+PRI 1
8
+PRI 0

+ 14
- 0
interpreter/makefile View File

@@ -0,0 +1,14 @@
1
+SRCC:= ./src/*.c
2
+
3
+all: interpreter
4
+
5
+interpreter: ./src/interpreter.y ./src/interpreter.l ./src/instructions.c
6
+	yacc -d ./src/interpreter.y
7
+	lex ./src/interpreter.l
8
+	gcc lex.yy.c y.tab.c ./src/instructions.c -Isrc -o interpreter
9
+
10
+run: interpreter
11
+	./interpreter < input.txt
12
+
13
+clean:
14
+	rm -f lex.yy.c interpreter y.tab.h y.tab.c *.o

+ 145
- 0
interpreter/src/instructions.c View File

@@ -0,0 +1,145 @@
1
+#include <stdio.h>
2
+#include "instructions.h"
3
+
4
+struct instruction {
5
+    char ins;
6
+    int arg1;
7
+    int arg2;
8
+    int arg3;
9
+};
10
+
11
+struct instruction instructions[MAX_INSTRUCTIONS_SIZE];
12
+int current_line;
13
+int has_error;
14
+
15
+int memory[MAX_MEMORY_SIZE];
16
+
17
+int exec(int ip);
18
+int valid_memory_addr(int address);
19
+
20
+/***** Public funciton *****/
21
+
22
+void asm_init() {
23
+    current_line = 0;
24
+    has_error = 0;
25
+}
26
+
27
+void asm_add_3(char ins, int arg1, int arg2, int arg3) {
28
+    if (current_line >= MAX_INSTRUCTIONS_SIZE) {
29
+        fprintf(stderr, "ERROR readfile : Too much instructions, please modify value of MAX_INSTRUCTIONS_SIZE.\n");
30
+        has_error = 1;
31
+        return;
32
+    }
33
+
34
+    // ip are validated at runtime; memory addr are validated here
35
+    if (ins == AFC || ins == JMF) {
36
+        if (!valid_memory_addr(arg1)) {
37
+            fprintf(stderr, "ERROR readfile : INVALID addr at line %d, please verify that addr is in range 0 to MAX_MEMORY_SIZE\n", current_line);
38
+            has_error = 1;
39
+            return;
40
+        }
41
+    } else if (ins == JMP) {
42
+        // do nothing
43
+    } else {
44
+        if (!(valid_memory_addr(arg1) && valid_memory_addr(arg2)
45
+            && valid_memory_addr(arg3))) {
46
+            fprintf(stderr, "ERROR readfile : INVALID addr at line %d, please verify that addr is in range 0 to MAX_MEMORY_SIZE\n", current_line);
47
+            has_error = 1;
48
+            return;
49
+        }
50
+    }
51
+
52
+    // When OK
53
+    instructions[current_line].ins = ins;
54
+    instructions[current_line].arg1 = arg1;
55
+    instructions[current_line].arg2 = arg2;
56
+    instructions[current_line].arg3 = arg3;
57
+    current_line++;
58
+}
59
+
60
+void asm_add_2(char ins, int arg1, int arg2) {
61
+    asm_add_3(ins, arg1, arg2, 0);
62
+}
63
+
64
+void asm_add_1(char ins, int arg1) {
65
+    asm_add_3(ins, arg1, 0, 0);
66
+}
67
+
68
+void asm_run() {
69
+    int ip = 0;
70
+    if (has_error) {
71
+        fprintf(stderr, "ERROR run : abandoned due to previous error.\n");
72
+        return;
73
+    }
74
+    printf("INFO run : begin\n");
75
+    while (ip >= 0 && ip < current_line) {
76
+        // wait for user input
77
+        //getchar();
78
+        // execution
79
+        ip = exec(ip);
80
+    }
81
+    printf("INFO run : end\n");
82
+}
83
+
84
+/***** Private funciton *****/
85
+
86
+int valid_memory_addr(int addr) {
87
+    return addr >= 0 && addr < MAX_MEMORY_SIZE;
88
+}
89
+
90
+int exec(int ip) {
91
+    int next_ip = ip + 1;
92
+    char ins = instructions[ip].ins;
93
+    int arg1 = instructions[ip].arg1;
94
+    int arg2 = instructions[ip].arg2;
95
+    int arg3 = instructions[ip].arg3;
96
+    printf("%d : ", ip);
97
+
98
+    // execute inst
99
+    switch (ins) {
100
+    case ADD:
101
+        printf("ADD @%d = @%d[%d] + @%d[%d]\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
102
+        memory[arg1] = memory[arg2] + memory[arg3]; break;
103
+    case MUL:
104
+        printf("MUL @%d = @%d[%d] * @%d[%d]\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
105
+        memory[arg1] = memory[arg2] * memory[arg3]; break;
106
+    case SOU:
107
+        printf("SOU @%d = @%d[%d] - @%d[%d]\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
108
+        memory[arg1] = memory[arg2] - memory[arg3]; break;
109
+    case DIV:
110
+        printf("DIV @%d = @%d[%d] / @%d[%d]\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
111
+        memory[arg1] = memory[arg2] / memory[arg3]; break;
112
+    case COP:
113
+        printf("COP @%d = @%d[%d]\n", arg1, arg2, memory[arg2]);
114
+        memory[arg1] = memory[arg2]; break;
115
+    case AFC:
116
+        printf("AFC @%d = %d\n", arg1, arg2);
117
+        memory[arg1] = arg2; break;
118
+    case JMP:
119
+        printf("JMP to %d\n", arg1);
120
+        next_ip = arg1; break;
121
+    case JMF:
122
+        printf("JMF cond@%d[%d] to %d\n", arg1, memory[arg1], arg2);
123
+        if (memory[arg1] == 0) next_ip = arg2;
124
+        break;
125
+    case INF:
126
+        printf("INF @%d = @%d[%d] < @%d[%d] ? 1 : 0\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
127
+        memory[arg1] = memory[arg2] < memory[arg3] ? 1 : 0;
128
+        break;
129
+    case SUP:
130
+        printf("SUP @%d = @%d[%d] > @%d[%d] ? 1 : 0\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
131
+        memory[arg1] = memory[arg2] > memory[arg3] ? 1 : 0;
132
+        break;
133
+    case EQU:
134
+        printf("EQU @%d = @%d[%d] == @%d[%d] ? 1 : 0\n", arg1, arg2, memory[arg2], arg3, memory[arg3]);
135
+        memory[arg1] = memory[arg2] ==  memory[arg3] ? 1 : 0;
136
+        break;
137
+    case PRI:
138
+        printf("PRI @%d[%d]\n", arg1, memory[arg1]);
139
+        break;
140
+    default:
141
+        fprintf(stderr, "ERROR run : unknown inst.\n");
142
+    }
143
+
144
+    return next_ip;
145
+}

+ 26
- 0
interpreter/src/instructions.h View File

@@ -0,0 +1,26 @@
1
+#ifndef __INSTRUCTIONS_H__
2
+#define __INSTRUCTIONS_H__
3
+
4
+#define ADD 1
5
+#define MUL 2
6
+#define SOU 3
7
+#define DIV 4
8
+#define COP 5
9
+#define AFC 6
10
+#define JMP 7
11
+#define JMF 8
12
+#define INF 9
13
+#define SUP 10
14
+#define EQU 11
15
+#define PRI 12
16
+
17
+#define MAX_INSTRUCTIONS_SIZE 256
18
+#define MAX_MEMORY_SIZE 256
19
+
20
+void asm_init();
21
+void asm_add_3(char ins, int arg1, int arg2, int arg3);
22
+void asm_add_2(char ins, int arg1, int arg2);
23
+void asm_add_1(char ins, int arg1);
24
+void asm_run();
25
+
26
+#endif // #ifndef __INSTRUCTIONS_H__

+ 38
- 0
interpreter/src/interpreter.l View File

@@ -0,0 +1,38 @@
1
+%{
2
+    #include "y.tab.h"
3
+%}
4
+
5
+vSEP    [ \t\r\n]
6
+
7
+%%
8
+
9
+ADD {return tADD;}
10
+MUL {return tMUL;}
11
+SOU {return tSOU;}
12
+DIV {return tDIV;}
13
+COP {return tCOP;}
14
+AFC {return tAFC;}
15
+JMP {return tJMP;}
16
+JMF {return tJMF;}
17
+INF {return tINF;}
18
+SUP {return tSUP;}
19
+EQU {return tEQU;}
20
+PRI {return tPRI;}
21
+
22
+-?[0-9]+  {
23
+        yylval.nb = atoi(yytext);
24
+        return tNB;
25
+        }
26
+
27
+
28
+{vSEP}  {}
29
+
30
+.       {
31
+        fprintf(stderr, "ERROR lex : Unknown pattern %s", yytext);
32
+        exit(1);
33
+        }
34
+
35
+%%
36
+
37
+int yywrap(void) { return 1; }
38
+//int main(int argc, char *argv[]) { while (yylex()!=0) ; return 0; }

+ 73
- 0
interpreter/src/interpreter.y View File

@@ -0,0 +1,73 @@
1
+%{
2
+    #include <stdio.h>
3
+    #include "instructions.h"
4
+    int yylex();
5
+    void yyerror(char*);
6
+    int yydebug = 1;
7
+    extern int yylineno;
8
+%}
9
+
10
+/* Union for yylval */
11
+%union {
12
+    int nb;
13
+}
14
+
15
+%token tADD tMUL tSOU tDIV tCOP tAFC tJMP tJMF tINF tSUP tEQU tPRI
16
+
17
+%token <nb> tNB
18
+
19
+%%
20
+
21
+%start File;
22
+
23
+File:
24
+    Instructions;
25
+
26
+Instructions:
27
+    /* epsilon */
28
+    | Instructions Instruction
29
+    ;
30
+
31
+Instruction:
32
+    tADD tNB tNB tNB
33
+        {asm_add_3(ADD, $2, $3, $4);}
34
+    | tMUL tNB tNB tNB
35
+        {asm_add_3(MUL, $2, $3, $4);}
36
+    | tSOU tNB tNB tNB
37
+        {asm_add_3(SOU, $2, $3, $4);}
38
+    | tDIV tNB tNB tNB
39
+        {asm_add_3(DIV, $2, $3, $4);}
40
+    | tCOP tNB tNB
41
+        {asm_add_2(COP, $2, $3);}
42
+    | tAFC tNB tNB
43
+        {asm_add_2(AFC, $2, $3);}
44
+    | tJMP tNB
45
+        {asm_add_1(JMP, $2);}
46
+    | tJMF tNB tNB
47
+        {asm_add_2(JMF, $2, $3);}
48
+    | tINF tNB tNB tNB
49
+        {asm_add_3(INF, $2, $3, $4);}
50
+    | tSUP tNB tNB tNB
51
+        {asm_add_3(SUP, $2, $3, $4);}
52
+    | tEQU tNB tNB tNB
53
+        {asm_add_3(EQU, $2, $3, $4);}
54
+    | tPRI tNB
55
+        {asm_add_1(PRI, $2);}
56
+    ;
57
+
58
+
59
+%%
60
+
61
+void yyerror(char* str) {
62
+    extern int yylineno;
63
+    fprintf(stderr, "ERROR yyparse : Line %d: %s\n", yylineno, str);
64
+}
65
+
66
+int main(int argc, char *argv[]) {
67
+    asm_init();
68
+    yyparse();
69
+    printf("INFO yyparse : Parsing End\n");
70
+    asm_run();
71
+    return 0;
72
+}
73
+

Loading…
Cancel
Save