// Copyright © 2017 Project Golan, all rights reserved. // See COPYING for more information. #include "m_tokbuf.h" #include #include // Static Functions ----------------------------------------------------------| // // M_TokBuf_tokProcess // static enum M_tkprc M_TokBuf_tokProcess(M_token *tok, void *udata) { switch(tok->type) { default: return tokproc_next; case tok_eof: return tokproc_done; case tok_lnend: case tok_cmtlin: return tokproc_skip; } } // // M_TokBuf_print // static void M_TokBuf_print(M_tkbuf *tb) { for(int i = 0; i < tb->tend; i++) printf("[%i]%i: %p %s%s\n", i, tb->toks[i].type, tb->toks[i].textV, tb->toks[i].textV, i == tb->tpos ? " <-- cursor is here" : ""); printf("---\n"); } // Extern Functions ----------------------------------------------------------| // // M_TokBuf_Ctor // void M_TokBuf_Ctor(M_tkbuf *tb) { tb->toks = calloc(tb->bend, sizeof(M_token)); if(!tb->tokProcess) tb->tokProcess = M_TokBuf_tokProcess; } // // M_TokBuf_Dtor // void M_TokBuf_Dtor(M_tkbuf *tb) { if(tb->toks) for(int i = 0; i < tb->bend; i++) M_Vec_clear(tb->toks[i].text); free(tb->toks); } // // M_TokBuf_Get // M_token *M_TokBuf_Get(M_tkbuf *tb) { if(++tb->tpos < tb->tend) return &tb->toks[tb->tpos]; // Free beginning of buffer. for(int i = 0; i < tb->bbeg; i++) { M_Vec_clear(tb->toks[i].text); tb->toks[i] = (M_token){0}; } // Move end of buffer to beginning. if(tb->tend) for(int i = tb->tend - tb->bbeg, j = 0; i < tb->tend; i++, j++) { tb->toks[j] = tb->toks[i]; tb->toks[i] = (M_token){0}; } // Get new tokens. for(tb->tpos = tb->tend = tb->bbeg; tb->tend < tb->bend; tb->tend++) { skip: M_Tk_Parse(tb->fp, &tb->toks[tb->tend]); switch(tb->tokProcess(&tb->toks[tb->tend], tb->udata)) { case tokproc_next: break; case tokproc_done: goto done; case tokproc_skip: goto skip; } } done: return &tb->toks[tb->tpos]; } // // M_TokBuf_UnGet // M_token *M_TokBuf_UnGet(M_tkbuf *tb) { return &tb->toks[tb->tpos--]; } // // M_TokBuf_ReGet // M_token *M_TokBuf_ReGet(M_tkbuf *tb) { return &tb->toks[tb->tpos]; } // // M_TokBuf_Drop // bool M_TokBuf_Drop(M_tkbuf *tb, M_toktype t) { if(M_TokBuf_Get(tb)->type != t) {M_TokBuf_UnGet(tb); return false;} else return true; } // EOF