commit 1c2d30ac9180186a1853609d31a036f9c770c875
parent 6a318a2529db284b56aeaad5beb5643fa23c7acf
Author: Drew DeVault <sir@cmpwn.com>
Date: Thu, 24 Dec 2020 11:01:27 -0500
parse: parse measurement expressions
Diffstat:
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);