Anonymous avatar Anonymous committed 88e7632

Put in some of the code for finding the free variables in an expression.

Comments (0)

Files changed (3)

 LINKFLAGS=-linkpkg
 OCAMLOPTFLAGS=
 
-SRC_FILES := blub_types.mli blub_error.ml blub_misc.ml blub_common.ml blub_ast.ml blub_environment.ml blub_typecheck.ml blub_llvm.ml blub_vm.ml blub_list.ml blub_parse.mly blub_vector.ml blub_num.ml blub_string.ml blub_lexer.mll blub_primitives.ml blub_interp.ml
+SRC_FILES := blub_types.mli blub_error.ml blub_misc.ml blub_common.ml blub_ast.ml blub_environment.ml blub_typecheck.ml blub_closure.ml blub_llvm.ml blub_vm.ml blub_list.ml blub_parse.mly blub_vector.ml blub_num.ml blub_string.ml blub_lexer.mll blub_primitives.ml blub_interp.ml
 ML_FILES  := $(filter %.ml,$(patsubst %.mll,%.ml,$(SRC_FILES:%.mly=%.ml)))
 MLI_FILES := $(filter %.mli,$(SRC_FILES:%.mly=%.mli))
 CMX_FILES := $(ML_FILES:%.ml=%.cmx) 
+open Format
+open Blub_types
+open Blub_common
+
+module VarSet = Set.Make(struct
+			    type t = variable
+			    let compare e1 e2 = compare e1 e2
+			  end)
+
+let pp_set ppe f s =
+  let l = VarSet.elements s in
+  pp_list ppe f l
+;;
+
+(*
+  TODO globals need to be included in the bound_vars
+  TODO when we are compiling in a runtime environment, there are many more
+  bound variables than there would be otherwise
+*)
+
+let rec find_free (bound_vars:VarSet.t) ast = 
+  let rec find = function
+      A_lit _ -> VarSet.empty
+    | A_ref v -> 
+	if VarSet.mem v bound_vars then
+	  VarSet.empty
+	else
+	  VarSet.add v VarSet.empty
+    | A_cnd (e1, e2, e3) -> 
+	VarSet.union (find e1)
+	  (VarSet.union (find e2) (find e3))
+    | A_seq exprs -> 
+	Array.fold_right (fun expr acc ->
+			    VarSet.union (find expr) acc)
+	  exprs VarSet.empty
+    | A_abs (params, _, body) -> 
+	let bound_vars = Array.fold_right 
+	  (fun param acc ->
+	     VarSet.add param acc)
+	  params bound_vars
+	in
+	find_free bound_vars body
+    | A_app (fn, args) -> 
+	let arg_free = Array.fold_right (fun expr acc ->
+					   VarSet.union (find expr) acc)
+	  args VarSet.empty
+	in
+	VarSet.union (find fn) arg_free
+    | A_let _ -> assert false
+    | A_callcc _ -> assert false
+    | A_set _ -> assert false
+  in
+  let free_vars = find ast in
+  printf "FREE VARS: %a\n%!" (pp_set pp_var) free_vars;
+  free_vars
+;;
+
 	| A_seq exprs ->
 	    Array.fold_right (bc_compile env) exprs next
 	| A_abs (params, varargs, body) ->
+	    (* Gather up all the free variables... not currently used for
+	       anything, and this stage maybe should be deferred. *)
+	    (* FIXME this is far from the full, true set of bound variables *)
+	    let bound_vars = Array.fold_right 
+	      (fun var acc ->
+		 Blub_closure.VarSet.add var acc)
+	      params Blub_closure.VarSet.empty 
+	    in
+	    let _ = try
+	      Blub_closure.find_free bound_vars body
+	    with _ -> Blub_closure.VarSet.empty
+	    in
+
+
 	    (* NOTE that this is a completely deferred compilation, which will
 	       allow us to compile it in terms of the *live* environment rather
 	       than with everything unbound.  However, there are many cases
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.