Advertisement
Guest User

Untitled

a guest
Jun 25th, 2014
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 7.76 KB | None | 0 0
  1. import scala.collection.mutable.ArraySeq
  2.  
  3. object StateOOInterp {
  4.   sealed abstract class Expr
  5.  
  6.   case class Id(id: Symbol) extends Expr
  7.   case class Num(n: Float) extends Expr
  8.   case class Add(lhs: Expr, rhs: Expr) extends Expr
  9.   case class Mult(lhs: Expr, rhs: Expr) extends Expr
  10.   case class Let(id: Symbol, namedExpr: Expr, body: Expr) extends Expr
  11.  
  12.   case class New(className: Symbol, fields: Expr*) extends Expr
  13.   case class GetField(objExpr: Expr, fieldName: Symbol) extends Expr
  14.   case class Call(objExpr: Expr, methodName: Symbol, args: Expr*)
  15.     extends Expr
  16.  
  17.   case class SetField(objExpr: Expr, fieldName: Symbol, e: Expr) extends Expr
  18.   case class Set(id: Symbol, e: Expr) extends Expr
  19.   case class Seqn(exprs: Expr*) extends Expr
  20.  
  21.   case class Class(
  22.     superClass: Symbol,
  23.     fields: Seq[Symbol],
  24.     methods: Map[Symbol, Method])
  25.  
  26.   case class Method(body: Expr, params: Symbol*)
  27.  
  28.   sealed abstract class Value
  29.   // Note how Object now holds Locations instead of Values
  30.   case class Object(className: Symbol, fields: Seq[Location]) extends Value
  31.   case class NumV(n: Float) extends Value
  32.  
  33.   type Env = Map[Symbol, Location]
  34.   type Location = Int
  35.  
  36.   class Store(size: Int) extends scala.collection.mutable.Map[Location, Value] {
  37.     val memory = new ArraySeq[Value](size)
  38.     private var _nextFreeLocation = 0
  39.     private var _free = size
  40.  
  41.     override def +=(kv: (Location, Value)) = {
  42.       val (k, v) = kv
  43.       val oldVal = memory(k)
  44.       memory(k) = v
  45.       if (oldVal == null) _free -= 1
  46.       this
  47.     }
  48.  
  49.     override def -=(k: Location) = {
  50.       val oldVal = memory(k)
  51.       memory(k) = null
  52.       if (oldVal != null) _free += 1
  53.       this
  54.     }
  55.  
  56.     override def get(k: Location) = {
  57.       val v = memory(k)
  58.       if (v == null) None else Some(v)
  59.     }
  60.  
  61.     override def iterator = new Iterator[(Location, Value)] {
  62.       private var _i = 0
  63.       private def findNext(l: Location) = {
  64.         var j = l
  65.         while (j < memory.size && memory(j) == null) j += 1
  66.         j
  67.       }
  68.       override def hasNext = findNext(_i) < memory.size
  69.       override def next = {
  70.         _i = findNext(_i)
  71.         val k = _i
  72.         val v = memory(_i)
  73.         _i += 1
  74.         (k, v)
  75.       }
  76.     }
  77.  
  78.     def malloc(v: Value): Location = {
  79.       val loc = findNextFreeLocation()
  80.       this += loc -> v
  81.       loc
  82.     }
  83.  
  84.     private def findNextFreeLocation(): Location = {
  85.       if (_free <= 0) sys.error("Store is full")
  86.       while (memory(_nextFreeLocation) != null) {
  87.         _nextFreeLocation += 1
  88.         if (_nextFreeLocation >= size) _nextFreeLocation = 0
  89.       }
  90.       _nextFreeLocation
  91.     }
  92.   }
  93.  
  94.   /**
  95.    * Returns all fields in the path from the root to className in the
  96.    * inheritance tree
  97.    */
  98.   def fieldsInPath(
  99.     className: Symbol,
  100.     classes: Map[Symbol, Class]): List[Symbol] = className match {
  101.     case 'Object => List()
  102.     case _ => {
  103.       val clazz = classes.getOrElse(
  104.         className,
  105.         sys.error("Unknown class %s".format(className)))
  106.       fieldsInPath(clazz.superClass, classes) ++ clazz.fields
  107.     }
  108.   }
  109.  
  110.   /**
  111.    * Returns the first method found in the path from className to the root in
  112.    * the inheritance tree or None
  113.    */
  114.   def lookupMethod(
  115.     methodName: Symbol,
  116.     className: Symbol,
  117.     classes: Map[Symbol, Class]): Option[Method] = className match {
  118.     case 'Object => None
  119.     case _ => {
  120.       val clazz = classes.getOrElse(
  121.         className,
  122.         sys.error("Unknown class %s".format(className)))
  123.       if (clazz.methods.contains(methodName)) Some(clazz.methods(methodName))
  124.       else lookupMethod(methodName, clazz.superClass, classes)
  125.     }
  126.   }
  127.  
  128.   def interp(
  129.     e: Expr,
  130.     env: Env,
  131.     store: Store,
  132.     classes: Map[Symbol, Class]): Location = e match {
  133.     case Num(n) => store.malloc(NumV(n))
  134.  
  135.     case Add(lhs, rhs) => {
  136.       val lhsV = store(interp(lhs, env, store, classes))
  137.       val rhsV = store(interp(rhs, env, store, classes))
  138.       (lhsV, rhsV) match {
  139.         case (NumV(a), NumV(b)) => store.malloc(NumV(a + b))
  140.         case _ => sys.error("Can only add numbers")
  141.       }
  142.     }
  143.  
  144.     case Mult(lhs, rhs) => {
  145.       val lhsV = store(interp(lhs, env, store, classes))
  146.       val rhsV = store(interp(rhs, env, store, classes))
  147.       (lhsV, rhsV) match {
  148.         case (NumV(a), NumV(b)) => store.malloc(NumV(a * b))
  149.         case _ => sys.error("Can only multiply numbers")
  150.       }
  151.     }
  152.  
  153.     case Let(id, namedExpr, body) => {
  154.       val loc = interp(namedExpr, env, store, classes)
  155.       interp(body, env + (id -> loc), store, classes)
  156.     }
  157.  
  158.     case Seqn() => sys.error("Need at least one expression for Seqn")
  159.     case Seqn(exprs @ _*) => exprs.foldLeft[Location](-1) {
  160.       case (_, e) => interp(e, env, store, classes)
  161.     }
  162.  
  163.     case Id(id) => {
  164.       env.get(id) match {
  165.         case Some(loc) => loc
  166.         case None => sys.error("%s is not found".format(id))
  167.       }
  168.     }
  169.  
  170.     case New(className, args @ _*) => {
  171.       if(!classes.contains(className)){
  172.         sys.error("class not found")
  173.       }
  174.       store.malloc(Object(className, args.map(expr => interp(expr, env, store, classes))))
  175.     }
  176.  
  177.     case GetField(objExpr, fieldName) => {
  178.       val loc = interp(objExpr, env, store, classes)
  179.       store.get(loc) match {
  180.         case Some(x) => x match{
  181.           case Object(className, fields) => {
  182.             val fieldIndex = fieldsInPath(className, classes) lastIndexOf fieldName
  183.             if(fieldIndex == -1 ){
  184.               sys.error("the field %s does not exist".format(fieldName))
  185.             }
  186.             fields(fieldIndex)
  187.           }
  188.           case v => sys.error("can only access field of object but got: "+v)  
  189.         }
  190.         case None => sys.error("location is empty")
  191.       }
  192.     }
  193.  
  194.     case Call(objExpr, methodName, args @ _*) => {
  195.       val loc = interp(objExpr, env, store, classes)
  196.       store.get(loc) match {
  197.         case Some(x) => x match{
  198.           case Object(className, fields) => {
  199.             val method = lookupMethod(methodName, className, classes) getOrElse
  200.               sys.error("methodname is unknown")
  201.             val evaledArgs = args map (expr => interp(expr, env, store, classes))
  202.             val argBindings = method.params zip evaledArgs
  203.             val fieldBindings = fieldsInPath(className,classes) zip fields
  204.             val thisBinding = 'this -> loc
  205.             interp(method.body, env ++ fieldBindings ++ argBindings + thisBinding, store, classes)
  206.           }
  207.           case v => sys.error("can only access method of object but got: "+v)  
  208.         }
  209.         case None => sys.error("location is empty")
  210.       }
  211.     }
  212.  
  213.     case SetField(objExpr, fieldName, e) => {
  214.       val loc = interp(objExpr, env, store, classes)
  215.       store.get(loc) match {
  216.         case Some(x) => x match {
  217.           case Object(className, fields) => {
  218.             val fieldIndex = fieldsInPath(className, classes) indexOf fieldName
  219.             if(fieldIndex == -1 ){
  220.               sys.error("the field %s does not exist".format(fieldName))
  221.             }
  222.             val eLoc = interp(e, env, store, classes)
  223.             //store +=(fields(fieldIndex), store.get(eLoc).get)
  224.             store(fields(fieldIndex)) = store.get(eLoc).get
  225.             store -= eLoc
  226.             fields(fieldIndex)
  227.           }
  228.           case v => sys.error("can only set field of object but got: " + v)
  229.         }
  230.         case None => sys.error("location is empty")
  231.       }
  232.     }
  233.    
  234.     case Set(id, e) => {
  235.       val eLoc = interp(e, env, store, classes)
  236.       env get id match {
  237.         case Some(loc) => {
  238.           store(loc) = store.get(eLoc).get
  239.           store -= eLoc
  240.           loc
  241.         }
  242.         case None => sys.error("id %s not found".format(id))
  243.       }
  244.     }
  245.   }
  246. }
  247.  
  248. //
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement