#include "structures.h" struct term *reconstruct_term( char *buffer); char *term_image(struct term *t); int reconstruct_int(char *buffer, int *offset,int i); /* ============================================================ | copy_string() | |----------------------------------------------------------| | Params : 1)a string | | Desc : copies the string, allocating the right amount of memory | | | Returns: pointer to the copy | |==========================================================| */ char *copy_string(char *st) { int i=strlen(st); char *result=malloc(i+1); strcpy(result,st); return result; } term_ptr read_pipe(int pipe_id) { char size_buffer[2]; char *buffer; int size,n,offset=0; term_ptr result; if (n=read(pipe_id,size_buffer,2)>0) { size=reconstruct_int(size_buffer,&offset,2); buffer=malloc(size+2); n=read(pipe_id,buffer+2,size); if (n!=size) return NULL; buffer[0]=size_buffer[0]; buffer[1]=size_buffer[1]; result=reconstruct_term(buffer); free(buffer); return result; } else return NULL; } void write_pipe(int pipe_id,term_ptr term) { char *buffer = term_image(term); int offset=0; int size=reconstruct_int(buffer,&offset,2)+2; write(pipe_id, buffer, size); free(buffer); } /* ============================================================ | term_size() | |----------------------------------------------------------| | Params : 1)a term | | | | Returns: returns the size of the binary_image of the term| |==========================================================| */ int term_size(struct term *t) { int i,s=0; for (i=0;iarity;i++) { s+=term_size(t->argument_array[i]); } if (t->term_type==STRING) s+=strlen(t->const_string)+4; else s+=sizeof(t->functor)+4; return s; } /* ============================================================ | nth_byte() | |----------------------------------------------------------| | Params : 1)an integer | | 2)an integer | | | | Returns: the nth byte of the first argument (least significant byte is position 0 |==========================================================| */ char nth_byte(int k,int position) { char result; result=(char)(0xFF&(k>>(position*8))); return result; } /* ============================================================ | reconstruct_int() | |----------------------------------------------------------| | Params : 1) pointer to a byte array | | 2) number of bytes | | | | Returns: the integer represented by the bytes | |==========================================================| */ int reconstruct_int(char *buffer, int *offset,int i) { int j; int result=0; int template; for (j=0;jarity;i++) address=dump_term(address,t->argument_array[i]); size=(t->term_type==STRING?strlen(t->const_string):sizeof(t->functor)); *(address++)=nth_byte(t->term_type,0); *(address++)=nth_byte(t->arity,0); *(address++)=nth_byte(size,1); *(address++)=nth_byte(size,0); if (t->term_type!=STRING) for(i=size-1;i>=0;i--) *(address++)=nth_byte(t->functor,i); else { memcpy(address,t->const_string,size); address+=size; } return address; } /* ============================================================ | term_image() | |----------------------------------------------------------| | Params : 1)a term | | Desc : creates a binary image of the term | | | Returns: a pointer to the beginning of the image | |==========================================================| */ char *term_image(struct term *t) { int l=term_size(t); char *image=malloc(l+2); dump_term(image+2,t); image[0]=nth_byte(l,1); image[1]=nth_byte(l,0); return image; } struct term *term_stack[255]; int stack_pointer=0; void push_term(struct term *t) { if (stack_pointer<=255) { term_stack[stack_pointer]=t; stack_pointer++; } } struct term *pop_term() { if (stack_pointer >0) { stack_pointer--; return term_stack[stack_pointer]; } else return NULL; } typedef char (* next_byte_function)(int *, char *); /* ============================================================ | reconstruct_term() | |----------------------------------------------------------| | Desc : reconstructs the term represented by the byte stream | | | Returns: a term | |==========================================================| */ struct term *reconstruct_term(char *buffer) { int progress=0; int buffer_size=reconstruct_int(buffer,&progress,2); while(progress=0;i--) args[i]=pop_term(); push_term(maketerm(term_type, functor, arity, const_string, args)); } return pop_term(); } /* makes a term from the given components */ struct term *maketerm(int term_type,int functor, int arity,char *const_string, struct term **argument_array) { struct term *result; result=(struct term *)malloc(sizeof(struct term)); if (result==NULL){printf("no memory for 'maketerm'\n");exit(0);} result->term_type=term_type; result->functor=functor; if (term_type==STRING) { if (const_string==NULL) result->const_string=NULL; else { result->const_string=(char *)malloc(strlen(const_string)+1); strcpy(result->const_string,const_string); } } else result->const_string = NULL; result->arity=arity; result->argument_array=argument_array; return result; } /* makes an array of term pointers */ struct term **maketermarray(int n) { term_pointer *res; int i; if (n>0) res=(term_pointer *)calloc(n,sizeof(term_pointer)); else res=NULL; for(i=0;iarity); for (i=0;iarity;i++) arg_array[i]=copy_term(t->argument_array[i]); return maketerm(t->term_type,t->functor,t->arity,t->const_string,arg_array); } /* ============================================================ | free_term() | |----------------------------------------------------------| | Params : 1)an interpreter term | | | | | | Desc : frees the memory occupied by term, recursively | | | | Returns:Nothing | |==========================================================| */ void free_term(struct term *t) { int i; if (t==NULL) return; if(t->arity > 0){ /* Free argument array. */ free(t->argument_array); for(i=0;iarity;i++) free_term(t->argument_array[i]); free(t->argument_array); } /* Free the string. */ if(t->term_type == STRING) free(t->const_string); /* Free the term. */ free(t); } /* ============================================================ | term_template() | |----------------------------------------------------------| | Params : 1) a string representing the term structure | | Desc : creates the term according to the template. | | | Returns: a term | |==========================================================| */ term_ptr term_template(char *template) { char c; while(*template) { c=*(template++); if (isdigit(c)) { int arity=c-'0'; term_ptr *args=maketermarray(arity); term_ptr t=maketerm(NONVAR,0,arity,NULL,args); for(;arity>0;arity--) { args[arity-1]=pop_term(); } push_term(t); } else switch (c) { case 'i':push_term(maketerm(INTEGER,0,0,NULL,NULL)); break; case 's':push_term(maketerm(STRING,0,0,NULL,NULL)); break; case 'n':push_term(maketerm(NONVAR,0,0,NULL,NULL)); break; } } return pop_term(); }