harec

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

commit 5a58ba55c2b8e8119ffd28f1c6af348e6bad85d9
parent cba5917f5dd3cfc7336db55f3150fb1a5baa6e0e
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Mon, 11 Jan 2021 11:26:56 -0500

parse: implement allocation expressions

Diffstat:
Minclude/ast.h | 23+++++++++++++++++++++++
Msrc/parse.c | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 98 insertions(+), 0 deletions(-)

diff --git a/include/ast.h b/include/ast.h @@ -116,6 +116,28 @@ struct ast_expression_access { }; }; +enum alloc_kind { + ALLOC_KIND_ALLOC, + ALLOC_KIND_APPEND, + ALLOC_KIND_FREE, +}; + +struct ast_append_values { + struct ast_expression *value; + struct ast_append_values *next; +}; + +struct ast_expression_allocation { + enum alloc_kind kind; + struct ast_expression *expr; + // For allocs only + struct ast_type *type; + // For appends only + bool variadic; + struct ast_append_values *values; + struct ast_expression *cap; +}; + struct ast_expression_assert { struct ast_expression *cond; struct ast_expression *message; @@ -245,6 +267,7 @@ struct ast_expression { enum expr_type type; union { struct ast_expression_access access; + struct ast_expression_allocation alloc; struct ast_expression_assert assert; struct ast_expression_assign assign; struct ast_expression_binarithm binarithm; diff --git a/src/parse.c b/src/parse.c @@ -1120,6 +1120,72 @@ parse_index_slice_expression(struct lexer *lexer, struct ast_expression *lvalue) } static struct ast_expression * +parse_allocation_expression(struct lexer *lexer) +{ + trenter(TR_PARSE, "allocation"); + struct ast_expression *exp = xcalloc(1, sizeof(struct ast_expression)); + struct token tok = {0}; + switch (lex(lexer, &tok)) { + case T_ALLOC: + trace(TR_PARSE, "alloc"); + exp->alloc.kind = ALLOC_KIND_ALLOC; + want(lexer, T_LPAREN, NULL); + exp->alloc.type = parse_type(lexer); + want(lexer, T_COMMA, NULL); + exp->alloc.expr = parse_simple_expression(lexer); + switch (lex(lexer, &tok)) { + case T_COMMA: + exp->alloc.cap = parse_simple_expression(lexer); + want(lexer, T_RPAREN, NULL); + break; + case T_RPAREN: + break; + default: + synassert(false, &tok, T_COMMA, T_RPAREN, T_EOF); + } + break; + case T_APPEND: + trace(TR_PARSE, "append"); + exp->alloc.kind = ALLOC_KIND_APPEND; + want(lexer, T_LPAREN, NULL); + exp->alloc.expr = parse_simple_expression(lexer); + want(lexer, T_COMMA, NULL); + struct ast_append_values **next = &exp->alloc.values; + while (tok.token != T_RPAREN) { + *next = xcalloc(1, sizeof(struct ast_append_values)); + if (lex(lexer, &tok) == T_ELLIPSIS) { + exp->alloc.variadic = true; + (*next)->value = parse_simple_expression(lexer); + if (lex(lexer, &tok) != T_COMMA) { + unlex(lexer, &tok); + } + want(lexer, T_RPAREN, &tok); + break; + } + unlex(lexer, &tok); + (*next)->value = parse_simple_expression(lexer); + if (lex(lexer, &tok) != T_COMMA) { + unlex(lexer, &tok); + want(lexer, T_RPAREN, &tok); + } + next = &(*next)->next; + } + break; + case T_FREE: + trace(TR_PARSE, "free"); + exp->alloc.kind = ALLOC_KIND_FREE; + want(lexer, T_LPAREN, NULL); + exp->alloc.expr = parse_simple_expression(lexer); + want(lexer, T_RPAREN, NULL); + break; + default: + assert(0); + } + trleave(TR_PARSE, NULL); + return exp; +} + +static struct ast_expression * parse_postfix_expression(struct lexer *lexer, struct ast_expression *lvalue) { trace(TR_PARSE, "postfix"); @@ -1128,9 +1194,18 @@ parse_postfix_expression(struct lexer *lexer, struct ast_expression *lvalue) // postfix-expression in the specification struct token tok; switch (lex(lexer, &tok)) { + case T_ALLOC: + case T_APPEND: + case T_FREE: + synassert(lvalue == NULL, &tok, T_LPAREN, T_DOT, T_LBRACKET, + T_EOF); + unlex(lexer, &tok); + return parse_allocation_expression(lexer); case T_ABORT: case T_ASSERT: case T_STATIC: + synassert(lvalue == NULL, &tok, T_LPAREN, T_DOT, T_LBRACKET, + T_EOF); unlex(lexer, &tok); return parse_assertion_expression(lexer); case T_SIZE: