Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] View of /branches/vis15/src/compiler/low-to-tree/env.sml
ViewVC logotype

View of /branches/vis15/src/compiler/low-to-tree/env.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3842 - (download) (annotate)
Tue May 10 14:25:30 2016 UTC (3 years, 7 months ago) by jhr
File size: 3515 byte(s)
working on merge
(* env.sml
 *
 * This code is part of the Diderot Project (http://diderot-language.cs.uchicago.edu)
 *
 * COPYRIGHT (c) 2016 The University of Chicago
 * All rights reserved.
 *)

structure Env : sig

  (* the translated bindings of LowIR variables.  If the variable has a vector type,
   * then it is bound to a vector of expression trees, otherwise it is bound to a
   * single tree.
   *)
    datatype binding
      = TREE of TreeIR.exp         (* variable bound to a target expression tree *)
      | VEC of TreeTypes.vec_layout * TreeIR.exp list

    type t

  (* create a new environment *)
    val new : unit -> t

  (* get the binding for a variable *)
    val useVar : t -> LowIR.var -> binding

  (* add a binding to the environment *)
    val bindVar : t * LowIR.var * TreeIR.exp -> unit

  (* set the definition of a variable, where the RHS is either a literal constant or a variable *)
    val bindSimple : t * LowIR.var * TreeIR.exp -> unit

  (* record a local variable *)
    val addLocal : t * TreeVar.t -> t

  (* at the end of a block, we need to assign any pending expressions to locals.  The
   * blkStms list and the resulting statement list are in reverse order.
   *)
    val flushPending : t * TreeIR.stm list -> t * TreeIR.stm list

  (* close off a scope by turning the stms and locals into a TreeIR block *)
    val endScope : t * TreeIR.stm list -> TreeIR.block

  end = struct

    structure VT = LowIR.Var.Tbl

    datatype binding
      = TREE of TreeIR.exp
      | VEC of TreeTypes.vec_layout * TreeIR.exp list

    datatype t = E of {
	tbl : (bool * binding) VT.hash_table,
	locals : TreeVar.t list
      }

    fun decCount (LowIR.V{useCnt, ...}) = let
	  val n = !useCnt - 1
	  in
	    useCnt := n;  (n <= 0)
	  end

    fun new () = E{tbl = VT.mkTable (256, Fail "tbl"), locals=[]}

  (* use a variable.  If this is its last use, we remove it from the table *)
    fun useVar (env as E{tbl, ...}) = let
	  val find = VT.find tbl
	  val remove = VT.remove tbl
	  fun use x = let
		fun removeUnused () = if (decCount x) then ignore(VT.remove tbl x) else ()
		in
		  case UnifyVars.eqClassOf x
		   of SOME y => (case find y
			 of SOME(isSimple, binding) => binding
			  | NONE => raise Fail(concat ["useVar(", LowIR.Var.toString x, ")"])
			(* end case *))
		    | NONE => (case find x
			 of SOME(true, binding) => (removeUnused(); binding)
			  | SOME(false, binding) => (removeUnused(); binding)
			  | NONE => raise Fail(concat ["useVar(", LowIR.Var.toString x, ")"])
			(* end case *))
		  (* end case *)
		end
	  in
	    use
	  end

    fun bindVar (E{tbl, ...}, x, b) = VT.insert tbl (x, (false, TREE b))

    fun bindSimple (E{tbl, ...}, x, b) = VT.insert tbl (x, (true, TREE b))

    fun addLocal (E{tbl, locals}, x) = E{tbl=tbl, locals=x::locals}

    fun flushPending (E{tbl, locals}, blkStms) = let
          fun doVar (x, (false, TREE e), (locals, stms)) = let
                val t = Util.newLocalVar x
                in
                  VT.insert tbl (x, (true, TREE(TreeIR.E_Var t)));
                  (t::locals, TreeIR.S_Assign(t, e)::stms)
                end
	    | doVar (x, (false, VEC(layout, es)), (locals, stms)) = raise Fail "FIXME"
            | doVar (_, _, acc) = acc
          val (locals, stms) = VT.foldi doVar (locals, blkStms) tbl
          in
            (E{tbl=tbl, locals=locals}, stms)
          end

    fun endScope (E{locals, ...}, stms) = TreeIR.Block{
            locals = List.rev locals,
            body = stms
          }

  end

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0