From 1df4aa90ce10dca629b8af73e74f884ab2339096 Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Fri, 21 Jul 2017 15:25:58 +0100 Subject: [PATCH] Fix struct parameter bugs --- core/fmt.odin | 38 ++++++++++++-- core/os.odin | 2 +- src/check_expr.cpp | 124 ++++++++++++++++++++++----------------------- src/gb/gb.h | 25 ++++++++- src/parser.cpp | 2 + src/types.cpp | 30 +++++------ 6 files changed, 139 insertions(+), 82 deletions(-) diff --git a/core/fmt.odin b/core/fmt.odin index 3d16e309c..2dd87b28f 100644 --- a/core/fmt.odin +++ b/core/fmt.odin @@ -26,6 +26,7 @@ FmtInfo :: struct { width: int; prec: int; + indent: int; reordered: bool; good_arg_index: bool; @@ -757,8 +758,24 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) { } write_string(fi.buf, info.name); write_byte(fi.buf, '{'); + defer write_byte(fi.buf, '}'); + + hash := fi.hash; defer fi.hash = hash; + indent := fi.indent; defer fi.indent -= 1; + + fi.hash = false; + fi.indent += 1; + + if hash do write_byte(fi.buf, '\n'); + for _, i in b.names { - if i > 0 do write_string(fi.buf, ", "); + if !hash && i > 0 do write_string(fi.buf, ", "); + if hash { + for in 0..fi.indent { + write_byte(fi.buf, '\t'); + } + } + write_string(fi.buf, b.names[i]); write_string(fi.buf, " = "); @@ -768,8 +785,9 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) { data := cast(^u8)v.data + b.offsets[i]; fmt_arg(fi, any{rawptr(data), t}, 'v'); } + + if hash do write_string(fi.buf, ",\n"); } - write_byte(fi.buf, '}'); case: fmt_value(fi, any{v.data, info.base}, verb); @@ -877,8 +895,21 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) { write_byte(fi.buf, '{'); defer write_byte(fi.buf, '}'); + hash := fi.hash; defer fi.hash = hash; + indent := fi.indent; defer fi.indent -= 1; + + fi.hash = false; + fi.indent += 1; + + if hash do write_byte(fi.buf, '\n'); + for _, i in info.names { - if i > 0 do write_string(fi.buf, ", "); + if !hash && i > 0 do write_string(fi.buf, ", "); + if hash { + for in 0..fi.indent { + write_byte(fi.buf, '\t'); + } + } write_string(fi.buf, info.names[i]); write_string(fi.buf, " = "); @@ -889,6 +920,7 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) { data := cast(^u8)v.data + info.offsets[i]; fmt_arg(fi, any{rawptr(data), t}, 'v'); } + if hash do write_string(fi.buf, ",\n"); } case Union: diff --git a/core/os.odin b/core/os.odin index 8f87051ad..798bf299e 100644 --- a/core/os.odin +++ b/core/os.odin @@ -20,7 +20,7 @@ read_entire_file :: proc(name: string) -> (data: []u8, success: bool) { return nil, false; } - if length == 0 { + if length <= 0 { return nil, true; } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 1ee250ed2..fcaf943a7 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -828,15 +828,16 @@ void check_struct_field_decl(Checker *c, AstNode *decl, Array *fields, type = t_invalid; } - if (is_type_empty_union(type)) { - error(vd->names[0], "An empty union cannot be used as a field type in %.*s", LIT(context)); - type = t_invalid; + if (type != nullptr) { + if (is_type_empty_union(type)) { + error(vd->names[0], "An empty union cannot be used as a field type in %.*s", LIT(context)); + type = t_invalid; + } + if (!c->context.allow_polymorphic_types && is_type_polymorphic(base_type(type))) { + error(vd->names[0], "Invalid use of a polymorphic type in %.*s", LIT(context)); + type = t_invalid; + } } - if (!c->context.allow_polymorphic_types && is_type_polymorphic(base_type(type))) { - error(vd->names[0], "Invalid use of a polymorphic type in %.*s", LIT(context)); - type = t_invalid; - } - Array default_values = {}; defer (array_free(&default_values)); @@ -896,7 +897,7 @@ void check_struct_field_decl(Checker *c, AstNode *decl, Array *fields, e->Variable.default_is_undef = true; } else if (b.mode != Addressing_Constant) { error(b.expr, "Default field value must be a constant"); - } else if (is_type_any(e->type)) { + } else if (is_type_any(e->type) || is_type_union(e->type)) { gbString str = type_to_string(e->type); error(b.expr, "A struct field of type `%s` cannot have a default value", str); gb_string_free(str); @@ -905,10 +906,10 @@ void check_struct_field_decl(Checker *c, AstNode *decl, Array *fields, } name_field_index++; - } else { - GB_ASSERT(type != nullptr); } + GB_ASSERT(e->type != nullptr); + GB_ASSERT(is_type_typed(e->type)); if (is_blank_ident(name_token)) { array_add(fields, e); @@ -8191,14 +8192,19 @@ gbString write_struct_fields_to_string(gbString str, Array params) { return str; } -gbString string_append_token(gbString str, Token token) { - if (token.string.len > 0) { - return gb_string_append_length(str, &token.string[0], token.string.len); +gbString string_append_string(gbString str, String string) { + if (string.len > 0) { + return gb_string_append_length(str, &string[0], string.len); } return str; } +gbString string_append_token(gbString str, Token token) { + return string_append_string(str, token.string); +} + + gbString write_expr_to_string(gbString str, AstNode *node) { if (node == nullptr) return str; @@ -8225,8 +8231,8 @@ gbString write_expr_to_string(gbString str, AstNode *node) { case_end; case_ast_node(bd, BasicDirective, node); - str = gb_string_appendc(str, "#"); - str = gb_string_append_length(str, &bd->name[0], bd->name.len); + str = gb_string_append_rune(str, '#'); + str = string_append_string(str, bd->name); case_end; case_ast_node(ud, Undef, node); @@ -8239,19 +8245,17 @@ gbString write_expr_to_string(gbString str, AstNode *node) { case_ast_node(cl, CompoundLit, node); str = write_expr_to_string(str, cl->type); - str = gb_string_appendc(str, "{"); + str = gb_string_append_rune(str, '{'); for_array(i, cl->elems) { - if (i > 0) { - str = gb_string_appendc(str, ", "); - } + if (i > 0) str = gb_string_appendc(str, ", "); str = write_expr_to_string(str, cl->elems[i]); } - str = gb_string_appendc(str, "}"); + str = gb_string_append_rune(str, '}'); case_end; case_ast_node(te, TagExpr, node); - str = gb_string_appendc(str, "#"); + str = gb_string_append_rune(str, '#'); str = string_append_token(str, te->name); str = write_expr_to_string(str, te->expr); case_end; @@ -8263,14 +8267,14 @@ gbString write_expr_to_string(gbString str, AstNode *node) { case_ast_node(de, DerefExpr, node); str = write_expr_to_string(str, de->expr); - str = gb_string_appendc(str, "^"); + str = gb_string_append_rune(str, '^'); case_end; case_ast_node(be, BinaryExpr, node); str = write_expr_to_string(str, be->left); - str = gb_string_appendc(str, " "); + str = gb_string_append_rune(str, ' '); str = string_append_token(str, be->op); - str = gb_string_appendc(str, " "); + str = gb_string_append_rune(str, ' '); str = write_expr_to_string(str, be->right); case_end; @@ -8284,14 +8288,14 @@ gbString write_expr_to_string(gbString str, AstNode *node) { case_ast_node(pe, ParenExpr, node); - str = gb_string_appendc(str, "("); + str = gb_string_append_rune(str, '('); str = write_expr_to_string(str, pe->expr); - str = gb_string_appendc(str, ")"); + str = gb_string_append_rune(str, ')'); case_end; case_ast_node(se, SelectorExpr, node); str = write_expr_to_string(str, se->expr); - str = gb_string_appendc(str, "."); + str = gb_string_append_rune(str, '.'); str = write_expr_to_string(str, se->selector); case_end; @@ -8299,25 +8303,25 @@ gbString write_expr_to_string(gbString str, AstNode *node) { str = write_expr_to_string(str, ta->expr); str = gb_string_appendc(str, ".("); str = write_expr_to_string(str, ta->type); - str = gb_string_appendc(str, ")"); + str = gb_string_append_rune(str, ')'); case_end; case_ast_node(tc, TypeCast, node); str = gb_string_appendc(str, "cast("); str = write_expr_to_string(str, tc->type); - str = gb_string_appendc(str, ")"); + str = gb_string_append_rune(str, ')'); str = write_expr_to_string(str, tc->expr); case_end; case_ast_node(ie, IndexExpr, node); str = write_expr_to_string(str, ie->expr); - str = gb_string_appendc(str, "["); + str = gb_string_append_rune(str, '['); str = write_expr_to_string(str, ie->index); - str = gb_string_appendc(str, "]"); + str = gb_string_append_rune(str, ']'); case_end; case_ast_node(se, SliceExpr, node); str = write_expr_to_string(str, se->expr); - str = gb_string_appendc(str, "["); + str = gb_string_append_rune(str, '['); str = write_expr_to_string(str, se->low); str = gb_string_appendc(str, ".."); str = write_expr_to_string(str, se->high); @@ -8325,11 +8329,11 @@ gbString write_expr_to_string(gbString str, AstNode *node) { str = gb_string_appendc(str, ".."); str = write_expr_to_string(str, se->max); } - str = gb_string_appendc(str, "]"); + str = gb_string_append_rune(str, ']'); case_end; case_ast_node(e, Ellipsis, node); - str = gb_string_appendc(str, ".."); + str = gb_string_appendc(str, "..."); str = write_expr_to_string(str, e->expr); case_end; @@ -8346,21 +8350,21 @@ gbString write_expr_to_string(gbString str, AstNode *node) { case_ast_node(pt, PolyType, node); - str = gb_string_appendc(str, "$"); + str = gb_string_append_rune(str, '$'); str = write_expr_to_string(str, pt->type); if (pt->specialization != nullptr) { - str = gb_string_appendc(str, "/"); + str = gb_string_append_rune(str, '/'); str = write_expr_to_string(str, pt->specialization); } case_end; case_ast_node(pt, PointerType, node); - str = gb_string_appendc(str, "^"); + str = gb_string_append_rune(str, '^'); str = write_expr_to_string(str, pt->type); case_end; case_ast_node(at, ArrayType, node); - str = gb_string_appendc(str, "["); + str = gb_string_append_rune(str, '['); if (at->count != nullptr && at->count->kind == AstNode_UnaryExpr && at->count->UnaryExpr.op.kind == Token_Ellipsis) { @@ -8368,7 +8372,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) { } else { str = write_expr_to_string(str, at->count); } - str = gb_string_appendc(str, "]"); + str = gb_string_append_rune(str, ']'); str = write_expr_to_string(str, at->elem); case_end; @@ -8380,14 +8384,14 @@ gbString write_expr_to_string(gbString str, AstNode *node) { case_ast_node(vt, VectorType, node); str = gb_string_appendc(str, "[vector "); str = write_expr_to_string(str, vt->count); - str = gb_string_appendc(str, "]"); + str = gb_string_append_rune(str, ']'); str = write_expr_to_string(str, vt->elem); case_end; case_ast_node(mt, MapType, node); str = gb_string_appendc(str, "map["); str = write_expr_to_string(str, mt->key); - str = gb_string_appendc(str, "]"); + str = gb_string_append_rune(str, ']'); str = write_expr_to_string(str, mt->value); case_end; @@ -8404,24 +8408,22 @@ gbString write_expr_to_string(gbString str, AstNode *node) { for_array(i, f->names) { AstNode *name = f->names[i]; - if (i > 0) { - str = gb_string_appendc(str, ", "); - } + if (i > 0) str = gb_string_appendc(str, ", "); str = write_expr_to_string(str, name); } if (f->names.count > 0) { if (f->type == nullptr && f->default_value != nullptr) { - str = gb_string_appendc(str, " "); + str = gb_string_append_rune(str, ' '); } str = gb_string_appendc(str, ":"); } if (f->type != nullptr) { - str = gb_string_appendc(str, " "); + str = gb_string_append_rune(str, ' '); str = write_expr_to_string(str, f->type); } if (f->default_value != nullptr) { if (f->type != nullptr) { - str = gb_string_appendc(str, " "); + str = gb_string_append_rune(str, ' '); } str = gb_string_appendc(str, "= "); str = write_expr_to_string(str, f->default_value); @@ -8448,9 +8450,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) { } for_array(i, f->list) { - if (i > 0) { - str = gb_string_appendc(str, ", "); - } + if (i > 0) str = gb_string_appendc(str, ", "); if (has_name) { str = write_expr_to_string(str, f->list[i]); } else { @@ -8473,9 +8473,9 @@ gbString write_expr_to_string(gbString str, AstNode *node) { case_ast_node(f, UnionField, node); str = write_expr_to_string(str, f->name); - str = gb_string_appendc(str, "{"); + str = gb_string_append_rune(str, '{'); str = write_expr_to_string(str, f->list); - str = gb_string_appendc(str, "}"); + str = gb_string_append_rune(str, '}'); case_end; case_ast_node(ce, CallExpr, node); @@ -8516,39 +8516,39 @@ gbString write_expr_to_string(gbString str, AstNode *node) { if (st->is_packed) str = gb_string_appendc(str, "#packed "); if (st->is_ordered) str = gb_string_appendc(str, "#ordered "); if (st->is_raw_union) str = gb_string_appendc(str, "#raw_union "); - str = gb_string_appendc(str, "{"); + str = gb_string_append_rune(str, '{'); str = write_struct_fields_to_string(str, st->fields); - str = gb_string_appendc(str, "}"); + str = gb_string_append_rune(str, '}'); case_end; // case_ast_node(st, RawUnionType, node); // str = gb_string_appendc(str, "raw_union "); - // str = gb_string_appendc(str, "{"); + // str = gb_string_append_rune(str, '{'); // str = write_struct_fields_to_string(str, st->fields); - // str = gb_string_appendc(str, "}"); + // str = gb_string_append_rune(str, '}'); // case_end; case_ast_node(st, UnionType, node); str = gb_string_appendc(str, "union "); - str = gb_string_appendc(str, "{"); + str = gb_string_append_rune(str, '{'); str = write_struct_fields_to_string(str, st->variants); - str = gb_string_appendc(str, "}"); + str = gb_string_append_rune(str, '}'); case_end; case_ast_node(et, EnumType, node); str = gb_string_appendc(str, "enum "); if (et->base_type != nullptr) { str = write_expr_to_string(str, et->base_type); - str = gb_string_appendc(str, " "); + str = gb_string_append_rune(str, ' '); } - str = gb_string_appendc(str, "{"); + str = gb_string_append_rune(str, '{'); for_array(i, et->fields) { if (i > 0) { str = gb_string_appendc(str, ", "); } str = write_expr_to_string(str, et->fields[i]); } - str = gb_string_appendc(str, "}"); + str = gb_string_append_rune(str, '}'); case_end; } diff --git a/src/gb/gb.h b/src/gb/gb.h index 457e5306c..e613100bb 100644 --- a/src/gb/gb.h +++ b/src/gb/gb.h @@ -1,4 +1,4 @@ -/* gb.h - v0.28 - Ginger Bill's C Helper Library - public domain +/* gb.h - v0.29 - Ginger Bill's C Helper Library - public domain - no warranty implied; use at your own risk This is a single header file with a bunch of useful stuff @@ -58,6 +58,7 @@ TODOS - More date & time functions VERSION HISTORY + 0.29 - Add extras for gbString 0.28 - Handle UCS2 correctly in Win32 part 0.27 - OSX fixes and Linux gbAffinity 0.26d - Minor changes to how gbFile works @@ -1521,6 +1522,8 @@ GB_DEF void gb_string_clear (gbString str); GB_DEF gbString gb_string_append (gbString str, gbString const other); GB_DEF gbString gb_string_append_length (gbString str, void const *other, isize num_bytes); GB_DEF gbString gb_string_appendc (gbString str, char const *other); +GB_DEF gbString gb_string_append_rune (gbString str, Rune r); +GB_DEF gbString gb_string_append_fmt (gbString str, char const *fmt, ...); GB_DEF gbString gb_string_set (gbString str, char const *cstr); GB_DEF gbString gb_string_make_space_for (gbString str, isize add_len); GB_DEF isize gb_string_allocation_size(gbString const str); @@ -6573,6 +6576,26 @@ gb_inline gbString gb_string_appendc(gbString str, char const *other) { return gb_string_append_length(str, other, gb_strlen(other)); } +gbString gb_string_append_rune(gbString str, Rune r) { + if (r >= 0) { + u8 buf[8] = {0}; + isize len = gb_utf8_encode_rune(buf, r); + return gb_string_append_length(str, buf, len); + } + return str; +} + +gbString gb_string_append_fmt(gbString str, char const *fmt, ...) { + isize res; + char buf[4096] = {0}; + va_list va; + va_start(va, fmt); + res = gb_snprintf_va(str, gb_count_of(buf)-1, fmt, va); + va_end(va); + return gb_string_append_length(str, buf, res); +} + + gbString gb_string_set(gbString str, char const *cstr) { isize len = gb_strlen(cstr); diff --git a/src/parser.cpp b/src/parser.cpp index 4e764d2a6..b24aea6cf 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2618,6 +2618,8 @@ bool is_literal_type(AstNode *node) { case AstNode_ArrayType: case AstNode_VectorType: case AstNode_StructType: + case AstNode_UnionType: + case AstNode_EnumType: case AstNode_DynamicArrayType: case AstNode_MapType: case AstNode_CallExpr: diff --git a/src/types.cpp b/src/types.cpp index ab215fde4..13480eb3f 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -2254,17 +2254,17 @@ gbString write_type_to_string(gbString str, Type *type) { str = gb_string_appendc(str, "type"); } else { String name = type->Generic.name; - str = gb_string_appendc(str, "$"); + str = gb_string_append_rune(str, '$'); str = gb_string_append_length(str, name.text, name.len); if (type->Generic.specialized != nullptr) { - str = gb_string_appendc(str, "/"); + str = gb_string_append_rune(str, '/'); str = write_type_to_string(str, type->Generic.specialized); } } break; case Type_Pointer: - str = gb_string_appendc(str, "^"); + str = gb_string_append_rune(str, '^'); str = write_type_to_string(str, type->Pointer.elem); break; @@ -2304,7 +2304,7 @@ gbString write_type_to_string(gbString str, Type *type) { str = gb_string_append_length(str, f->token.string.text, f->token.string.len); // str = gb_string_appendc(str, " = "); } - str = gb_string_appendc(str, "}"); + str = gb_string_append_rune(str, '}'); break; case Type_Union: @@ -2314,7 +2314,7 @@ gbString write_type_to_string(gbString str, Type *type) { if (i > 0) str = gb_string_appendc(str, ", "); str = write_type_to_string(str, t); } - str = gb_string_appendc(str, "}"); + str = gb_string_append_rune(str, '}'); break; case Type_Struct: { @@ -2333,16 +2333,16 @@ gbString write_type_to_string(gbString str, Type *type) { str = gb_string_appendc(str, ": "); str = write_type_to_string(str, f->type); } - str = gb_string_appendc(str, "}"); + str = gb_string_append_rune(str, '}'); } break; case Type_Map: { str = gb_string_appendc(str, "map["); if (type->Map.count > 0) { - str = gb_string_appendc(str, gb_bprintf("%d, ", cast(int)type->Map.count)); + str = gb_string_append_fmt(str, "%d, ", cast(int)type->Map.count); } str = write_type_to_string(str, type->Map.key); - str = gb_string_appendc(str, "]"); + str = gb_string_append_rune(str, ']'); str = write_type_to_string(str, type->Map.value); } break; @@ -2418,27 +2418,27 @@ gbString write_type_to_string(gbString str, Type *type) { case Type_BitField: str = gb_string_appendc(str, "bit_field "); if (type->BitField.custom_align != 0) { - str = gb_string_appendc(str, gb_bprintf("#align %d ", cast(int)type->BitField.custom_align)); + str = gb_string_append_fmt(str, "#align %d ", cast(int)type->BitField.custom_align); } - str = gb_string_appendc(str, "{"); + str = gb_string_append_rune(str, '{'); for (isize i = 0; i < type->BitField.field_count; i++) { Entity *f = type->BitField.fields[i]; GB_ASSERT(f->kind == Entity_Variable); GB_ASSERT(f->type != nullptr && f->type->kind == Type_BitFieldValue); - str = gb_string_appendc(str, "{"); + str = gb_string_append_rune(str, '{'); if (i > 0) { str = gb_string_appendc(str, ", "); } str = gb_string_append_length(str, f->token.string.text, f->token.string.len); - str = gb_string_appendc(str, " : "); - str = gb_string_appendc(str, gb_bprintf("%lld", cast(long long)f->type->BitFieldValue.bits)); + str = gb_string_appendc(str, ": "); + str = gb_string_append_fmt(str, "%lld", cast(long long)f->type->BitFieldValue.bits); } - str = gb_string_appendc(str, "}"); + str = gb_string_append_rune(str, '}'); break; case Type_BitFieldValue: - str = gb_string_appendc(str, gb_bprintf("(bit field value with %d bits)", cast(int)type->BitFieldValue.bits)); + str = gb_string_append_fmt(str, "(bit field value with %d bits)", cast(int)type->BitFieldValue.bits); break; }