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