tree.sml 5.26 KB
structure Tree: TREE = struct

  datatype binop = Plus
                 | Minus
                 | Mul
                 | Div
                 | And
                 | Or
                 | LShift
                 | RShift
                 | ARShift
                 | Xor

  datatype relop = EQ
                 | NE
                 | LT
                 | GT
                 | LE
                 | GE
                 | ULT
                 | ULE
                 | UGT
                 | UGE

  datatype exp = Const of Int32.int
               | Name of Label.t
               | Temp of Temp.t
               | Param of int
               | Mem of exp
               | BinOp of binop * exp * exp
               | Call of exp * exp list
               | ESeq of stm list * exp
  and stm = Move of exp * exp
               | Jump of exp * Label.t list
               | CJump of relop * exp * exp * Label.t * Label.t
               | Seq of stm list
               | Label of Label.t

  type func = {
    name: Label.t,
    nparams: int,
    body: stm list,
    ret: Temp.t
  }

  type prg = {
    funcs: func list
  }

  fun output_binop str = fn
      Plus => TextIO.output (str, "PLUS")
    | Minus => TextIO.output (str, "MINUS")
    | Mul => TextIO.output (str, "MUL")
    | Div => TextIO.output (str, "DIV")
    | And => TextIO.output (str, "AND")
    | Or => TextIO.output (str, "OR")
    | LShift => TextIO.output (str, "LSHIFT")
    | RShift => TextIO.output (str, "RSHIFT")
    | ARShift => TextIO.output (str, "ARSHIFT")
    | Xor => TextIO.output (str, "XOR")

  fun output_relop str = fn
      EQ => TextIO.output (str, "EQ")
    | NE => TextIO.output (str, "NE")
    | LT => TextIO.output (str, "LT")
    | GT => TextIO.output (str, "GT")
    | LE => TextIO.output (str, "LE")
    | GE => TextIO.output (str, "GE")
    | ULT => TextIO.output (str, "ULT")
    | ULE => TextIO.output (str, "ULE")
    | UGT => TextIO.output (str, "UGT")
    | UGE => TextIO.output (str, "UGE")

  fun output_exp str = fn
      Const(i) =>
        (TextIO.output (str, "CONST(");
         TextIO.output (str, Int32.toString i);
         TextIO.output (str, ")"))
    | Name(l) =>
        (TextIO.output (str, "NAME(");
         TextIO.output (str, Label.toString l);
         TextIO.output (str, ")"))
    | Temp(t) =>
        (TextIO.output (str, "TEMP(");
         TextIO.output (str, Temp.toString t);
         TextIO.output (str, ")"))
    | Param(i) =>
        (TextIO.output (str, "PARAM(");
         TextIO.output (str, Int.toString i);
         TextIO.output (str, ")"))
    | Mem(e1) =>
        (TextIO.output (str, "MEM(");
         output_exp str e1;
         TextIO.output (str, ")"))
    | BinOp(bop, e1, e2) =>
        (TextIO.output (str, "BINOP(");
         output_binop str bop;
         TextIO.output (str, ", ");
         output_exp str e1;
         TextIO.output (str, ", ");
         output_exp str e2;
         TextIO.output (str, ")"))
    | Call(e1, args) =>
        (TextIO.output (str, "CALL(");
         output_exp str e1;
         map (fn arg => (TextIO.output (str, ", ");
                       output_exp str arg)) args;
         TextIO.output (str, ")"))
    | ESeq(stms, e) =>
        (TextIO.output (str, "ESEQ(");
         map (fn arg => (output_stm str arg;
                         TextIO.output (str, ", "))) stms;
         output_exp str e;
         TextIO.output (str, ")"))
  and output_stm str = fn
      Move(e1, e2) =>
        (TextIO.output (str, "MOVE(");
         output_exp str e1;
         TextIO.output (str, ", ");
         output_exp str e2;
         TextIO.output (str, ")"))
    | Jump(e, ls) =>
        (TextIO.output (str, "JUMP(");
         output_exp str e;
         map (fn l => (TextIO.output (str, ", ");
                       TextIO.output (str, Label.toString l))) ls;
         TextIO.output (str, ")"))
    | CJump(rop, e1, e2, l1, l2) =>
        (TextIO.output (str, "CJUMP(");
         output_relop str rop;
         TextIO.output (str, ", ");
         output_exp str e1;
         TextIO.output (str, ", ");
         output_exp str e2;
         TextIO.output (str, ", ");
         TextIO.output (str, Label.toString l1);
         TextIO.output (str, ", ");
         TextIO.output (str, Label.toString l2);
         TextIO.output (str, ")"))
    | Seq(stms) =>
        (TextIO.output (str, "SEQ(");
         output_stm_list str stms;
         TextIO.output (str, ")"))
    | Label(l) =>
        (TextIO.output (str, "LABEL(");
         TextIO.output (str, Label.toString l);
         TextIO.output (str, ")"))
  and output_stm_list str stms =
    let val sep = ref ""
    in map (fn s => (TextIO.output (str, !sep);
                     output_stm str s;
                     sep := ", ")) stms
    end

  fun output_func str (f: func) =
    (TextIO.output (str, Label.toString (#name f));
     TextIO.output (str, "(");
     TextIO.output (str, Int.toString (#nparams f));
     TextIO.output (str, ") {\n");
     (map (fn s => (TextIO.output (str, "  ");
                    output_stm str s;
                    TextIO.output (str, "\n"))) (#body f));
     TextIO.output (str, "  return ");
     TextIO.output (str, Temp.toString (#ret f));
     TextIO.output (str, "\n}\n"))

  fun output_prg str (p: prg) =
    (map (fn f => (output_func str f;
                  TextIO.output (str, "\n"))) (#funcs p);
     ())

end