///////#include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include "cursor.h" enum {SUCCESS=0,QUIT,CONTINUE,STEP,DEBUG,Bad}; // // Memory attachments to join // // Graphs in memory are intermediate processing // structures with inut,output but are opaque // to lazyj. // // There are two type, fixed key, inline linkage and // variable key external linkage. // // inkline links, fixed key first // this is specially useful for joining // word list structures, or plaintext. // // Memory is an array of int // The module does arimetic on array indeces // Key size is per instnce of a convolve. // set at init_mem_cursos // current is an array index into the lineqr int array, // a count of one is a singleton // start points to attachment space, an array of integers // state points back tstart of sequence // reads and write to memory using join grammar // It has three ops, Comma, Dot, and the Parenth pair // Every node contains an offsert to the next sequence // and a parent, all array index arithmetic // // {op,parent,count,spare,actual key data} // // Macros get access raw mem // #define KEY_I(a) (char *) &buf[a+2] #define LINK_I(a) buf[a+2] #define LEN_I(a) buf[a+1] #define OP_I(a) buf[a] #define SHORT_REC(a,b,c) buf[a]=b; buf[a+1]=4 // Nodes can be short or long // short nodes have the Null key // back up and update the parent sequences in memory int set_offsets(int link_i,int *buf,int offset){ do { link_i= LINK_I(link_i); // linked backward LEN_I(link_i)= LEN_I(link_i) + offset; } while(link_i != 0); } // Append to current sequence // fill the empty node int memAppend(PCursor self) { // long old_i,new_i,next_i,link_i; int size; int *buf; char *c; Element* e = &self->element; // if(self->logic != Output) return(Null); size = self->key_size; buf= (int *) self->start; old_i = (long) self->current; // array index from record count // Short or long record? if(OP_I(old_i) != ',') // Comma is the long record. new_i = old_i + 4; else new_i=old_i + size + 4; self->current= (void *) new_i; next_i = new_i + 4 + size; LEN_I(new_i) = 4 + size; OP_I(new_i) = ','; // The new location already has a Null record with a valid link back link_i = LINK_I(new_i); strcpy((char *) KEY_I(new_i),e->key); // Move the terminating null record the end. SHORT_REC(next_i,'@',LINK_I(new_i)); // update the parenth sequences in memory set_offsets(new_i,buf,size+4); return(Null); } // Get current op/key pair int memFetch(PCursor self) { long index; int size; int *buf; Element * e = &self->element; // space is an array of ints size = self->key_size; buf = (int *) self->start; index = (long) self->current; e->op = (char) OP_I(index); if(e->op == ',') strcpy(e->key, ((char *) buf)+index+4); else *e->key=0; return (Null); } // step one record // Close the previous sequence, terminate. int memBranch(PCursor self ){ long link_i,g,old_i,new_i,next_i; int* buf; int size = self->key_size; buf = (int *) self->start; old_i = (long) self->current; if(OP_I(old_i) != ',') new_i = old_i +4; else { new_i = old_i+size+4; // A Null valid Null record should be right here } self->current = (void *) new_i; next_i = new_i + 4; OP_I(new_i) = ')'; LEN_I(new_i) = 4; // Null teminator link_i = LINK_I(new_i); SHORT_REC(next_i,'@',LINK_I(link_i)); set_offsets(new_i,buf,4); return(Null); } // step one record int memStep(PCursor self ){ int* buf; int size = self->key_size; buf = (int *) self->start; long index = (long) self->current; size = self->key_size; if(OP_I(index) != '@') { if(OP_I(index) != ',') self->current= (void *) (index+4); else self->current= (void *)(index+size+4); } return(Null); } // step one record int memSkip(PCursor self ){ long old_i = (long) self->current; int* buf = (int *) self->start; long link_i = LINK_I(old_i); self->current= (void *) (link_i + LEN_I(old_i)); return(Null); } // start a new sequence // this could be memSkip with two modes int memDescend(PCursor self) { long link_i,g,old_i,new_i,next_i; int* buf; int size; size = self->key_size; buf = (int *) self->start; old_i = (long) self->current; if(self->mode == Output) { // Pass new sequence header link_i = LINK_I(old_i); if(OP_I(old_i) == '(') // start of sequence node. new_i = old_i + 4; else { new_i=old_i + size + 4; } self->current = (void*) new_i; // point to next node next_i = new_i + 4; link_i = LINK_I(next_i); // Valid Null pointer hs the link // set sequence header OP_I(new_i) ='('; LEN_I(new_i) = 4; link_i = LINK_I(new_i); SHORT_REC(next_i,'@',new_i); set_offsets(new_i,buf,4); } else { new_i =old_i + LEN_I(link_i); // count self->current = (void*) new_i; } return(Null); } int memDescendAppend(PCursor self) { memDescend(self); return(memAppend(self)); } int ExecMem(PCursor self,int method,void * data){ if(method == Append) return(memAppend(self)); else if(method == Fetch) return(memFetch(self)); else if(method == Skip) return(memSkip(self)); else if(method == Step) return(memStep(self)); // push and pop of the database index else if(method == Set) self->state=self->current; else if(method == Reset) self->current=self->state; return(Null); } int EvalMem(PCursor self,PCursor other) { int status; Element *self_elem = &self->element; Element *other_elem = &other->element; // Any signal from the other cursor? if(self->mode == Done) { self->mode = Null; return(Done); } switch(self_elem->op) { case '@': // This should be null, changed for debug visibility status = Done; break; case '.': status= MatchKey(self_elem,other_elem); if(status != Match) // Match status = Singleton; // Singleton Dot is a group of one break; case ',': status = MatchKey(self_elem,other_elem); break; //The grouping opcodes case '(': status=Push; break; case ')': status= End; break; default: status=Null; } return(status); } // // called provides space to allow // multiple instnces of memory spaces PCursor InitMemCursor(int* argc,char * args[]) { PCursor self=(PCursor) args[1]; int * buf; int size_rec,count_rec; size_rec = atoi(*args);args++; count_rec = atoi(*args);args++;; buf = malloc(size_rec*count_rec); self->start=buf; self->current=0; buf[2]=4; // length buf[1]= 0; //pointing to the start sequence header buf[0] = '('; //sequence head opecode // Terminator buf[4]='@'; buf[5]=0; return(self); } void del_memory_cursor(PCursor p) { // check to make sure no other cursos are hanging on this // particular MEM instanc via dup_cursort // How? Dunno yet, garbage collection del_cursor(p); } // MatchKey is the attachment definition of match // Lazy JSON allows for a wildcard or key match // returns 0 or 1 int InitMem(void) { return(0); } int MatchKey(Element* p, Element* q) { if(p->op=='*' || q->op == '*') return(Match); if(*p->key || *q->key) { // Null keys do not match,yet if(!strcmp(p->key,q->key)) return(Match); } else return(Null); } #define print_head(i) \ printf("\n%d %c %d %d ",i,buf[i],buf[i+1],buf[i+2]) void PrintMem(int * argc,char * args[]) { PCursor self = (PCursor) args[1]; int c,i; char op; int* buf; int size; size = self->key_size; buf = (int *) self->start; i=0; do { print_head(i); if(buf[i] == '(' || buf[i] == '@' || buf[i]== ')') { printf("\n"); i = i + 4; } else if(buf[i] == ',') { printf("%s\n",KEY_I(i)); i = i + size+4; } } while(buf[i] != '@'); print_head(i);printf("\n"); } void SaveMem(int * argc, char * args[]) { PCursor self=(PCursor)args[1]; FILE *fout = fopen(args[2],"wb"); int * buff=self->start; if(!fout) return; fwrite(buff,sizeof(int),*(buff+2),fout); } // External linkage memory // cursor->start hold the original text // cursor->current is an integer pointer in the // index stack // Indices link back inot the source. // Components of a nore typedef struct Extnode{ int parent; // outer holder int next; // ditto int source; // indexes source int spare; // make a quad boundary }ExtNode; int StepExt(PCursor self ){ self->current++; return(Null); } // Skip one record int SkipExt(PCursor self ){ ExtNode * node = self->start; long old_i = (long) self->current; long k =node[old_i].next; self->current = (void *)k; return(Null); } int FetchExt(PCursor self ){ ExtNode * node = self->start; long i = (long) self->current; char * buf= self->pointer; self->element.key = &buf[node[i].source]; return(Null); } #define EvalExtMem EvalMem int AppendExt(PCursor self) { // append the tagged key to te end of source // be sure to replace null node ExtNode* node = self->start; long i = (long) self->current; int parent=node[i].parent; node[i+1]=node[i]; node[i].next=i+1; node[parent].next++; } // // Load requires the file name of an external idnex // Top level should have alreadyloaded the source // int LoadExt(int * argc, char * args[]) { FILE* fin; char * buf; char name[20]; PCursor self = (PCursor) args[1]; self->start = (void *) malloc(200*sizeof(ExtNode)); ExtNode * node= self->start; node->source=0; // no source strcpy(name,args[1]); strcpy(strchr(name,'.')+1,"idx"); fin=fopen(name,"rb"); if(!fin) return(-1); while(!feof(fin) ) { fscanf(fin,"%d %d %d",node->parent,node->next,node->source); node++; } } int ExecExt(PCursor self,int method,void * data){ if(method == Append) return(AppendExt(self)); else if(method == Fetch) return(FetchExt(self)); else if(method == Skip) return(SkipExt(self)); else if(method == Step) return(StepExt(self)); // push and pop of the database index else if(method == Set) self->state=self->current; else if(method == Reset) self->current=self->state; return(Null); } // called provides space to allow // multiple instnces of memory spaces PCursor InitExt(int * argc,void * args[]) { int * buf; int size_rec = atoi(*args);args++; int count_rec = atoi(*args);args++; PCursor self = args[1]; // set up aleady by exec ExtNode* node= (ExtNode*) malloc(size_rec*count_rec); self->current=0; self->start = node; self->exec = ExecExt; self->eval = EvalMem; // both memory modules share eval // Set a start and end node, // the grammar will append or fill it later // Start node node->source=0; node->next=1; node->parent=0; // End Node node++; node->parent=0; node->next=0; node->source=0; return(self); } ///////////////// // Confiugre and control //////////////// int ExecShellCommand(int* argc,char * args[]){ char * cmd = args[0]; if(cmd) if( !strcmp(cmd,"quit")) return(QUIT); if( !strcmp(cmd,"SaveSlot")) SaveMem(argc,args); if( !strcmp(cmd,"PrintSlot")) PrintMem(argc,args); if( !strcmp(cmd,"Init")) InitMem(); if( !strcmp(cmd,"InitSlot")) InitMemCursor(argc,args); return(0); }
Memory interface to join
Subscribe to:
Posts (Atom)
No comments:
Post a Comment