fltp.c (2566B)
1 /* 2 * Forth-Like Tree Protocol 3 */ 4 5 #include <u.h> 6 #include <libc.h> 7 8 #include "fltp.h" 9 10 FLTWord dict[] = { 11 {&dict[1], "{", fltpstartlist}, 12 {&dict[2], "}", fltpendlist}, 13 {nil, ".n", fltpgetline}, 14 }; 15 16 FLTP * 17 initfltp(void){ 18 FLTP *new; 19 new = mallocz(sizeof(FLTP), 1); 20 new->fp = new->rs; 21 *(new->fp) = fltpmain; // TODO: should be actual func 22 new->tbuf = malloc(FLTTokenBufSize); 23 new->wp = dict; 24 return new; 25 } 26 27 void 28 evalfltp(FLTP *fltp, char *buf, long nbytes){ 29 fltp->bp = buf; 30 fltp->nbytes = nbytes; 31 (*fltp->fp)(fltp); 32 } 33 34 FLTNode * 35 createfltnode(FLTNode *prev, FLTNode *parent, char *buf, long nbytes) 36 { 37 FLTNode *new; 38 new = malloc(sizeof(FLTNode) + nbytes); 39 new->prev = prev; 40 new->next = nil; 41 new->parent = parent; 42 new->nbytes = nbytes; 43 memcpy((char *)new + sizeof(FLTNode), buf, nbytes); 44 if(prev != nil) prev->next = new; 45 return new; 46 } 47 48 FLTWord * 49 getfltword(char *str, long nbytes, FLTWord *wp) 50 { 51 if(nbytes >= FLTWordSize) return nil; 52 for(; wp != nil; wp = wp->prev){ 53 if(strlen(wp->str) != nbytes) continue; 54 if(memcmp(wp->str, str, nbytes) == 0) return wp; 55 } 56 return nil; 57 } 58 59 void 60 fltpmain(FLTP *fltp){ 61 FLTWord *wp; 62 for(;;){ 63 fltpgettoken(fltp); 64 if(fltp->ti > 0){ 65 fltp->np = createfltnode(fltp->np, fltp->pnp, fltp->tbuf, fltp->ti); 66 wp = getfltword(fltp->tbuf, fltp->ti, fltp->wp); 67 if(wp != nil) wp->fp(fltp); // TODO: should utilise fltp->rs ??? 68 } 69 if(fltp->nbytes == 0) break; 70 } 71 } 72 73 void 74 fltpgettoken(FLTP *fltp){ 75 int c; 76 fltp->ti = 0; 77 for(;;){ 78 if(fltp->ti >= FLTTokenBufSize) sysfatal("fltpgettoken: token buffer overflow"); 79 c = *fltp->bp; 80 fltp->bp++; 81 fltp->nbytes--; 82 if(strchr(" \t\n", c) != nil) break; 83 fltp->tbuf[fltp->ti] = c; 84 fltp->ti++; 85 if(fltp->nbytes == 0) sysfatal("fltpgettoken: input buffer overflow (unterminated token)"); 86 } 87 } 88 89 void 90 fltpstartlist(FLTP *fltp){ 91 fltp->pnp = fltp->np; 92 } 93 94 void 95 fltpendlist(FLTP *fltp){ 96 if(fltp->pnp == nil) sysfatal("fltpendlist: nil in parent pointer"); 97 fltp->pnp = fltp->pnp->parent; 98 } 99 100 void 101 fltpgetline(FLTP *fltp){ 102 int c; 103 fltp->ti = 0; 104 for(;;){ 105 if(fltp->ti >= FLTTokenBufSize) sysfatal("fltpgetline: token buffer overflow"); 106 c = *fltp->bp; 107 fltp->bp++; 108 fltp->nbytes--; 109 if(c == '\n') break; 110 fltp->tbuf[fltp->ti] = c; 111 fltp->ti++; 112 if(fltp->nbytes == 0){ 113 fprint(2,"tbuf: %.*s\n", fltp->ti, fltp->tbuf); 114 sysfatal("fltpgetline: input buffer overflow (unterminated token)"); 115 } 116 } 117 // unlike fltpgettoken, we create new node even if the line is empty 118 fltp->np = createfltnode(fltp->np, fltp->np, fltp->tbuf, fltp->ti); 119 }