/**************************************************************************/ /* Expressions.c: module for basic operations on expressions in memory */ /* */ /* Thorsten Brehm, 4/2001 */ /**************************************************************************/ #include #include #include #include #include "hatfile.h" #include "Expressions.h" #include "hatgeneral.h" #include "hashtable.h" AppNode* newAppNode(int arity) { AppNode* a = (AppNode*) calloc(1,sizeof(AppNode)); a->args = (ExprPtr*) calloc(arity,sizeof(ExprNode)); a->arity = arity; return a; } void freeAppNode(AppNode* a) { if (a==NULL) return; if (a->arity>0) free(a->args); free(a); } void setAppNodeFun(AppNode* a,ExprNode* e) { a->fun = e; } ExprNode* getAppNodeFun(AppNode* a) { return a->fun; } /* arguments numbered 0..arity-1 */ void setAppNodeArg(AppNode* a,int i,ExprNode* e) { /*if (i>=a->arity) { fprintf(stderr,"ERROR: index out of arity range...\n"); exit(1); }*/ a->args[i] = e; } ExprNode* getAppNodeArg(AppNode* a,int i) { /*if (i>=a->arity) { fprintf(stderr,"ERROR: index out of arity range...\n"); exit(1); }*/ return a->args[i]; } IdentNode* newIdentNode(char* name,int infix,int prio) { IdentNode* id = (IdentNode*) malloc(sizeof(IdentNode)); id->name = name; id->infixtype = infix; id->infixpriority = prio; return id; } void freeIdentNode(IdentNode* id) { free(id); } ExprNode* newExprNode(int type) { ExprNode* e = (ExprNode*) calloc(1,sizeof(ExprNode)); e->type = type; return e; } /* free a single node */ void freeExprNode(ExprNode* e) { if (e!=NULL) free(e); } /* free the entire structure */ void freeExpr(ExprNode* e) { int i; if (e!=NULL) { switch(e->type) { case HatApplication: i=0; while (i++v.appval->arity) freeExpr(getAppNodeArg(e->v.appval,i-1)); freeExpr(e->v.appval->fun); freeAppNode(e->v.appval); break; case HatIdentifier: case HatConstructor: freeIdentNode(e->v.identval); break; case HatSATA: freeExpr(e->v.expr); break; case HatDouble: free(e->v.doubleval); break; case MESSAGE: case HatCString: freeStr(e->v.message); break; } freeExprNode(e); } } int getExprArity(ExprNode* e) { if (e==NULL) return 0; switch(e->type) { case HatApplication: return getExprArity(e->v.appval->fun)+e->v.appval->arity; case HatSATA: return getExprArity(e->v.expr); default: return 0; } } int getExprInfixPrio(ExprNode* e) { if (e==NULL) return 0; switch(e->type) { case HatApplication: return getExprInfixPrio(e->v.appval->fun); case HatSATA: return getExprInfixPrio(e->v.expr); case HatIdentifier: case HatConstructor: return e->v.identval->infixpriority; default: return 0; } } #define CUT_MESSAGE "" #define CYCLE_MESSAGE "" #define MAXCYCLES 255 char* cycleID(int i) { int j=0; char s[5]; do { s[j++] = 'a'+(i % 26); // allow characters a-z (0-25) i = i/26; } while ((i!=0)&&(j<5)); s[j]=0; // set strings sentinel return newStr(s); } char* addCycle(filepointer* cycles,filepointer newoffset) { int i=0; while ((iv.message = newStr(CUT_MESSAGE); return exp; // nesting reached the given boundary! } while (fileoffset!=0) { #ifdef DebugbuildExpr printf("building expression... 0x%x\n",fileoffset); #endif fileoffset=hatFollowTrace(handle,fileoffset); // follow the trace along all SATs and indirections b = getNodeType(handle,fileoffset); #ifdef DebugbuildExpr printf("node type: %i\n",b); #endif switch (b) { case HatApplication: // Application { int i=0,arity; AppNode* apn; ExprNode* fun; filepointer functionOffset; if (isInHashTable(hash,fileoffset)) { // detected a cycle? exp = newExprNode(MESSAGE); exp->v.message = addCycle(cycles,fileoffset); // get id for this cycle return exp; // cycle detected! } addToHashTable(hash,fileoffset); arity=getAppArity(); apn=newAppNode(arity); exp = newExprNode(HatApplication); exp->v.appval = apn; functionOffset = getAppFun(); #ifdef DebugbuildExpr printf("Found application of arity: %i\n",arity); #endif while (i++