Skip to content

Commit

Permalink
further trait work
Browse files Browse the repository at this point in the history
  • Loading branch information
Wren H committed Sep 22, 2024
1 parent 8a5f4ea commit c0edeaa
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 29 deletions.
6 changes: 4 additions & 2 deletions lib/frontend/ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,12 @@ type 'a trait = {
type 'a impl = {
data : data;
parent : 'a;
polys : 'a list;
args : ('a * 'a typ) list;
assocs : ('a * 'a typ) list;
impls : ('a, yes) definition list;
(* we give each impl function a unique name alongside it's
name predefined from the trait
*)
impls : ('a * ('a, yes) definition) list;
}
[@@deriving show { with_path = false }]

Expand Down
9 changes: 8 additions & 1 deletion lib/frontend/parser.ml
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,14 @@ let impl =
let* t = typ in
return (i, t))))
in
let* impls = parens @@ many definition_body in
let* impls =
parens
@@ many
@@
let* id = id in
let* d = definition_body in
return (id, d)
in
return @@ ({ data = d (); parent; args; assocs; impls } : 'a impl)

let toplevel =
Expand Down
49 changes: 25 additions & 24 deletions lib/frontend/trait_resolution.ml
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,25 @@ let zipby (l1 : ('a * 'b) list) (l2 : ('a * 'c) list) :
in
go l1 l2

type resolved_by =
| Global of resolved impl
| Local of resolved * resolved trait_bound (* type, trait *)

type ctx = {
traits : resolved trait list;
methods : (resolved * resolved trait) list;
impls : resolved impl list;
by_trait : (resolved trait * resolved impl list) list;
impls : resolved_by list;
by_trait : (resolved trait * resolved_by list) list;
local_polys : resolved list;
}

let impl_collection : resolved impl by_uuid = new_by_uuid 100
let impl_collection : resolved_by by_uuid = new_by_uuid 100

let rec search_impls (ctx : ctx) (want : 'a trait_bound) :
('a impl, string) result =
(resolved_by, string) result =
(* this function searches the context, trying to find a valid
impl for some given trait bound
also handles recursively trying to find all of the "lower"
impls
TODO: does this actually handle
does NOT try and find "lower" dependency impls
*)
let name, args, assocs = want in
match
Expand All @@ -52,12 +53,17 @@ let rec search_impls (ctx : ctx) (want : 'a trait_bound) :
match xs with
| [] -> err "no matching impl found!"
| impl :: xs ->
let impl_args, impl_assocs =
match impl with
| Global i -> (i.args, i.assocs)
| Local (_, (_, args, assocs)) -> (args, assocs)
in
(* we want to figure out if we can find an
impl that matches the given constraints that we have
*)
let twice f (a, b) = (f a, f b) in
let* args' = zipby args impl.args in
let* assocs' = zipby assocs impl.assocs in
let* args' = zipby args impl_args in
let* assocs' = zipby assocs impl_assocs in
(* copy to ensure no "cross influences" *)
let args' = List.map (twice copy_typ) args' in
let assocs' = List.map (twice copy_typ) assocs' in
Expand All @@ -75,18 +81,8 @@ let rec search_impls (ctx : ctx) (want : 'a trait_bound) :
|> List.flatten
in
let map =
(* make sure to account for the fact that the
impl might also have "loose" polys lying around
for example in the case of
impl<a> foo<a> {}
and those are rigid
TODO: this resolution does not handle said cases
properly, as we have no way of expressing that
these are valid to unify with other rigid
polys, but not with anything else
*)
make_metas (ctx.local_polys @ impl.polys) all_metas
(* make sure to keep local rigids rigid *)
make_metas ctx.local_polys all_metas
in
(* turn all the polys that aren't rigid into metas *)
let args'inst =
Expand All @@ -107,7 +103,12 @@ let rec search_impls (ctx : ctx) (want : 'a trait_bound) :
in
(* if we get to here, everything unified nicely, so
we have a match!
now we need to use the map that we got earlier,
take the trait that we're dealing with, and
find impls for all of the traits that are bounds
for this one
*)
failwith "tmp"
ok @@ impl
in
failwith "tmp")
go impls)
4 changes: 3 additions & 1 deletion lib/frontend/typecheck.ml
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,9 @@ let typecheck_definition (ctx : ctx) (d : (resolved, yes) definition)

let typecheck_impl (ctx: ctx) (i: resolved impl): (unit, string) result =
(* TODO: check that args match the trait *)
List.map (typecheck_definition ctx) i.impls
i.impls
|> List.map snd (* we don't care about the unique name at the moment *)
|> List.map (typecheck_definition ctx)
|> collect
|> Result.map_error (String.concat " ")
|> Result.map (fun _ -> ())
Expand Down
2 changes: 1 addition & 1 deletion test.kha
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
))

(impl 5 0 ((1 TyInt)) () (
(let 2 () () ((6 TyInt)) TyString ($ (-1) 6))
9 (let 2 () () ((6 TyInt)) TyString ($ (-1) 6))
))

(let 8 () () () TyString ($ (2) int))

0 comments on commit c0edeaa

Please sign in to comment.