diff --git a/src/g_objdef.c b/src/g_objdef.c index a07753a..beadf92 100644 --- a/src/g_objdef.c +++ b/src/g_objdef.c @@ -1,6 +1,6 @@ // Copyright © 2017 Project Golan, all rights reserved. #include "g_object.h" -#include "m_token.h" +#include "m_tokbuf.h" #include "m_str.h" #include "m_darray.h" @@ -52,10 +52,6 @@ // Static Functions ----------------------------------------------------------| _Noreturn static void G_ObjDef_throw (struct G_dodst *st, char const *emsg); -static M_token *G_ObjDef_getToken(struct G_dodst *st); -static M_token *G_ObjDef_unget (struct G_dodst *st); -static M_token *G_ObjDef_reget (struct G_dodst *st); -static bool G_ObjDef_drop (struct G_dodst *st, M_tokty t); [[__optional_args(1)]] static M_token *G_ObjDef_expect (struct G_dodst *st, M_tokty t, char const *exp); [[__optional_args(1)]] @@ -71,20 +67,19 @@ GDCC_HashMap_Decl(G_anims, char const *, struct G_manim) typedef struct G_dodst { - __prop throw {call: G_ObjDef_throw (this)} - __prop getToken {call: G_ObjDef_getToken(this)} - __prop unget {call: G_ObjDef_unget (this)} - __prop drop {call: G_ObjDef_drop (this)} - __prop expect {call: G_ObjDef_expect (this)} - __prop getArgs {call: G_ObjDef_getArgs (this)} - __prop reget {call: G_ObjDef_reget (this)} + __prop getToken {call: M_TokBuf_Get (->tbPtr)} + __prop unget {call: M_TokBuf_UnGet (->tbPtr)} + __prop reget {call: M_TokBuf_ReGet (->tbPtr)} + __prop drop {call: M_TokBuf_Drop (->tbPtr)} + __prop expect {call: G_ObjDef_expect (this)} + __prop throw {call: G_ObjDef_throw (this)} + __prop getArgs {call: G_ObjDef_getArgs(this)} jmp_buf ejmp; int lines; char const *fname; FILE *fp; - int tpos, tend; - M_token toks[G_dodTokEnd]; + M_tkbuf tb, *tbPtr; } G_dodst; typedef union G_odprm @@ -174,65 +169,19 @@ _Noreturn static void G_ObjDef_throw(G_dodst *st, char const *emsg) } // -// G_ObjDef_getToken +// G_ObjDef_tokProcess // -static M_token *G_ObjDef_getToken(G_dodst *st) +static enum M_tkprc G_ObjDef_tokProcess(M_token *tok, void *udata) { - if(++st->tpos < st->tend) - return &st->toks[st->tpos]; + G_dodst *st = (G_dodst *)udata; - memmove(&st->toks[0], &st->toks[st->tend - G_dodTokBeg], - sizeof(M_token) * G_dodTokBeg); + tok->line = st->lines; - for(st->tpos = st->tend = G_dodTokBeg; st->tend < G_dodTokEnd; st->tend++) - { - skip: - M_Tk_Parse(st->fp, &st->toks[st->tend]); - st->toks[st->tend].line = st->lines; - - switch(st->toks[st->tend].type) { - default: break; - case tok_eof: goto done; - case tok_lnend: st->lines++; - case tok_cmtlin: goto skip; - } - } - - /* - for(int i = 0; i < st->tend; i++) - printf("%i: %s%s\n", st->toks[i].type, st->toks[i].text, i == st->tpos ? " <-- cursor is here" : ""); - */ - -done: - return &st->toks[st->tpos]; -} - -// -// G_ObjDef_unget -// -static M_token *G_ObjDef_unget(G_dodst *st) -{ - return &st->toks[st->tpos--]; -} - -// -// G_ObjDef_reget -// -static M_token *G_ObjDef_reget(G_dodst *st) -{ - return &st->toks[st->tpos]; -} - -// -// G_ObjDef_drop -// -static bool G_ObjDef_drop(G_dodst *st, M_tokty t) -{ - if(st->getToken()->type != t) { - st->unget(); - return false; - } else { - return true; + switch(tok->type) { + default: return tokproc_next; + case tok_eof: return tokproc_done; + case tok_lnend: st->lines++; + case tok_cmtlin: return tokproc_skip; } } @@ -545,13 +494,20 @@ void G_ObjDef_Init(void) // void G_ObjDef_Load(char const *fname) { - G_dodst st = {.fp = fopen(fname, "r"), .fname = fname, .lines = 1}; + G_dodst st = {.fname = fname, .lines = 1, .tbPtr = &st.tb, + .tb = {.bbeg = G_dodTokBeg, .bend = G_dodTokEnd, + .tokProcess = G_ObjDef_tokProcess, .udata = &st}}; + + st.fp = fopen(fname, "r"); + st.tb.fp = st.fp; if(!st.fp) { fprintf(stderr, "ObjDef: couldn't open file '%s'\n", fname); goto done; } + st.tb.toks = calloc(G_dodTokEnd, sizeof(M_token)); + if(setjmp(st.ejmp) == 1) goto done; @@ -577,6 +533,7 @@ void G_ObjDef_Load(char const *fname) printf("ObjDef: '%s' loaded.\n", fname); done: + free(st.tb.toks); fclose(st.fp); } diff --git a/src/m_tokbuf.c b/src/m_tokbuf.c new file mode 100644 index 0000000..70e003c --- /dev/null +++ b/src/m_tokbuf.c @@ -0,0 +1,70 @@ +// Copyright © 2017 Project Golan, all rights reserved. +#include "m_tokbuf.h" + +#include + +// Extern Functions ----------------------------------------------------------| + +// +// M_TokBuf_Get +// +[[__optional_args(1)]] +M_token *M_TokBuf_Get(M_tkbuf *tb) +{ + if(++tb->tpos < tb->tend) + return &tb->toks[tb->tpos]; + + memmove(&tb->toks[0], &tb->toks[tb->tend - tb->bbeg], + sizeof(M_token) * tb->bbeg); + + 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: + /* + for(int i = 0; i < tb->tend; i++) + printf("%i: %s%s\n", tb->toks[i].type, tb->toks[i].text, i == tb->tpos ? " <-- cursor is here" : ""); + */ + + 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_tokty t) +{ + if(tb->get()->type != t) { + tb->unget(); + return false; + } else { + return true; + } +} + +// EOF diff --git a/src/m_tokbuf.h b/src/m_tokbuf.h new file mode 100644 index 0000000..9fca0dd --- /dev/null +++ b/src/m_tokbuf.h @@ -0,0 +1,39 @@ +// Copyright © 2017 Project Golan, all rights reserved. +#ifndef m_tokbuf_h +#define m_tokbuf_h + +#include "m_token.h" + +// Extern Functions ----------------------------------------------------------| + +M_token *M_TokBuf_Get(struct M_tkbuf *tb); +M_token *M_TokBuf_UnGet(struct M_tkbuf *tb); +M_token *M_TokBuf_ReGet(struct M_tkbuf *tb); +bool M_TokBuf_Drop(struct M_tkbuf *tb, M_tokty t); + +// Types ---------------------------------------------------------------------| + +enum M_tkprc +{ + tokproc_next, + tokproc_done, + tokproc_skip +}; + +typedef struct M_tkbuf +{ + __prop get {call: M_TokBuf_Get (this)} + __prop unget {call: M_TokBuf_UnGet(this)} + __prop reget {call: M_TokBuf_ReGet(this)} + __prop drop {call: M_TokBuf_Drop (this)} + + FILE *fp; + M_token *toks; + int tpos, tend; + int bbeg, bend; + void *udata; + + enum M_tkprc (*tokProcess)(M_token *tok, void *udata); +} M_tkbuf; + +#endif