#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;
|
|
}
|