Skip to content

Commit

Permalink
Fixed MapObj to use LinkedHashMap as fields (#240)
Browse files Browse the repository at this point in the history
  • Loading branch information
d01c2 authored Jul 23, 2024
1 parent 236ffa8 commit 67b039d
Show file tree
Hide file tree
Showing 8 changed files with 25 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ trait ObjBasicDomainDecl { self: Self =>
tname = tname,
map = (for {
(k, fieldV) <- fields
} yield AValue.from(k) -> AbsValue(fieldV.value)).toMap,
} yield AValue.from(k) -> AbsValue(fieldV)).toMap,
order = Some(m.keys.map(AValue.from)),
)
case ListObj(values) => KeyWiseList(values.map(AbsValue(_)))
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/esmeta/injector/Injector.scala
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ class Injector(
val2str(p).map(propStr => {
for {
field <- fields
value <- props.get(Str(field)).map(_.value.toPureValue)
value <- props.get(Str(field)).map(_.toPureValue)
} value match
case sv: SimpleValue =>
set += s"${field.toLowerCase}: ${sv2str(sv)}"
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/esmeta/state/Heap.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import esmeta.error.NotSupported.Category.*
import esmeta.ir.{Func => IRFunc, *}
import esmeta.es.builtin.*
import esmeta.util.BaseUtils.*
import scala.collection.mutable.{Map => MMap}
import scala.collection.mutable.{Map => MMap, LinkedHashMap => LMMap}

/** IR heaps */
case class Heap(
Expand Down Expand Up @@ -82,7 +82,7 @@ case class Heap(
m: Map[PureValue, PureValue],
)(using CFG): Addr = {
val irMap =
if (tname == "Record") MapObj(tname, MMap(), 0) else MapObj(tname)
if (tname == "Record") MapObj(tname, LMMap(), 0) else MapObj(tname)
for ((k, v) <- m) irMap.update(k, v)
if (hasSubMap(tname))
val subMap = MapObj("SubMap")
Expand Down
33 changes: 11 additions & 22 deletions src/main/scala/esmeta/state/Obj.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@ import esmeta.cfg.*
import esmeta.error.*
import esmeta.ir.{Func => IRFunc, *}
import esmeta.parser.ESValueParser
import scala.collection.mutable.{Map => MMap}
import scala.collection.mutable.{LinkedHashMap => LMMap}

// Objects
sealed trait Obj extends StateElem {

/** getters */
def apply(field: PureValue): Value = (this, field) match
case (SymbolObj(desc), Str("Description")) => desc
case (MapObj(_, fields, _), field) =>
fields.get(field).fold[Value](Absent)(_.value)
case (MapObj(_, fields, _), field) => fields.getOrElse(field, Absent)
case (ListObj(values), Math(decimal)) =>
val idx = decimal.toInt
if (0 <= idx && idx < values.length) values(idx)
Expand All @@ -23,15 +22,15 @@ sealed trait Obj extends StateElem {

/** copy of object */
def copied: Obj = this match
case MapObj(tname, fields, size) => MapObj(tname, MMap.from(fields), size)
case MapObj(tname, fields, size) => MapObj(tname, LMMap.from(fields), size)
case ListObj(values) => ListObj(Vector.from(values))
case _ => this
}

/** map objects */
case class MapObj(
var ty: String, // TODO handle type
val fields: MMap[PureValue, MapObj.Field],
val fields: LMMap[PureValue, Value],
var size: Int,
) extends Obj {

Expand All @@ -43,30 +42,23 @@ case class MapObj(

/** updates */
def update(field: PureValue, value: Value): this.type =
val id = fields
.get(field)
.map(_.creationTime)
.getOrElse({ size += 1; size })
fields += field -> MapObj.Field(value, id)
fields += field -> value
this

/** deletes */
def delete(field: PureValue): this.type = { fields -= field; this }

/** pairs of map */
def pairs: Map[PureValue, Value] = (fields.map {
case (k, (MapObj.Field(v, _))) => k -> v
case (k, v) => k -> v
}).toMap

/** keys of map */
def keys: Vector[PureValue] = keys(intSorted = false)
def keys(intSorted: Boolean): Vector[PureValue] = {
if (!intSorted) {
if (ty == "SubMap")
fields.toVector
.sortBy(_._2._2)
.map(_._1)
else fields.toVector.map(_._1).sortBy(_.toString)
if (ty == "SubMap") fields.keys.toVector
else fields.keys.toVector.sortBy(_.toString)
} else
(for {
case (Str(s), _) <- fields.toVector
Expand All @@ -79,24 +71,21 @@ case class MapObj(
}
object MapObj {

/** field values */
case class Field(value: Value, creationTime: Int)

/** apply with type model */
def apply(tname: String)(fields: (PureValue, Value)*)(using CFG): MapObj =
val obj: MapObj = MapObj(tname)
for { ((k, v), idx) <- fields.zipWithIndex }
obj.fields += k -> Field(v, idx + obj.size)
obj.fields += k -> v
obj.size += fields.size
obj

def apply(tname: String)(using cfg: CFG): MapObj =
// TODO do not explicitly store methods in object but use a type model when
// accessing methods
val methods = cfg.tyModel.getMethod(tname)
val obj = MapObj(tname, MMap(), methods.size)
val obj = MapObj(tname, LMMap(), methods.size)
for { ((name, fname), idx) <- methods.zipWithIndex }
obj.fields += Str(name) -> Field(Clo(cfg.fnameMap(fname), Map()), idx)
obj.fields += Str(name) -> Clo(cfg.fnameMap(fname), Map())
obj
}

Expand Down
1 change: 0 additions & 1 deletion src/main/scala/esmeta/state/util/UnitWalker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ trait UnitWalker extends BasicUnitWalker {
case ListObj(values) => walkIterable(values, walk)
case SymbolObj(desc) => walk(desc)
case _: YetObj =>
def walk(field: MapObj.Field): Unit = walk(field.value)

// value
def walk(v: Value): Unit = v match
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/esmeta/ty/ValueTy.scala
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,12 @@ case class ValueTy(
case MapObj(tname, props, _) =>
isSubTy(tname, name.set) ||
(tname == "Record" && (props.forall {
case (Str(key), MapObj.Field(value, _)) =>
case (Str(key), value) =>
record(key).contains(value, heap)
case _ => false
})) ||
(tname == "SubMap" && (props.forall {
case (key, MapObj.Field(value, _)) =>
case (key, value) =>
ValueTy(pureValue = subMap.key).contains(key, heap) &&
ValueTy(pureValue = subMap.value).contains(value, heap)
}))
Expand Down
7 changes: 4 additions & 3 deletions src/test/scala/esmeta/state/StringifyTinyTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import esmeta.cfg.*
import esmeta.ir.{Func => IRFunc, FuncKind => IRFuncKind, *}
import esmeta.es.*
import esmeta.util.BaseUtils.*
import scala.collection.mutable.{Map => MMap, ListBuffer}
import scala.collection.mutable.{Map => MMap, LinkedHashMap => LMMap}
import scala.collection.mutable.ListBuffer

/** stringify test */
class StringifyTinyTest extends StateTest {
Expand Down Expand Up @@ -88,9 +89,9 @@ class StringifyTinyTest extends StateTest {
// -------------------------------------------------------------------------
// Objects
// -------------------------------------------------------------------------
lazy val map = MapObj("A", MMap(), 0)
lazy val map = MapObj("A", LMMap(), 0)
lazy val singleMap =
MapObj("A", MMap(Str("p") -> MapObj.Field(Str("p"), 0)), 1)
MapObj("A", LMMap(Str("p") -> Str("p")), 1)
lazy val list = ListObj(Vector(Math(42), Str("x")))
lazy val symbol = SymbolObj(Str("description"))
lazy val yet = YetObj("A", "message")
Expand Down
8 changes: 4 additions & 4 deletions src/test/scala/esmeta/ty/ContainsTinyTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package esmeta.ty
import esmeta.cfg.*
import esmeta.ir.{Func => IRFunc, FuncKind => IRFuncKind, *}
import esmeta.state.*
import scala.collection.mutable.{Map => MMap}
import scala.collection.mutable.{Map => MMap, LinkedHashMap => LMMap}
import esmeta.es.*

/** contains test */
Expand Down Expand Up @@ -41,10 +41,10 @@ class ContainsTinyTest extends TyTest {

// pre-defined heap
lazy val mapAddr = NamedAddr("mapAddr")
lazy val mapObj = MapObj("A", MMap(), 0)
lazy val mapObj = MapObj("A", LMMap(), 0)
lazy val recordAddr = NamedAddr("recordAddr")
lazy val recordObj =
MapObj("Record", MMap(Str("P") -> MapObj.Field(Number(42), 0)), 1)
MapObj("Record", LMMap(Str("P") -> Number(42)), 1)
lazy val nilAddr = NamedAddr("nilAddr")
lazy val nilObj = ListObj(Vector())
lazy val listAddr = NamedAddr("listAddr")
Expand All @@ -53,7 +53,7 @@ class ContainsTinyTest extends TyTest {
lazy val symbolObj = SymbolObj(Str("desc"))
lazy val subMapAddr = NamedAddr("subMapAddr")
lazy val subMapObj =
MapObj("SubMap", MMap(symbolAddr -> MapObj.Field(Number(42), 0)), 1)
MapObj("SubMap", LMMap(symbolAddr -> Number(42)), 1)
given Heap = Heap(
MMap(
mapAddr -> mapObj,
Expand Down

0 comments on commit 67b039d

Please sign in to comment.