# # Test of generic types # # Copyright © 2023 Samuel Lidén Borell # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # type NonGeneric1 = struct { int x } type NonGeneric2 = struct { bool b int y } type NonGeneric3 = struct { int a int x } type Generic1 = struct { Generic2 same Generic2 fixed Generic2 also_same slot T elem } type Generic2 = struct { slot T elem } type Generic3 = struct { ref Generic2 a ref Generic2 b [2]Generic1 arr } type Generic4 = struct { Generic3 tt_ut Generic3 tt_uu Generic3 tt_uv Generic3 tu_ut Generic3 tu_uu Generic3 tu_uv Generic3 tv_ut Generic3 tv_uu Generic3 tv_uv } func generics_test1() { NonGeneric1 ng1 = (.x=1100) NonGeneric2 ng2 = (.b=true, .y=2200) NonGeneric3 ng3 = (.a=3300, .x=3400) Generic2 g2_int = (.elem = 111) Generic2 g2 = (.elem = refto ng1) Generic1 g1 = ( .same = (.elem = refto ng1), # TODO omitting the "," gives "Unbalances parenthesis" (because the parser thinks that the expr ends) .fixed = (.elem = refto ng3), .also_same = g2, .elem = refto ng1 ) var Generic2 g2_int_b = g2_int g2_int_b.elem = 222 var Generic1 g1_b g1_b = g1 g1_b.same.elem = refto ng1 g1_b.fixed.elem = refto ng3 g1_b.elem = refto ng1 # FIXME implement runtime-computed literals var Generic1 g1_bool = ( .same = (.elem = true), .fixed = (.elem = refto ng3), .also_same = (.elem = false), .elem = true, ) assert g1_bool.same.elem # XXX fails due to runtime-computed literals being unimplemented assert g1_bool.fixed.elem ref_is refto ng3 assert not g1_bool.also_same.elem assert g1_bool.elem g1_bool.fixed.elem = refto ng3 g1_bool.also_same.elem = true var Generic2 g2_bool = (.elem = true) var Generic2> g2_nested = ( .elem = refto g2_int ) g2_nested.elem = refto g2_int g2_nested.elem.elem = 333 var Generic2> g2_nested_bool = ( .elem = refto g2_bool ) var Generic2>> g2_doublenested = ( .elem = refto g2_nested ) g2_doublenested.elem = refto g2_nested g2_doublenested.elem.elem = refto g2_int g2_doublenested.elem.elem.elem = 444 var Generic3 g3_intbool = ( .a = refto g2_int, .b = refto g2_bool, .arr = [g1_bool, g1_bool] ) g3_intbool.a = refto g2_int g3_intbool.b = refto g2_bool g3_intbool.arr = [g1_bool, g1_bool] # FIXME gives "Incompatible types" #g3_intbool.arr[1] = g1_bool # FIXME causes an assertion failure in ir.c:add_result #var Generic3>, ref Generic2> g3_nested = ( # .a = refto g2_doublenested, # .b = refto g2_nested_bool, # .arr = [ # ( # .same = (.elem = refto g2_bool), # .fixed = (.elem = refto ng3), # .also_same = (.elem = refto g2_bool), # .elem = refto g2_bool, # ), # ( # .same = (.elem = refto g2_bool), # .fixed = (.elem = refto ng3), # .also_same = (.elem = refto g2_bool), # .elem = refto g2_bool, # ), # ] #) var int i = 123 var ref var int intref = refto i var Generic4 g4_bound = get_g4_bound() # FIXME .62: error: Unexpected symbol after operator # XXX this could be solved by parsing < as a type parameter IF it is followed by a type # XXX but that will prevent value parameters / dependent types from working on non-methods. E.g. work<10,int> #var Generic4 g4_params = get_g4_params(i, intref) g2_int_b = deref g3_intbool.get_a() i = g3_intbool.get_a_elem() g3_intbool.set_b(refto g2_bool) g3_intbool.set_inner(true) } func get_g4_bound() -> Generic4 { while true { } } func get_g4_params(slot A x, slot B y) -> var Generic4 { slot B b = y NonGeneric3 ng3 = (.a = 123, .x = 456) Generic2 g2_b = (.elem=y) Generic2 g2_ng3 = (.elem = refto ng3) Generic3 g3_bb = ( .a = refto g2_b, .b = refto g2_b, .arr = [ ( .same = g2_b, .fixed = (.elem = refto ng3), .also_same = g2_b, .elem = y ), ( .same = g2_b, .fixed = g2_ng3, .also_same = g2_b, .elem = y )], ) var Generic4 thing # TODO need to assign "thing" before the variable can be used. #thing.tv_uv = g3_bb while true {} } func Generic3.get_a() -> ref Generic2 { return this.a } func Generic3.get_a_elem() -> slot T { return this.a.elem } func Generic3.set_b(ref Generic2 value) { this.b = value } func Generic3.set_inner(slot U inner) { this.arr[1].same.elem = inner } func generics_test() { # TODO fails due to various unimplemented stuff #generics_test1() }