From d9bd770992d85f07b86ce6366154c691b5c07347 Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Tue, 6 Dec 2016 14:06:31 +0000 Subject: [PATCH] Fix enumeration constant expressions; Remove empty file error --- src/checker/expr.c | 18 ++++++++++-------- src/parser.c | 12 +++++++++--- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/checker/expr.c b/src/checker/expr.c index d0414e2fc..5cb448eb1 100644 --- a/src/checker/expr.c +++ b/src/checker/expr.c @@ -850,7 +850,7 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod if (f->value != NULL) { check_expr(c, &o, f->value); if (o.mode != Addressing_Constant) { - error_node(f->value, "Enumeration value must be a constant integer"); + error_node(f->value, "Enumeration value must be a constant integer %d"); o.mode = Addressing_Invalid; } if (o.mode != Addressing_Invalid) { @@ -1337,7 +1337,7 @@ end: bool check_unary_op(Checker *c, Operand *o, Token op) { // TODO(bill): Handle errors correctly - Type *type = base_type(base_vector_type(o->type)); + Type *type = base_type(get_enum_base_type(base_vector_type(o->type))); gbString str = NULL; switch (op.kind) { case Token_Add: @@ -1373,7 +1373,7 @@ bool check_unary_op(Checker *c, Operand *o, Token op) { bool check_binary_op(Checker *c, Operand *o, Token op) { // TODO(bill): Handle errors correctly - Type *type = base_type(base_vector_type(o->type)); + Type *type = base_type(get_enum_base_type(base_vector_type(o->type))); switch (op.kind) { case Token_Sub: case Token_SubEq: @@ -1450,6 +1450,8 @@ bool check_value_is_expressible(Checker *c, ExactValue in_value, Type *type, Exa return true; } + type = get_enum_base_type(type); + if (is_type_boolean(type)) { return in_value.kind == ExactValue_Bool; } else if (is_type_string(type)) { @@ -1527,13 +1529,13 @@ bool check_value_is_expressible(Checker *c, ExactValue in_value, Type *type, Exa } void check_is_expressible(Checker *c, Operand *o, Type *type) { - GB_ASSERT(type->kind == Type_Basic); + GB_ASSERT(is_type_constant_type(type)); GB_ASSERT(o->mode == Addressing_Constant); if (!check_value_is_expressible(c, o->value, type, &o->value)) { gbString a = expr_to_string(o->expr); gbString b = type_to_string(type); - if (is_type_numeric(o->type) && is_type_numeric(type)) { - if (!is_type_integer(o->type) && is_type_integer(type)) { + if (is_type_numeric(get_enum_base_type(o->type)) && is_type_numeric(get_enum_base_type(type))) { + if (!is_type_integer(get_enum_base_type(o->type)) && is_type_integer(get_enum_base_type(type))) { error_node(o->expr, "`%s` truncated to `%s`", a, b); } else { error_node(o->expr, "`%s = %lld` overflows `%s`", a, o->value.value_integer, b); @@ -1624,7 +1626,7 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) { if (o->mode == Addressing_Constant) { Type *type = base_type(o->type); - if (type->kind != Type_Basic) { + if (!is_type_constant_type(o->type)) { gbString xt = type_to_string(o->type); gbString err_str = expr_to_string(node); error(op, "Invalid type, `%s`, for constant unary expression `%s`", xt, err_str); @@ -2296,7 +2298,7 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) { return; } - if (type->kind != Type_Basic) { + if (!is_type_constant_type(type)) { gbString xt = type_to_string(x->type); gbString err_str = expr_to_string(node); error(op, "Invalid type, `%s`, for constant binary expression `%s`", xt, err_str); diff --git a/src/parser.c b/src/parser.c index b0b2fe4a3..6514e0b20 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1176,6 +1176,11 @@ Token expect_closing(AstFile *f, TokenKind kind, String context) { } void expect_semicolon(AstFile *f, AstNode *s) { + if (f->prev_token.kind == Token_CloseBrace || + f->prev_token.kind == Token_CloseBrace) { + return; + } + if (f->curr_token.kind != Token_CloseParen && f->curr_token.kind != Token_CloseBrace) { switch (f->curr_token.kind) { @@ -3267,6 +3272,10 @@ ParseFileError parse_files(Parser *p, char *init_filename) { ParseFileError err = init_ast_file(&file, import_path); if (err != ParseFile_None) { + if (err == ParseFile_EmptyFile) { + return ParseFile_None; + } + if (pos.line != 0) { gb_printf_err("%.*s(%td:%td) ", LIT(pos.file), pos.line, pos.column); } @@ -3278,9 +3287,6 @@ ParseFileError parse_files(Parser *p, char *init_filename) { case ParseFile_InvalidFile: gb_printf_err("Invalid file"); break; - case ParseFile_EmptyFile: - gb_printf_err("File is empty"); - break; case ParseFile_Permission: gb_printf_err("File permissions problem"); break;