Interpreteur OK + ajout makefile
This commit is contained in:
parent
56ee58bb48
commit
dfdcf2feb4
26 changed files with 579 additions and 6076 deletions
BIN
.DS_Store
vendored
BIN
.DS_Store
vendored
Binary file not shown.
|
@ -5,6 +5,11 @@
|
||||||
<option name="linkedExternalProjectsSettings">
|
<option name="linkedExternalProjectsSettings">
|
||||||
<MakefileProjectSettings>
|
<MakefileProjectSettings>
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="modules">
|
||||||
|
<set>
|
||||||
|
<option value="$PROJECT_DIR$" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
<option name="version" value="2" />
|
<option name="version" value="2" />
|
||||||
</MakefileProjectSettings>
|
</MakefileProjectSettings>
|
||||||
</option>
|
</option>
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<module classpath="External" type="CPP_MODULE" version="4" />
|
<module classpath="External" external.linked.project.id="projet_systeme" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="Makefile" type="CPP_MODULE" version="4" />
|
12
Makefile
12
Makefile
|
@ -0,0 +1,12 @@
|
||||||
|
all : compiler
|
||||||
|
|
||||||
|
compiler: analyse_lexicale.lex analyse_syntaxique.y table_symboles.c table_fonctions.c
|
||||||
|
bison -d -t analyse_syntaxique.y -v
|
||||||
|
flex analyse_lexicale.lex
|
||||||
|
gcc -w *.c -ly -o compiler
|
||||||
|
|
||||||
|
run: compiler
|
||||||
|
./compiler < test_file
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f lex.yy.c compiler analyse_syntaxique.output analyse_syntaxique.tab.c analyse_syntaxique.tab.h
|
BIN
a.out
BIN
a.out
Binary file not shown.
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,107 +0,0 @@
|
||||||
/* A Bison parser, made by GNU Bison 3.0.4. */
|
|
||||||
|
|
||||||
/* Bison interface for Yacc-like parsers in C
|
|
||||||
|
|
||||||
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* As a special exception, you may create a larger work that contains
|
|
||||||
part or all of the Bison parser skeleton and distribute that work
|
|
||||||
under terms of your choice, so long as that work isn't itself a
|
|
||||||
parser generator using the skeleton or a modified version thereof
|
|
||||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
|
||||||
the parser skeleton itself, you may (at your option) remove this
|
|
||||||
special exception, which will cause the skeleton and the resulting
|
|
||||||
Bison output files to be licensed under the GNU General Public
|
|
||||||
License without this special exception.
|
|
||||||
|
|
||||||
This special exception was added by the Free Software Foundation in
|
|
||||||
version 2.2 of Bison. */
|
|
||||||
|
|
||||||
#ifndef YY_YY_ANALYSE_SYNTAXIQUE_TAB_H_INCLUDED
|
|
||||||
# define YY_YY_ANALYSE_SYNTAXIQUE_TAB_H_INCLUDED
|
|
||||||
/* Debug traces. */
|
|
||||||
#ifndef YYDEBUG
|
|
||||||
# define YYDEBUG 1
|
|
||||||
#endif
|
|
||||||
#if YYDEBUG
|
|
||||||
extern int yydebug;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Token type. */
|
|
||||||
#ifndef YYTOKENTYPE
|
|
||||||
# define YYTOKENTYPE
|
|
||||||
enum yytokentype
|
|
||||||
{
|
|
||||||
tENTIER = 258,
|
|
||||||
tENTIEREXP = 259,
|
|
||||||
tADD = 260,
|
|
||||||
tSUB = 261,
|
|
||||||
tMUL = 262,
|
|
||||||
tDIV = 263,
|
|
||||||
tPO = 264,
|
|
||||||
tPF = 265,
|
|
||||||
tAO = 266,
|
|
||||||
tAF = 267,
|
|
||||||
tERROR = 268,
|
|
||||||
tAPPERSAND = 269,
|
|
||||||
tPV = 270,
|
|
||||||
tVIRGULE = 271,
|
|
||||||
tAFFECTATION = 272,
|
|
||||||
tEGAL = 273,
|
|
||||||
tDIFF = 274,
|
|
||||||
tLT = 275,
|
|
||||||
tGT = 276,
|
|
||||||
tGTE = 277,
|
|
||||||
tLTE = 278,
|
|
||||||
tMAIN = 279,
|
|
||||||
tINT = 280,
|
|
||||||
tPRINT = 281,
|
|
||||||
tRETURN = 282,
|
|
||||||
tOR = 283,
|
|
||||||
tAND = 284,
|
|
||||||
tIF = 285,
|
|
||||||
tELSE = 286,
|
|
||||||
tWHILE = 287,
|
|
||||||
tCONST = 288,
|
|
||||||
tVAR = 289,
|
|
||||||
tNOT = 290
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Value type. */
|
|
||||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
|
||||||
|
|
||||||
union YYSTYPE
|
|
||||||
{
|
|
||||||
#line 1 "analyse_syntaxique.y" /* yacc.c:1909 */
|
|
||||||
|
|
||||||
int nombre;
|
|
||||||
char id[30];
|
|
||||||
|
|
||||||
#line 95 "analyse_syntaxique.tab.h" /* yacc.c:1909 */
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef union YYSTYPE YYSTYPE;
|
|
||||||
# define YYSTYPE_IS_TRIVIAL 1
|
|
||||||
# define YYSTYPE_IS_DECLARED 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
extern YYSTYPE yylval;
|
|
||||||
|
|
||||||
int yyparse (void);
|
|
||||||
|
|
||||||
#endif /* !YY_YY_ANALYSE_SYNTAXIQUE_TAB_H_INCLUDED */
|
|
|
@ -80,14 +80,14 @@ Fonctions : Fonction Fonctions ;
|
||||||
|
|
||||||
Fonction : tINT tVAR tPO Params tPF Body;*/
|
Fonction : tINT tVAR tPO Params tPF Body;*/
|
||||||
|
|
||||||
C : Fonctions;
|
C : {generate_instruction_1(&array, JMP, -1);} Fonctions;
|
||||||
|
|
||||||
Fonctions: Main;
|
Fonctions: Main;
|
||||||
Fonctions: Fonction Fonctions;
|
Fonctions: Fonction Fonctions;
|
||||||
|
|
||||||
|
|
||||||
Main : tINT tMAIN {add_function(&table_fonctions, "Main", RET_INT, array.index); table.depth++;} tPO Params tPF Body {print_table(&table);remove_symboles(&table); table.depth--;};
|
Main : tINT tMAIN {update_jmp(&array, 0, array.index); add_function(&table_fonctions, "Main", RET_INT, array.index); table.depth++;} tPO Params tPF Body {print_table(&table);remove_symboles(&table); table.depth--;};
|
||||||
Fonction : Function_type tVAR {{add_function(&table_fonctions, $2, return_type, array.index); table.depth++;}} tPO Params tPF Body {generate_instruction_0(&array, RET_FUN); print_table(&table);remove_symboles(&table); table.depth--;};
|
Fonction : Function_type tVAR {{add_function(&table_fonctions, $2, return_type, array.index); table.depth++;}} tPO Params tPF Body {print_table(&table);remove_symboles(&table); table.depth--;};
|
||||||
|
|
||||||
Function_type: tINT {type = TYPE_INT;} ;
|
Function_type: tINT {type = TYPE_INT;} ;
|
||||||
Function_type: tINT tMUL {type = TYPE_INT_PTR;};
|
Function_type: tINT tMUL {type = TYPE_INT_PTR;};
|
||||||
|
@ -129,8 +129,8 @@ Valeur : tVAR {add_symbole_top(&table, $1, type, INITIALISED, table.depth);} tAF
|
||||||
Valeur : tVAR {add_symbole_top(&table, $1, type, NOT_INITIALISED, table.depth);};
|
Valeur : tVAR {add_symbole_top(&table, $1, type, NOT_INITIALISED, table.depth);};
|
||||||
|
|
||||||
|
|
||||||
Aff : tVAR tAFFECTATION E tPV {int varAddr = variable_exists(&table, $1); generate_instruction_2(&array, COP, varAddr, $3); free_temp(&table);};
|
Aff : tVAR tAFFECTATION E tPV {int varAddr = variable_exists(&table, $1); generate_instruction_2(&array, COP, varAddr, $3); free_temp(&table); };
|
||||||
Aff : tMUL tVAR tAFFECTATION E tPV {int varAddr = variable_exists(&table, $2); generate_instruction_2(&array, COP_STR, varAddr, $4); free_temp(&table);};
|
Aff : tMUL tVAR tAFFECTATION E tPV {int varAddr = variable_exists(&table, $2); generate_instruction_2(&array, COP_STR, varAddr, $4); free_temp(&table); };
|
||||||
|
|
||||||
|
|
||||||
E : tENTIER {int vt = new_temp(&table); generate_instruction_2(&array, AFC, vt, $1); $$ = vt;};
|
E : tENTIER {int vt = new_temp(&table); generate_instruction_2(&array, AFC, vt, $1); $$ = vt;};
|
||||||
|
@ -141,11 +141,11 @@ E : E tSUB E {generate_instruction_3(&array, SOU, $1, $1, $3); free_temp(&table)
|
||||||
E : E tDIV E {generate_instruction_3(&array, DIV, $1, $1, $3); free_temp(&table); $$ = $1;} ;
|
E : E tDIV E {generate_instruction_3(&array, DIV, $1, $1, $3); free_temp(&table); $$ = $1;} ;
|
||||||
E : tSUB E {printf("Variable negative\n");} ;
|
E : tSUB E {printf("Variable negative\n");} ;
|
||||||
E : Invocation {
|
E : Invocation {
|
||||||
int vt = new_temp(&table);
|
//int vt = new_temp(&table);
|
||||||
generate_instruction_2(&array, COP, vt, $1);
|
//generate_instruction_2(&array, COP, vt, $1);
|
||||||
remove_symboles(&table);
|
remove_symboles(&table);
|
||||||
table.depth--;
|
table.depth--;
|
||||||
$$ = vt;};
|
$$ = $1;};
|
||||||
E : tPO E tPF {printf("Parenthèse\n"); $$ = $2; } ;
|
E : tPO E tPF {printf("Parenthèse\n"); $$ = $2; } ;
|
||||||
E : tAPPERSAND tVAR {int vt = new_temp(&table); int varAddr = variable_exists(&table, $2); generate_instruction_2(&array, LEA, vt, varAddr); $$ = vt;};
|
E : tAPPERSAND tVAR {int vt = new_temp(&table); int varAddr = variable_exists(&table, $2); generate_instruction_2(&array, LEA, vt, varAddr); $$ = vt;};
|
||||||
E : tMUL tVAR {int vt = new_temp(&table); int varAddr = variable_exists(&table, $2); generate_instruction_2(&array, COP, vt, varAddr); generate_instruction_2(&array, COP_LD, vt, vt); $$ = vt;};
|
E : tMUL tVAR {int vt = new_temp(&table); int varAddr = variable_exists(&table, $2); generate_instruction_2(&array, COP, vt, varAddr); generate_instruction_2(&array, COP_LD, vt, vt); $$ = vt;};
|
||||||
|
@ -194,10 +194,10 @@ Cond : E tOR E {generate_instruction_3(&array, OR, $1, $1, $3); free_temp(&table
|
||||||
Cond : tNOT Cond {generate_instruction_2(&array, NOT, $2, $2); $$ = $2;} ;
|
Cond : tNOT Cond {generate_instruction_2(&array, NOT, $2, $2); $$ = $2;} ;
|
||||||
Cond : E {$$ = $1; };
|
Cond : E {$$ = $1; };
|
||||||
|
|
||||||
Invocation : tVAR tPO {table.depth++; prepare_function_call(&table); return_value = (table.indexAvailableTop - 1);} Args tPF
|
Invocation : tVAR tPO {table.depth++; prepare_function_call(&table); return_value = (table.indexAvailableBottom);} Args tPF
|
||||||
{int function_index = function_exists(&table_fonctions, $1);
|
{int function_index = function_exists(&table_fonctions, $1);
|
||||||
int jmp_addr = (table_fonctions.array[function_index]).start_addr;
|
int jmp_addr = (table_fonctions.array[function_index]).start_addr;
|
||||||
generate_instruction_2(&array, CALL, jmp_addr, (array.index + 1));
|
generate_instruction_2(&array, CALL, jmp_addr, table.indexAvailableTop);
|
||||||
$$ = return_value;
|
$$ = return_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -173,13 +173,13 @@ void exportInstructions(instructions_array * array){
|
||||||
switch (op) {
|
switch (op) {
|
||||||
//0 parameters
|
//0 parameters
|
||||||
case RET_FUN:
|
case RET_FUN:
|
||||||
fprintf(file, "%d\t %s\n", i, operationName(op));
|
fprintf(file, "%s\n", operationName(op));
|
||||||
break;
|
break;
|
||||||
//1 parameter
|
//1 parameter
|
||||||
case JMP:
|
case JMP:
|
||||||
case PRI:
|
case PRI:
|
||||||
case RET:
|
case RET:
|
||||||
fprintf(file, "%d\t %s %d\n", i, operationName(op), instru.reg1);
|
fprintf(file, "%s %d\n", operationName(op), instru.reg1);
|
||||||
break;
|
break;
|
||||||
//2 parameters
|
//2 parameters
|
||||||
case JMF:
|
case JMF:
|
||||||
|
@ -188,13 +188,13 @@ void exportInstructions(instructions_array * array){
|
||||||
case COP:
|
case COP:
|
||||||
case LEA:
|
case LEA:
|
||||||
case CALL:
|
case CALL:
|
||||||
fprintf(file, "%d\t %s %d %d\n", i, operationName(op), instru.reg1, instru.reg2);
|
fprintf(file, "%s %d %d\n", operationName(op), instru.reg1, instru.reg2);
|
||||||
break;
|
break;
|
||||||
case COP_LD:
|
case COP_LD:
|
||||||
fprintf(file, "%d\t %s %d [%d]\n", i, operationName(op), instru.reg1, instru.reg2);
|
fprintf(file, "%s %d [%d]\n", operationName(op), instru.reg1, instru.reg2);
|
||||||
break;
|
break;
|
||||||
case COP_STR:
|
case COP_STR:
|
||||||
fprintf(file, "%d\t %s [%d] %d\n", i, operationName(op), instru.reg1, instru.reg2);
|
fprintf(file, "%s [%d] %d\n", operationName(op), instru.reg1, instru.reg2);
|
||||||
break;
|
break;
|
||||||
//3 parameters
|
//3 parameters
|
||||||
case ADD:
|
case ADD:
|
||||||
|
@ -209,7 +209,7 @@ void exportInstructions(instructions_array * array){
|
||||||
case LTE:
|
case LTE:
|
||||||
case GT:
|
case GT:
|
||||||
case GTE:
|
case GTE:
|
||||||
fprintf(file, "%d\t %s %d %d %d\n", i, operationName(op), instru.reg1, instru.reg2, instru.reg3);
|
fprintf(file, "%s %d %d %d\n", operationName(op), instru.reg1, instru.reg2, instru.reg3);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
70
instructions.md
Normal file
70
instructions.md
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
## Instructions generated by our compiler
|
||||||
|
|
||||||
|
# ADD @A @B @C
|
||||||
|
> Adds the values stored in B and C and stores the result in A
|
||||||
|
|
||||||
|
# SOU @A @B @C
|
||||||
|
> Substracts the values stored in B and C and stores the result in A
|
||||||
|
|
||||||
|
# MUL @A @B @C
|
||||||
|
> Multiplies the values stored in B and C and stores the result in A
|
||||||
|
|
||||||
|
# DIV @A @B @C
|
||||||
|
> Divides the values stored in B and C and stores the result in A
|
||||||
|
|
||||||
|
# COP @A @B
|
||||||
|
> Copies at address A the contents from at address B
|
||||||
|
|
||||||
|
# AFC @A #B
|
||||||
|
> Copies at address A the value B
|
||||||
|
|
||||||
|
# JMF @A #B
|
||||||
|
> If the value located at address A is equal to 0 jumps to instruction number B
|
||||||
|
|
||||||
|
# JMP #A
|
||||||
|
> Jumps to instruction number A
|
||||||
|
|
||||||
|
# EQ @A @B @C
|
||||||
|
> If values located at adresses B and C are equal, writes 1 at address A else writes 0
|
||||||
|
|
||||||
|
# NEQ @A @B @C
|
||||||
|
> If values located at addresses B and C are not equal, writes 1 at address A else writes 0
|
||||||
|
|
||||||
|
# LT @A @B @C
|
||||||
|
> If value located at address B is less than the one located at address C, writes 1 at address A else writes 0
|
||||||
|
|
||||||
|
# GT @A @B @C
|
||||||
|
> If value located at address B is greater than the one located at address C, writes 1 at address A else writes 0
|
||||||
|
|
||||||
|
#LTE @A @B @C
|
||||||
|
> If value located at address B is less than or equal to the one located at address C, writes 1 at address A else writes 0
|
||||||
|
|
||||||
|
# GTE @A @B @C
|
||||||
|
> If value located at address B is greater than or equal to the one located at address C, writes 1 at address A else writes 0
|
||||||
|
|
||||||
|
# AND @A @B @C
|
||||||
|
> If the values located at addresses B and C are both greater or equal to 1 writes 1 at address A, else writes 0
|
||||||
|
|
||||||
|
# OR @A @B @C
|
||||||
|
> If the values located at addresses B and C are both equal to 0 writes 0 at address A, else writes 1
|
||||||
|
|
||||||
|
# NOT @A @B
|
||||||
|
> If the value at address B is greater or equal to 1, writes 0 at address A else writes 1
|
||||||
|
|
||||||
|
# PRI @A
|
||||||
|
> Prints the content located at address A
|
||||||
|
|
||||||
|
# LEA @A @B
|
||||||
|
> Copies the value of the address B at A
|
||||||
|
|
||||||
|
# COP_LD @A @B
|
||||||
|
> Copies the value pointed by B at address A
|
||||||
|
|
||||||
|
# COP_STR @A @B
|
||||||
|
> Copies the value of B at the address pointed by A
|
||||||
|
|
||||||
|
# RET @A
|
||||||
|
> Stores the return value at A, changes the values of EBP and ESP
|
||||||
|
|
||||||
|
# CALL #A #B
|
||||||
|
> Saves the values of EBP and the return address, upadtes EBP to EBP + B and jumps to instruction number A
|
|
@ -1,16 +1,26 @@
|
||||||
0 AFC 49 4
|
JMP 8
|
||||||
1 COP 1 49
|
COP 255 0
|
||||||
2 AFC 49 1
|
COP_LD 255 [255]
|
||||||
3 RET 49
|
COP 1 255
|
||||||
4 RET_FUN
|
COP 255 1
|
||||||
5 AFC 49 2
|
PRI 255
|
||||||
6 COP 0 49
|
AFC 255 1
|
||||||
7 LEA 49 0
|
RET 255
|
||||||
8 COP 1 49
|
AFC 255 21
|
||||||
9 AFC 49 2
|
COP 0 255
|
||||||
10 COP_STR [1] 49
|
LEA 255 0
|
||||||
11 COP 49 1
|
COP 1 255
|
||||||
12 COP_LD 49 [49]
|
COP 255 1
|
||||||
13 COP 2 49
|
COP 5 255
|
||||||
14 AFC 49 0
|
CALL 1 6
|
||||||
15 RET 49
|
COP 2 255
|
||||||
|
COP 255 2
|
||||||
|
PRI 255
|
||||||
|
LEA 255 2
|
||||||
|
COP 1 255
|
||||||
|
AFC 255 2
|
||||||
|
COP_STR [1] 255
|
||||||
|
COP 255 2
|
||||||
|
PRI 255
|
||||||
|
AFC 255 0
|
||||||
|
RET 255
|
||||||
|
|
BIN
interpreter/.DS_Store
vendored
Normal file
BIN
interpreter/.DS_Store
vendored
Normal file
Binary file not shown.
26
interpreter/input.txt
Normal file
26
interpreter/input.txt
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
JMP 8
|
||||||
|
COP 49 0
|
||||||
|
COP_LD 49 [49]
|
||||||
|
COP 1 49
|
||||||
|
COP 49 1
|
||||||
|
PRI 49
|
||||||
|
AFC 49 1
|
||||||
|
RET 49
|
||||||
|
AFC 49 21
|
||||||
|
COP 0 49
|
||||||
|
LEA 49 0
|
||||||
|
COP 1 49
|
||||||
|
COP 49 1
|
||||||
|
COP 5 49
|
||||||
|
CALL 1 6
|
||||||
|
COP 2 49
|
||||||
|
COP 49 2
|
||||||
|
PRI 49
|
||||||
|
LEA 49 2
|
||||||
|
COP 1 49
|
||||||
|
AFC 49 2
|
||||||
|
COP_STR [1] 49
|
||||||
|
COP 49 2
|
||||||
|
PRI 49
|
||||||
|
AFC 49 0
|
||||||
|
RET 49
|
BIN
interpreter/interpreter
Executable file
BIN
interpreter/interpreter
Executable file
Binary file not shown.
14
interpreter/makefile
Executable file
14
interpreter/makefile
Executable file
|
@ -0,0 +1,14 @@
|
||||||
|
SRCC:= ./src/*.c
|
||||||
|
|
||||||
|
all: interpreter
|
||||||
|
|
||||||
|
interpreter: ./src/interpreter.y ./src/interpreter.l ./src/instructions.c
|
||||||
|
yacc -d ./src/interpreter.y
|
||||||
|
lex ./src/interpreter.l
|
||||||
|
gcc lex.yy.c y.tab.c ./src/instructions.c -Isrc -o interpreter
|
||||||
|
|
||||||
|
run: interpreter
|
||||||
|
./interpreter < input.txt
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f lex.yy.c interpreter y.tab.h y.tab.c *.o
|
196
interpreter/src/instructions.c
Executable file
196
interpreter/src/instructions.c
Executable file
|
@ -0,0 +1,196 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "instructions.h"
|
||||||
|
|
||||||
|
int EBP = 0;
|
||||||
|
|
||||||
|
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 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 + EBP]);
|
||||||
|
memory[arg1 + EBP] = 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 + EBP], arg2);
|
||||||
|
if (memory[arg1 + EBP] == 0) next_ip = arg2;
|
||||||
|
break;
|
||||||
|
case LT:
|
||||||
|
printf("LT @%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 GT:
|
||||||
|
printf("GT @%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 LTE:
|
||||||
|
printf("LTE @%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 GTE:
|
||||||
|
printf("GTE @%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 EQ:
|
||||||
|
printf("EQ @%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 NEQ:
|
||||||
|
printf("NEQ @%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 AND:
|
||||||
|
printf("AND @%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 OR:
|
||||||
|
printf("OR @%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 NOT:
|
||||||
|
printf("OR @%d = ! @%d[%d] ? 1 : 0\n", arg1, arg2, memory[arg2]);
|
||||||
|
memory[arg1] = ! memory[arg2] ? 1 : 0;
|
||||||
|
break;
|
||||||
|
case LEA:
|
||||||
|
printf("LEA @%d = %d\n", arg1, arg2 + EBP);
|
||||||
|
memory[arg1 + EBP] = arg2 + EBP;
|
||||||
|
break;
|
||||||
|
case COP_LD:
|
||||||
|
printf("COP_LD @%d = @%d[%d]\n", arg1, arg2, memory[arg2]);
|
||||||
|
memory[arg1] = memory[memory[arg2]];
|
||||||
|
break;
|
||||||
|
case COP_STR:
|
||||||
|
printf("COP_STR @%d = @%d[%d]\n", arg1, arg2, memory[arg2]);
|
||||||
|
memory[memory[arg1]] = memory[arg2];
|
||||||
|
break;
|
||||||
|
case RET:
|
||||||
|
printf("RET @%d[%d] \n", arg1, memory[arg1 + EBP]);
|
||||||
|
if (EBP != 0){
|
||||||
|
next_ip = memory[EBP - 2];
|
||||||
|
EBP = memory[EBP - 1];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CALL:
|
||||||
|
memory[EBP + arg2 - 1] = EBP;
|
||||||
|
memory[EBP + arg2 - 2] = next_ip;
|
||||||
|
next_ip = arg1;
|
||||||
|
EBP += arg2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "ERROR run : unknown inst.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return next_ip;
|
||||||
|
}
|
38
interpreter/src/instructions.h
Normal file
38
interpreter/src/instructions.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#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 LT 9
|
||||||
|
#define GT 10
|
||||||
|
#define EQ 11
|
||||||
|
#define PRI 12
|
||||||
|
#define LTE 13
|
||||||
|
#define GTE 14
|
||||||
|
#define NEQ 15
|
||||||
|
#define AND 16
|
||||||
|
#define OR 17
|
||||||
|
#define NOT 18
|
||||||
|
#define LEA 19
|
||||||
|
#define COP_LD 20
|
||||||
|
#define COP_STR 21
|
||||||
|
#define CALL 22
|
||||||
|
#define RET 23
|
||||||
|
|
||||||
|
|
||||||
|
#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__
|
53
interpreter/src/interpreter.l
Executable file
53
interpreter/src/interpreter.l
Executable file
|
@ -0,0 +1,53 @@
|
||||||
|
%{
|
||||||
|
#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;}
|
||||||
|
LT {return tLT;}
|
||||||
|
LTE {return tLTE;}
|
||||||
|
GT {return tGT;}
|
||||||
|
GTE {return tGTE;}
|
||||||
|
EQ {return tEQ;}
|
||||||
|
NEQ {return tNEQ;}
|
||||||
|
PRI {return tPRI;}
|
||||||
|
AND {return tAND;}
|
||||||
|
OR {return tOR;}
|
||||||
|
NOT {return tNOT;}
|
||||||
|
RET {return tRET;}
|
||||||
|
LEA {return tLEA;}
|
||||||
|
COP_LD {return tCOP_LD;}
|
||||||
|
COP_STR {return tCOP_STR;}
|
||||||
|
CALL {return tCALL;}
|
||||||
|
|
||||||
|
"[" {return tOB;}
|
||||||
|
"]" {return tCB;}
|
||||||
|
|
||||||
|
|
||||||
|
-?[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; }
|
97
interpreter/src/interpreter.y
Executable file
97
interpreter/src/interpreter.y
Executable file
|
@ -0,0 +1,97 @@
|
||||||
|
%{
|
||||||
|
#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 tPRI tRET tCALL
|
||||||
|
%token tLT tLTE tGT tGTE tEQ tNEQ tAND tOR tNOT
|
||||||
|
%token tLEA tCOP_LD tCOP_STR
|
||||||
|
%token tOB tCB
|
||||||
|
%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);}
|
||||||
|
| tLT tNB tNB tNB
|
||||||
|
{asm_add_3(LT, $2, $3, $4);}
|
||||||
|
| tGT tNB tNB tNB
|
||||||
|
{asm_add_3(GT, $2, $3, $4);}
|
||||||
|
| tLTE tNB tNB tNB
|
||||||
|
{asm_add_3(LTE, $2, $3, $4);}
|
||||||
|
| tGTE tNB tNB tNB
|
||||||
|
{asm_add_3(GTE, $2, $3, $4);}
|
||||||
|
| tAND tNB tNB tNB
|
||||||
|
{asm_add_3(AND, $2, $3, $4);}
|
||||||
|
| tOR tNB tNB tNB
|
||||||
|
{asm_add_3(OR, $2, $3, $4);}
|
||||||
|
| tEQ tNB tNB tNB
|
||||||
|
{asm_add_3(EQ, $2, $3, $4);}
|
||||||
|
| tNEQ tNB tNB tNB
|
||||||
|
{asm_add_3(NEQ, $2, $3, $4);}
|
||||||
|
| tNOT tNB tNB
|
||||||
|
{asm_add_2(NOT, $2, $3);}
|
||||||
|
| tPRI tNB
|
||||||
|
{asm_add_1(PRI, $2);}
|
||||||
|
| tLEA tNB tNB
|
||||||
|
{asm_add_2(LEA, $2, $3);}
|
||||||
|
| tCOP_LD tNB tOB tNB tCB
|
||||||
|
{asm_add_2(COP_LD, $2, $4);}
|
||||||
|
| tCOP_STR tOB tNB tCB tNB
|
||||||
|
{asm_add_2(COP_STR, $3, $5);}
|
||||||
|
| tRET tNB
|
||||||
|
{asm_add_1(RET, $2);}
|
||||||
|
| tCALL tNB tNB
|
||||||
|
{asm_add_2(CALL, $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;
|
||||||
|
}
|
||||||
|
|
13
script.sh
13
script.sh
|
@ -2,17 +2,20 @@ bison -d -t analyse_syntaxique.y -v
|
||||||
flex analyse_lexicale.lex
|
flex analyse_lexicale.lex
|
||||||
gcc -w *.c -ly
|
gcc -w *.c -ly
|
||||||
echo "
|
echo "
|
||||||
int fonction1(int a){
|
int fonction1(int * a){
|
||||||
int b = 4;
|
int b = *a;
|
||||||
|
printf(b);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
int c = 2;
|
int l = 21;
|
||||||
int * p;
|
int * p = &l;
|
||||||
|
int c = fonction1(p);
|
||||||
|
printf(c);
|
||||||
p = &c;
|
p = &c;
|
||||||
*p = 2;
|
*p = 2;
|
||||||
int b = *p;
|
printf(c);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,6 @@ void free_temp(Table_Symboles * table){
|
||||||
int prepare_function_call(Table_Symboles * table){
|
int prepare_function_call(Table_Symboles * table){
|
||||||
prepare_argument_push(table);
|
prepare_argument_push(table);
|
||||||
prepare_argument_push(table);
|
prepare_argument_push(table);
|
||||||
prepare_argument_push(table);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int prepare_argument_push(Table_Symboles * table){
|
int prepare_argument_push(Table_Symboles * table){
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef TABLE_SYMBOLES_H
|
#ifndef TABLE_SYMBOLES_H
|
||||||
#define TABLE_SYMBOLES_H
|
#define TABLE_SYMBOLES_H
|
||||||
|
|
||||||
#define TABLE_SIZE 50
|
#define TABLE_SIZE 256
|
||||||
#define VARIABLE_SIZE 30
|
#define VARIABLE_SIZE 30
|
||||||
|
|
||||||
enum Symbole_Type {TYPE_INT , TYPE_CONST_INT, TYPE_INT_PTR};
|
enum Symbole_Type {TYPE_INT , TYPE_CONST_INT, TYPE_INT_PTR};
|
||||||
|
|
16
test_file
Normal file
16
test_file
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
int fonction1(int * a){
|
||||||
|
int b = *a;
|
||||||
|
printf(b);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
int l = 21;
|
||||||
|
int * p = &l;
|
||||||
|
int c = fonction1(p);
|
||||||
|
printf(c);
|
||||||
|
p = &c;
|
||||||
|
*p = 2;
|
||||||
|
printf(c);
|
||||||
|
|
||||||
|
return 0;
|
BIN
xilinx/.DS_Store
vendored
Normal file
BIN
xilinx/.DS_Store
vendored
Normal file
Binary file not shown.
Loading…
Reference in a new issue