HelenOS sources
This source file includes following definitions.
- parse_texpr
- parse_tapply
- parse_tpostfix
- parse_pf_taccess
- parse_pf_tindex
- parse_tparen
- parse_tprimitive
- parse_tliteral
- parse_tnameref
- parse_recovery_texpr
#include <assert.h>
#include <stdlib.h>
#include "cspan.h"
#include "debug.h"
#include "lex.h"
#include "list.h"
#include "mytypes.h"
#include "parse.h"
#include "p_expr.h"
#include "stree.h"
#include "p_type.h"
static stree_texpr_t *parse_tapply(parse_t *parse);
static stree_texpr_t *parse_tpostfix(parse_t *parse);
static stree_texpr_t *parse_pf_taccess(parse_t *parse, stree_texpr_t *a);
static stree_texpr_t *parse_pf_tindex(parse_t *parse, stree_texpr_t *a);
static stree_texpr_t *parse_tparen(parse_t *parse);
static stree_texpr_t *parse_tprimitive(parse_t *parse);
static stree_texpr_t *parse_tliteral(parse_t *parse);
static stree_texpr_t *parse_tnameref(parse_t *parse);
static stree_texpr_t *parse_recovery_texpr(parse_t *parse);
stree_texpr_t *parse_texpr(parse_t *parse)
{
#ifdef DEBUG_PARSE_TRACE
printf("Parse type expression.\n");
#endif
if (parse_is_error(parse))
return parse_recovery_texpr(parse);
return parse_tapply(parse);
}
static stree_texpr_t *parse_tapply(parse_t *parse)
{
stree_texpr_t *gtype;
stree_texpr_t *aexpr;
stree_texpr_t *targ;
stree_tapply_t *tapply;
gtype = parse_tpostfix(parse);
if (lcur_lc(parse) != lc_slash)
return gtype;
tapply = stree_tapply_new();
tapply->gtype = gtype;
list_init(&tapply->targs);
targ = NULL;
while (lcur_lc(parse) == lc_slash) {
if (parse_is_error(parse))
break;
lskip(parse);
targ = parse_tpostfix(parse);
list_append(&tapply->targs, targ);
}
aexpr = stree_texpr_new(tc_tapply);
aexpr->u.tapply = tapply;
tapply->texpr = aexpr;
if (targ != NULL)
aexpr->cspan = cspan_merge(gtype->cspan, targ->cspan);
else
aexpr->cspan = gtype->cspan;
return aexpr;
}
static stree_texpr_t *parse_tpostfix(parse_t *parse)
{
stree_texpr_t *a;
stree_texpr_t *tmp;
a = parse_tparen(parse);
while (lcur_lc(parse) == lc_period || lcur_lc(parse) == lc_lsbr) {
if (parse_is_error(parse))
break;
switch (lcur_lc(parse)) {
case lc_period:
tmp = parse_pf_taccess(parse, a);
break;
case lc_lsbr:
tmp = parse_pf_tindex(parse, a);
break;
default:
lunexpected_error(parse);
tmp = parse_recovery_texpr(parse);
break;
}
a = tmp;
}
return a;
}
static stree_texpr_t *parse_pf_taccess(parse_t *parse, stree_texpr_t *a)
{
stree_texpr_t *texpr;
stree_ident_t *ident;
stree_taccess_t *taccess;
lmatch(parse, lc_period);
ident = parse_ident(parse);
taccess = stree_taccess_new();
taccess->arg = a;
taccess->member_name = ident;
texpr = stree_texpr_new(tc_taccess);
texpr->u.taccess = taccess;
taccess->texpr = texpr;
texpr->cspan = cspan_merge(a->cspan, ident->cspan);
return texpr;
}
static stree_texpr_t *parse_pf_tindex(parse_t *parse, stree_texpr_t *a)
{
stree_texpr_t *texpr;
stree_tindex_t *tindex;
stree_expr_t *expr;
cspan_t *cs1;
tindex = stree_tindex_new();
tindex->base_type = a;
tindex->n_args = 0;
list_init(&tindex->args);
lmatch(parse, lc_lsbr);
if (lcur_lc(parse) != lc_rsbr && lcur_lc(parse) != lc_comma) {
while (b_true) {
if (parse_is_error(parse))
break;
expr = parse_expr(parse);
tindex->n_args += 1;
list_append(&tindex->args, expr);
if (lcur_lc(parse) == lc_rsbr)
break;
lmatch(parse, lc_comma);
}
} else {
tindex->n_args = 1;
while (lcur_lc(parse) == lc_comma) {
if (parse_is_error(parse))
break;
lskip(parse);
tindex->n_args += 1;
}
}
lmatch(parse, lc_rsbr);
cs1 = lprev_span(parse);
texpr = stree_texpr_new(tc_tindex);
texpr->u.tindex = tindex;
tindex->texpr = texpr;
texpr->cspan = cspan_merge(a->cspan, cs1);
return texpr;
}
static stree_texpr_t *parse_tparen(parse_t *parse)
{
stree_texpr_t *texpr;
cspan_t *cs0, *cs1;
if (lcur_lc(parse) == lc_lparen) {
cs0 = lcur_span(parse);
lskip(parse);
texpr = parse_texpr(parse);
lmatch(parse, lc_rparen);
cs1 = lprev_span(parse);
texpr->cspan = cspan_merge(cs0, cs1);
} else {
texpr = parse_tprimitive(parse);
}
return texpr;
}
static stree_texpr_t *parse_tprimitive(parse_t *parse)
{
stree_texpr_t *texpr;
switch (lcur_lc(parse)) {
case lc_ident:
texpr = parse_tnameref(parse);
break;
case lc_bool:
case lc_char:
case lc_int:
case lc_string:
case lc_resource:
texpr = parse_tliteral(parse);
break;
default:
lunexpected_error(parse);
texpr = parse_recovery_texpr(parse);
break;
}
return texpr;
}
static stree_texpr_t *parse_tliteral(parse_t *parse)
{
stree_tliteral_t *tliteral;
tliteral_class_t tlc;
stree_texpr_t *texpr;
switch (lcur_lc(parse)) {
case lc_bool:
tlc = tlc_bool;
break;
case lc_char:
tlc = tlc_char;
break;
case lc_int:
tlc = tlc_int;
break;
case lc_string:
tlc = tlc_string;
break;
case lc_resource:
tlc = tlc_resource;
break;
default:
assert(b_false);
}
lskip(parse);
tliteral = stree_tliteral_new(tlc);
texpr = stree_texpr_new(tc_tliteral);
texpr->u.tliteral = tliteral;
tliteral->texpr = texpr;
texpr->cspan = lprev_span(parse);
return texpr;
}
static stree_texpr_t *parse_tnameref(parse_t *parse)
{
stree_tnameref_t *tnameref;
stree_texpr_t *texpr;
tnameref = stree_tnameref_new();
tnameref->name = parse_ident(parse);
texpr = stree_texpr_new(tc_tnameref);
texpr->u.tnameref = tnameref;
tnameref->texpr = texpr;
texpr->cspan = tnameref->name->cspan;
return texpr;
}
static stree_texpr_t *parse_recovery_texpr(parse_t *parse)
{
stree_tliteral_t *tliteral;
stree_texpr_t *texpr;
(void) parse;
tliteral = stree_tliteral_new(tlc_int);
texpr = stree_texpr_new(tc_tliteral);
texpr->u.tliteral = tliteral;
tliteral->texpr = texpr;
return texpr;
}
HelenOS homepage, sources at GitHub