harec

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

commit 56853be54d30eded69604d2d6efd3cefd6e1e805
parent dcce8b33f57727f8b29dce99a5bf0785b20cb99e
Author: Drew DeVault <sir@cmpwn.com>
Date:   Wed, 23 Dec 2020 13:24:50 -0500

check: initial support for assignments

Diffstat:
Minclude/ast.h | 2+-
Minclude/expr.h | 6++++++
Msrc/check.c | 27++++++++++++++++++++++++++-
Msrc/parse.c | 8++++----
4 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/include/ast.h b/include/ast.h @@ -91,7 +91,7 @@ struct ast_expression_access { }; struct ast_expression_assign { - struct ast_expression *lvalue, *rvalue; + struct ast_expression *object, *value; bool indirect; }; diff --git a/include/expr.h b/include/expr.h @@ -44,6 +44,11 @@ struct expression_access { // TODO: Details for index, field selection }; +struct expression_assign { + struct expression *object, *value; + bool indirect; +}; + enum binarithm_operator { BIN_BAND, BIN_BNOT, @@ -112,6 +117,7 @@ struct expression { bool terminates; union { struct expression_access access; + struct expression_assign assign; struct expression_binarithm binarithm; struct expression_binding binding; union expression_constant constant; diff --git a/src/check.c b/src/check.c @@ -53,6 +53,29 @@ check_expr_access(struct context *ctx, } static void +check_expr_assign(struct context *ctx, + const struct ast_expression *aexpr, + struct expression *expr) +{ + trace(TR_CHECK, "assign"); + expr->type = EXPR_ASSIGN; + expr->assign.indirect = aexpr->assign.indirect; + expr->assign.object = calloc(1, sizeof(struct expression)); + expr->assign.value = calloc(1, sizeof(struct expression)); + + check_expression(ctx, aexpr->assign.object, expr->assign.object); + check_expression(ctx, aexpr->assign.value, expr->assign.value); + + if (aexpr->assign.indirect) { + assert(0); // TODO + } else { + assert(expr->assign.object->type == EXPR_ACCESS); // Invariant + // TODO: Test assignability rules: + assert(expr->assign.object->result->storage == expr->assign.value->result->storage); + } +} + +static void check_expr_binarithm(struct context *ctx, const struct ast_expression *aexpr, struct expression *expr) @@ -262,8 +285,10 @@ check_expression(struct context *ctx, check_expr_access(ctx, aexpr, expr); break; case EXPR_ASSERT: - case EXPR_ASSIGN: assert(0); // TODO + case EXPR_ASSIGN: + check_expr_assign(ctx, aexpr, expr); + break; case EXPR_BINARITHM: check_expr_binarithm(ctx, aexpr, expr); break; diff --git a/src/parse.c b/src/parse.c @@ -778,14 +778,14 @@ parse_binding_list(struct parser *par) } static struct ast_expression * -parse_assignment(struct parser *par, struct ast_expression *lvalue, bool indirect) +parse_assignment(struct parser *par, struct ast_expression *object, bool indirect) { trenter(TR_PARSE, "assign"); - struct ast_expression *rvalue = parse_complex_expression(par); + struct ast_expression *value = parse_complex_expression(par); struct ast_expression *expr = calloc(1, sizeof(struct ast_expression)); expr->type = EXPR_ASSIGN; - expr->assign.lvalue = lvalue; - expr->assign.rvalue = rvalue; + expr->assign.object = object; + expr->assign.value = value; expr->assign.indirect = indirect; trleave(TR_PARSE, NULL); return expr;