compiler,std: implement ZON support

This commit allows using ZON (Zig Object Notation) in a few ways.

* `@import` can be used to load ZON at comptime and convert it to a
  normal Zig value. In this case, `@import` must have a result type.
* `std.zon.parse` can be used to parse ZON at runtime, akin to the
  parsing logic in `std.json`.
* `std.zon.stringify` can be used to convert arbitrary data structures
  to ZON at runtime, again akin to `std.json`.
This commit is contained in:
Mason Remaley
2024-11-04 14:03:36 -08:00
committed by mlugg
parent 953355ebea
commit 13c6eb0d71
145 changed files with 8786 additions and 434 deletions

View File

@@ -0,0 +1,9 @@
pub fn main() void {
const f: struct { value: []const i32 } = @import("zon/addr_slice.zon");
_ = f;
}
// error
// imports=zon/addr_slice.zon
//
// addr_slice.zon:2:14: error: pointers are not available in ZON

View File

@@ -0,0 +1,10 @@
export fn entry() void {
const f: [4]u8 = @import("zon/array.zon");
_ = f;
}
// error
// imports=zon/array.zon
//
// array.zon:1:2: error: expected type '[4]u8'
// tmp.zig:2:30: note: imported here

View File

@@ -0,0 +1,9 @@
export fn entry() void {
_ = @import(
"bogus-does-not-exist.zon",
);
}
// error
//
// :3:9: error: unable to open 'bogus-does-not-exist.zon': FileNotFound

View File

@@ -0,0 +1,125 @@
export fn testVoid() void {
const f: void = @import("zon/neg_inf.zon");
_ = f;
}
export fn testInStruct() void {
const f: struct { f: [*]const u8 } = @import("zon/neg_inf.zon");
_ = f;
}
export fn testError() void {
const f: struct { error{foo} } = @import("zon/neg_inf.zon");
_ = f;
}
export fn testInUnion() void {
const f: union(enum) { a: void, b: [*c]const u8 } = @import("zon/neg_inf.zon");
_ = f;
}
export fn testInVector() void {
const f: @Vector(0, [*c]const u8) = @import("zon/neg_inf.zon");
_ = f;
}
export fn testInOpt() void {
const f: *const ?[*c]const u8 = @import("zon/neg_inf.zon");
_ = f;
}
export fn testComptimeField() void {
const f: struct { comptime foo: ??u8 = null } = @import("zon/neg_inf.zon");
_ = f;
}
export fn testEnumLiteral() void {
const f: @TypeOf(.foo) = @import("zon/neg_inf.zon");
_ = f;
}
export fn testNestedOpt1() void {
const f: ??u8 = @import("zon/neg_inf.zon");
_ = f;
}
export fn testNestedOpt2() void {
const f: ?*const ?u8 = @import("zon/neg_inf.zon");
_ = f;
}
export fn testNestedOpt3() void {
const f: *const ?*const ?*const u8 = @import("zon/neg_inf.zon");
_ = f;
}
export fn testOpt() void {
const f: ?u8 = @import("zon/neg_inf.zon");
_ = f;
}
export fn testNonExhaustiveEnum() void {
const f: enum(u8) { _ } = @import("zon/neg_inf.zon");
_ = f;
}
export fn testUntaggedUnion() void {
const f: union { foo: void } = @import("zon/neg_inf.zon");
_ = f;
}
export fn testTaggedUnionVoid() void {
const f: union(enum) { foo: void } = @import("zon/neg_inf.zon");
_ = f;
}
export fn testVisited() void {
const V = struct {
?f32, // Adds `?f32` to the visited list
??f32, // `?f32` is already visited, we need to detect the nested opt anyway
f32,
};
const f: V = @import("zon/neg_inf.zon");
_ = f;
}
export fn testMutablePointer() void {
const f: *i32 = @import("zon/neg_inf.zon");
_ = f;
}
// error
// imports=zon/neg_inf.zon
//
// tmp.zig:2:29: error: type 'void' is not available in ZON
// tmp.zig:7:50: error: type '[*]const u8' is not available in ZON
// tmp.zig:7:50: note: ZON does not allow many-pointers
// tmp.zig:12:46: error: type 'error{foo}' is not available in ZON
// tmp.zig:17:65: error: type '[*c]const u8' is not available in ZON
// tmp.zig:17:65: note: ZON does not allow C pointers
// tmp.zig:22:49: error: type '[*c]const u8' is not available in ZON
// tmp.zig:22:49: note: ZON does not allow C pointers
// tmp.zig:27:45: error: type '[*c]const u8' is not available in ZON
// tmp.zig:27:45: note: ZON does not allow C pointers
// tmp.zig:32:61: error: type '??u8' is not available in ZON
// tmp.zig:32:61: note: ZON does not allow nested optionals
// tmp.zig:42:29: error: type '??u8' is not available in ZON
// tmp.zig:42:29: note: ZON does not allow nested optionals
// tmp.zig:47:36: error: type '?*const ?u8' is not available in ZON
// tmp.zig:47:36: note: ZON does not allow nested optionals
// tmp.zig:52:50: error: type '?*const ?*const u8' is not available in ZON
// tmp.zig:52:50: note: ZON does not allow nested optionals
// tmp.zig:82:26: error: type '??f32' is not available in ZON
// tmp.zig:82:26: note: ZON does not allow nested optionals
// tmp.zig:87:29: error: type '*i32' is not available in ZON
// tmp.zig:87:29: note: ZON does not allow mutable pointers
// neg_inf.zon:1:1: error: expected type '@Type(.enum_literal)'
// tmp.zig:37:38: note: imported here
// neg_inf.zon:1:1: error: expected type '?u8'
// tmp.zig:57:28: note: imported here
// neg_inf.zon:1:1: error: expected type 'tmp.testNonExhaustiveEnum__enum_490'
// tmp.zig:62:39: note: imported here
// neg_inf.zon:1:1: error: expected type 'tmp.testUntaggedUnion__union_492'
// tmp.zig:67:44: note: imported here
// neg_inf.zon:1:1: error: expected type 'tmp.testTaggedUnionVoid__union_495'
// tmp.zig:72:50: note: imported here

View File

@@ -0,0 +1,10 @@
export fn entry() void {
const f: comptime_float = @import("zon/inf.zon");
_ = f;
}
// error
// imports=zon/inf.zon
//
// inf.zon:1:1: error: expected type 'comptime_float'
// tmp.zig:2:39: note: imported here

View File

@@ -0,0 +1,10 @@
export fn entry() void {
const f: comptime_float = @import("zon/nan.zon");
_ = f;
}
// error
// imports=zon/nan.zon
//
// nan.zon:1:1: error: expected type 'comptime_float'
// tmp.zig:2:39: note: imported here

View File

@@ -0,0 +1,10 @@
export fn entry() void {
const f: comptime_float = @import("zon/neg_inf.zon");
_ = f;
}
// error
// imports=zon/neg_inf.zon
//
// neg_inf.zon:1:1: error: expected type 'comptime_float'
// tmp.zig:2:39: note: imported here

View File

@@ -0,0 +1,9 @@
export fn entry() void {
const f: struct { foo: type } = @import("zon/doc_comment.zon");
_ = f;
}
// error
// imports=zon/doc_comment.zon
//
// doc_comment.zon:1:1: error: expected expression, found 'a document comment'

View File

@@ -0,0 +1,9 @@
export fn entry() void {
const f: f32 = @import("zon/double_negation_float.zon");
_ = f;
}
// error
// imports=zon/double_negation_float.zon
//
// double_negation_float.zon:1:1: error: expected number or 'inf' after '-'

View File

@@ -0,0 +1,9 @@
export fn entry() void {
const f: i32 = @import("zon/double_negation_int.zon");
_ = f;
}
// error
// imports=zon/double_negation_int.zon
//
// double_negation_int.zon:1:1: error: expected number or 'inf' after '-'

View File

@@ -0,0 +1,11 @@
const std = @import("std");
export fn entry() void {
const E = enum { foo };
const f: struct { E, E } = @import("zon/enum_embedded_null.zon");
_ = f;
}
// error
// imports=zon/enum_embedded_null.zon
//
// enum_embedded_null.zon:2:6: error: identifier cannot contain null bytes

View File

@@ -0,0 +1,11 @@
export fn entry() void {
const U = union(enum) { a: void };
const f: U = @import("zon/simple_union.zon");
_ = f;
}
// error
// imports=zon/simple_union.zon
//
// simple_union.zon:1:9: error: expected type 'void'
// tmp.zig:3:26: note: imported here

View File

@@ -0,0 +1,9 @@
export fn entry() void {
const f: u8 = @import("zon/invalid_character.zon");
_ = f;
}
// error
// imports=zon/invalid_character.zon
//
// invalid_character.zon:1:3: error: invalid escape character: 'a'

View File

@@ -0,0 +1,9 @@
export fn entry() void {
const f: u128 = @import("zon/invalid_number.zon");
_ = f;
}
// error
// imports=zon/invalid_number.zon
//
// invalid_number.zon:1:19: error: invalid digit 'a' for decimal base

View File

@@ -0,0 +1,9 @@
export fn entry() void {
const f: []const u8 = @import("zon/invalid_string.zon");
_ = f;
}
// error
// imports=zon/invalid_string.zon
//
// invalid_string.zon:1:5: error: invalid escape character: 'a'

View File

@@ -0,0 +1,10 @@
export fn entry() void {
const f: u128 = @import("zon/leading_zero_in_integer.zon");
_ = f;
}
// error
// imports=zon/leading_zero_in_integer.zon
//
// leading_zero_in_integer.zon:1:1: error: number '0012' has leading zero
// leading_zero_in_integer.zon:1:1: note: use '0o' prefix for octal literals

View File

@@ -0,0 +1,9 @@
export fn entry() void {
const f: u8 = @import("zon/neg_char.zon");
_ = f;
}
// error
// imports=zon/neg_char.zon
//
// neg_char.zon:1:1: error: expected number or 'inf' after '-'

View File

@@ -0,0 +1,9 @@
export fn entry() void {
const f: u8 = @import("zon/neg_nan.zon");
_ = f;
}
// error
// imports=zon/neg_nan.zon
//
// neg_nan.zon:1:1: error: expected number or 'inf' after '-'

View File

@@ -0,0 +1,11 @@
export fn entry() void {
const f: i8 = @import("zon/negative_zero.zon");
_ = f;
}
// error
// imports=zon/negative_zero.zon
//
// negative_zero.zon:1:2: error: integer literal '-0' is ambiguous
// negative_zero.zon:1:2: note: use '0' for an integer zero
// negative_zero.zon:1:2: note: use '-0.0' for a floating-point signed zero

View File

@@ -0,0 +1,9 @@
export fn entry() void {
const f = @import("zon/simple_union.zon");
_ = f;
}
// error
// imports=zon/simple_union.zon
//
// tmp.zig:2:23: error: '@import' of ZON must have a known result type

View File

@@ -0,0 +1,10 @@
export fn entry() void {
const f: i66 = @import("zon/large_number.zon");
_ = f;
}
// error
// imports=zon/large_number.zon
//
// large_number.zon:1:1: error: type 'i66' cannot represent integer value '36893488147419103232'
// tmp.zig:2:28: note: imported here

View File

@@ -0,0 +1,16 @@
export fn entry() void {
{
const f: u6 = @import("zon/char_32.zon");
_ = f;
}
{
const f: u5 = @import("zon/char_32.zon");
_ = f;
}
}
// error
// imports=zon/char_32.zon
//
// char_32.zon:1:1: error: type 'u5' cannot represent integer value '32'
// tmp.zig:7:31: note: imported here

View File

@@ -0,0 +1,16 @@
export fn entry() void {
{
const f: i7 = @import("zon/char_32.zon");
_ = f;
}
{
const f: i6 = @import("zon/char_32.zon");
_ = f;
}
}
// error
// imports=zon/char_32.zon
//
// char_32.zon:1:1: error: type 'i6' cannot represent integer value '32'
// tmp.zig:7:31: note: imported here

View File

@@ -0,0 +1,16 @@
export fn entry() void {
{
const f: u6 = @import("zon/int_32.zon");
_ = f;
}
{
const f: u5 = @import("zon/int_32.zon");
_ = f;
}
}
// error
// imports=zon/int_32.zon
//
// int_32.zon:1:1: error: type 'u5' cannot represent integer value '32'
// tmp.zig:7:31: note: imported here

View File

@@ -0,0 +1,16 @@
export fn entry() void {
{
const f: i7 = @import("zon/int_32.zon");
_ = f;
}
{
const f: i6 = @import("zon/int_32.zon");
_ = f;
}
}
// error
// imports=zon/int_32.zon
//
// int_32.zon:1:1: error: type 'i6' cannot represent integer value '32'
// tmp.zig:7:31: note: imported here

View File

@@ -0,0 +1,16 @@
export fn entry() void {
{
const f: i7 = @import("zon/int_neg_33.zon");
_ = f;
}
{
const f: i6 = @import("zon/int_neg_33.zon");
_ = f;
}
}
// error
// imports=zon/int_neg_33.zon
//
// int_neg_33.zon:1:1: error: type 'i6' cannot represent integer value '-33'
// tmp.zig:7:31: note: imported here

View File

@@ -0,0 +1,10 @@
export fn entry() void {
const f: u64 = @import("zon/int_neg_33.zon");
_ = f;
}
// error
// imports=zon/int_neg_33.zon
//
// int_neg_33.zon:1:1: error: type 'u64' cannot represent integer value '-33'
// tmp.zig:2:28: note: imported here

View File

@@ -0,0 +1,82 @@
export fn testFloatA() void {
const f: ?f32 = @import("zon/vec2.zon");
_ = f;
}
export fn testFloatB() void {
const f: *const ?f32 = @import("zon/vec2.zon");
_ = f;
}
export fn testFloatC() void {
const f: ?*const f32 = @import("zon/vec2.zon");
_ = f;
}
export fn testBool() void {
const f: ?bool = @import("zon/vec2.zon");
_ = f;
}
export fn testInt() void {
const f: ?i32 = @import("zon/vec2.zon");
_ = f;
}
const Enum = enum { foo };
export fn testEnum() void {
const f: ?Enum = @import("zon/vec2.zon");
_ = f;
}
export fn testEnumLit() void {
const f: ?@TypeOf(.foo) = @import("zon/vec2.zon");
_ = f;
}
export fn testArray() void {
const f: ?[1]u8 = @import("zon/vec2.zon");
_ = f;
}
const Union = union {};
export fn testUnion() void {
const f: ?Union = @import("zon/vec2.zon");
_ = f;
}
export fn testSlice() void {
const f: ?[]const u8 = @import("zon/vec2.zon");
_ = f;
}
export fn testVector() void {
const f: ?@Vector(3, f32) = @import("zon/vec2.zon");
_ = f;
}
// error
// imports=zon/vec2.zon
//
// vec2.zon:1:2: error: expected type '?f32'
// tmp.zig:2:29: note: imported here
// vec2.zon:1:2: error: expected type '*const ?f32'
// tmp.zig:7:36: note: imported here
// vec2.zon:1:2: error: expected type '?*const f32'
// tmp.zig:12:36: note: imported here
// vec2.zon:1:2: error: expected type '?bool'
// tmp.zig:17:30: note: imported here
// vec2.zon:1:2: error: expected type '?i32'
// tmp.zig:22:29: note: imported here
// vec2.zon:1:2: error: expected type '?tmp.Enum'
// tmp.zig:28:30: note: imported here
// vec2.zon:1:2: error: expected type '?@Type(.enum_literal)'
// tmp.zig:33:39: note: imported here
// vec2.zon:1:2: error: expected type '?[1]u8'
// tmp.zig:38:31: note: imported here
// vec2.zon:1:2: error: expected type '?tmp.Union'
// tmp.zig:44:31: note: imported here
// vec2.zon:1:2: error: expected type '?[]const u8'
// tmp.zig:49:36: note: imported here
// vec2.zon:1:2: error: expected type '?@Vector(3, f32)'
// tmp.zig:54:41: note: imported here

View File

@@ -0,0 +1,19 @@
const Struct = struct { f: bool };
export fn testStruct() void {
const f: ?Struct = @import("zon/nan.zon");
_ = f;
}
const Tuple = struct { bool };
export fn testTuple() void {
const f: ?Tuple = @import("zon/nan.zon");
_ = f;
}
// error
// imports=zon/nan.zon
//
//nan.zon:1:1: error: expected type '?tmp.Struct'
//tmp.zig:3:32: note: imported here
//nan.zon:1:1: error: expected type '?struct { bool }'
//tmp.zig:9:31: note: imported here

View File

@@ -0,0 +1,10 @@
export fn entry() void {
const f: [5]u8 = @import("zon/hello.zon");
_ = f;
}
// error
// imports=zon/hello.zon
//
// hello.zon:1:1: error: expected type '[5]u8'
// tmp.zig:2:30: note: imported here

View File

@@ -0,0 +1,11 @@
const std = @import("std");
export fn entry() void {
const f: struct { name: u8 } = @import("zon/struct_dup_field.zon");
_ = f;
}
// error
// imports=zon/struct_dup_field.zon
//
// struct_dup_field.zon:2:6: error: duplicate struct field name
// struct_dup_field.zon:3:6: note: duplicate name here

View File

@@ -0,0 +1,14 @@
export fn entry() void {
const Vec2 = struct {
comptime x: f32 = 1.5,
comptime y: f32 = 2.5,
};
const f: Vec2 = @import("zon/vec2.zon");
_ = f;
}
// error
// imports=zon/vec2.zon
//
// vec2.zon:1:19: error: value stored in comptime field does not match the default value of the field
// tmp.zig:6:29: note: imported here

View File

@@ -0,0 +1,9 @@
export fn entry() void {
const f: bool = @import("zon/syntax_error.zon");
_ = f;
}
// error
// imports=zon/syntax_error.zon
//
// syntax_error.zon:3:13: error: expected ',' after initializer

View File

@@ -0,0 +1,14 @@
export fn entry() void {
const T = struct {
comptime f32 = 1.5,
comptime f32 = 2.5,
};
const f: T = @import("zon/tuple.zon");
_ = f;
}
// error
// imports=zon/tuple.zon
//
// tuple.zon:1:9: error: value stored in comptime field does not match the default value of the field
// tmp.zig:6:26: note: imported here

View File

@@ -0,0 +1,9 @@
export fn entry() void {
const f: struct { foo: type } = @import("zon/type_decl.zon");
_ = f;
}
// error
// imports=zon/type_decl.zon
//
// type_decl.zon:2:12: error: types are not available in ZON

View File

@@ -0,0 +1,10 @@
export fn entry() void {
const f: [3]i32 = @import("zon/type_expr_array.zon");
_ = f;
}
// error
// imports=zon/type_expr_array.zon
//
// type_expr_array.zon:1:1: error: types are not available in ZON
// type_expr_array.zon:1:1: note: replace the type with '.'

View File

@@ -0,0 +1,10 @@
export fn entry() void {
const f: i32 = @import("zon/type_expr_fn.zon");
_ = f;
}
// error
// imports=zon/type_expr_fn.zon
//
// type_expr_fn.zon:1:1: error: types are not available in ZON
// type_expr_fn.zon:1:1: note: replace the type with '.'

View File

@@ -0,0 +1,10 @@
export fn entry() void {
const f: struct { x: f32, y: f32 } = @import("zon/type_expr_struct.zon");
_ = f;
}
// error
// imports=zon/type_expr_struct.zon
//
// type_expr_struct.zon:1:1: error: types are not available in ZON
// type_expr_struct.zon:1:1: note: replace the type with '.'

View File

@@ -0,0 +1,10 @@
export fn entry() void {
const f: struct { f32, f32 } = @import("zon/type_expr_tuple.zon");
_ = f;
}
// error
// imports=zon/type_expr_tuple.zon
//
// type_expr_tuple.zon:1:1: error: types are not available in ZON
// type_expr_tuple.zon:1:1: note: replace the type with '.'

View File

@@ -0,0 +1,10 @@
export fn entry() void {
const f: bool = @import("zon/struct.zon");
_ = f;
}
// error
// imports=zon/struct.zon
//
// struct.zon:1:2: error: expected type 'bool'
// tmp.zig:2:29: note: imported here

View File

@@ -0,0 +1,9 @@
export fn entry() void {
const f: i8 = @import("zon/unescaped_newline.zon");
_ = f;
}
// error
// imports=zon/unescaped_newline.zon
//
// unescaped_newline.zon:1:1: error: expected expression, found 'invalid token'

View File

@@ -0,0 +1,11 @@
export fn entry() void {
const f: struct { value: bool } = @import("zon/unknown_ident.zon");
_ = f;
}
// error
// imports=zon/unknown_ident.zon
//
// unknown_ident.zon:2:14: error: invalid expression
// unknown_ident.zon:2:14: note: ZON allows identifiers 'true', 'false', 'null', 'inf', and 'nan'
// unknown_ident.zon:2:14: note: precede identifier with '.' for an enum literal

View File

@@ -0,0 +1,10 @@
export fn entry() void {
const f: @Vector(3, f32) = @import("zon/tuple.zon");
_ = f;
}
// error
// imports=zon/tuple.zon
//
// tuple.zon:1:2: error: expected 3 vector elements; found 2
// tmp.zig:2:40: note: imported here

View File

@@ -0,0 +1,10 @@
export fn entry() void {
const f: @Vector(1, f32) = @import("zon/tuple.zon");
_ = f;
}
// error
// imports=zon/tuple.zon
//
// tuple.zon:1:2: error: expected 1 vector elements; found 2
// tmp.zig:2:40: note: imported here

View File

@@ -0,0 +1,10 @@
export fn entry() void {
const f: @Vector(2, bool) = @import("zon/tuple.zon");
_ = f;
}
// error
// imports=zon/tuple.zon
//
// tuple.zon:1:4: error: expected type 'bool'
// tmp.zig:2:41: note: imported here

View File

@@ -0,0 +1,10 @@
export fn entry() void {
const f: union { foo: void } = @import("zon/void.zon");
_ = f;
}
// error
// imports=zon/void.zon
//
// void.zon:1:11: error: void literals are not available in ZON
// void.zon:1:11: note: void union payloads can be represented by enum literals

View File

@@ -44,9 +44,9 @@ comptime {
//
// :5:23: error: expected error union type, found 'comptime_int'
// :10:23: error: expected error union type, found '@TypeOf(.{})'
// :15:23: error: expected error union type, found 'tmp.test2__struct_493'
// :15:23: error: expected error union type, found 'tmp.test2__struct_494'
// :15:23: note: struct declared here
// :20:27: error: expected error union type, found 'tmp.test3__struct_495'
// :20:27: error: expected error union type, found 'tmp.test3__struct_496'
// :20:27: note: struct declared here
// :25:23: error: expected error union type, found 'struct { comptime *const [5:0]u8 = "hello" }'
// :31:13: error: expected error union type, found 'u32'

View File

@@ -0,0 +1,3 @@
.{
.value = &.{ 1, 2, 3 },
}

View File

@@ -0,0 +1 @@
.{ 'a', 'b', 'c' }

View File

@@ -0,0 +1 @@
' '

View File

@@ -0,0 +1,3 @@
[LocalizedFileNames]
invalid_zon_2.zig=@invalid_zon_2.zig,0
invalid_zon_1.zig=@invalid_zon_1.zig,0

View File

@@ -0,0 +1,2 @@
//! Doc comments aren't allowed in ZON
.{}

View File

@@ -0,0 +1 @@
--1.0

View File

@@ -0,0 +1 @@
--1

View File

@@ -0,0 +1,4 @@
.{
.@"\x00",
10,
}

View File

@@ -0,0 +1 @@
"hello"

View File

@@ -0,0 +1 @@
inf

View File

@@ -0,0 +1 @@
32

View File

@@ -0,0 +1 @@
-33

View File

@@ -0,0 +1 @@
'\a'

View File

@@ -0,0 +1 @@
368934881474191032a32

View File

@@ -0,0 +1 @@
"\"\a\""

View File

@@ -0,0 +1 @@
36893488147419103232

View File

@@ -0,0 +1 @@
0012

View File

@@ -0,0 +1 @@
nan

View File

@@ -0,0 +1 @@
-'a'

View File

@@ -0,0 +1 @@
-inf

View File

@@ -0,0 +1 @@
-nan

View File

@@ -0,0 +1 @@
-0

View File

@@ -0,0 +1 @@
.{ .a = 10 }

View File

@@ -0,0 +1,4 @@
.{
.boolean = true,
.number = 123,
}

View File

@@ -0,0 +1,4 @@
.{
.name = 10,
.name = 20,
}

View File

@@ -0,0 +1,4 @@
.{
.boolean = true
.number = 123,
}

View File

@@ -0,0 +1 @@
.{ 1.5, 2 }

View File

@@ -0,0 +1,3 @@
.{
.foo = struct {},
}

View File

@@ -0,0 +1 @@
[3]i32{1, 2, 3}

View File

@@ -0,0 +1 @@
fn foo() void {}

View File

@@ -0,0 +1 @@
Vec2{ .x = 1.0, .y = 2.0 }

View File

@@ -0,0 +1 @@
Vec2{1.0, 2.0}

View File

@@ -0,0 +1,2 @@
"a
b"

View File

@@ -0,0 +1,3 @@
.{
.value = truefalse,
}

View File

@@ -0,0 +1 @@
.{ .x = 1.5, .y = 2 }

View File

@@ -0,0 +1 @@
.{ .foo = {} }