harec

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

commit 05d4c2825e41ad0c7113aa8c39032e4d9d6aa975
parent 725964bae88bcea1307f627f50682fc537af72bb
Author: Drew DeVault <sir@cmpwn.com>
Date:   Tue, 23 Feb 2021 08:50:41 -0500

parse: implement error propagation

Diffstat:
Minclude/ast.h | 5+++++
Minclude/expr.h | 1+
Minclude/lex.h | 1+
Msrc/check.c | 2++
Msrc/eval.c | 1+
Msrc/gen.c | 2++
Msrc/lex.c | 4++++
Msrc/main.c | 2--
Msrc/parse.c | 10++++++++--
9 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/include/ast.h b/include/ast.h @@ -265,6 +265,10 @@ struct ast_expression_measure { }; }; +struct ast_expression_propagate { + struct ast_expression *value; +}; + struct ast_expression_return { struct ast_expression *value; }; @@ -344,6 +348,7 @@ struct ast_expression { struct ast_expression_list list; struct ast_expression_match match; struct ast_expression_measure measure; + struct ast_expression_propagate propagate; struct ast_expression_return _return; struct ast_expression_slice slice; struct ast_expression_struct _struct; diff --git a/include/expr.h b/include/expr.h @@ -28,6 +28,7 @@ enum expr_type { EXPR_LIST, EXPR_MATCH, EXPR_MEASURE, + EXPR_PROPAGATE, EXPR_RETURN, EXPR_SLICE, EXPR_STRUCT, diff --git a/include/lex.h b/include/lex.h @@ -106,6 +106,7 @@ enum lexical_token { T_PLUS, T_PLUSEQ, T_PLUSPLUS, + T_QUESTION, T_RBRACE, T_RBRACKET, T_RPAREN, diff --git a/src/check.c b/src/check.c @@ -2042,6 +2042,8 @@ check_expression(struct context *ctx, case EXPR_MEASURE: check_expr_measure(ctx, aexpr, expr, hint); break; + case EXPR_PROPAGATE: + assert(0); // TODO case EXPR_RETURN: check_expr_return(ctx, aexpr, expr, hint); break; diff --git a/src/eval.c b/src/eval.c @@ -545,6 +545,7 @@ eval_expr(struct context *ctx, struct expression *in, struct expression *out) case EXPR_IF: case EXPR_LIST: case EXPR_MATCH: + case EXPR_PROPAGATE: case EXPR_RETURN: case EXPR_SWITCH: // Excluded from translation-compatible subset diff --git a/src/gen.c b/src/gen.c @@ -2570,6 +2570,8 @@ gen_expression(struct gen_context *ctx, case EXPR_MEASURE: gen_expr_measure(ctx, expr, out); break; + case EXPR_PROPAGATE: + assert(0); // TODO case EXPR_RETURN: gen_expr_return(ctx, expr, out); break; diff --git a/src/lex.c b/src/lex.c @@ -114,6 +114,7 @@ static const char *tokens[] = { [T_PLUS] = "+", [T_PLUSEQ] = "+=", [T_PLUSPLUS] = "++", + [T_QUESTION] = "?", [T_RBRACE] = "}", [T_RBRACKET] = "]", [T_RPAREN] = ")", @@ -897,6 +898,9 @@ _lex(struct lexer *lexer, struct token *out) case ';': out->token = T_SEMICOLON; break; + case '?': + out->token = T_QUESTION; + break; default: out->token = T_ERROR; break; diff --git a/src/main.c b/src/main.c @@ -6,7 +6,6 @@ #include <unistd.h> #include "ast.h" #include "check.h" -#include "dump.h" #include "emit.h" #include "gen.h" #include "lex.h" @@ -140,7 +139,6 @@ main(int argc, char *argv[]) builtin_types_init(); check(&ts, tags, &aunit, &unit); if (stage == STAGE_CHECK) { - dump_unit(&unit); return 0; } diff --git a/src/parse.c b/src/parse.c @@ -1386,6 +1386,7 @@ parse_postfix_expression(struct lexer *lexer, struct ast_expression *lvalue) lvalue = parse_plain_expression(lexer); } + struct ast_expression *exp; switch (lex(lexer, &tok)) { case T_LPAREN: unlex(lexer, &tok); @@ -1393,8 +1394,7 @@ parse_postfix_expression(struct lexer *lexer, struct ast_expression *lvalue) break; case T_DOT: trenter(TR_PARSE, "field-access"); - struct ast_expression *exp = - mkexpr(&lexer->loc); + exp = mkexpr(&lexer->loc); exp->type = EXPR_ACCESS; switch (lex(lexer, &tok)) { @@ -1420,6 +1420,12 @@ parse_postfix_expression(struct lexer *lexer, struct ast_expression *lvalue) unlex(lexer, &tok); lvalue = parse_index_slice_expression(lexer, lvalue); break; + case T_QUESTION: + exp = mkexpr(&lexer->loc); + exp->type = EXPR_PROPAGATE; + exp->propagate.value = lvalue; + lvalue = exp; + break; default: unlex(lexer, &tok); return lvalue;