diff --git a/lang/README.md b/lang/README.md index 0d3255a04..ef8a60bca 100644 --- a/lang/README.md +++ b/lang/README.md @@ -353,8 +353,8 @@ decide := fn(): bool return !false #### inline_return_stack ```hb -$fun := fn(): [uint; 3] { - res := [uint].(0, 1, 2) +$fun := fn(): [3]uint { + res := .[0, 1, 2] return res } @@ -451,7 +451,7 @@ main := fn(): uint { align_of_Type_in_bytes := @alignof(foo.Type) hardcoded_pointer := @as(^u8, @bitcast(10)) ecall_that_returns_uint := @as(uint, @eca(1, foo.Type.(10, 20), 5, 6)) - embedded_array := @as([u8; 15], @embed("text.txt")) + embedded_array := @as([15]u8, @embed("text.txt")) two_fields := @len(foo.Type) string_length := @len("foo\0") the_struct_kind := @kindof(foo.Type) @@ -545,14 +545,14 @@ fib_iter := fn(n: uint): uint { ```hb main := fn(): uint { addr := @as(u16, 0x1FF) - msg := [u8].(0, 0, @intcast(addr), @intcast(addr >> 8)) + msg := u8.[0, 0, @intcast(addr), @intcast(addr >> 8)] _force_stack := &msg - arr := [uint].(1, 2, 4) + arr := .[1, 2, 4] return pass(&arr) + msg[3] } -pass := fn(arr: ^[uint; 3]): uint { +pass := fn(arr: ^[3]uint): uint { return arr[0] + arr[1] + arr[arr[1]] } ``` @@ -582,7 +582,7 @@ foo := fn(a: uint, b: uint, c: uint): uint { _edge_case := @as(uint, idk) main := fn(): uint { - big_array := @as([u8; 128], idk) + big_array := @as([128]u8, idk) i := 0 loop if i >= 128 break else { big_array[i] = 69 @@ -862,7 +862,7 @@ main := fn(): uint { if glob_stru.a != 0 return 200 glob_stru = .(1, 1) - strus := [Stru].(glob_stru, glob_stru, glob_stru) + strus := Stru.[glob_stru, glob_stru, glob_stru] i := 0 loop if i == 3 break else { strus[i] = new_stru() @@ -870,7 +870,7 @@ main := fn(): uint { } if strus[2].a != 0 return 100 - strus = [Stru].(glob_stru, glob_stru, glob_stru) + strus = Stru.[glob_stru, glob_stru, glob_stru] i = 0 loop if i == 3 break else { strus[i] = @inline(new_stru) @@ -965,7 +965,7 @@ StructC := struct {c: uint} some_index := fn(): ?uint return 0 -heap := [u8].(0, 1, 2) +heap := u8.[0, 1, 2] optionala := fn(): ?StructA { i := some_index() @@ -1012,7 +1012,7 @@ Struct := struct { pad2: uint, } -file := [u8].(255) +file := u8.[255] opaque := fn(x: uint): uint { return file[x] @@ -1040,7 +1040,7 @@ get := fn(file: ^u8): ?uint { } } -some_file := [u8].(127, 255, 255, 255, 255, 255) +some_file := u8.[127, 255, 255, 255, 255, 255] foo := fn(): ?uint { gotten := get(&some_file[0]) @@ -1096,7 +1096,7 @@ dangle := fn(): ^uint return &0 #### advanced_floating_point_arithmetic ```hb -sin_table := [f32].(0.0, 0.02454122852291229, 0.04906767432741801, 0.07356456359966743, 0.0980171403295606, 0.1224106751992162, 0.1467304744553617, 0.1709618887603012, 0.1950903220161282, 0.2191012401568698, 0.2429801799032639, 0.2667127574748984, 0.2902846772544623, 0.3136817403988915, 0.3368898533922201, 0.3598950365349881, 0.3826834323650898, 0.4052413140049899, 0.4275550934302821, 0.4496113296546065, 0.4713967368259976, 0.492898192229784, 0.5141027441932217, 0.5349976198870972, 0.5555702330196022, 0.5758081914178453, 0.5956993044924334, 0.6152315905806268, 0.6343932841636455, 0.6531728429537768, 0.6715589548470183, 0.6895405447370668, 0.7071067811865475, 0.7242470829514669, 0.7409511253549591, 0.7572088465064845, 0.773010453362737, 0.7883464276266062, 0.8032075314806448, 0.8175848131515837, 0.8314696123025452, 0.844853565249707, 0.8577286100002721, 0.8700869911087113, 0.8819212643483549, 0.8932243011955153, 0.9039892931234433, 0.9142097557035307, 0.9238795325112867, 0.9329927988347388, 0.9415440651830208, 0.9495281805930367, 0.9569403357322089, 0.9637760657954398, 0.970031253194544, 0.9757021300385286, 0.9807852804032304, 0.9852776423889412, 0.989176509964781, 0.99247953459871, 0.9951847266721968, 0.9972904566786902, 0.9987954562051724, 0.9996988186962042, 1.0, 0.9996988186962042, 0.9987954562051724, 0.9972904566786902, 0.9951847266721969, 0.99247953459871, 0.989176509964781, 0.9852776423889412, 0.9807852804032304, 0.9757021300385286, 0.970031253194544, 0.9637760657954398, 0.9569403357322089, 0.9495281805930367, 0.9415440651830208, 0.9329927988347388, 0.9238795325112867, 0.9142097557035307, 0.9039892931234434, 0.8932243011955152, 0.881921264348355, 0.8700869911087115, 0.8577286100002721, 0.8448535652497072, 0.8314696123025455, 0.8175848131515837, 0.8032075314806449, 0.7883464276266063, 0.7730104533627371, 0.7572088465064847, 0.740951125354959, 0.7242470829514669, 0.7071067811865476, 0.6895405447370671, 0.6715589548470186, 0.6531728429537766, 0.6343932841636455, 0.6152315905806269, 0.5956993044924335, 0.5758081914178454, 0.5555702330196022, 0.5349976198870972, 0.5141027441932218, 0.4928981922297841, 0.4713967368259979, 0.4496113296546069, 0.427555093430282, 0.4052413140049899, 0.3826834323650899, 0.3598950365349883, 0.3368898533922203, 0.3136817403988914, 0.2902846772544624, 0.2667127574748985, 0.2429801799032641, 0.21910124015687, 0.1950903220161286, 0.1709618887603012, 0.1467304744553618, 0.1224106751992163, 0.09801714032956083, 0.07356456359966773, 0.04906767432741797, 0.02454122852291233, 0.0, -0.02454122852291208, -0.04906767432741772, -0.0735645635996675, -0.09801714032956059, -0.1224106751992161, -0.1467304744553616, -0.170961888760301, -0.1950903220161284, -0.2191012401568698, -0.2429801799032638, -0.2667127574748983, -0.2902846772544621, -0.3136817403988912, -0.3368898533922201, -0.3598950365349881, -0.3826834323650897, -0.4052413140049897, -0.4275550934302818, -0.4496113296546067, -0.4713967368259976, -0.4928981922297839, -0.5141027441932216, -0.5349976198870969, -0.555570233019602, -0.5758081914178453, -0.5956993044924332, -0.6152315905806267, -0.6343932841636453, -0.6531728429537765, -0.6715589548470184, -0.6895405447370668, -0.7071067811865475, -0.7242470829514668, -0.7409511253549589, -0.7572088465064842, -0.7730104533627367, -0.7883464276266059, -0.8032075314806451, -0.8175848131515838, -0.8314696123025452, -0.844853565249707, -0.857728610000272, -0.8700869911087113, -0.8819212643483549, -0.8932243011955152, -0.9039892931234431, -0.9142097557035305, -0.9238795325112865, -0.932992798834739, -0.9415440651830208, -0.9495281805930367, -0.9569403357322088, -0.9637760657954398, -0.970031253194544, -0.9757021300385285, -0.9807852804032303, -0.9852776423889411, -0.9891765099647809, -0.9924795345987101, -0.9951847266721969, -0.9972904566786902, -0.9987954562051724, -0.9996988186962042, -1.0, -0.9996988186962042, -0.9987954562051724, -0.9972904566786902, -0.9951847266721969, -0.9924795345987101, -0.9891765099647809, -0.9852776423889412, -0.9807852804032304, -0.9757021300385286, -0.970031253194544, -0.96377606579544, -0.9569403357322089, -0.9495281805930368, -0.9415440651830209, -0.9329927988347391, -0.9238795325112866, -0.9142097557035306, -0.9039892931234433, -0.8932243011955153, -0.881921264348355, -0.8700869911087115, -0.8577286100002722, -0.8448535652497072, -0.8314696123025455, -0.817584813151584, -0.8032075314806453, -0.7883464276266061, -0.7730104533627369, -0.7572088465064846, -0.7409511253549591, -0.724247082951467, -0.7071067811865477, -0.6895405447370672, -0.6715589548470187, -0.6531728429537771, -0.6343932841636459, -0.6152315905806274, -0.5956993044924332, -0.5758081914178452, -0.5555702330196022, -0.5349976198870973, -0.5141027441932219, -0.4928981922297843, -0.4713967368259979, -0.449611329654607, -0.4275550934302825, -0.4052413140049904, -0.3826834323650904, -0.359895036534988, -0.33688985339222, -0.3136817403988915, -0.2902846772544625, -0.2667127574748986, -0.2429801799032642, -0.2191012401568702, -0.1950903220161287, -0.1709618887603018, -0.1467304744553624, -0.122410675199216, -0.09801714032956051, -0.07356456359966741, -0.04906767432741809, -0.02454122852291245) +sin_table := f32.[0.0, 0.02454122852291229, 0.04906767432741801, 0.07356456359966743, 0.0980171403295606, 0.1224106751992162, 0.1467304744553617, 0.1709618887603012, 0.1950903220161282, 0.2191012401568698, 0.2429801799032639, 0.2667127574748984, 0.2902846772544623, 0.3136817403988915, 0.3368898533922201, 0.3598950365349881, 0.3826834323650898, 0.4052413140049899, 0.4275550934302821, 0.4496113296546065, 0.4713967368259976, 0.492898192229784, 0.5141027441932217, 0.5349976198870972, 0.5555702330196022, 0.5758081914178453, 0.5956993044924334, 0.6152315905806268, 0.6343932841636455, 0.6531728429537768, 0.6715589548470183, 0.6895405447370668, 0.7071067811865475, 0.7242470829514669, 0.7409511253549591, 0.7572088465064845, 0.773010453362737, 0.7883464276266062, 0.8032075314806448, 0.8175848131515837, 0.8314696123025452, 0.844853565249707, 0.8577286100002721, 0.8700869911087113, 0.8819212643483549, 0.8932243011955153, 0.9039892931234433, 0.9142097557035307, 0.9238795325112867, 0.9329927988347388, 0.9415440651830208, 0.9495281805930367, 0.9569403357322089, 0.9637760657954398, 0.970031253194544, 0.9757021300385286, 0.9807852804032304, 0.9852776423889412, 0.989176509964781, 0.99247953459871, 0.9951847266721968, 0.9972904566786902, 0.9987954562051724, 0.9996988186962042, 1.0, 0.9996988186962042, 0.9987954562051724, 0.9972904566786902, 0.9951847266721969, 0.99247953459871, 0.989176509964781, 0.9852776423889412, 0.9807852804032304, 0.9757021300385286, 0.970031253194544, 0.9637760657954398, 0.9569403357322089, 0.9495281805930367, 0.9415440651830208, 0.9329927988347388, 0.9238795325112867, 0.9142097557035307, 0.9039892931234434, 0.8932243011955152, 0.881921264348355, 0.8700869911087115, 0.8577286100002721, 0.8448535652497072, 0.8314696123025455, 0.8175848131515837, 0.8032075314806449, 0.7883464276266063, 0.7730104533627371, 0.7572088465064847, 0.740951125354959, 0.7242470829514669, 0.7071067811865476, 0.6895405447370671, 0.6715589548470186, 0.6531728429537766, 0.6343932841636455, 0.6152315905806269, 0.5956993044924335, 0.5758081914178454, 0.5555702330196022, 0.5349976198870972, 0.5141027441932218, 0.4928981922297841, 0.4713967368259979, 0.4496113296546069, 0.427555093430282, 0.4052413140049899, 0.3826834323650899, 0.3598950365349883, 0.3368898533922203, 0.3136817403988914, 0.2902846772544624, 0.2667127574748985, 0.2429801799032641, 0.21910124015687, 0.1950903220161286, 0.1709618887603012, 0.1467304744553618, 0.1224106751992163, 0.09801714032956083, 0.07356456359966773, 0.04906767432741797, 0.02454122852291233, 0.0, -0.02454122852291208, -0.04906767432741772, -0.0735645635996675, -0.09801714032956059, -0.1224106751992161, -0.1467304744553616, -0.170961888760301, -0.1950903220161284, -0.2191012401568698, -0.2429801799032638, -0.2667127574748983, -0.2902846772544621, -0.3136817403988912, -0.3368898533922201, -0.3598950365349881, -0.3826834323650897, -0.4052413140049897, -0.4275550934302818, -0.4496113296546067, -0.4713967368259976, -0.4928981922297839, -0.5141027441932216, -0.5349976198870969, -0.555570233019602, -0.5758081914178453, -0.5956993044924332, -0.6152315905806267, -0.6343932841636453, -0.6531728429537765, -0.6715589548470184, -0.6895405447370668, -0.7071067811865475, -0.7242470829514668, -0.7409511253549589, -0.7572088465064842, -0.7730104533627367, -0.7883464276266059, -0.8032075314806451, -0.8175848131515838, -0.8314696123025452, -0.844853565249707, -0.857728610000272, -0.8700869911087113, -0.8819212643483549, -0.8932243011955152, -0.9039892931234431, -0.9142097557035305, -0.9238795325112865, -0.932992798834739, -0.9415440651830208, -0.9495281805930367, -0.9569403357322088, -0.9637760657954398, -0.970031253194544, -0.9757021300385285, -0.9807852804032303, -0.9852776423889411, -0.9891765099647809, -0.9924795345987101, -0.9951847266721969, -0.9972904566786902, -0.9987954562051724, -0.9996988186962042, -1.0, -0.9996988186962042, -0.9987954562051724, -0.9972904566786902, -0.9951847266721969, -0.9924795345987101, -0.9891765099647809, -0.9852776423889412, -0.9807852804032304, -0.9757021300385286, -0.970031253194544, -0.96377606579544, -0.9569403357322089, -0.9495281805930368, -0.9415440651830209, -0.9329927988347391, -0.9238795325112866, -0.9142097557035306, -0.9039892931234433, -0.8932243011955153, -0.881921264348355, -0.8700869911087115, -0.8577286100002722, -0.8448535652497072, -0.8314696123025455, -0.817584813151584, -0.8032075314806453, -0.7883464276266061, -0.7730104533627369, -0.7572088465064846, -0.7409511253549591, -0.724247082951467, -0.7071067811865477, -0.6895405447370672, -0.6715589548470187, -0.6531728429537771, -0.6343932841636459, -0.6152315905806274, -0.5956993044924332, -0.5758081914178452, -0.5555702330196022, -0.5349976198870973, -0.5141027441932219, -0.4928981922297843, -0.4713967368259979, -0.449611329654607, -0.4275550934302825, -0.4052413140049904, -0.3826834323650904, -0.359895036534988, -0.33688985339222, -0.3136817403988915, -0.2902846772544625, -0.2667127574748986, -0.2429801799032642, -0.2191012401568702, -0.1950903220161287, -0.1709618887603018, -0.1467304744553624, -0.122410675199216, -0.09801714032956051, -0.07356456359966741, -0.04906767432741809, -0.02454122852291245] sin := fn(theta: f32): f32 { PI := 3.14159265358979323846 @@ -1289,9 +1289,9 @@ main := fn(): void { #### big_array_crash ```hb -sin_table := [int].(0, 174, 348, 523, 697, 871, 1045, 1218, 1391, 1564, 1736, 1908, 2079, 2249, 2419, 2588, 2756, 2923, 3090, 3255, 3420, 3583, 3746, 3907, 4067, 4226, 4384, 4540, 4695, 4848, 5000, 5150, 5299, 5446, 5591, 5735, 5877, 6018, 6156, 6293, 6427, 6560, 6691, 6819, 6946, 7071, 7193, 7313, 7431, 7547, 7660, 7771, 7880, 7986, 8090, 8191, 8290, 8386, 8480, 8571, 8660, 8746, 8829, 8910, 8987, 9063, 9135, 9205, 9271, 9335, 9396, 9455, 9510, 9563, 9612, 9659, 9702, 9743, 9781, 9816, 9848, 9877, 9902, 9925, 9945, 9961, 9975, 9986, 9993, 9998, 10000) +sin_table := .[0, 174, 348, 523, 697, 871, 1045, 1218, 1391, 1564, 1736, 1908, 2079, 2249, 2419, 2588, 2756, 2923, 3090, 3255, 3420, 3583, 3746, 3907, 4067, 4226, 4384, 4540, 4695, 4848, 5000, 5150, 5299, 5446, 5591, 5735, 5877, 6018, 6156, 6293, 6427, 6560, 6691, 6819, 6946, 7071, 7193, 7313, 7431, 7547, 7660, 7771, 7880, 7986, 8090, 8191, 8290, 8386, 8480, 8571, 8660, 8746, 8829, 8910, 8987, 9063, 9135, 9205, 9271, 9335, 9396, 9455, 9510, 9563, 9612, 9659, 9702, 9743, 9781, 9816, 9848, 9877, 9902, 9925, 9945, 9961, 9975, 9986, 9993, 9998, 10000] -main := fn(): int return sin_table[10] +main := fn(): uint return sin_table[10] ``` #### returning_global_struct @@ -1347,7 +1347,7 @@ main := fn(): uint { ```hb U := struct {u: uint} main := fn(): uint { - arr := @as([U; 2 * 2], idk) + arr := @as([2 * 2]U, idk) i := 0 loop if i == 2 * 2 break else { @@ -1393,8 +1393,8 @@ decide := fn(u: uint): U return .(u, 0, 0) #### wide_ret ```hb OemIdent := struct { - dos_version: [u8; 8], - dos_version_name: [u8; 8], + dos_version: [8]u8, + dos_version_name: [8]u8, } Stru := struct { @@ -1408,7 +1408,7 @@ small_struct := fn(): Stru { maina := fn(major: uint, minor: uint): OemIdent { _f := small_struct() - ver := [u8].(0, 0, 0, 3, 1, 0, 0, 0) + ver := u8.[0, 0, 0, 3, 1, 0, 0, 0] return OemIdent.(ver, ver) } @@ -1688,7 +1688,7 @@ main := fn(): void { #### tests_ptr_to_ptr_copy ```hb main := fn(): uint { - back_buffer := @as([u8; 1024 * 10], idk) + back_buffer := @as([1024 * 10]u8, idk) n := 0 loop if n >= 1024 break else { @@ -1697,7 +1697,7 @@ main := fn(): uint { } n = 1 loop if n >= 10 break else { - *(@as(^[u8; 1024], @bitcast(&back_buffer)) + n) = *@bitcast(&back_buffer) + *(@as(^[1024]u8, @bitcast(&back_buffer)) + n) = *@bitcast(&back_buffer) n += 1 } return back_buffer[1024 * 2] diff --git a/lang/src/fmt.rs b/lang/src/fmt.rs index 99cd5c38e..b6be8a9b2 100644 --- a/lang/src/fmt.rs +++ b/lang/src/fmt.rs @@ -2,8 +2,8 @@ use { crate::{ lexer::{self, Lexer, TokenKind}, parser::{ - self, CommentOr, CtorField, EnumField, Expr, FieldList, Poser, Radix, StructField, - UnionField, + self, CommentOr, CtorField, EnumField, Expr, FieldList, ListKind, Poser, Radix, + StructField, UnionField, }, }, core::{ @@ -60,7 +60,7 @@ fn token_group(kind: TokenKind) -> TokenGroup { Colon => TG::Colon, Semi | Comma => TG::Comma, Dot => TG::Dot, - Ctor | Tupl | TArrow => TG::Ctor, + Ctor | Arr | Tupl | TArrow => TG::Ctor, LParen | RParen => TG::Paren, LBrace | RBrace | LBrack | RBrack => TG::Bracket, Number | Float => TG::Number, @@ -391,35 +391,40 @@ impl<'a> Formatter<'a> { }, ) } - Expr::Tupl { + Expr::List { pos, + kind: term, ty: Some(&Expr::Slice { pos: spos, size: Some(&Expr::Number { value, .. }), item }), fields, trailing_comma, } if value as usize == fields.len() => self.fmt( - &Expr::Tupl { + &Expr::List { pos, + kind: term, ty: Some(&Expr::Slice { pos: spos, size: None, item }), fields, trailing_comma, }, f, ), - Expr::Tupl { ty, fields, trailing_comma, .. } => { + Expr::List { ty, kind: term, fields, trailing_comma, .. } => { if let Some(ty) = ty { self.fmt_paren(ty, f, unary)?; } - f.write_str(".(")?; - self.fmt_list(f, trailing_comma, ")", ",", fields, Self::fmt) + let (start, end) = match term { + ListKind::Tuple => (".(", ")"), + ListKind::Array => (".[", "]"), + }; + f.write_str(start)?; + self.fmt_list(f, trailing_comma, end, ",", fields, Self::fmt) } Expr::Slice { item, size, .. } => { f.write_str("[")?; - self.fmt(item, f)?; if let Some(size) = size { - f.write_str("; ")?; self.fmt(size, f)?; } - f.write_str("]") + f.write_str("]")?; + self.fmt(item, f) } Expr::Index { base, index } => { self.fmt(base, f)?; diff --git a/lang/src/lexer.rs b/lang/src/lexer.rs index 1130cd8ec..7de8d45cc 100644 --- a/lang/src/lexer.rs +++ b/lang/src/lexer.rs @@ -138,6 +138,7 @@ pub enum TokenKind { Ctor, Tupl, + Arr, TArrow, Or, @@ -347,6 +348,7 @@ gen_token_kind! { #[punkt] Ctor = ".{", Tupl = ".(", + Arr = ".[", TArrow = "=>", // #define OP: each `#[prec]` delimeters a level of precedence from lowest to highest #[ops] @@ -550,6 +552,7 @@ impl<'a> Lexer<'a> { } b'.' if self.advance_if(b'{') => T::Ctor, b'.' if self.advance_if(b'(') => T::Tupl, + b'.' if self.advance_if(b'[') => T::Arr, b'=' if self.advance_if(b'>') => T::TArrow, b'&' if self.advance_if(b'&') => T::And, b'|' if self.advance_if(b'|') => T::Or, diff --git a/lang/src/parser.rs b/lang/src/parser.rs index afa898f3d..93919a981 100644 --- a/lang/src/parser.rs +++ b/lang/src/parser.rs @@ -486,14 +486,20 @@ impl<'a, 'b> Parser<'a, 'b> { body: self.ptr_expr()?, }, T::Ctor => self.ctor(pos, None), - T::Tupl => self.tupl(pos, None), + T::Tupl => self.tupl(pos, None, ListKind::Tuple), + T::Arr => self.tupl(pos, None, ListKind::Array), T::LBrack => E::Slice { - item: self.ptr_unit_expr()?, - size: self.advance_if(T::Semi).then(|| self.ptr_expr()).trans()?, - pos: { - self.expect_advance(T::RBrack)?; - pos + size: { + if self.advance_if(T::RBrack) { + None + } else { + let adv = self.ptr_expr()?; + self.expect_advance(T::RBrack)?; + Some(adv) + } }, + item: self.ptr_unit_expr()?, + pos, }, T::Band | T::Mul | T::Xor | T::Sub | T::Que | T::Not | T::Dot => E::UnOp { pos, @@ -547,7 +553,7 @@ impl<'a, 'b> Parser<'a, 'b> { loop { let token = self.token; - if matches!(token.kind, T::LParen | T::Ctor | T::Dot | T::Tupl | T::LBrack) { + if matches!(token.kind, T::LParen | T::Ctor | T::Dot | T::Tupl | T::Arr | T::LBrack) { self.next(); } @@ -558,7 +564,8 @@ impl<'a, 'b> Parser<'a, 'b> { trailing_comma: core::mem::take(&mut self.trailing_sep), }, T::Ctor => self.ctor(token.start, Some(expr)), - T::Tupl => self.tupl(token.start, Some(expr)), + T::Tupl => self.tupl(token.start, Some(expr), ListKind::Tuple), + T::Arr => self.tupl(token.start, Some(expr), ListKind::Array), T::LBrack => E::Index { base: self.arena.alloc(expr), index: { @@ -586,11 +593,12 @@ impl<'a, 'b> Parser<'a, 'b> { Some(expr) } - fn tupl(&mut self, pos: Pos, ty: Option>) -> Expr<'a> { - Expr::Tupl { + fn tupl(&mut self, pos: Pos, ty: Option>, kind: ListKind) -> Expr<'a> { + Expr::List { pos, + kind, ty: ty.map(|ty| self.arena.alloc(ty)), - fields: self.collect_list(TokenKind::Comma, TokenKind::RParen, Self::expr), + fields: self.collect_list(TokenKind::Comma, kind.term(), Self::expr), trailing_comma: core::mem::take(&mut self.trailing_sep), } } @@ -1029,8 +1037,9 @@ generate_expr! { trailing_comma: bool, }, /// `[Expr] LIST('.(', ',', ')', Ident [':' Expr])` - Tupl { + List { pos: Pos, + kind: ListKind, ty: Option<&'a Self>, fields: &'a [Self], trailing_comma: bool, @@ -1091,6 +1100,20 @@ generate_expr! { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ListKind { + Tuple, + Array, +} +impl ListKind { + fn term(self) -> TokenKind { + match self { + ListKind::Tuple => TokenKind::RParen, + ListKind::Array => TokenKind::RBrack, + } + } +} + impl Expr<'_> { pub fn declares(&self, iden: DeclId, source: &str) -> Option { match *self { diff --git a/lang/src/son.rs b/lang/src/son.rs index ab7021e5b..f6386ce79 100644 --- a/lang/src/son.rs +++ b/lang/src/son.rs @@ -11,7 +11,7 @@ use { parser::{ self, idfl::{self}, - CommentOr, CtorField, DeclId, Expr, ExprRef, FieldList, MatchBranch, Pos, + CommentOr, CtorField, DeclId, Expr, ExprRef, FieldList, ListKind, MatchBranch, Pos, }, ty::{ self, Arg, ArrayLen, CompState, ConstData, EnumData, EnumField, FTask, FuncData, @@ -1607,14 +1607,14 @@ impl<'a> Codegen<'a> { Expr::Directive { name: "inline", args: [func, args @ ..], .. } => { self.gen_call(func, args, true) } - Expr::Tupl { pos, ty, fields, .. } => { - let ty = ty + Expr::List { pos, kind, ty, fields, .. } => { + let rty = ty .map(|ty| self.ty(ty)) .or(ctx.ty.map(|ty| self.tys.inner_of(ty).unwrap_or(ty))) .map(ty::Id::expand); - match ty { - None => { + match (rty, kind) { + (None, ListKind::Tuple) => { let arg_base = self.tys.tmp.args.len(); let mut values = Vec::with_capacity(fields.len()); for field in fields { @@ -1651,7 +1651,35 @@ impl<'a> Codegen<'a> { Some(Value::ptr(mem).ty(tupl.into())) } - Some(ty::Kind::Struct(s)) => { + (None, ListKind::Array) => { + let mut array_meta = None::<(ty::Id, Nid)>; + let mut offset = 0; + for field in fields { + let (elem, mem) = match array_meta { + Some((ty, mem)) => { + (self.checked_expr(field, ty, "array element")?, mem) + } + None => { + let expr = self.expr(field)?; + let aty = self.tys.make_array(expr.ty, fields.len() as _); + let mem = self.new_stack(pos, aty); + array_meta = Some((expr.ty, mem)); + (expr, mem) + } + }; + let mem = self.offset(mem, offset); + self.store_mem(mem, elem.ty, elem.id); + offset += self.tys.size_of(elem.ty); + } + + let Some((_, mem)) = array_meta else { + return self.error(pos, "can not infer the type of the array element, \ + array is empty, has no explicit type, and type is not obvious from the context"); + }; + + Some(Value::ptr(mem).ty(self.ci.nodes[mem].ty)) + } + (Some(ty::Kind::Struct(s)), ListKind::Tuple) => { let mem = self.new_stack(pos, s.into()); let mut offs = OffsetIter::new(s, self.tys); for field in fields { @@ -1683,15 +1711,17 @@ impl<'a> Codegen<'a> { } Some(Value::ptr(mem).ty(s.into())) } - Some(ty::Kind::Slice(s)) => { - let slice = &self.tys.ins.slices[s]; - let len = slice.len().unwrap_or(fields.len()); - let elem = slice.elem; + (Some(kty), ListKind::Array) => { + let (len, elem) = if ty.is_none() + && let ty::Kind::Slice(a) = kty + { + let arr = &self.tys.ins.slices[a]; + (arr.len().unwrap_or(fields.len()), arr.elem) + } else { + (fields.len(), kty.compress()) + }; let elem_size = self.tys.size_of(elem); - let aty = slice.len().map_or_else( - || self.tys.make_array(elem, len as ArrayLen), - |_| s.into(), - ); + let aty = self.tys.make_array(elem, len as ArrayLen); if len != fields.len() { return self.error( @@ -1716,11 +1746,10 @@ impl<'a> Codegen<'a> { Some(Value::ptr(mem).ty(aty)) } - Some(t) => self.error( + (Some(t), ListKind::Tuple) => self.error( pos, fa!( - "the {}type of the constructor is `{}`, \ - but thats not a struct nor slice or array", + "the {}type of the constructor is `{}`, but thats not a struct", if ty.is_some() { "" } else { "inferred " }, self.ty_display(t.compress()), ),