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

SCM Repository

[diderot] View of /trunk/src/compiler/translate/translate.sml
ViewVC logotype

View of /trunk/src/compiler/translate/translate.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 227 - (download) (annotate)
Wed Aug 4 05:27:13 2010 UTC (9 years, 2 months ago) by jhr
File size: 5414 byte(s)
  Working on lifting
(* translate.sml
 *
 * COPYRIGHT (c) 2010 The Diderot Project (http://diderot.cs.uchicago.edu)
 * All rights reserved.
 *
 * Translate Simple-AST code into the IL representation.
 *)

structure Translate : sig

    val translate : Simple.program -> HighIL.program

  end = struct

    structure S = Simple
    structure VMap = Var.Map
    structure VSet = Var.Set
    structure IL = HighIL

    fun lookup env x = (case VMap.find (env, x)
	   of SOME x' => x'
	    | NONE => raise Fail(concat[
		  "no binding for ", Var.uniqueNameOf x, " in environment"
		])
	  (* end case *))

  (* create a new instance of a variable *)
    fun newVar x = IL.Var.new (Var.nameOf x)

  (* expression translation *)
    fun cvtExp (env, lhs, exp) = (case exp
	   of S.E_Var x => [(lhs, IL.VAR(lookup env x))]
	    | S.E_Lit lit => [(lhs, IL.LIT lit)]
	    | S.E_Tuple xs => raise Fail "E_Tuple not implemeted"
	    | S.E_Apply(f, tyArgs, args, ty) => let
		val args' = List.map (lookup env) args
		in
		  TranslateBasis.translate (lhs, f, tyArgs, args')
		end
	    | S.E_Cons args => [(lhs, IL.CONS(List.map (lookup env) args))]
	    | S.E_Input(name, NONE) => [(lhs, IL.OP(HighOps.Input name, []))]
	    | S.E_Input(name, SOME dflt) =>
		[(lhs, IL.OP(HighOps.InputWithDefault name, [lookup env dflt]))]
	    | S.E_Field fld => [(lhs, IL.OP(HighOps.Field fld, []))]
	    | S.E_LoadImage info => [(lhs, IL.OP(HighOps.LoadImage info, []))]
	  (* end case *))

  (* convert a Simple AST block to an IL statement.  We return the statement that represents the
   * block, plus the environment mapping Simple AST variables to their current SSA representations
   * and the set of Simple AST variables that were assigned to in the block.
   *)
    fun cvtBlock (env, S.Block stms) = let
	  fun toBlock (env, assigned, [], assignments) =
		(IL.mkBLOCK{succ=IL.dummy, body=List.rev assignments}, env, assigned)
	    | toBlock (env, assigned, S.S_Assign(x, e)::rest, assignments) = let
		val x' = newVar x
		val stms = cvtExp(env, x', e)
		val assigned = VSet.add(assigned, x)
		val env = VMap.insert(env, x, x')
		in
		  toBlock (env, assigned, rest, stms@assignments)
		end
	    | toBlock (env, assigned, stms, assignments) = let
		val (succ, env, assigned) = toStmt (env, assigned, stms)
		val blk = IL.mkBLOCK{succ=succ, body=List.rev assignments}
		in
		  IL.addPred (succ, blk);
		  (blk, env, assigned)
		end
	  and toStmt (env, assigned, []) =
		(IL.mkBLOCK{succ=IL.dummy, body=[]}, env, assigned)
	    | toStmt (env, assigned, stms as stm::rest) = (case stm
		 of S.S_Assign _ => toBlock (env, assigned, stms, [])
		  | S.S_IfThenElse(x, b1, b2) => let
		      val x' = lookup env x
		      val (s1, env1, assigned1) = cvtBlock(env, b1)
		      val (s2, env2, assigned2) = cvtBlock(env, b2)
		      val assigned = VSet.union(assigned1, assigned2)
		      val (env, phis) = let
			    fun mkPhi (x, (env, phis)) = let
				  val x1 = lookup env1 x
				  val x2 = lookup env2 x
				  val x' = newVar x
				  in
				    (VMap.insert(env, x, x'), (x', [x1, x2])::phis)
				  end
			    in
			      VSet.foldl mkPhi (env, []) assigned
			    end
		      val stm = IL.mkIF{cond=x', thenBranch=s1, elseBranch=s2}
		      in
			case rest
			 of [] => (stm, env, assigned)
			  | _ => let
			      val (join, env, assigned) = toStmt (env, assigned, rest)
			      in
				IL.addPred (join, stm);
				IL.setSucc (stm, join);
				(stm, env, assigned)
			      end
			(* end case *)
		      end
		  | S.S_New(name, xs) => let
		      val xs' = List.map (lookup env) xs
		      in
			case rest
			 of [] => (IL.mkNEW{actor=name, args=xs', succ=IL.dummy}, env, assigned)
			  | _ => let
			      val (succ, env, assigned) = toStmt (env, assigned, rest)
			      val stm = IL.mkNEW{actor=name, args=xs', succ=succ}
			      in
				IL.addPred (succ, stm);
				(stm, env, assigned)
			      end
		      end
		  | S.S_Die => (IL.mkDIE(), env, assigned)
		  | S.S_Stabilize => (IL.mkSTABILIZE(), env, assigned)
		(* end case *))
	  in
	    toStmt (env, VSet.empty, stms)
	  end

    fun translate (S.Program{globals, staticInit, globalInit, actors}) = let
	  val (globalInit, env, _) = cvtBlock (VMap.empty, globalInit)
	(* get the SSA names for the globals and a reduced environment *)
	  val (env, globs) = let
		val lookup = lookup env
		fun cvtVar (x, (env, globs)) = let
		      val x' = lookup x
		      in
			(VMap.insert(env, x, x'), x'::globs)
		      end
		val (env, globs) = List.foldl cvtVar (VMap.empty, []) globals
		in
		  (env, List.rev globs)
		end
	  fun cvtActor (S.Actor{name, params, state, stateInit, methods}) = let
		val (env, params) = let
		      fun cvtParam (x, (env, xs)) = let
			    val x' = newVar x
			    in
			      (VMap.insert(env, x, x'), x'::xs)
			    end
		      val (env, params) = List.foldl cvtParam (env, []) params
		      in
			(env, List.rev params)
		      end
		val (stateInit, env, _) = cvtBlock (env, stateInit)
		val state = List.map (lookup env) state
		fun cvtMethod (S.Method(name, blk)) = let
		      val (body, _, _) = cvtBlock (env, blk)
		      in
			IL.Method(name, body)
		      end
		in
		  IL.Actor{
		      name = name,
		      params = params,
		      state = state,
		      stateInit = stateInit,
		      methods = List.map cvtMethod methods
		    }
		end
	  in
	    IL.Program{
		globals = globs,
		globalInit = globalInit,
		actors = List.map cvtActor actors
	      }
	  end

  end

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