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

SCM Repository

[diderot] View of /trunk/src/compiler/c-util/print-as-c.sml
ViewVC logotype

View of /trunk/src/compiler/c-util/print-as-c.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1368 - (download) (annotate)
Wed Jun 22 20:58:28 2011 UTC (8 years ago) by jhr
Original Path: trunk/src/compiler/c-target/print-as-c.sml
File size: 8305 byte(s)
  merging changes from pure-cfg
(* print-as-c.sml
 *
 * COPYRIGHT (c) 2011 The Diderot Project (http://diderot-language.cs.uchicago.edu)
 * All rights reserved.
 *
 * Print the CLang representation using C99 syntax.
 *)

structure PrintAsC : sig

    type strm

    val new : TextIO.outstream -> strm

    val close : strm -> unit

    val output : strm * CLang.decl -> unit

  end = struct

    structure CL = CLang
    structure PP = TextIOPP

    type strm = PP.stream

    val indent = (PP.Abs 4)	(* standard indentation amount *)

    fun new outs = PP.openOut {dst = outs, wid = 90}

    val close = PP.closeStream

    fun output (strm, decl) = let
	  val str = PP.string strm
	  fun sp () = PP.space strm 1
	  fun inHBox f = (PP.openHBox strm; f(); PP.closeBox strm)
	  fun ppComLn s = (
		inHBox (fn () => (str "// "; str s));
		PP.newline strm)
	  fun ppList {pp, sep, l} = let
		fun ppList' [] = ()
		  | ppList' [x] = pp x
		  | ppList' (x::xs) = (pp x; sep(); ppList' xs)
		in
		  ppList' l
		end
	  fun ppTy (ty, optVar) = let
		fun getBaseTy (CL.T_Ptr ty) = getBaseTy ty
		  | getBaseTy (CL.T_Array(ty, _)) = getBaseTy ty
		  | getBaseTy (CL.T_Num rty) = (case rty
		       of RawTypes.RT_Int8 => "int8_t"
			| RawTypes.RT_UInt8 => "uint8_t"
			| RawTypes.RT_Int16 => "int16_t"
			| RawTypes.RT_UInt16 => "uint16_t"
			| RawTypes.RT_Int32 => "int32_t"
			| RawTypes.RT_UInt32 => "uint32_t"
			| RawTypes.RT_Int64 => "int64_t"
			| RawTypes.RT_UInt64 => "uint64_t"
			| RawTypes.RT_Float => "float"
			| RawTypes.RT_Double => "double"
		      (* end case *))
		  | getBaseTy (CL.T_Named ty) = ty
		fun pp (isFirst, CL.T_Ptr ty, optVar) = (
		      if isFirst then sp() else ();
		      case ty
		       of CL.T_Array _ => (
			    str "(*"; pp(false, ty, optVar); str ")")
			| _ => (str "*"; pp(false, ty, optVar))
		      (* end case *))
		  | pp (isFirst, CL.T_Array(ty, optN), optVar) = (
		      pp (isFirst, ty, optVar);
		      case optN
		       of NONE => str "[]"
			| SOME n => (str "["; str(Int.toString n); str "]")
		      (* end case *))
		  | pp (isFirst, _, SOME x) = (
		      if isFirst then sp() else ();
		      str x)
		  | pp (_, _, NONE) = ()
		in
		  str (getBaseTy ty);
		  pp (true, ty, optVar)
		end
          fun ppAttrs [] = ()
            | ppAttrs attrs = (
                ppList {pp=str, sep=sp, l = attrs};
                sp())
	  fun ppDecl dcl = (case dcl
		 of CL.D_Comment l => List.app ppComLn l
		  | CL.D_Verbatim l =>
		      List.app (fn s => (str s; PP.newline strm)) l
		  | CL.D_Var(attrs, ty, x, optInit) => (
		      inHBox (fn () => (
			ppAttrs attrs;
			ppTy (ty, SOME x);
			case optInit
			 of SOME init => (sp(); str "="; sp(); ppInit init)
			  | NONE => ()
			(* end case *);
			str ";"));
		      PP.newline strm)
		  | CL.D_Func(attrs, ty, f, params, body) => (
		      inHBox (fn () => (
			ppAttrs attrs;
			ppTy(ty, SOME f);
			sp(); str "(";
			ppList {pp=ppParam, sep=fn () => (str ","; sp()), l=params};
			str ")"));
		      PP.newline strm;
		      ppBlock (case body of CL.S_Block stms => stms | stm => [stm]))
		  | CL.D_StructDef(fields, tyName) => (
		      str "typedef struct {"; 
		      PP.openVBox strm indent;
			List.app (fn (ty, x) => (
			    PP.newline strm;
			    inHBox (fn () => (ppTy(ty, SOME x); str ";"))))
			  fields;
		      PP.closeBox strm;
		      PP.newline strm;
		      inHBox (fn () => (str "}"; sp(); str tyName; str ";"));
		      PP.newline strm)
		(* end case *))
	  and ppParam (CL.PARAM(attrs, ty, x)) = (
		ppAttrs attrs;
		ppTy(ty, SOME(CL.varToString x)))
	  and ppInit init = (case init
		 of CL.I_Exp e => ppExp e
		  | CL.I_Struct fields => (
		      str "{";
		      PP.openHVBox strm indent;
			List.app (fn (lab, init) => (
			    PP.break strm;
			    inHBox (fn () => (
			      str("." ^ lab); sp(); str "="; sp(); ppInit init; str ","))))
			  fields;
		      PP.closeBox strm;
		      str "}")
		  | CL.I_Array elems => (
		      str "{";
		      PP.openHVBox strm indent;
			List.app (fn (i, init) => (
			    PP.break strm;
			    inHBox (fn () => (
			      str(concat["[", Int.toString i, "]"]); sp(); str "="; sp();
			      ppInit init; str ","))))
			  elems;
		      PP.closeBox strm;
		      str "}")
		(* end case *))
	  and ppBlock stms =  (
		str "{";
		PP.openVBox strm indent;
		  PP.newline strm;
		  List.app ppStm stms;
		PP.closeBox strm;
		str "}"; PP.newline strm)
	  and ppStm stm = (case stm
		 of CL.S_Block stms => ppBlock stms
		  | CL.S_Comment l => List.app ppComLn l
		  | CL.S_Decl(attrs, ty, x, NONE) => (
		      inHBox ( fn () => (
		        ppAttrs attrs;
                        ppTy(ty, SOME x); str ";"));
                      PP.newline strm)
		  | CL.S_Decl(attrs, ty, x, SOME e) => (
		      inHBox (fn () => (
		        ppAttrs attrs;
			ppTy(ty, SOME x); sp(); str "="; sp(); ppInit e; str ";"));
		      PP.newline strm)
		  | CL.S_Exp e => (
		      inHBox (fn () => (ppExp e; str ";"));
		      PP.newline strm)
		  | CL.S_If(e, blk, CL.S_Block[]) =>
		      inHBox (fn () => (str "if"; sp(); ppExp e; ppStms blk))
		  | CL.S_If(e, blk1, blk2) => (
		      inHBox (fn () => (str "if"; sp(); ppExp e)); ppStms blk1;
		      str "else"; ppStms blk2)
		  | CL.S_While(e, blk) => (
		      inHBox (fn () => (str "while"; sp(); ppExp e)); ppStms blk)
		  | CL.S_For(inits, cond, incrs, blk) => let
		      fun ppInit (ty, x, e) = inHBox (fn () => (
			    ppTy(ty, SOME x);
			    sp(); str "="; sp();
			    ppExp e))
		      in
			inHBox (fn () => (
			  str "for"; sp(); str "(";
			  ppList {pp = ppInit, sep = fn () => str ",", l = inits};
			  str ";"; sp();
			  ppExp cond; str ";"; sp();
			  ppList {pp = ppExp, sep = fn () => str ",", l = incrs}));
			  str ")";
			ppStms blk
		      end
		  | CL.S_Call(f, args) => (
		      inHBox (fn () => (str f; ppArgs args; str ";"));
		      PP.newline strm)
		  | CL.S_Return(SOME e) => (
		      inHBox (fn () => (str "return"; sp(); ppExp e; str ";"));
		      PP.newline strm)
		  | CL.S_Return _ => (str "return;"; PP.newline strm)
		  | CL.S_Break => (str "break;"; PP.newline strm)
		  | CL.S_Continue => (str "continue;"; PP.newline strm)
		(* end case *))
	  and ppStms (CL.S_Block stms) = (sp(); ppBlock stms)
	    | ppStms stm = (
		PP.openVBox strm indent;
		  PP.newline strm;
		  ppStm stm;
		PP.closeBox strm)
	  and ppExp e = (case e
		 of CL.E_Grp e => (str "("; ppExp e; str ")")
		  | CL.E_AssignOp(lhs, rator, rhs) => (
		      ppExp lhs; sp(); str(CL.assignopToString rator); sp(); ppExp rhs)
		  | CL.E_BinOp(e1, rator, e2) => (ppExp e1; str(CL.binopToString rator); ppExp e2)
		  | CL.E_UnOp(rator, e) => (str(CL.unopToString rator); ppExp e)
		  | CL.E_PostOp(e, rator) => (ppExp e; str(CL.postopToString rator))
		  | CL.E_Apply(f, args) => (str f; ppArgs args)
		  | CL.E_Subscript(e1, e2) => (ppExp e1; str "["; ppExp e2; str "]")
		  | CL.E_Select(e, f) => (ppExp e; str "."; str f)
		  | CL.E_Indirect(e, f) => (ppExp e; str "->"; str f)
		  | CL.E_Cast(ty, e) => (
		      str "("; ppTy(ty, NONE); str ")"; ppExp e)
		  | CL.E_Var x => str(CL.varToString x)
		  | CL.E_Int(n, CL.T_Num(RawTypes.RT_Int64)) =>
		      str(IntegerLit.toString n ^ "l")
		  | CL.E_Int(n, _) => str(IntegerLit.toString n)
		  | CL.E_Flt(f, ty) => let
		      val isDouble = (case ty
			     of CL.T_Num(RawTypes.RT_Float) => false
			      | _ => true
			    (* end case *))
		    (* NOTE: the CLang.mkFlt function guarantees that f is non-negative *)
		      val f = if FloatLit.same(FloatLit.posInf, f)
			      then if isDouble
				then "HUGE_VAL"
				else "HUGE_VALF"
			    else if FloatLit.same(FloatLit.nan, f)
			      then if isDouble
				then "nan(\"\")"
				else "nanf(\"\")"
			    else if isDouble
			      then FloatLit.toString f
			      else FloatLit.toString f ^ "f"
		      in
			str f
		      end
		  | CL.E_Bool b => str(Bool.toString b)
		  | CL.E_Str s => str(concat["\"", String.toCString s, "\""])
		  | CL.E_Sizeof ty => (str "sizeof("; ppTy(ty, NONE); str ")")
		(* end case *))
	  and ppArgs args = (
		str "(";
		PP.openHOVBox strm indent;
		  PP.cut strm;
		  ppList {
		      pp = fn e => (PP.openHBox strm; ppExp e; PP.closeBox strm),
		      sep = fn () => (str ","; sp()),
		      l = args
		    };
		  str ")";
		PP.closeBox strm)
	  in
	    ppDecl decl
	  end

  end

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