You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

52 lines
1.5 KiB

  1. module Set = import "data/set.ml"
  2. open import "prelude.ml"
  3. type update_flag = Updatable | Function
  4. type lambda_form 'a <- { name : string, free_vars : Set.t string, args : list string, update : update_flag, body : 'a }
  5. type stg_atom =
  6. | Var of string
  7. | Int of int
  8. type stg_pattern =
  9. | Con_pat of int * list string
  10. | Default
  11. type stg_primitive =
  12. | Add
  13. | Sub
  14. | Mul
  15. | Div
  16. | Equ
  17. type stg_expr =
  18. | Let of list (lambda_form stg_expr) * stg_expr
  19. | Case of stg_expr * string * list (stg_pattern * stg_expr)
  20. | App of stg_atom * list stg_atom
  21. | Con of int * int * list stg_atom
  22. | Prim of stg_primitive * list stg_atom
  23. | Atom of stg_atom
  24. type stg_def =
  25. | Fun of { name : string, args : list string, body : stg_expr, is_con : option int }
  26. | Ffi_def of { name : string, fent : string, arity : int }
  27. let stg_fv =
  28. let rec go = function
  29. | Atom a -> go_atom a
  30. | Let (lfs, e) ->
  31. let fv = go e
  32. fv `Set.difference` Set.from_list (map (.name) lfs)
  33. | App (a, args) -> foldl Set.union Set.empty (map go_atom (a::args))
  34. | Con (_, _, i) -> foldl Set.union Set.empty (map go_atom i)
  35. | Case (ex, binder, pats) ->
  36. foldl go_pat (go ex) pats
  37. |> Set.delete binder
  38. | Prim (_, args) -> foldl Set.union Set.empty (map go_atom args)
  39. and go_atom = function
  40. | Int _ -> Set.empty
  41. | Var e -> Set.singleton e
  42. and go_pat set = function
  43. | Default, e -> Set.union set (go e)
  44. | Con_pat (_, args), e -> Set.union set (go e `Set.difference` Set.from_list args)
  45. go