forked from GitHub/gf-core
readExpr/readType/readContext can now identify local variables
This commit is contained in:
@@ -302,6 +302,7 @@ PgfExprParser::PgfExprParser(PgfText *input, PgfUnmarshaller *unmarshaller)
|
||||
u = unmarshaller;
|
||||
token_pos = NULL;
|
||||
token_value = NULL;
|
||||
bs = NULL;
|
||||
|
||||
token();
|
||||
}
|
||||
@@ -641,6 +642,18 @@ PgfExpr PgfExprParser::parse_term()
|
||||
return u->emeta(id);
|
||||
}
|
||||
case PGF_TOKEN_IDENT: {
|
||||
PgfBind *last = bs;
|
||||
size_t index = 0;
|
||||
while (last != NULL) {
|
||||
if (textcmp(&last->var,token_value) == 0) {
|
||||
PgfExpr e = u->evar(index);
|
||||
token();
|
||||
return e;
|
||||
}
|
||||
last = last->next;
|
||||
index++;
|
||||
}
|
||||
|
||||
PgfExpr e = u->efun(token_value);
|
||||
token();
|
||||
return e;
|
||||
@@ -715,9 +728,9 @@ PgfExpr PgfExprParser::parse_arg()
|
||||
return arg;
|
||||
}
|
||||
|
||||
PgfBind *PgfExprParser::parse_bind(PgfBind *next)
|
||||
bool PgfExprParser::parse_bind()
|
||||
{
|
||||
PgfBind *last = next;
|
||||
PgfBind *last = bs;
|
||||
PgfBindType bind_type = PGF_BIND_TYPE_EXPLICIT;
|
||||
|
||||
if (token_tag == PGF_TOKEN_LCURLY) {
|
||||
@@ -734,10 +747,12 @@ PgfBind *PgfExprParser::parse_bind(PgfBind *next)
|
||||
}
|
||||
|
||||
PgfBind *bind = (PgfBind *) malloc(sizeof(PgfBind)+var->size+1);
|
||||
if (bind == NULL)
|
||||
goto error;
|
||||
bind->bind_type = bind_type;
|
||||
bind->next = last;
|
||||
bind->next = bs;
|
||||
memcpy(&bind->var, var, sizeof(PgfText)+var->size+1);
|
||||
last = bind;
|
||||
bs = bind;
|
||||
|
||||
token();
|
||||
|
||||
@@ -755,39 +770,41 @@ PgfBind *PgfExprParser::parse_bind(PgfBind *next)
|
||||
token();
|
||||
}
|
||||
|
||||
return last;
|
||||
return true;
|
||||
|
||||
error:
|
||||
while (last != next) {
|
||||
PgfBind *tmp = last;
|
||||
last = last->next;
|
||||
free(tmp);
|
||||
}
|
||||
return NULL;
|
||||
pop_binds(last);
|
||||
return false;
|
||||
}
|
||||
|
||||
PgfBind *PgfExprParser::parse_binds(PgfBind *next)
|
||||
bool PgfExprParser::parse_binds()
|
||||
{
|
||||
PgfBind *last = bs;
|
||||
for (;;) {
|
||||
PgfBind *binds = parse_bind(next);
|
||||
if (binds == NULL) {
|
||||
while (next != NULL) {
|
||||
PgfBind *tmp = next;
|
||||
next = next->next;
|
||||
free(tmp);
|
||||
}
|
||||
break;
|
||||
if (!parse_bind()) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
next = binds;
|
||||
|
||||
if (token_tag != PGF_TOKEN_COMMA)
|
||||
break;
|
||||
|
||||
token();
|
||||
}
|
||||
|
||||
return next;
|
||||
return true;
|
||||
|
||||
error:
|
||||
pop_binds(last);
|
||||
return false;
|
||||
}
|
||||
|
||||
void PgfExprParser::pop_binds(PgfBind *last)
|
||||
{
|
||||
while (bs != last) {
|
||||
PgfBind *tmp = bs;
|
||||
bs = bs->next;
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
PgfExpr PgfExprParser::parse_expr()
|
||||
@@ -797,8 +814,8 @@ PgfExpr PgfExprParser::parse_expr()
|
||||
if (token_tag == PGF_TOKEN_LAMBDA) {
|
||||
token();
|
||||
|
||||
PgfBind* bs = parse_binds(NULL);
|
||||
if (bs == NULL)
|
||||
PgfBind *last = bs;
|
||||
if (!parse_binds())
|
||||
return 0;
|
||||
|
||||
if (token_tag != PGF_TOKEN_RARROW) {
|
||||
@@ -810,7 +827,7 @@ PgfExpr PgfExprParser::parse_expr()
|
||||
if (expr == 0)
|
||||
goto error;
|
||||
|
||||
while (bs != NULL) {
|
||||
while (bs != last) {
|
||||
PgfExpr abs_expr = u->eabs(bs->bind_type, &bs->var, expr);
|
||||
u->free_ref(expr);
|
||||
expr = abs_expr;
|
||||
@@ -823,12 +840,7 @@ PgfExpr PgfExprParser::parse_expr()
|
||||
return expr;
|
||||
|
||||
error:
|
||||
while (bs != NULL) {
|
||||
PgfBind *tmp = bs;
|
||||
bs = bs->next;
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
pop_binds(last);
|
||||
return 0;
|
||||
} else {
|
||||
expr = parse_term();
|
||||
@@ -854,11 +866,13 @@ error:
|
||||
}
|
||||
}
|
||||
|
||||
bool PgfExprParser::parse_hypos(size_t *n_hypos, PgfTypeHypo **hypos)
|
||||
bool PgfExprParser::parse_hypos(size_t *n_hypos, PgfTypeHypo **hypos,
|
||||
PgfBind **pbs)
|
||||
{
|
||||
PgfText *var;
|
||||
PgfBindType bind_type = PGF_BIND_TYPE_EXPLICIT;
|
||||
|
||||
*pbs = bs;
|
||||
for (;;) {
|
||||
if (bind_type == PGF_BIND_TYPE_EXPLICIT &&
|
||||
token_tag == PGF_TOKEN_LCURLY) {
|
||||
@@ -870,7 +884,7 @@ bool PgfExprParser::parse_hypos(size_t *n_hypos, PgfTypeHypo **hypos)
|
||||
if (token_tag == PGF_TOKEN_IDENT || token_tag == PGF_TOKEN_WILD) {
|
||||
var = token_value;
|
||||
} else {
|
||||
return false;
|
||||
goto error;
|
||||
}
|
||||
|
||||
*hypos = (PgfTypeHypo*) realloc(*hypos, sizeof(PgfTypeHypo)*(*n_hypos+1));
|
||||
@@ -880,6 +894,14 @@ bool PgfExprParser::parse_hypos(size_t *n_hypos, PgfTypeHypo **hypos)
|
||||
bt->type = 0;
|
||||
(*n_hypos)++;
|
||||
|
||||
PgfBind *bind = (PgfBind *) malloc(sizeof(PgfBind)+var->size+1);
|
||||
if (bind == NULL)
|
||||
goto error;
|
||||
bind->bind_type = bind_type;
|
||||
bind->next = *pbs;
|
||||
memcpy(&bind->var, var, sizeof(PgfText)+var->size+1);
|
||||
*pbs = bind;
|
||||
|
||||
token();
|
||||
|
||||
if (bind_type == PGF_BIND_TYPE_IMPLICIT &&
|
||||
@@ -896,9 +918,17 @@ bool PgfExprParser::parse_hypos(size_t *n_hypos, PgfTypeHypo **hypos)
|
||||
}
|
||||
|
||||
if (bind_type == PGF_BIND_TYPE_IMPLICIT)
|
||||
return false;
|
||||
goto error;
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
while (*pbs != bs) {
|
||||
PgfBind *tmp = *pbs;
|
||||
*pbs = (*pbs)->next;
|
||||
free(tmp);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static
|
||||
@@ -919,6 +949,7 @@ PgfType PgfExprParser::parse_type()
|
||||
|
||||
size_t n_hypos = 0;
|
||||
PgfTypeHypo *hypos = NULL;
|
||||
PgfBind *last = bs;
|
||||
|
||||
PgfText *cat = NULL;
|
||||
|
||||
@@ -930,6 +961,7 @@ PgfType PgfExprParser::parse_type()
|
||||
token();
|
||||
|
||||
size_t n_start = n_hypos;
|
||||
PgfBind *new_bs = bs;
|
||||
|
||||
if ((token_tag == PGF_TOKEN_IDENT &&
|
||||
(lookahead(',') ||
|
||||
@@ -937,11 +969,13 @@ PgfType PgfExprParser::parse_type()
|
||||
(token_tag == PGF_TOKEN_LCURLY) ||
|
||||
(token_tag == PGF_TOKEN_WILD)) {
|
||||
|
||||
if (!parse_hypos(&n_hypos, &hypos))
|
||||
if (!parse_hypos(&n_hypos, &hypos, &new_bs))
|
||||
goto exit;
|
||||
|
||||
if (token_tag != PGF_TOKEN_COLON)
|
||||
if (token_tag != PGF_TOKEN_COLON) {
|
||||
bs = new_bs; // to be recycled
|
||||
goto exit;
|
||||
}
|
||||
|
||||
token();
|
||||
} else {
|
||||
@@ -956,8 +990,10 @@ PgfType PgfExprParser::parse_type()
|
||||
size_t n_end = n_hypos;
|
||||
|
||||
PgfType type = parse_type();
|
||||
if (type == 0)
|
||||
bs = new_bs;
|
||||
if (type == 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (token_tag != PGF_TOKEN_RPAR)
|
||||
goto exit;
|
||||
@@ -1026,6 +1062,8 @@ exit:
|
||||
}
|
||||
free(hypos);
|
||||
|
||||
pop_binds(last);
|
||||
|
||||
free(cat);
|
||||
|
||||
while (n_args > 0) {
|
||||
@@ -1040,12 +1078,14 @@ PgfTypeHypo *PgfExprParser::parse_context(size_t *p_n_hypos)
|
||||
{
|
||||
size_t n_hypos = 0;
|
||||
PgfTypeHypo *hypos = NULL;
|
||||
PgfBind *last = bs;
|
||||
|
||||
for (;;) {
|
||||
if (token_tag == PGF_TOKEN_LPAR) {
|
||||
token();
|
||||
|
||||
size_t n_start = n_hypos;
|
||||
PgfBind *new_bs = bs;
|
||||
|
||||
if ((token_tag == PGF_TOKEN_IDENT &&
|
||||
(lookahead(',') ||
|
||||
@@ -1053,11 +1093,13 @@ PgfTypeHypo *PgfExprParser::parse_context(size_t *p_n_hypos)
|
||||
(token_tag == PGF_TOKEN_LCURLY) ||
|
||||
(token_tag == PGF_TOKEN_WILD)) {
|
||||
|
||||
if (!parse_hypos(&n_hypos, &hypos))
|
||||
if (!parse_hypos(&n_hypos, &hypos, &new_bs))
|
||||
goto exit;
|
||||
|
||||
if (token_tag != PGF_TOKEN_COLON)
|
||||
if (token_tag != PGF_TOKEN_COLON) {
|
||||
bs = new_bs; // to be recycled
|
||||
goto exit;
|
||||
}
|
||||
|
||||
token();
|
||||
} else {
|
||||
@@ -1072,6 +1114,7 @@ PgfTypeHypo *PgfExprParser::parse_context(size_t *p_n_hypos)
|
||||
size_t n_end = n_hypos;
|
||||
|
||||
PgfType type = parse_type();
|
||||
bs = new_bs;
|
||||
if (type == 0)
|
||||
goto exit;
|
||||
|
||||
@@ -1098,6 +1141,7 @@ PgfTypeHypo *PgfExprParser::parse_context(size_t *p_n_hypos)
|
||||
}
|
||||
|
||||
exit:
|
||||
pop_binds(last);
|
||||
*p_n_hypos = n_hypos;
|
||||
return hypos;
|
||||
}
|
||||
|
||||
@@ -164,6 +164,7 @@ class PGF_INTERNAL_DECL PgfExprParser {
|
||||
PgfText *inp;
|
||||
const char *token_pos, *pos;
|
||||
uint32_t ch;
|
||||
PgfBind *bs;
|
||||
|
||||
bool getc();
|
||||
void putc(uint32_t ch);
|
||||
@@ -176,14 +177,15 @@ public:
|
||||
void token();
|
||||
bool lookahead(int ch);
|
||||
|
||||
PgfBind *parse_bind(PgfBind *next);
|
||||
PgfBind *parse_binds(PgfBind *next);
|
||||
bool parse_bind();
|
||||
bool parse_binds();
|
||||
void pop_binds(PgfBind *last);
|
||||
|
||||
PgfExpr parse_arg();
|
||||
PgfExpr parse_term();
|
||||
PgfExpr parse_expr();
|
||||
|
||||
bool parse_hypos(size_t *n_hypos, PgfTypeHypo **hypos);
|
||||
bool parse_hypos(size_t *n_hypos, PgfTypeHypo **hypos, PgfBind **pbs);
|
||||
PgfType parse_type();
|
||||
PgfTypeHypo *parse_context(size_t *p_n_hypos);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user