harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 1c2d30ac9180186a1853609d31a036f9c770c875
parent 6a318a2529db284b56aeaad5beb5643fa23c7acf
Author: Drew DeVault <sir@cmpwn.com>
Date:   Thu, 24 Dec 2020 11:01:27 -0500

parse: parse measurement expressions

Diffstat:
Minclude/ast.h | 10++++++++++
Minclude/expr.h | 15+++++++++++++++
Msrc/check.c | 1+
Msrc/parse.c | 38+++++++++++++++++++++++++++++++++++++-
4 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/include/ast.h b/include/ast.h @@ -126,6 +126,15 @@ struct ast_expression_list { struct ast_expression_list *next; }; +struct ast_expression_measure { + enum measure_operator op; + union { + struct ast_expression *value; + struct ast_type *type; + // TODO: Field selection + }; +}; + struct ast_expression_return { struct ast_expression *value; }; @@ -144,6 +153,7 @@ struct ast_expression { struct ast_expression_binding binding; struct ast_expression_constant constant; struct ast_expression_list list; + struct ast_expression_measure measure; struct ast_expression_return _return; struct ast_expression_unarithm unarithm; }; diff --git a/include/expr.h b/include/expr.h @@ -105,6 +105,21 @@ struct expression_list { struct expressions exprs; }; +enum measure_operator { + M_LEN, + M_SIZE, + M_OFFSET, +}; + +struct expression_measure { + enum measure_operator op; + union { + struct expression *value; + const struct type *type; + // TODO: Field selection + }; +}; + struct expression_return { struct expression *value; }; diff --git a/src/check.c b/src/check.c @@ -369,6 +369,7 @@ check_expression(struct context *ctx, break; case EXPR_MATCH: case EXPR_MEASURE: + assert(0); // TODO case EXPR_RETURN: check_expr_return(ctx, aexpr, expr); break; diff --git a/src/parse.c b/src/parse.c @@ -491,6 +491,41 @@ parse_plain_expression(struct parser *par) assert(0); // Unreachable } +static struct ast_expression *parse_postfix_expression(struct parser *par); + +static struct ast_expression * +parse_measurement_expression(struct parser *par) +{ + trace(TR_PARSE, "measurement"); + + struct ast_expression *exp = calloc(1, sizeof(struct ast_expression)); + exp->type = EXPR_MEASURE; + + struct token tok; + lex(par->lex, &tok); + + want(par, T_LPAREN, NULL); + switch (tok.token) { + case T_SIZE: + exp->measure.op = M_SIZE; + exp->measure.type = calloc(1, sizeof(struct ast_type)); + parse_type(par, exp->measure.type); + break; + case T_LEN: + exp->measure.op = M_LEN; + exp->measure.value = parse_postfix_expression(par); + break; + case T_OFFSET: + exp->measure.op = M_OFFSET; + assert(0); // TODO + default: + synassert(false, &tok, T_SIZE, T_LEN, T_OFFSET, T_EOF); + } + + want(par, T_RPAREN, NULL); + return exp; +} + static struct ast_expression * parse_postfix_expression(struct parser *par) { @@ -506,7 +541,8 @@ parse_postfix_expression(struct parser *par) case T_SIZE: case T_LEN: case T_OFFSET: - assert(0); // TODO: measurement expression + unlex(par->lex, &tok); + return parse_measurement_expression(par); case T_LPAREN: lvalue = parse_complex_expression(par); want(par, T_LPAREN, &tok);