commit cee199ce90d574664b349d82c7abd8b97e9e4b2c
parent 0f8aea205dcc546002d9c30d5119c590b7045db0
Author: Drew DeVault <sir@cmpwn.com>
Date: Fri, 23 Apr 2021 08:12:21 -0400
parse: implement static slice mutations
Signed-off By: Drew DeVault <sir@cmpwn.com>
Diffstat:
3 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/include/ast.h b/include/ast.h
@@ -143,6 +143,7 @@ struct ast_expression_append {
struct ast_expression *expr;
struct ast_expression *variadic;
struct ast_append_values *values;
+ bool is_static;
};
struct ast_expression_assert {
@@ -220,6 +221,7 @@ struct ast_expression_defer {
struct ast_expression_delete {
struct ast_expression *expr;
+ bool is_static;
};
struct ast_expression_for {
@@ -244,6 +246,7 @@ struct ast_expression_insert {
struct ast_expression *expr;
struct ast_expression *variadic;
struct ast_append_values *values;
+ bool is_static;
};
struct ast_expression_list {
diff --git a/src/check.c b/src/check.c
@@ -331,6 +331,7 @@ check_expr_append(struct context *ctx,
struct errors *errors)
{
assert(aexpr->type == EXPR_APPEND);
+ assert(!aexpr->append.is_static); // TODO
expr->type = EXPR_APPEND;
expr->result = &builtin_type_void;
expr->append.expr = xcalloc(sizeof(struct expression), 1);
@@ -1365,6 +1366,7 @@ check_expr_delete(struct context *ctx,
struct errors *errors)
{
expr->type = EXPR_DELETE;
+ assert(!aexpr->delete.is_static); // TODO
expr->result = &builtin_type_void;
struct expression *dexpr = expr->delete.expr =
xcalloc(1, sizeof(struct expression));
diff --git a/src/parse.c b/src/parse.c
@@ -1261,7 +1261,7 @@ parse_allocation_expression(struct lexer *lexer)
}
static struct ast_expression *
-parse_slice_mutation(struct lexer *lexer)
+parse_slice_mutation(struct lexer *lexer, bool is_static)
{
struct ast_expression *exp = NULL;
struct token tok = {0};
@@ -1278,10 +1278,12 @@ parse_slice_mutation(struct lexer *lexer)
switch (exp->type) {
case EXPR_APPEND:
exp->append.expr = parse_expression(lexer);
+ exp->append.is_static = is_static;
next = &exp->append.values;
break;
case EXPR_INSERT:
exp->insert.expr = parse_expression(lexer);
+ exp->insert.is_static = is_static;
next = &exp->insert.values;
break;
default:
@@ -1324,6 +1326,7 @@ parse_slice_mutation(struct lexer *lexer)
exp->type = EXPR_DELETE;
want(lexer, T_LPAREN, NULL);
exp->delete.expr = parse_expression(lexer);
+ exp->delete.is_static = is_static;
want(lexer, T_RPAREN, NULL);
break;
default:
@@ -1432,16 +1435,27 @@ parse_builtin_expression(struct lexer *lexer)
case T_DELETE:
case T_INSERT:
unlex(lexer, &tok);
- return parse_slice_mutation(lexer);
- case T_ABORT:
- case T_ASSERT:
+ return parse_slice_mutation(lexer, false);
case T_STATIC:
- if (tok.token == T_STATIC) {
+ switch (lex(lexer, &tok)) {
+ case T_ABORT:
+ case T_ASSERT:
+ unlex(lexer, &tok);
return parse_assertion_expression(lexer, true);
- } else {
+ case T_APPEND:
+ case T_DELETE:
+ case T_INSERT:
unlex(lexer, &tok);
- return parse_assertion_expression(lexer, false);
- }
+ return parse_slice_mutation(lexer, true);
+ default:
+ synassert(false, &tok, T_ABORT, T_ASSERT,
+ T_APPEND, T_DELETE, T_INSERT, T_EOF);
+ };
+ break;
+ case T_ABORT:
+ case T_ASSERT:
+ unlex(lexer, &tok);
+ return parse_assertion_expression(lexer, false);
case T_SIZE:
case T_LEN:
case T_OFFSET:
@@ -2060,6 +2074,11 @@ parse_expression(struct lexer *lexer)
case T_ASSERT:
unlex(lexer, &tok);
return parse_assertion_expression(lexer, true);
+ case T_APPEND:
+ case T_INSERT:
+ case T_DELETE:
+ unlex(lexer, &tok);
+ return parse_slice_mutation(lexer, true);
default:
synassert(false, &tok, T_LET, T_CONST, T_ABORT, T_ASSERT, T_EOF);
}