|
|
- module Set = import "data/set.ml"
- open import "prelude.ml"
-
- type update_flag = Updatable | Function
-
- type lambda_form 'a <- { name : string, free_vars : Set.t string, args : list string, update : update_flag, body : 'a }
-
- type stg_atom =
- | Var of string
- | Int of int
-
- type stg_pattern =
- | Con_pat of int * list string
- | Default
-
- type stg_primitive =
- | Add
- | Sub
- | Mul
- | Div
- | Equ
-
- type stg_expr =
- | Let of list (lambda_form stg_expr) * stg_expr
- | Case of stg_expr * string * list (stg_pattern * stg_expr)
- | App of stg_atom * list stg_atom
- | Con of int * int * list stg_atom
- | Prim of stg_primitive * list stg_atom
- | Atom of stg_atom
-
- type stg_def =
- | Fun of { name : string, args : list string, body : stg_expr, is_con : option int }
- | Ffi_def of { name : string, fent : string, arity : int }
-
- let stg_fv =
- let rec go = function
- | Atom a -> go_atom a
- | Let (lfs, e) ->
- let fv = go e
- fv `Set.difference` Set.from_list (map (.name) lfs)
- | App (a, args) -> foldl Set.union Set.empty (map go_atom (a::args))
- | Con (_, _, i) -> foldl Set.union Set.empty (map go_atom i)
- | Case (ex, binder, pats) ->
- foldl go_pat (go ex) pats
- |> Set.delete binder
- | Prim (_, args) -> foldl Set.union Set.empty (map go_atom args)
- and go_atom = function
- | Int _ -> Set.empty
- | Var e -> Set.singleton e
- and go_pat set = function
- | Default, e -> Set.union set (go e)
- | Con_pat (_, args), e -> Set.union set (go e `Set.difference` Set.from_list args)
- go
|