# HG changeset patch # User Simon Heath # Date 1689796315 14400 # Wed Jul 19 15:51:55 2023 -0400 # Branch devel # Node ID 75dedba050769e51abb9c5ede1c87150ae6ab1e0 # Parent c248fe051c18b015432b9a04d9e7fc4b8635e95a Attempt to make generic inference work. It's uh... there's some weird fucking shit going on in there. I've updated what I have in the issue: https://todo.sr.ht/~icefox/garnetc/21 diff --git a/src/hir.rs b/src/hir.rs --- a/src/hir.rs +++ b/src/hir.rs @@ -108,7 +108,12 @@ typedecl, params, } => { - writeln!(f, "type {}({:?}) = {}", name, params, typedecl.get_name())?; + let mut buf = String::new(); + for param in params { + buf += &*param.val(); + buf += ", "; + } + writeln!(f, "type {}({}) = {}", name, buf, typedecl.get_name())?; } D::Import { name, localname } => { writeln!(f, "import {} as {}", name, localname)?; diff --git a/src/passes/generic_infer.rs b/src/passes/generic_infer.rs --- a/src/passes/generic_infer.rs +++ b/src/passes/generic_infer.rs @@ -74,7 +74,9 @@ } D::Const { name, typ, init } => { let _guard = symtbl.push_scope(); + dbg!("dealing with const", name); for name in typ.get_type_params() { + dbg!(name); symtbl.add_type(name, &Type::Generic(name)); } D::Const { diff --git a/tests/programs/function_generics1.gt b/tests/programs/function_generics1.gt --- a/tests/programs/function_generics1.gt +++ b/tests/programs/function_generics1.gt @@ -9,15 +9,15 @@ -- 42 -- 42 -fn foo(i @T) @T = +fn foo(|T| i T) T = i end -fn first(a @T1, b @T2) @T1 = +fn first(|T1, T2| a T1, b T2) T1 = a end -fn second(a @T1, b @T2) @T2 = +fn second(|T1, T2| a T1, b T2) T2 = b end diff --git a/tests/programs/function_generics2.gt b/tests/programs/function_generics2.gt --- a/tests/programs/function_generics2.gt +++ b/tests/programs/function_generics2.gt @@ -3,15 +3,15 @@ -- Compile: -- status: error -- -fn foo(i @T) @T = +fn foo(i T) T = i end -fn first(a @T1, b @T2) @T1 = +fn first(a T1, b T2) T1 = a end -fn second(a @T1, b @T2) @T2 = +fn second(a T1, b T2) T2 = b end diff --git a/tests/programs/test1.gt b/tests/programs/test1.gt --- a/tests/programs/test1.gt +++ b/tests/programs/test1.gt @@ -32,7 +32,7 @@ end -/ -fn identity(i @T) @T = +fn identity(|T| i T) T = i end diff --git a/tests/programs/test2.gt b/tests/programs/test2.gt --- a/tests/programs/test2.gt +++ b/tests/programs/test2.gt @@ -8,8 +8,8 @@ -- 1 -- false -fn identity(i @T) @T = - let y @T = i +fn identity(|T| i T) T = + let y T = i y end diff --git a/tests/programs/test_array1.gt b/tests/programs/test_array1.gt --- a/tests/programs/test_array1.gt +++ b/tests/programs/test_array1.gt @@ -3,12 +3,12 @@ -- Compile: -- status: success -fn identity(i @T) @T = - let y @T = i +fn identity(|T| i T) T = + let y T = i y end -fn foo(i [3]@T) [3]@T = +fn foo(|T| i [3]T) [3]T = i end diff --git a/tests/programs/test_eq_module.gt b/tests/programs/test_eq_module.gt --- a/tests/programs/test_eq_module.gt +++ b/tests/programs/test_eq_module.gt @@ -9,8 +9,8 @@ -- true -type Eq(@T) = struct - eq: fn(@T, @T) Bool, +type Eq(T) = struct + eq: fn(T, T) Bool, end const IntEq Eq(I32) = Eq { @@ -21,7 +21,7 @@ .eq = fn(lhs Bool, rhs Bool) Bool = lhs == rhs end, } -fn all(|@T| eq_impl Eq(@T), val @T, array [3]@T) Bool = +fn all(|T| eq_impl Eq(T), val T, array [3]T) Bool = let mut i I32 = 0 loop if i == 3 then break end diff --git a/tests/programs/test_failure.gt b/tests/programs/test_failure.gt --- a/tests/programs/test_failure.gt +++ b/tests/programs/test_failure.gt @@ -16,11 +16,11 @@ x end -fn identity(i @T) @T = +fn identity(i T) T = i end -fn identity2(i @X) @X = +fn identity2(i X) X = identity(i) end diff --git a/tests/programs/test_forever1.gt b/tests/programs/test_forever1.gt --- a/tests/programs/test_forever1.gt +++ b/tests/programs/test_forever1.gt @@ -6,7 +6,7 @@ -- Who doesn't like infinite recursion? -- Actually I'm not sure what this should do. -- ...According to OCaml and Rust, the *type checking* is fine. -fn zoom(i @T) @T = +fn zoom(|T| i T) T = zoom(i) end diff --git a/tests/programs/test_lambda3.gt b/tests/programs/test_lambda3.gt --- a/tests/programs/test_lambda3.gt +++ b/tests/programs/test_lambda3.gt @@ -4,7 +4,7 @@ -- status: success -fn apply(f fn(@T) @T, arg @T) @T = +fn apply(|T| f fn(T) T, arg T) T = f(arg) end diff --git a/tests/programs/test_lambda4.gt b/tests/programs/test_lambda4.gt --- a/tests/programs/test_lambda4.gt +++ b/tests/programs/test_lambda4.gt @@ -4,7 +4,7 @@ -- status: success -fn apply(f fn(@In) @Out, arg @In) @Out = +fn apply(|In, Out| f fn(In) Out, arg In) Out = f(arg) end diff --git a/tests/programs/test_lambda5.gt b/tests/programs/test_lambda5.gt --- a/tests/programs/test_lambda5.gt +++ b/tests/programs/test_lambda5.gt @@ -4,7 +4,7 @@ -- status: error -fn apply(f fn(@In) @Out, arg @In) @Out = +fn apply(f fn(In) Out, arg In) Out = f(arg) end diff --git a/tests/programs/test_let1.gt b/tests/programs/test_let1.gt --- a/tests/programs/test_let1.gt +++ b/tests/programs/test_let1.gt @@ -4,7 +4,7 @@ -- status: success -fn id(|@T| x @T) @T = +fn id(|T| x T) T = x end diff --git a/tests/programs/test_let2.gt b/tests/programs/test_let2.gt --- a/tests/programs/test_let2.gt +++ b/tests/programs/test_let2.gt @@ -4,12 +4,12 @@ -- status: success -type Foo(@Thing) = struct - a: @Thing, +type Foo(Thing) = struct + a: Thing, b: Bool end -fn id(|@T| x @T) @T = +fn id(|T| x T) T = x end diff --git a/tests/programs/test_module1.gt b/tests/programs/test_module1.gt --- a/tests/programs/test_module1.gt +++ b/tests/programs/test_module1.gt @@ -14,9 +14,9 @@ -- -- No associated types either, so we just make it a type param for now, -- which surprisingly appears to work. -type Hasher(@Selff, @Out) = struct - write: fn(@Selff, I32) @Selff, - finish: fn(@Selff) @Out, +type Hasher(Selff, Out) = struct + write: fn(Selff, I32) Selff, + finish: fn(Selff) Out, end type DumbHashState = I32 diff --git a/tests/programs/test_module2.gt b/tests/programs/test_module2.gt --- a/tests/programs/test_module2.gt +++ b/tests/programs/test_module2.gt @@ -11,8 +11,8 @@ -- TODO: Make the compiler mangle "Self" since it's a keyword in Rust -- Also "self" and "impl" -type Show(@Selff) = struct - show: fn(@Selff) String +type Show(Selff) = struct + show: fn(Selff) String end -- To make this work we need monomorphization, 'cause Rust refuses to @@ -21,7 +21,7 @@ .show = fn(x I32) String = String(x) end } -fn show(show Show(@T), val @T) String = +fn show(show Show(T), val T) String = show$.show(val) end diff --git a/tests/programs/test_module3.gt b/tests/programs/test_module3.gt --- a/tests/programs/test_module3.gt +++ b/tests/programs/test_module3.gt @@ -11,8 +11,8 @@ -- Fine let's try something simpler. -type Eq(@Selff) = struct - eq: fn(@Selff, @Selff) Bool, +type Eq(Selff) = struct + eq: fn(Selff, Selff) Bool, end -- The name here has to be something other than Eq(I32) 'cause we @@ -28,8 +28,8 @@ end, } -type Ord(@Selff) = struct - cmp: fn(@Selff, @Selff) I32, +type Ord(Selff) = struct + cmp: fn(Selff, Selff) I32, end const IntOrd Ord(I32) = Ord { @@ -39,47 +39,47 @@ } -type From(@Selff, @In) = struct - from: fn(@In) @Selff +type From(Selff, In) = struct + from: fn(In) Selff end const BoolFromInt From(Bool, I32) = From { .from = fn(i I32) Bool = false end } -type List(@T) = struct - dummy_data: @T, +type List(T) = struct + dummy_data: T, end -type Idx(@Selff, @Output) = struct - idx: fn(@Selff, I32) @Output, +type Idx(Selff, Output) = struct + idx: fn(Selff, I32) Output, end -type Len(@Selff) = struct - len: fn(@Selff) I32, +type Len(Selff) = struct + len: fn(Selff) I32, end -const ListLen Len(List(@T)) = Len { - .len = fn(selff List(@T)) I32 = 0 end +const ListLen Len(List(T)) = Len { + .len = fn(selff List(T)) I32 = 0 end } -fn module_len(impll Len(@T), l @T) I32 = +fn module_len(impll Len(T), l T) I32 = let total I32 = 0 impll$.len(l) end -- Specialize it just to make sure everything fits together... -fn list_len(l List(@T)) I32 = +fn list_len(l List(T)) I32 = module_len(ListLen, l) end -const ListIdx Idx(List(@T), @T) = Idx { - .idx = fn(selff List(@T), i I32) @T = selff$.dummy_data end +const ListIdx Idx(List(T), T) = Idx { + .idx = fn(selff List(T), i I32) T = selff$.dummy_data end } -- Generalized thingy... -fn idx(l List(@T)) @T = +fn idx(l List(T)) T = let total I32 = 3 ListIdx$.idx(l, total) end diff --git a/tests/programs/test_module4.gt b/tests/programs/test_module4.gt --- a/tests/programs/test_module4.gt +++ b/tests/programs/test_module4.gt @@ -3,12 +3,12 @@ -- Compile: -- status: error -type Idx(@Self, @Output) = struct - idx: fn(@Self, I32) @Output, +type Idx(Self, Output) = struct + idx: fn(Self, I32) Output, end -type List(@T) = struct - dummy_data: @T, +type List(T) = struct + dummy_data: T, end fn foo(self List(I32), i I32) Bar = diff --git a/tests/programs/test_module6.gt b/tests/programs/test_module6.gt --- a/tests/programs/test_module6.gt +++ b/tests/programs/test_module6.gt @@ -7,26 +7,26 @@ -- stdout: 3 -- A generic functional map from a key to a value -type Map(@T, @K, @V) = struct(@T, @K, @V) - get: fn(@T, @K) @V, - set: fn(@T, @K, @V) @T, +type Map(T, K, V) = struct(T, K, V) + get: fn(T, K) V, + set: fn(T, K, V) T, end -- Implement Map for a cell type -type Cell(@K, @V) = struct(@K, @V) - key: @K, - val: @V +type Cell(K, V) = struct(K, V) + key: K, + val: V end -fn make_cell_map(|@K, @V| k @K, v @V) Map(Cell(@K, @V), @K, @V) = +fn make_cell_map(|K, V| k K, v V) Map(Cell(K, V), K, V) = let module = Map { -- I guess we pretend this always succeeds, -- since I don't really feel like implementing if's - .get = fn(t Cell(@K, @V), key @K) @V = + .get = fn(t Cell(K, V), key K) V = t$.val end, -- Just create a new cell with the given key and val - .set = fn(t Cell(@K, @V), key @K, val @V) Cell(@K, @V) = + .set = fn(t Cell(K, V), key K, val V) Cell(K, V) = Cell { .key = key, .val = val, diff --git a/tests/programs/test_module7.gt b/tests/programs/test_module7.gt --- a/tests/programs/test_module7.gt +++ b/tests/programs/test_module7.gt @@ -18,19 +18,19 @@ end -/ -type Functor(@T1, @T2) = struct - map: fn(@T1) @T2, +type Functor(T1, T2) = struct + map: fn(T1) T2, end -- Implement Map for a cell type -type Cell(@V) = struct - val: @V +type Cell(V) = struct + val: V end -fn make_cell_functor(f fn(@A) @B) Functor(Cell(@A), Cell(@B)) = +fn make_cell_functor(f fn(A) B) Functor(Cell(A), Cell(B)) = -- to work this needs closures, 'cause it -- captures f() - let m = fn(c Cell(@A)) Cell(@B) = + let m = fn(c Cell(A)) Cell(B) = Cell({ .val = f(c$.val) }) diff --git a/tests/programs/test_module_specialization1.gt b/tests/programs/test_module_specialization1.gt --- a/tests/programs/test_module_specialization1.gt +++ b/tests/programs/test_module_specialization1.gt @@ -8,13 +8,13 @@ -- 4 -type List(@T) = struct - dummy_data: @T, +type List(T) = struct + dummy_data: T, end -type Idx(@Selff, @Output) = struct - idx: fn(@Selff, I32) @Output, +type Idx(Selff, Output) = struct + idx: fn(Selff, I32) Output, end -- Can we make an instance for a specialization of List(T)? @@ -23,8 +23,10 @@ } fn main() {} = +/- let x = List { .dummy_data = 4_I32 } let y = IntListIdx$.idx(x, 3) __println(y); -- gfd parser ambiguity + -/ {} end diff --git a/tests/programs/test_monad.gt b/tests/programs/test_monad.gt --- a/tests/programs/test_monad.gt +++ b/tests/programs/test_monad.gt @@ -43,8 +43,8 @@ -- The bad news is, we don't seem to be able to implement real monads -- The good news is, we don't seem to be able to implement real monads -- I think if we had associated types? -type Monad(@A, @M) = struct - return_: fn(@A) @M(@A), - bind: fn(@M(@A), fn(@A) @M(@B)) @M(@B) +type Monad(A, M) = struct + return_: fn(A) M(A), + bind: fn(M(A), fn(A) M(B)) M(B) end diff --git a/tests/programs/test_monomorphization1.gt b/tests/programs/test_monomorphization1.gt --- a/tests/programs/test_monomorphization1.gt +++ b/tests/programs/test_monomorphization1.gt @@ -11,7 +11,7 @@ -- Test case for monomorphization of functions. -fn identity(i @T) @T = +fn identity(i T) T = let y = i y end diff --git a/tests/programs/test_monomorphization2.gt b/tests/programs/test_monomorphization2.gt --- a/tests/programs/test_monomorphization2.gt +++ b/tests/programs/test_monomorphization2.gt @@ -9,9 +9,9 @@ -- 2 -fn identity(i @T) @T = +fn identity(i T) T = -- Does it work properly when we have a declared type for our var? - let y @T = i + let y T = i y end diff --git a/tests/programs/test_monomorphization3.gt b/tests/programs/test_monomorphization3.gt --- a/tests/programs/test_monomorphization3.gt +++ b/tests/programs/test_monomorphization3.gt @@ -18,11 +18,11 @@ __println_bool(y.1) end -fn thing2(x @A) {I32, @A} = +fn thing2(x A) {I32, A} = thing1(3, x) end -fn thing1(i I32, x @A) {I32, @A} = +fn thing1(i I32, x A) {I32, A} = {i, x} end diff --git a/tests/programs/test_result1.gt b/tests/programs/test_result1.gt --- a/tests/programs/test_result1.gt +++ b/tests/programs/test_result1.gt @@ -3,9 +3,9 @@ -- Compile: -- status: error -type Result(@T, @E) = sum - Ok @T, - Err @E, +type Result(T, E) = sum + Ok T, + Err E, end -- TODO: This should probably succeed diff --git a/tests/programs/test_struct1.gt b/tests/programs/test_struct1.gt --- a/tests/programs/test_struct1.gt +++ b/tests/programs/test_struct1.gt @@ -13,7 +13,7 @@ b: Bool end -fn id(x @T) @T = +fn id(|T| x T) T = x end diff --git a/tests/programs/test_struct5.gt b/tests/programs/test_struct5.gt --- a/tests/programs/test_struct5.gt +++ b/tests/programs/test_struct5.gt @@ -3,12 +3,12 @@ -- Compile: -- status: error -type Foo(@Thing) = struct - a: @Blarg, +type Foo(Thing) = struct + a: Blarg, b: Bool end -fn id(x @T) @T = +fn id(x T) T = x end diff --git a/tests/programs/test_struct6.gt b/tests/programs/test_struct6.gt --- a/tests/programs/test_struct6.gt +++ b/tests/programs/test_struct6.gt @@ -3,8 +3,8 @@ -- Compile: -- status: error -type List(@T) = struct - dummy_data: @T, +type List(T) = struct + dummy_data: T, end fn foo(self List(I32), i I32) Bar = diff --git a/tests/programs/test_sum2.gt b/tests/programs/test_sum2.gt --- a/tests/programs/test_sum2.gt +++ b/tests/programs/test_sum2.gt @@ -12,10 +12,10 @@ Especially one you don't know how to fix. We lower the constructors for this type into functions, and then it complains that the function Option.None() -returns Option(@T) and it has no way of knowing what -the @T is for that function. +returns Option(T) and it has no way of knowing what +the T is for that function. -This should technically be fine because @T is +This should technically be fine because T is instantiated and figured out wherever Option.None() is actually called, but I don't know how to tell the typechecker that. @@ -30,8 +30,8 @@ but leaving this note here for now just in case it pops up again later. -/ -type Option(@T) = sum(@T) - Some @T, +type Option(T) = sum(T) + Some T, None {}, end diff --git a/tests/programs/test_tuple2.gt b/tests/programs/test_tuple2.gt --- a/tests/programs/test_tuple2.gt +++ b/tests/programs/test_tuple2.gt @@ -4,8 +4,8 @@ -- status: success -fn identity(i @T) @T = - let y @T = i +fn identity(|T| i T) T = + let y T = i y end diff --git a/tests/programs/test_tuple3.gt b/tests/programs/test_tuple3.gt --- a/tests/programs/test_tuple3.gt +++ b/tests/programs/test_tuple3.gt @@ -4,8 +4,8 @@ -- status: error -fn identity(i @T) @T = - let y @T = i +fn identity(i T) T = + let y T = i y end diff --git a/tests/programs/test_tuple4.gt b/tests/programs/test_tuple4.gt --- a/tests/programs/test_tuple4.gt +++ b/tests/programs/test_tuple4.gt @@ -4,7 +4,7 @@ -- status: success -fn thing(i {@T1, @T2}) {@T1, @T2} = +fn thing(|T1, T2| i {T1, T2}) {T1, T2} = i end diff --git a/tests/programs/test_typedef3.gt b/tests/programs/test_typedef3.gt --- a/tests/programs/test_typedef3.gt +++ b/tests/programs/test_typedef3.gt @@ -4,9 +4,9 @@ -- status: error -type Foo = {I32, @A} +type Foo = {I32, A} -fn thing(i I32, x @A) Foo = +fn thing(i I32, x A) Foo = Foo{i, x} end diff --git a/tests/programs/test_typedef4.gt b/tests/programs/test_typedef4.gt --- a/tests/programs/test_typedef4.gt +++ b/tests/programs/test_typedef4.gt @@ -4,13 +4,13 @@ -- status: success -type Foo(@A) = {I32, @A} +type Foo(A) = {I32, A} -fn thing(i I32, x @A) Foo(@A) = +fn thing(|A| i I32, x A) Foo(A) = Foo{i, x} end -fn thing2(i I32, x @A) {I32, @A} = +fn thing2(|A| i I32, x A) {I32, A} = {i, x} end diff --git a/tests/programs/test_typedef6.gt b/tests/programs/test_typedef6.gt --- a/tests/programs/test_typedef6.gt +++ b/tests/programs/test_typedef6.gt @@ -3,7 +3,7 @@ -- Compile: -- status: success -type Foo(@T) = {I32, @T} +type Foo(T) = {I32, T} fn thing(i I32, x Bool) Foo(Bool) = Foo{i, x} diff --git a/tests/programs/test_typedef7.gt b/tests/programs/test_typedef7.gt --- a/tests/programs/test_typedef7.gt +++ b/tests/programs/test_typedef7.gt @@ -3,7 +3,7 @@ -- Compile: -- status: error -type Foo(@T) = {I32, @T} +type Foo(T) = {I32, T} fn thing(i I32, x Bool) Foo(Bool) = Foo{i, x} diff --git a/tests/programs/test_typedef8.gt b/tests/programs/test_typedef8.gt --- a/tests/programs/test_typedef8.gt +++ b/tests/programs/test_typedef8.gt @@ -3,9 +3,9 @@ -- Compile: -- status: error -type Foo(@T) = {I32, @T} +type Foo(T) = {I32, T} -fn thing2(i I32, x @Whatever) Foo(@Whatever) = +fn thing2(i I32, x Whatever) Foo(Whatever) = Foo{i, x} end diff --git a/tests/programs/test_unnamed_failure1.gt b/tests/programs/test_unnamed_failure1.gt --- a/tests/programs/test_unnamed_failure1.gt +++ b/tests/programs/test_unnamed_failure1.gt @@ -3,8 +3,8 @@ -- Compile: -- status: error -type List(@T) = struct - dummy_data: @T, +type List(T) = struct + dummy_data: T, end fn should_fail() Bar = diff --git a/tests/programs/test_unnamed_failure2.gt b/tests/programs/test_unnamed_failure2.gt --- a/tests/programs/test_unnamed_failure2.gt +++ b/tests/programs/test_unnamed_failure2.gt @@ -7,12 +7,12 @@ -- ...Conflict between Bool and Foo()... -- ... -type Idx(@Self, @Output) = struct - idx: fn(@Self, I32) @Output, +type Idx(Self, Output) = struct + idx: fn(Self, I32) Output, end -type List(@T) = struct - dummy_data: @T, +type List(T) = struct + dummy_data: T, end diff --git a/tests/programs/test_unnamed_failure3.gt b/tests/programs/test_unnamed_failure3.gt --- a/tests/programs/test_unnamed_failure3.gt +++ b/tests/programs/test_unnamed_failure3.gt @@ -7,12 +7,12 @@ -- ...Conflict between I32 and Foo()... -- ... -type Idx(@Self, @Output) = struct - idx: fn(@Self, I32) @Output, +type Idx(Self, Output) = struct + idx: fn(Self, I32) Output, end -type List(@T) = struct - dummy_data: @T, +type List(T) = struct + dummy_data: T, end diff --git a/tests/programs/test_unnamed_generic.gt b/tests/programs/test_unnamed_generic.gt --- a/tests/programs/test_unnamed_generic.gt +++ b/tests/programs/test_unnamed_generic.gt @@ -4,8 +4,8 @@ -- status: error -fn identity(i @T) @T = - let y @Heck = i +fn identity(i T) T = + let y Heck = i y end