1
0
forked from GitHub/gf-core

readExpr/readType/readContext can now identify local variables

This commit is contained in:
Krasimir Angelov
2022-07-14 15:10:28 +02:00
parent 3ba3f24e3a
commit 9ded2096fd
2 changed files with 89 additions and 43 deletions

View File

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

View File

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