Split token buffering to m_tokbuf

master
Marrub 2017-09-21 00:18:11 -04:00
parent 7ca5c6275b
commit 891bbd4f39
3 changed files with 136 additions and 70 deletions

View File

@ -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);
}

70
src/m_tokbuf.c Normal file
View File

@ -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

39
src/m_tokbuf.h Normal file
View File

@ -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