|
|
@ -0,0 +1,462 @@ |
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
typedef struct Node Node; |
|
|
|
typedef struct Array Array; |
|
|
|
typedef struct Symbol Symbol; |
|
|
|
typedef struct SymbolTable SymbolTable; |
|
|
|
|
|
|
|
struct Array { |
|
|
|
Node **elements; |
|
|
|
int length; |
|
|
|
}; |
|
|
|
|
|
|
|
struct Symbol { |
|
|
|
char *name; |
|
|
|
int value; |
|
|
|
}; |
|
|
|
|
|
|
|
struct SymbolTable { |
|
|
|
Symbol **elements; |
|
|
|
int length; |
|
|
|
}; |
|
|
|
|
|
|
|
#define SymbolTable_initialiser {0,0}
|
|
|
|
SymbolTable symbolTable= SymbolTable_initialiser; |
|
|
|
|
|
|
|
Symbol *createSymbol(char *name) { |
|
|
|
Symbol *symbol= calloc(1, sizeof(Symbol)); |
|
|
|
symbol->name= strdup(name); |
|
|
|
return symbol; |
|
|
|
} |
|
|
|
|
|
|
|
Symbol *intern(char *name){ |
|
|
|
int left=0,right=symbolTable.length-1; |
|
|
|
|
|
|
|
while(left<=right){ |
|
|
|
int middle=(left+right)/2; |
|
|
|
int comp=strcmp(name,symbolTable.elements[middle]->name); |
|
|
|
|
|
|
|
if(comp<0){ |
|
|
|
right=middle-1; |
|
|
|
} |
|
|
|
else if(comp>0){ |
|
|
|
left=middle+1; |
|
|
|
} |
|
|
|
else{ |
|
|
|
return symbolTable.elements[middle]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
symbolTable.elements= realloc(symbolTable.elements,sizeof(symbolTable.elements[0]) * (symbolTable.length+1)); |
|
|
|
memmove(symbolTable.elements+left+1,symbolTable.elements+left,(symbolTable.length-left)*sizeof(symbolTable.elements[0])); |
|
|
|
symbolTable.length++; |
|
|
|
return symbolTable.elements[left]=createSymbol(name); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
void addSymbol(SymbolTable *symbolTable, Symbol *symbol) { |
|
|
|
|
|
|
|
if(symbolTable->length==0){ |
|
|
|
symbolTable->length++; |
|
|
|
symbolTable->elements= realloc(symbolTable->elements,sizeof(Symbol) * symbolTable->length); |
|
|
|
symbolTable->elements[0]=symbol; |
|
|
|
} |
|
|
|
else{ |
|
|
|
printf("taille>0\n"); |
|
|
|
|
|
|
|
symbolTable->length++; |
|
|
|
symbolTable->elements= realloc(symbolTable->elements,sizeof(Symbol*) * symbolTable->length); |
|
|
|
int j=0;int k=0;int indice =0; |
|
|
|
while(j<symbolTable->length-1 && k==0){ |
|
|
|
|
|
|
|
if(strcmp(symbol->name,symbolTable->elements[j]->name)<=0){ |
|
|
|
|
|
|
|
printf("plus petit que le reste\n"); |
|
|
|
k=k+1; |
|
|
|
} |
|
|
|
else{ |
|
|
|
printf("plus grand\n"); |
|
|
|
j=j+1;indice=j; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
for(k=symbolTable->length-1;k>indice;k--){ |
|
|
|
symbolTable->elements[k]=symbolTable->elements[k-1]; |
|
|
|
} |
|
|
|
symbolTable->elements[indice]=symbol; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
*/ |
|
|
|
int binary_search(SymbolTable *st, char *c){ |
|
|
|
int start=0,end=st->length-1; |
|
|
|
int m=0; |
|
|
|
while(end-start>1){ |
|
|
|
|
|
|
|
m=(end+start)/2; //printf("char : %s\n %s",c,st->elements[m]->name);
|
|
|
|
// printf("start : %i End : %i\n Compare : %i\n",start,end,strcmp(c,st->elements[m]->name));/**/
|
|
|
|
if(strcmp(c,st->elements[m]->name)==0){ |
|
|
|
return m; |
|
|
|
} |
|
|
|
else if(strcmp(c,st->elements[m]->name)<0){ |
|
|
|
end=m-1; |
|
|
|
} |
|
|
|
else{ |
|
|
|
start=m+1; |
|
|
|
} |
|
|
|
m=(end+start)/2; |
|
|
|
} |
|
|
|
// printf("Start : %i, m : %i, end : %i char : %s size :%i\n",start,m,end,c,st->length);
|
|
|
|
if(strcmp(c,st->elements[m]->name)<0){ |
|
|
|
return start; |
|
|
|
} |
|
|
|
else{ |
|
|
|
return end; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void addSymbol(SymbolTable *symbolTable, Symbol *symbol) { |
|
|
|
|
|
|
|
if(symbolTable->length==0){ |
|
|
|
|
|
|
|
symbolTable->length++; |
|
|
|
symbolTable->elements= realloc(symbolTable->elements,sizeof(Symbol) * symbolTable->length); |
|
|
|
symbolTable->elements[0]=symbol;//printf("indice de %s = %i\n",symbolTable->elements[0]->name,0);
|
|
|
|
return; |
|
|
|
} |
|
|
|
else{ |
|
|
|
|
|
|
|
|
|
|
|
symbolTable->length++; |
|
|
|
symbolTable->elements= realloc(symbolTable->elements,sizeof(Symbol*) * symbolTable->length); |
|
|
|
int indice=binary_search(symbolTable, symbol->name); |
|
|
|
|
|
|
|
for(int k=symbolTable->length-1;k>indice;k--){ |
|
|
|
symbolTable->elements[k]=symbolTable->elements[k-1]; |
|
|
|
} |
|
|
|
symbolTable->elements[indice]=symbol;//printf("indice de %s = %i\n",symbolTable->elements[indice]->name,indice);
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void arrayAppend(Array *array, Node *statement) { |
|
|
|
array->length++; |
|
|
|
array->elements= realloc(array->elements,sizeof(Node*) * array->length); |
|
|
|
array->elements[array->length-1] = statement; |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
|
void fusion(SymbolTable symbTable,int n, int d, int f){ |
|
|
|
char *r[f-d+1]; |
|
|
|
int m =(d+f)/2; |
|
|
|
int i1=d,i2=m,k=0; |
|
|
|
while(i1<=m && i2<=f){ |
|
|
|
if(strcmp(symbTable.elements[i1]->name,symbTable.elements[i2]->name)<0){ |
|
|
|
r[k]=symbTable.elements[i1]->name; |
|
|
|
i1++; |
|
|
|
|
|
|
|
} |
|
|
|
else{ |
|
|
|
r[k]=symbTable.elements[i2]->name; |
|
|
|
i2++; |
|
|
|
} |
|
|
|
k=k+1; |
|
|
|
} |
|
|
|
while(i1<=m){ |
|
|
|
r[k]=symbTable.elements[i1]->name; |
|
|
|
i1++; |
|
|
|
k++; |
|
|
|
} |
|
|
|
while(i2<=f){ |
|
|
|
r[k]=symbTable.elements[i2]->name; |
|
|
|
i2++; |
|
|
|
k++; |
|
|
|
} |
|
|
|
for(k=0;k<=f-d;k++){ |
|
|
|
symbTable.elements[d+k]->name=r[k]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void fusion(SymbolTable symbTable,int n, int d, int f){ |
|
|
|
char *r[f-d+1]; |
|
|
|
int m =(d+f)/2; |
|
|
|
int i1=d,i2=m,k=0; |
|
|
|
while(i1<=m && i2<=f){ |
|
|
|
if(strcmp(symbTable.elements[i1]->name,symbTable.elements[i2]->name)<0){ |
|
|
|
r[k]=symbTable.elements[i1]->name; |
|
|
|
i1++; |
|
|
|
|
|
|
|
} |
|
|
|
else{ |
|
|
|
r[k]=symbTable.elements[i2]->name; |
|
|
|
i2++; |
|
|
|
} |
|
|
|
k=k+1; |
|
|
|
} |
|
|
|
while(i1<=m){ |
|
|
|
r[k]=symbTable.elements[i1]->name; |
|
|
|
i1++; |
|
|
|
k++; |
|
|
|
} |
|
|
|
while(i2<=f){ |
|
|
|
r[k]=symbTable.elements[i2]->name; |
|
|
|
i2++; |
|
|
|
k++; |
|
|
|
} |
|
|
|
for(k=0;k<=f-d;k++){ |
|
|
|
symbTable.elements[d+k]->name=r[k]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void triFusion(SymbolTable symbTable,int n,int d,int f){ |
|
|
|
int m=(d+f)/2; |
|
|
|
triFusion(symbTable,n,d,m); |
|
|
|
triFusion(symbTable,n,m+1,f); |
|
|
|
fusion(symbTable,n,d,f); |
|
|
|
} |
|
|
|
*/ |
|
|
|
|
|
|
|
enum opcode { |
|
|
|
PRINT, |
|
|
|
INT, |
|
|
|
VAR, |
|
|
|
ADD, |
|
|
|
REPEAT, |
|
|
|
ASSIGN, |
|
|
|
BLOC |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
struct Node |
|
|
|
{ |
|
|
|
enum opcode type; |
|
|
|
union { |
|
|
|
Symbol *symbol; |
|
|
|
Array statement; |
|
|
|
Node *children[2]; |
|
|
|
int intValue; |
|
|
|
int index; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
Node *mkNode(enum opcode type) |
|
|
|
{ |
|
|
|
Node *node= calloc(1, sizeof(Node)); |
|
|
|
node->type= type; |
|
|
|
return node; |
|
|
|
} |
|
|
|
|
|
|
|
Node *mkPrint(Node *expr) |
|
|
|
{ |
|
|
|
Node *node= mkNode(PRINT); |
|
|
|
node->children[0]= expr; |
|
|
|
return node; |
|
|
|
} |
|
|
|
|
|
|
|
Node *mkInt(int value) |
|
|
|
{ |
|
|
|
Node *node= mkNode(INT); |
|
|
|
node->intValue= value; |
|
|
|
return node; |
|
|
|
} |
|
|
|
|
|
|
|
Node *mkVar(Symbol *symbol) |
|
|
|
{ |
|
|
|
Node *node= mkNode(VAR); |
|
|
|
node->symbol= symbol; |
|
|
|
return node; |
|
|
|
} |
|
|
|
|
|
|
|
Node *mkAdd(Node *lhs, Node *rhs) |
|
|
|
{ |
|
|
|
Node *node= mkNode(ADD); |
|
|
|
node->children[0]= lhs; |
|
|
|
node->children[1]= rhs; |
|
|
|
return node; |
|
|
|
} |
|
|
|
|
|
|
|
Node *mkRepeat(Node *count, Node *body) |
|
|
|
{ |
|
|
|
Node *node= mkNode(REPEAT); |
|
|
|
node->children[0]= count; |
|
|
|
node->children[1]= body; |
|
|
|
return node; |
|
|
|
} |
|
|
|
|
|
|
|
Node *mkAssign(Symbol *symbol, Node *assignable) |
|
|
|
{ |
|
|
|
Node *node= mkNode(ASSIGN); |
|
|
|
node->symbol= symbol; |
|
|
|
node->children[1]= assignable; |
|
|
|
return node; |
|
|
|
} |
|
|
|
|
|
|
|
Node *mkBloc(void) |
|
|
|
{ |
|
|
|
Node *node= mkNode(BLOC); |
|
|
|
node->statement.length= 0; |
|
|
|
node->statement.elements= 0; |
|
|
|
return node; |
|
|
|
} |
|
|
|
void blocAppend(Node *bloc, Node *statement) { |
|
|
|
arrayAppend(&bloc->statement, statement); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int variables[26]; |
|
|
|
|
|
|
|
int evaluate(Node *node) |
|
|
|
{ |
|
|
|
switch (node->type) { |
|
|
|
case PRINT: { |
|
|
|
int value= evaluate(node->children[0]); |
|
|
|
printf("PRINT %i\n", value); |
|
|
|
return value; |
|
|
|
} |
|
|
|
case INT: { |
|
|
|
return node->intValue; |
|
|
|
} |
|
|
|
case VAR: { |
|
|
|
return node->symbol->value; |
|
|
|
} |
|
|
|
case ADD: { |
|
|
|
int lhs= evaluate(node->children[0]); |
|
|
|
int rhs= evaluate(node->children[1]); |
|
|
|
return lhs + rhs; |
|
|
|
} |
|
|
|
case REPEAT: { |
|
|
|
int count= evaluate(node->children[0]); |
|
|
|
Node *body= node->children[1]; |
|
|
|
int result= 0; |
|
|
|
while (count-- > 0) result= evaluate(body); |
|
|
|
return result; |
|
|
|
} |
|
|
|
case ASSIGN: { |
|
|
|
int assignable= evaluate(node->children[1]); |
|
|
|
node->symbol->value= assignable; |
|
|
|
return assignable; |
|
|
|
} |
|
|
|
case BLOC: { |
|
|
|
int Nb_instruction= node->statement.length; |
|
|
|
int result= 0; |
|
|
|
for(int i=0; i < Nb_instruction; i++) { |
|
|
|
result= evaluate(node->statement.elements[i]); |
|
|
|
} |
|
|
|
return result; |
|
|
|
} |
|
|
|
} |
|
|
|
printf("this cannot happen\n"); |
|
|
|
abort(); |
|
|
|
} |
|
|
|
|
|
|
|
int findS(SymbolTable *st, char *c){ |
|
|
|
int i=0; |
|
|
|
while(i<st->length){ |
|
|
|
if (strcmp(c,st->elements[i]->name)==0){ |
|
|
|
return st->elements[i]->value; |
|
|
|
} |
|
|
|
else{ |
|
|
|
i=i+1; |
|
|
|
} |
|
|
|
} |
|
|
|
addSymbol(st,createSymbol(c)); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char **argv) |
|
|
|
{ |
|
|
|
printf("%p\n",intern("red")); |
|
|
|
printf("%p\n",intern("red")); |
|
|
|
printf("%p\n",intern("red")); |
|
|
|
printf("%p\n",intern("yellow")); |
|
|
|
printf("%p\n",intern("yellow")); |
|
|
|
printf("%p\n",intern("red")); |
|
|
|
printf("%p\n",intern("black")); |
|
|
|
printf("%p\n",intern("white")); |
|
|
|
printf("%p\n",intern("red")); |
|
|
|
printf("%p\n",intern("yellow")); |
|
|
|
printf("%p\n",intern("black")); |
|
|
|
printf("%p\n",intern("white")); |
|
|
|
printf("%p\n",intern("red")); |
|
|
|
printf("%p\n",intern("yellow")); |
|
|
|
printf("%p\n",intern("black")); |
|
|
|
printf("%p\n",intern("white")); |
|
|
|
/* int valeur1=findS(&symbolTable, "black");
|
|
|
|
printf("Valeur de black : %i \n",valeur1);*/ |
|
|
|
|
|
|
|
|
|
|
|
for(int i= 0; i<symbolTable.length; i++) { |
|
|
|
printf("number : %i, value : %s\n",i, symbolTable.elements[i]->name); |
|
|
|
} |
|
|
|
|
|
|
|
//findS(SymbolTable *st, char *c) trouve un symbole dans la table, retourne la valeur, sinon cr�e une nouveau symbole dans la table
|
|
|
|
//d'abord lin�aire
|
|
|
|
//int strcmp(char *a, char *b) 0 if theyr are the same - if a <b + if a>b
|
|
|
|
|
|
|
|
variables[0]= 1; |
|
|
|
variables[1]= 2; |
|
|
|
variables[2]= 40; |
|
|
|
intern("cyan")->value=40; |
|
|
|
|
|
|
|
|
|
|
|
/*Node *program=
|
|
|
|
mkRepeat(mkAdd(mkVar(0), mkVar(1)), |
|
|
|
mkPrint(mkInt(42))); |
|
|
|
|
|
|
|
|
|
|
|
REPEAT A+B { |
|
|
|
PRINT C = C + 1 |
|
|
|
} |
|
|
|
|
|
|
|
Node *program= |
|
|
|
mkRepeat(mkAdd(mkVar(0), mkVar(1)), |
|
|
|
mkPrint(mkAssign(mkInt(2), |
|
|
|
mkAdd(mkVar(2), |
|
|
|
mkInt(1)))));*/ |
|
|
|
|
|
|
|
Node *bloc = mkBloc(); |
|
|
|
blocAppend(bloc, mkPrint(mkAssign(intern("purple"), |
|
|
|
mkAdd(mkVar(intern("purple")), |
|
|
|
mkInt(1))))); |
|
|
|
|
|
|
|
blocAppend(bloc,mkPrint(mkAssign(intern("cyan"), |
|
|
|
mkAdd(mkVar(intern("cyan")), |
|
|
|
mkInt(1))))); |
|
|
|
|
|
|
|
/*Node *instruction[2];
|
|
|
|
instruction[0] = mkPrint(mkAssign(mkInt(2), |
|
|
|
mkAdd(mkVar(2), |
|
|
|
mkInt(1)))); |
|
|
|
|
|
|
|
instruction[1] = mkPrint(mkAssign(mkInt(1), |
|
|
|
mkAdd(mkVar(1), |
|
|
|
mkInt(1))));*/ |
|
|
|
|
|
|
|
Node *program= |
|
|
|
mkRepeat(mkInt(3), |
|
|
|
bloc); |
|
|
|
|
|
|
|
int result= evaluate(program); |
|
|
|
|
|
|
|
printf("finished with result %i\n", result); |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |