Browse Source

Fix struct parameter bugs

Ginger Bill 8 years ago
parent
commit
1df4aa90ce
6 changed files with 139 additions and 82 deletions
  1. 35 3
      core/fmt.odin
  2. 1 1
      core/os.odin
  3. 62 62
      src/check_expr.cpp
  4. 24 1
      src/gb/gb.h
  5. 2 0
      src/parser.cpp
  6. 15 15
      src/types.cpp

+ 35 - 3
core/fmt.odin

@@ -26,6 +26,7 @@ FmtInfo :: struct {
 
 
 	width:     int;
 	width:     int;
 	prec:      int;
 	prec:      int;
+	indent:    int;
 
 
 	reordered:      bool;
 	reordered:      bool;
 	good_arg_index: 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_string(fi.buf, info.name);
 			write_byte(fi.buf, '{');
 			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 {
 			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, b.names[i]);
 				write_string(fi.buf, " = ");
 				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];
 					data := cast(^u8)v.data + b.offsets[i];
 					fmt_arg(fi, any{rawptr(data), t}, 'v');
 					fmt_arg(fi, any{rawptr(data), t}, 'v');
 				}
 				}
+
+				if hash do write_string(fi.buf, ",\n");
 			}
 			}
-			write_byte(fi.buf, '}');
 
 
 		case:
 		case:
 			fmt_value(fi, any{v.data, info.base}, verb);
 			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, '{');
 		write_byte(fi.buf, '{');
 		defer 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 {
 		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, info.names[i]);
 			write_string(fi.buf, " = ");
 			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];
 				data := cast(^u8)v.data + info.offsets[i];
 				fmt_arg(fi, any{rawptr(data), t}, 'v');
 				fmt_arg(fi, any{rawptr(data), t}, 'v');
 			}
 			}
+			if hash do write_string(fi.buf, ",\n");
 		}
 		}
 
 
 	case Union:
 	case Union:

+ 1 - 1
core/os.odin

@@ -20,7 +20,7 @@ read_entire_file :: proc(name: string) -> (data: []u8, success: bool) {
 		return nil, false;
 		return nil, false;
 	}
 	}
 
 
-	if length == 0 {
+	if length <= 0 {
 		return nil, true;
 		return nil, true;
 	}
 	}
 
 

+ 62 - 62
src/check_expr.cpp

@@ -828,16 +828,17 @@ void check_struct_field_decl(Checker *c, AstNode *decl, Array<Entity *> *fields,
 		type = t_invalid;
 		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 (!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 (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;
+		}
 	}
 	}
 
 
-
 	Array<Operand> default_values = {};
 	Array<Operand> default_values = {};
 	defer (array_free(&default_values));
 	defer (array_free(&default_values));
 	if (vd->values.count > 0 && allow_default_values) {
 	if (vd->values.count > 0 && allow_default_values) {
@@ -896,7 +897,7 @@ void check_struct_field_decl(Checker *c, AstNode *decl, Array<Entity *> *fields,
 				e->Variable.default_is_undef = true;
 				e->Variable.default_is_undef = true;
 			} else if (b.mode != Addressing_Constant) {
 			} else if (b.mode != Addressing_Constant) {
 				error(b.expr, "Default field value must be a 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);
 				gbString str = type_to_string(e->type);
 				error(b.expr, "A struct field of type `%s` cannot have a default value", str);
 				error(b.expr, "A struct field of type `%s` cannot have a default value", str);
 				gb_string_free(str);
 				gb_string_free(str);
@@ -905,10 +906,10 @@ void check_struct_field_decl(Checker *c, AstNode *decl, Array<Entity *> *fields,
 			}
 			}
 
 
 			name_field_index++;
 			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)) {
 		if (is_blank_ident(name_token)) {
 			array_add(fields, e);
 			array_add(fields, e);
@@ -8191,14 +8192,19 @@ gbString write_struct_fields_to_string(gbString str, Array<AstNode *> params) {
 	return str;
 	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;
 	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) {
 gbString write_expr_to_string(gbString str, AstNode *node) {
 	if (node == nullptr)
 	if (node == nullptr)
 		return str;
 		return str;
@@ -8225,8 +8231,8 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
 	case_end;
 	case_end;
 
 
 	case_ast_node(bd, BasicDirective, node);
 	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_end;
 
 
 	case_ast_node(ud, Undef, node);
 	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);
 	case_ast_node(cl, CompoundLit, node);
 		str = write_expr_to_string(str, cl->type);
 		str = write_expr_to_string(str, cl->type);
-		str = gb_string_appendc(str, "{");
+		str = gb_string_append_rune(str, '{');
 		for_array(i, cl->elems) {
 		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 = write_expr_to_string(str, cl->elems[i]);
 		}
 		}
-		str = gb_string_appendc(str, "}");
+		str = gb_string_append_rune(str, '}');
 	case_end;
 	case_end;
 
 
 
 
 	case_ast_node(te, TagExpr, node);
 	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 = string_append_token(str, te->name);
 		str = write_expr_to_string(str, te->expr);
 		str = write_expr_to_string(str, te->expr);
 	case_end;
 	case_end;
@@ -8263,14 +8267,14 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
 
 
 	case_ast_node(de, DerefExpr, node);
 	case_ast_node(de, DerefExpr, node);
 		str = write_expr_to_string(str, de->expr);
 		str = write_expr_to_string(str, de->expr);
-		str = gb_string_appendc(str, "^");
+		str = gb_string_append_rune(str, '^');
 	case_end;
 	case_end;
 
 
 	case_ast_node(be, BinaryExpr, node);
 	case_ast_node(be, BinaryExpr, node);
 		str = write_expr_to_string(str, be->left);
 		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 = 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);
 		str = write_expr_to_string(str, be->right);
 	case_end;
 	case_end;
 
 
@@ -8284,14 +8288,14 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
 
 
 
 
 	case_ast_node(pe, ParenExpr, 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 = write_expr_to_string(str, pe->expr);
-		str = gb_string_appendc(str, ")");
+		str = gb_string_append_rune(str, ')');
 	case_end;
 	case_end;
 
 
 	case_ast_node(se, SelectorExpr, node);
 	case_ast_node(se, SelectorExpr, node);
 		str = write_expr_to_string(str, se->expr);
 		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);
 		str = write_expr_to_string(str, se->selector);
 	case_end;
 	case_end;
 
 
@@ -8299,25 +8303,25 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
 		str = write_expr_to_string(str, ta->expr);
 		str = write_expr_to_string(str, ta->expr);
 		str = gb_string_appendc(str, ".(");
 		str = gb_string_appendc(str, ".(");
 		str = write_expr_to_string(str, ta->type);
 		str = write_expr_to_string(str, ta->type);
-		str = gb_string_appendc(str, ")");
+		str = gb_string_append_rune(str, ')');
 	case_end;
 	case_end;
 		case_ast_node(tc, TypeCast, node);
 		case_ast_node(tc, TypeCast, node);
 		str = gb_string_appendc(str, "cast(");
 		str = gb_string_appendc(str, "cast(");
 		str = write_expr_to_string(str, tc->type);
 		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);
 		str = write_expr_to_string(str, tc->expr);
 	case_end;
 	case_end;
 
 
 	case_ast_node(ie, IndexExpr, node);
 	case_ast_node(ie, IndexExpr, node);
 		str = write_expr_to_string(str, ie->expr);
 		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 = write_expr_to_string(str, ie->index);
-		str = gb_string_appendc(str, "]");
+		str = gb_string_append_rune(str, ']');
 	case_end;
 	case_end;
 
 
 	case_ast_node(se, SliceExpr, node);
 	case_ast_node(se, SliceExpr, node);
 		str = write_expr_to_string(str, se->expr);
 		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 = write_expr_to_string(str, se->low);
 		str = gb_string_appendc(str, "..");
 		str = gb_string_appendc(str, "..");
 		str = write_expr_to_string(str, se->high);
 		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 = gb_string_appendc(str, "..");
 			str = write_expr_to_string(str, se->max);
 			str = write_expr_to_string(str, se->max);
 		}
 		}
-		str = gb_string_appendc(str, "]");
+		str = gb_string_append_rune(str, ']');
 	case_end;
 	case_end;
 
 
 	case_ast_node(e, Ellipsis, node);
 	case_ast_node(e, Ellipsis, node);
-		str = gb_string_appendc(str, "..");
+		str = gb_string_appendc(str, "...");
 		str = write_expr_to_string(str, e->expr);
 		str = write_expr_to_string(str, e->expr);
 	case_end;
 	case_end;
 
 
@@ -8346,21 +8350,21 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
 
 
 
 
 	case_ast_node(pt, PolyType, 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);
 		str = write_expr_to_string(str, pt->type);
 		if (pt->specialization != nullptr) {
 		if (pt->specialization != nullptr) {
-			str = gb_string_appendc(str, "/");
+			str = gb_string_append_rune(str, '/');
 			str = write_expr_to_string(str, pt->specialization);
 			str = write_expr_to_string(str, pt->specialization);
 		}
 		}
 	case_end;
 	case_end;
 
 
 	case_ast_node(pt, PointerType, node);
 	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);
 		str = write_expr_to_string(str, pt->type);
 	case_end;
 	case_end;
 
 
 	case_ast_node(at, ArrayType, node);
 	case_ast_node(at, ArrayType, node);
-		str = gb_string_appendc(str, "[");
+		str = gb_string_append_rune(str, '[');
 		if (at->count != nullptr &&
 		if (at->count != nullptr &&
 		    at->count->kind == AstNode_UnaryExpr &&
 		    at->count->kind == AstNode_UnaryExpr &&
 		    at->count->UnaryExpr.op.kind == Token_Ellipsis) {
 		    at->count->UnaryExpr.op.kind == Token_Ellipsis) {
@@ -8368,7 +8372,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
 		} else {
 		} else {
 			str = write_expr_to_string(str, at->count);
 			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);
 		str = write_expr_to_string(str, at->elem);
 	case_end;
 	case_end;
 
 
@@ -8380,14 +8384,14 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
 	case_ast_node(vt, VectorType, node);
 	case_ast_node(vt, VectorType, node);
 		str = gb_string_appendc(str, "[vector ");
 		str = gb_string_appendc(str, "[vector ");
 		str = write_expr_to_string(str, vt->count);
 		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);
 		str = write_expr_to_string(str, vt->elem);
 	case_end;
 	case_end;
 
 
 	case_ast_node(mt, MapType, node);
 	case_ast_node(mt, MapType, node);
 		str = gb_string_appendc(str, "map[");
 		str = gb_string_appendc(str, "map[");
 		str = write_expr_to_string(str, mt->key);
 		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);
 		str = write_expr_to_string(str, mt->value);
 	case_end;
 	case_end;
 
 
@@ -8404,24 +8408,22 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
 
 
 		for_array(i, f->names) {
 		for_array(i, f->names) {
 			AstNode *name = f->names[i];
 			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);
 			str = write_expr_to_string(str, name);
 		}
 		}
 		if (f->names.count > 0) {
 		if (f->names.count > 0) {
 			if (f->type == nullptr && f->default_value != nullptr) {
 			if (f->type == nullptr && f->default_value != nullptr) {
-				str = gb_string_appendc(str, " ");
+				str = gb_string_append_rune(str, ' ');
 			}
 			}
 			str = gb_string_appendc(str, ":");
 			str = gb_string_appendc(str, ":");
 		}
 		}
 		if (f->type != nullptr) {
 		if (f->type != nullptr) {
-			str = gb_string_appendc(str, " ");
+			str = gb_string_append_rune(str, ' ');
 			str = write_expr_to_string(str, f->type);
 			str = write_expr_to_string(str, f->type);
 		}
 		}
 		if (f->default_value != nullptr) {
 		if (f->default_value != nullptr) {
 			if (f->type != nullptr) {
 			if (f->type != nullptr) {
-				str = gb_string_appendc(str, " ");
+				str = gb_string_append_rune(str, ' ');
 			}
 			}
 			str = gb_string_appendc(str, "= ");
 			str = gb_string_appendc(str, "= ");
 			str = write_expr_to_string(str, f->default_value);
 			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) {
 		for_array(i, f->list) {
-			if (i > 0) {
-				str = gb_string_appendc(str, ", ");
-			}
+			if (i > 0) str = gb_string_appendc(str, ", ");
 			if (has_name) {
 			if (has_name) {
 				str = write_expr_to_string(str, f->list[i]);
 				str = write_expr_to_string(str, f->list[i]);
 			} else {
 			} else {
@@ -8473,9 +8473,9 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
 
 
 	case_ast_node(f, UnionField, node);
 	case_ast_node(f, UnionField, node);
 		str = write_expr_to_string(str, f->name);
 		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 = write_expr_to_string(str, f->list);
-		str = gb_string_appendc(str, "}");
+		str = gb_string_append_rune(str, '}');
 	case_end;
 	case_end;
 
 
 	case_ast_node(ce, CallExpr, node);
 	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_packed)    str = gb_string_appendc(str, "#packed ");
 		if (st->is_ordered)   str = gb_string_appendc(str, "#ordered ");
 		if (st->is_ordered)   str = gb_string_appendc(str, "#ordered ");
 		if (st->is_raw_union) str = gb_string_appendc(str, "#raw_union ");
 		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 = write_struct_fields_to_string(str, st->fields);
-		str = gb_string_appendc(str, "}");
+		str = gb_string_append_rune(str, '}');
 	case_end;
 	case_end;
 
 
 	// case_ast_node(st, RawUnionType, node);
 	// case_ast_node(st, RawUnionType, node);
 	// 	str = gb_string_appendc(str, "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 = write_struct_fields_to_string(str, st->fields);
-	// 	str = gb_string_appendc(str, "}");
+	// 	str = gb_string_append_rune(str, '}');
 	// case_end;
 	// case_end;
 
 
 	case_ast_node(st, UnionType, node);
 	case_ast_node(st, UnionType, node);
 		str = gb_string_appendc(str, "union ");
 		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 = write_struct_fields_to_string(str, st->variants);
-		str = gb_string_appendc(str, "}");
+		str = gb_string_append_rune(str, '}');
 	case_end;
 	case_end;
 
 
 	case_ast_node(et, EnumType, node);
 	case_ast_node(et, EnumType, node);
 		str = gb_string_appendc(str, "enum ");
 		str = gb_string_appendc(str, "enum ");
 		if (et->base_type != nullptr) {
 		if (et->base_type != nullptr) {
 			str = write_expr_to_string(str, et->base_type);
 			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) {
 		for_array(i, et->fields) {
 			if (i > 0) {
 			if (i > 0) {
 				str = gb_string_appendc(str, ", ");
 				str = gb_string_appendc(str, ", ");
 			}
 			}
 			str = write_expr_to_string(str, et->fields[i]);
 			str = write_expr_to_string(str, et->fields[i]);
 		}
 		}
-		str = gb_string_appendc(str, "}");
+		str = gb_string_append_rune(str, '}');
 	case_end;
 	case_end;
 	}
 	}
 
 

+ 24 - 1
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
                  - no warranty implied; use at your own risk
 
 
 	This is a single header file with a bunch of useful stuff
 	This is a single header file with a bunch of useful stuff
@@ -58,6 +58,7 @@ TODOS
 	- More date & time functions
 	- More date & time functions
 
 
 VERSION HISTORY
 VERSION HISTORY
+	0.29  - Add extras for gbString
 	0.28  - Handle UCS2 correctly in Win32 part
 	0.28  - Handle UCS2 correctly in Win32 part
 	0.27  - OSX fixes and Linux gbAffinity
 	0.27  - OSX fixes and Linux gbAffinity
 	0.26d - Minor changes to how gbFile works
 	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         (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_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_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_set            (gbString str, char const *cstr);
 GB_DEF gbString gb_string_make_space_for (gbString str, isize add_len);
 GB_DEF gbString gb_string_make_space_for (gbString str, isize add_len);
 GB_DEF isize    gb_string_allocation_size(gbString const str);
 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));
 	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) {
 gbString gb_string_set(gbString str, char const *cstr) {
 	isize len = gb_strlen(cstr);
 	isize len = gb_strlen(cstr);

+ 2 - 0
src/parser.cpp

@@ -2618,6 +2618,8 @@ bool is_literal_type(AstNode *node) {
 	case AstNode_ArrayType:
 	case AstNode_ArrayType:
 	case AstNode_VectorType:
 	case AstNode_VectorType:
 	case AstNode_StructType:
 	case AstNode_StructType:
+	case AstNode_UnionType:
+	case AstNode_EnumType:
 	case AstNode_DynamicArrayType:
 	case AstNode_DynamicArrayType:
 	case AstNode_MapType:
 	case AstNode_MapType:
 	case AstNode_CallExpr:
 	case AstNode_CallExpr:

+ 15 - 15
src/types.cpp

@@ -2254,17 +2254,17 @@ gbString write_type_to_string(gbString str, Type *type) {
 			str = gb_string_appendc(str, "type");
 			str = gb_string_appendc(str, "type");
 		} else {
 		} else {
 			String name = type->Generic.name;
 			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);
 			str = gb_string_append_length(str, name.text, name.len);
 			if (type->Generic.specialized != nullptr) {
 			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);
 				str = write_type_to_string(str, type->Generic.specialized);
 			}
 			}
 		}
 		}
 		break;
 		break;
 
 
 	case Type_Pointer:
 	case Type_Pointer:
-		str = gb_string_appendc(str, "^");
+		str = gb_string_append_rune(str, '^');
 		str = write_type_to_string(str, type->Pointer.elem);
 		str = write_type_to_string(str, type->Pointer.elem);
 		break;
 		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_append_length(str, f->token.string.text, f->token.string.len);
 			// str = gb_string_appendc(str, " = ");
 			// str = gb_string_appendc(str, " = ");
 		}
 		}
-		str = gb_string_appendc(str, "}");
+		str = gb_string_append_rune(str, '}');
 		break;
 		break;
 
 
 	case Type_Union:
 	case Type_Union:
@@ -2314,7 +2314,7 @@ gbString write_type_to_string(gbString str, Type *type) {
 			if (i > 0) str = gb_string_appendc(str, ", ");
 			if (i > 0) str = gb_string_appendc(str, ", ");
 			str = write_type_to_string(str, t);
 			str = write_type_to_string(str, t);
 		}
 		}
-		str = gb_string_appendc(str, "}");
+		str = gb_string_append_rune(str, '}');
 		break;
 		break;
 
 
 	case Type_Struct: {
 	case Type_Struct: {
@@ -2333,16 +2333,16 @@ gbString write_type_to_string(gbString str, Type *type) {
 			str = gb_string_appendc(str, ": ");
 			str = gb_string_appendc(str, ": ");
 			str = write_type_to_string(str, f->type);
 			str = write_type_to_string(str, f->type);
 		}
 		}
-		str = gb_string_appendc(str, "}");
+		str = gb_string_append_rune(str, '}');
 	} break;
 	} break;
 
 
 	case Type_Map: {
 	case Type_Map: {
 		str = gb_string_appendc(str, "map[");
 		str = gb_string_appendc(str, "map[");
 		if (type->Map.count > 0) {
 		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 = 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);
 		str = write_type_to_string(str, type->Map.value);
 	} break;
 	} break;
 
 
@@ -2418,27 +2418,27 @@ gbString write_type_to_string(gbString str, Type *type) {
 	case Type_BitField:
 	case Type_BitField:
 		str = gb_string_appendc(str, "bit_field ");
 		str = gb_string_appendc(str, "bit_field ");
 		if (type->BitField.custom_align != 0) {
 		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++) {
 		for (isize i = 0; i < type->BitField.field_count; i++) {
 			Entity *f = type->BitField.fields[i];
 			Entity *f = type->BitField.fields[i];
 			GB_ASSERT(f->kind == Entity_Variable);
 			GB_ASSERT(f->kind == Entity_Variable);
 			GB_ASSERT(f->type != nullptr && f->type->kind == Type_BitFieldValue);
 			GB_ASSERT(f->type != nullptr && f->type->kind == Type_BitFieldValue);
-			str = gb_string_appendc(str, "{");
+			str = gb_string_append_rune(str, '{');
 			if (i > 0) {
 			if (i > 0) {
 				str = gb_string_appendc(str, ", ");
 				str = gb_string_appendc(str, ", ");
 			}
 			}
 			str = gb_string_append_length(str, f->token.string.text, f->token.string.len);
 			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;
 		break;
 
 
 	case Type_BitFieldValue:
 	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;
 		break;
 	}
 	}