mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-20 01:48:21 +00:00
Fix enumeration constant expressions; Remove empty file error
This commit is contained in:
@@ -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);
|
||||
|
||||
12
src/parser.c
12
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;
|
||||
|
||||
Reference in New Issue
Block a user