harec

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

commit e81307e4dc2f4eea650499cdc6a635c0b04aaf54
parent 064f0240f37e483ff6d1019b1172930953142814
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sun, 20 Dec 2020 15:18:45 -0500

parse: parse control-statement

Diffstat:
Minclude/ast.h | 5+++++
Minclude/expr.h | 4+++-
Msrc/check.c | 4+++-
Msrc/gen.c | 4+++-
Msrc/parse.c | 49+++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/include/ast.h b/include/ast.h @@ -102,11 +102,16 @@ struct ast_expression_list { struct ast_expression_list *next; }; +struct ast_return_expression { + struct ast_expression *value; +}; + struct ast_expression { enum expr_type type; union { struct ast_constant_expression constant; struct ast_expression_list list; + struct ast_return_expression _return; }; }; diff --git a/include/expr.h b/include/expr.h @@ -9,10 +9,11 @@ enum expr_type { EXPR_ASSIGN, EXPR_BINARITHM, EXPR_BINDING_LIST, + EXPR_BREAK, EXPR_CALL, EXPR_CAST, EXPR_CONSTANT, - EXPR_CONTROL, + EXPR_CONTINUE, EXPR_FOR, EXPR_FREE, EXPR_FUNC, @@ -21,6 +22,7 @@ enum expr_type { EXPR_LIST, EXPR_MATCH, EXPR_MEASURE, + EXPR_RETURN, EXPR_SLICE, EXPR_STRUCT, EXPR_SWITCH, diff --git a/src/check.c b/src/check.c @@ -119,13 +119,14 @@ check_expression(struct context *ctx, case EXPR_ASSIGN: case EXPR_BINARITHM: case EXPR_BINDING_LIST: + case EXPR_BREAK: case EXPR_CALL: case EXPR_CAST: assert(0); // TODO case EXPR_CONSTANT: check_expr_constant(ctx, aexpr, expr); break; - case EXPR_CONTROL: + case EXPR_CONTINUE: case EXPR_FOR: case EXPR_FREE: case EXPR_FUNC: @@ -137,6 +138,7 @@ check_expression(struct context *ctx, break; case EXPR_MATCH: case EXPR_MEASURE: + case EXPR_RETURN: case EXPR_SLICE: case EXPR_STRUCT: case EXPR_SWITCH: diff --git a/src/gen.c b/src/gen.c @@ -157,13 +157,14 @@ gen_expression(struct gen_context *ctx, case EXPR_ASSIGN: case EXPR_BINARITHM: case EXPR_BINDING_LIST: + case EXPR_BREAK: case EXPR_CALL: case EXPR_CAST: assert(0); // TODO case EXPR_CONSTANT: gen_constant(ctx, expr, out); break; - case EXPR_CONTROL: + case EXPR_CONTINUE: case EXPR_FOR: case EXPR_FREE: case EXPR_FUNC: @@ -175,6 +176,7 @@ gen_expression(struct gen_context *ctx, break; case EXPR_MATCH: case EXPR_MEASURE: + case EXPR_RETURN: case EXPR_SLICE: case EXPR_STRUCT: case EXPR_SWITCH: diff --git a/src/parse.c b/src/parse.c @@ -394,6 +394,40 @@ parse_scope_expression(struct parser *par, struct ast_expression *exp) } static void +parse_control_statement(struct parser *par, struct ast_expression *exp) +{ + trenter(TR_PARSE, "control-expression"); + + struct token tok; + switch (lex(par->lex, &tok)) { + case T_BREAK: + case T_CONTINUE: + assert(0); // TODO + case T_RETURN: + trace(TR_PARSE, "return"); + exp->type = EXPR_RETURN; + exp->_return.value = NULL; + struct token tok; + switch (lex(par->lex, &tok)) { + case T_SEMICOLON: + unlex(par->lex, &tok); + break; + default: + unlex(par->lex, &tok); + exp->_return.value = + calloc(1, sizeof(struct ast_expression)); + parse_complex_expression(par, exp->_return.value); + break; + } + break; + default: + synassert(false, &tok, T_BREAK, T_CONTINUE, T_RETURN, T_EOF); + } + + trleave(TR_PARSE, NULL); +} + +static void parse_expression_list(struct parser *par, struct ast_expression *exp) { trenter(TR_PARSE, "expression-list"); @@ -417,6 +451,21 @@ parse_expression_list(struct parser *par, struct ast_expression *exp) case T_RBRACE: more = false; break; + case T_BREAK: + case T_CONTINUE: + case T_RETURN: + unlex(par->lex, &tok); + *next = calloc(1, sizeof(struct ast_expression_list)); + cur = *next; + + curexp = calloc(1, sizeof(struct ast_expression)); + parse_control_statement(par, curexp); + cur->expr = curexp; + + want(par, T_SEMICOLON, &tok); + want(par, T_RBRACE, &tok); + more = false; + break; default: *next = calloc(1, sizeof(struct ast_expression_list)); cur = *next;