From a83f1d602c6f50eb9ab0448a20f0ecb80fefcead Mon Sep 17 00:00:00 2001
From: Joshua Wise <jwise@andrew.cmu.edu>
Date: Sat, 10 Jul 2010 00:33:56 -0400
Subject: [PATCH] Add strings to the IR

---
 sources.cm          |  1 +
 trans/stringref.sml | 33 +++++++++++++++++++++++++++++++++
 trans/trans.sml     |  1 +
 trans/tree.sml      |  2 ++
 trans/treeutils.sml |  2 ++
 5 files changed, 39 insertions(+)
 create mode 100644 trans/stringref.sml

diff --git a/sources.cm b/sources.cm
index edf6e49..3ab3930 100644
--- a/sources.cm
+++ b/sources.cm
@@ -26,6 +26,7 @@ Group is
 
 	trans/temp.sml
         trans/label.sml
+	trans/stringref.sml
 	trans/tree.sml
 	trans/treeutils.sml
 	trans/trans.sml
diff --git a/trans/stringref.sml b/trans/stringref.sml
new file mode 100644
index 0000000..f78bd95
--- /dev/null
+++ b/trans/stringref.sml
@@ -0,0 +1,33 @@
+(* L3 Compiler
+ * Stringreforaries
+ * Like temporaries, except more different
+ * Author: Joshua Wise <jwise@cs.cmu.edu>
+ *)
+
+signature STRINGREF = 
+sig
+  type stringref
+
+  val reset : unit -> unit	(* resets stringref numbering *)
+  val new : string -> stringref	(* returns a unique new stringref *)
+  val name : stringref -> string	(* returns the name of a stringref *)
+  val compare : stringref * stringref -> order (* comparison function *)
+end
+
+structure Stringref :> STRINGREF = 
+struct
+  type stringref = int
+
+  local
+    val counter = ref 1
+    val strings = ref []
+  in
+    (* warning: calling reset() may jeopardize uniqueness of stringrefs! *)
+    fun reset () = ( counter := 1 ; strings := [] )
+    fun new (s : string) = !counter before ( strings := (!counter, s) :: !strings ; counter := !counter + 1 )
+  end
+
+  fun name t = "S" ^ Int.toString t
+		      
+  fun compare (t1,t2) = Int.compare (t1,t2)
+end
diff --git a/trans/trans.sml b/trans/trans.sml
index 73968d9..0ec6574 100644
--- a/trans/trans.sml
+++ b/trans/trans.sml
@@ -98,6 +98,7 @@ struct
         (* after type-checking, id must be declared; do not guard lookup *)
             T.TEMP (Symbol.look' env id)
         | trans_exp env vartypes (A.ConstExp c) = T.CONST(c)
+        | trans_exp env vartypes (A.StringExp s) = T.STRING(Stringref.new s)
         | trans_exp env vartypes (A.OpExp(oper, [e1, e2])) =
             T.BINOP(trans_oper oper, trans_exp env vartypes e1, trans_exp env vartypes e2)
         | trans_exp env vartypes (A.OpExp(oper, [e])) =
diff --git a/trans/tree.sml b/trans/tree.sml
index 2111fc1..d03180e 100644
--- a/trans/tree.sml
+++ b/trans/tree.sml
@@ -23,6 +23,7 @@ sig
     | CALL of Ast.ident * exp list
     | MEMORY of exp
     | ALLOC of exp
+    | STRING of Stringref.stringref
     | COND of exp * exp * exp
     | STMVAR of stm list * exp
     | NULLPTR
@@ -55,6 +56,7 @@ struct
     | CALL of Ast.ident * exp list
     | MEMORY of exp
     | ALLOC of exp
+    | STRING of Stringref.stringref
     | COND of exp * exp * exp
     | STMVAR of stm list * exp
     | NULLPTR
diff --git a/trans/treeutils.sml b/trans/treeutils.sml
index ec6be4d..a15b1a3 100644
--- a/trans/treeutils.sml
+++ b/trans/treeutils.sml
@@ -28,6 +28,7 @@ struct
     | effect (T.UNOP (_, a)) = effect a
     | effect (T.MEMORY _) = true
     | effect (T.ALLOC _) = true
+    | effect (T.STRING _) = false
     | effect (T.COND (a, b, c)) = (effect a) orelse (effect b) orelse (effect c)
     | effect (T.STMVAR (sl, e)) = true (* Has to be, to be safe <--- jwise is an assclown, he was too lazy to write a effect_stm *)
     | effect (T.NULLPTR) = false
@@ -77,6 +78,7 @@ struct
           Symbol.name f ^ "(" ^ (String.concatWith ", " (List.map (fn e => pp_exp e) l)) ^ ")"
       | pp_exp (T.MEMORY (exp)) = "M[" ^ pp_exp exp ^ "]"
       | pp_exp (T.ALLOC(e)) = "NEW(" ^ pp_exp e ^ ")"
+      | pp_exp (T.STRING(s)) = "STRING(" ^ (Stringref.name s) ^ ")"
       | pp_exp (T.COND(c,e1,e2)) = "(" ^ pp_exp c ^ ") ? (" ^ pp_exp e1 ^ ") : (" ^ pp_exp e2 ^ ")"
       | pp_exp (T.STMVAR(sl,v)) = "({" ^ (foldr (fn (st,s) => (pp_stm st) ^ "; " ^ s) "" sl) ^ (pp_exp v) ^ "})"
       | pp_exp (T.NULLPTR) = "NULL"
-- 
2.43.0