diff --git a/Interpreteur/src/instructions.c b/Interpreteur/src/instructions.c new file mode 100755 index 0000000..48b64f0 --- /dev/null +++ b/Interpreteur/src/instructions.c @@ -0,0 +1,159 @@ +#include +#include "instructions.h" + +struct instruction { + char ins; + int arg1; + int arg2; + int arg3; +}; + +struct instruction instructions[MAX_INSTRUCTIONS_SIZE]; +int current_line; +int has_error; + +int memory[MAX_MEMORY_SIZE]; + +int EBP=0; + +int exec(int ip); +int valid_memory_addr(int address); + +/***** Public funciton *****/ + +void asm_init() { + current_line = 0; + has_error = 0; +} + +void asm_add_3(char ins, int arg1, int arg2, int arg3) { + if (current_line >= MAX_INSTRUCTIONS_SIZE) { + fprintf(stderr, "ERROR readfile : Too much instructions, please modify value of MAX_INSTRUCTIONS_SIZE.\n"); + has_error = 1; + return; + } + + // ip are validated at runtime; memory addr are validated here + if (ins == AFC || ins == JMF) { + if (!valid_memory_addr(arg1)) { + fprintf(stderr, "ERROR readfile : INVALID addr at line %d, please verify that addr is in range 0 to MAX_MEMORY_SIZE\n", current_line); + has_error = 1; + return; + } + } else if (ins == JMP) { + // do nothing + } else { + if (!(valid_memory_addr(arg1) && valid_memory_addr(arg2) + && valid_memory_addr(arg3))) { + fprintf(stderr, "ERROR readfile : INVALID addr at line %d, please verify that addr is in range 0 to MAX_MEMORY_SIZE\n", current_line); + has_error = 1; + return; + } + } + + // When OK + instructions[current_line].ins = ins; + instructions[current_line].arg1 = arg1; + instructions[current_line].arg2 = arg2; + instructions[current_line].arg3 = arg3; + current_line++; +} + +void asm_add_2(char ins, int arg1, int arg2) { + asm_add_3(ins, arg1, arg2, 0); +} + +void asm_add_1(char ins, int arg1) { + asm_add_3(ins, arg1, 0, 0); +} + +void asm_run() { + int ip = 0; + if (has_error) { + fprintf(stderr, "ERROR run : abandoned due to previous error.\n"); + return; + } + printf("INFO run : begin\n"); + while (ip >= 0 && ip < current_line) { + // wait for user input + //getchar(); + // execution + ip = exec(ip); + } + printf("INFO run : end\n"); +} + +/***** Private funciton *****/ + +int valid_memory_addr(int addr) { + return addr >= 0 && addr < MAX_MEMORY_SIZE; +} + +int exec(int ip) { + int next_ip = ip + 1; + char ins = instructions[ip].ins; + int arg1 = instructions[ip].arg1; + int arg2 = instructions[ip].arg2; + int arg3 = instructions[ip].arg3; + printf("%d : ", ip); + + // execute inst + switch (ins) { + case ADD: + printf("ADD @%d = @%d[%d] + @%d[%d]\n", arg1, arg2, memory[arg2], arg3, memory[arg3]); + memory[arg1] = memory[arg2] + memory[arg3]; break; + case MUL: + printf("MUL @%d = @%d[%d] * @%d[%d]\n", arg1, arg2, memory[arg2], arg3, memory[arg3]); + memory[arg1] = memory[arg2] * memory[arg3]; break; + case SOU: + printf("SOU @%d = @%d[%d] - @%d[%d]\n", arg1, arg2, memory[arg2], arg3, memory[arg3]); + memory[arg1] = memory[arg2] - memory[arg3]; break; + case DIV: + printf("DIV @%d = @%d[%d] / @%d[%d]\n", arg1, arg2, memory[arg2], arg3, memory[arg3]); + memory[arg1] = memory[arg2] / memory[arg3]; break; + case COP: + printf("COP @%d = @%d[%d]\n", arg1, arg2, memory[arg2]); + memory[arg1] = memory[arg2]; break; + case AFC: + printf("AFC @%d = %d\n", arg1, arg2); + memory[arg1] = arg2; break; + case JMP: + printf("JMP to %d\n", arg1); + next_ip = arg1; break; + case JMF: + printf("JMF cond@%d[%d] to %d\n", arg1, memory[arg1], arg2); + if (memory[arg1] == 0) next_ip = arg2; + break; + case INF: + printf("INF @%d = @%d[%d] < @%d[%d] ? 1 : 0\n", arg1, arg2, memory[arg2], arg3, memory[arg3]); + memory[arg1] = memory[arg2] < memory[arg3] ? 1 : 0; + break; + case SUP: + printf("SUP @%d = @%d[%d] > @%d[%d] ? 1 : 0\n", arg1, arg2, memory[arg2], arg3, memory[arg3]); + memory[arg1] = memory[arg2] > memory[arg3] ? 1 : 0; + break; + case EQU: + printf("EQU @%d = @%d[%d] == @%d[%d] ? 1 : 0\n", arg1, arg2, memory[arg2], arg3, memory[arg3]); + memory[arg1] = memory[arg2] == memory[arg3] ? 1 : 0; + break; + case PRI: + printf("PRI @%d[%d]\n", arg1, memory[arg1]); + break; + case AFCA: + printf("AFCA @%d[%d] = @%d[%d]\n", arg1, memory[arg1], arg2+EBP, memory[arg2]+EBP); + memory[arg1]=memory[arg2]+EBP; + break; + case WR: + printf("WR @%d[%d] = @%d[%d] \n", memory[arg1+EBP], memory[memory[arg1+EBP]], arg2+EBP, memory[arg2+EBP] ); + memory[memory[arg1+EBP]]=memory[arg2+EBP]; + break; + case READ: + printf("READ @%d[%d] = @%d\n", arg1, memory[arg1], memory[memory[arg1+EBP]]); + memory[arg1]=memory[memory[arg1+EBP]]; + break; + default: + fprintf(stderr, "ERROR run : unknown inst.\n"); + } + + return next_ip; +} diff --git a/Interpreteur/src/instructions.h b/Interpreteur/src/instructions.h new file mode 100644 index 0000000..88be5d2 --- /dev/null +++ b/Interpreteur/src/instructions.h @@ -0,0 +1,29 @@ +#ifndef __INSTRUCTIONS_H__ +#define __INSTRUCTIONS_H__ + +#define ADD 1 +#define MUL 2 +#define SOU 3 +#define DIV 4 +#define COP 5 +#define AFC 6 +#define JMP 7 +#define JMF 8 +#define INF 9 +#define SUP 10 +#define EQU 11 +#define PRI 12 +#define AFCA 13 +#define WR 14 +#define READ 15 + +#define MAX_INSTRUCTIONS_SIZE 256 +#define MAX_MEMORY_SIZE 256 + +void asm_init(); +void asm_add_3(char ins, int arg1, int arg2, int arg3); +void asm_add_2(char ins, int arg1, int arg2); +void asm_add_1(char ins, int arg1); +void asm_run(); + +#endif // #ifndef __INSTRUCTIONS_H__ diff --git a/Interpreteur/src/interpreter.l b/Interpreteur/src/interpreter.l new file mode 100755 index 0000000..2829679 --- /dev/null +++ b/Interpreteur/src/interpreter.l @@ -0,0 +1,41 @@ +%{ + #include "y.tab.h" +%} + +vSEP [ \t\r\n] + +%% + +ADD {return tADD;} +MUL {return tMUL;} +SOU {return tSOU;} +DIV {return tDIV;} +COP {return tCOP;} +AFC {return tAFC;} +JMP {return tJMP;} +JMF {return tJMF;} +INF {return tINF;} +SUP {return tSUP;} +EQU {return tEQU;} +PRI {return tPRI;} +AFCA {return tAFCA;} +WR {return tWR;} +READ {return tREAD;} + +-?[0-9]+ { + yylval.nb = atoi(yytext); + return tNB; + } + + +{vSEP} {} + +. { + fprintf(stderr, "ERROR lex : Unknown pattern %s", yytext); + exit(1); + } + +%% + +int yywrap(void) { return 1; } +//int main(int argc, char *argv[]) { while (yylex()!=0) ; return 0; } diff --git a/Interpreteur/src/interpreter.y b/Interpreteur/src/interpreter.y new file mode 100755 index 0000000..7fefe8b --- /dev/null +++ b/Interpreteur/src/interpreter.y @@ -0,0 +1,79 @@ +%{ + #include + #include "instructions.h" + int yylex(); + void yyerror(char*); + int yydebug = 1; + extern int yylineno; +%} + +/* Union for yylval */ +%union { + int nb; +} + +%token tADD tMUL tSOU tDIV tCOP tAFC tJMP tJMF tINF tSUP tEQU tPRI tAFCA tWR tREAD + +%token tNB + +%% + +%start File; + +File: + Instructions; + +Instructions: + /* epsilon */ + | Instructions Instruction + ; + +Instruction: + tADD tNB tNB tNB + {asm_add_3(ADD, $2, $3, $4);} + | tMUL tNB tNB tNB + {asm_add_3(MUL, $2, $3, $4);} + | tSOU tNB tNB tNB + {asm_add_3(SOU, $2, $3, $4);} + | tDIV tNB tNB tNB + {asm_add_3(DIV, $2, $3, $4);} + | tCOP tNB tNB + {asm_add_2(COP, $2, $3);} + | tAFC tNB tNB + {asm_add_2(AFC, $2, $3);} + | tJMP tNB + {asm_add_1(JMP, $2);} + | tJMF tNB tNB + {asm_add_2(JMF, $2, $3);} + | tINF tNB tNB tNB + {asm_add_3(INF, $2, $3, $4);} + | tSUP tNB tNB tNB + {asm_add_3(SUP, $2, $3, $4);} + | tEQU tNB tNB tNB + {asm_add_3(EQU, $2, $3, $4);} + | tPRI tNB + {asm_add_1(PRI, $2);} + | tAFCA tNB tNB + {asm_add_2(AFCA, $2, $3);} + | tWR tNB tNB + {asm_add_2(WR, $2, $3);} + | tREAD tNB tNB + {asm_add_2(READ, $2, $3);} + ; + + +%% + +void yyerror(char* str) { + extern int yylineno; + fprintf(stderr, "ERROR yyparse : Line %d: %s\n", yylineno, str); +} + +int main(int argc, char *argv[]) { + asm_init(); + yyparse(); + printf("INFO yyparse : Parsing End\n"); + asm_run(); + return 0; +} +