Split token buffering to m_tokbuf
parent
7ca5c6275b
commit
891bbd4f39
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
// Copyright © 2017 Project Golan, all rights reserved.
|
||||
#include "m_tokbuf.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
// 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
|
|
@ -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
|
Loading…
Reference in New Issue