diff --git a/vm_tree.c b/vm_tree.c new file mode 100644 index 0000000..0ed03ba --- /dev/null +++ b/vm_tree.c @@ -0,0 +1,462 @@ +#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; +}