commit 05d4c2825e41ad0c7113aa8c39032e4d9d6aa975
parent 725964bae88bcea1307f627f50682fc537af72bb
Author: Drew DeVault <sir@cmpwn.com>
Date: Tue, 23 Feb 2021 08:50:41 -0500
parse: implement error propagation
Diffstat:
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;