interpreteur de base
This commit is contained in:
parent
83ace6d5af
commit
791facef81
4 changed files with 308 additions and 0 deletions
159
Interpreteur/src/instructions.c
Executable file
159
Interpreteur/src/instructions.c
Executable file
|
@ -0,0 +1,159 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#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;
|
||||||
|
}
|
29
Interpreteur/src/instructions.h
Normal file
29
Interpreteur/src/instructions.h
Normal file
|
@ -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__
|
41
Interpreteur/src/interpreter.l
Executable file
41
Interpreteur/src/interpreter.l
Executable file
|
@ -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; }
|
79
Interpreteur/src/interpreter.y
Executable file
79
Interpreteur/src/interpreter.y
Executable file
|
@ -0,0 +1,79 @@
|
||||||
|
%{
|
||||||
|
#include <stdio.h>
|
||||||
|
#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 <nb> 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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue