#include #include #include 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(jlength-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(ilength){ 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; iname); } //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 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; }