Skip to content

Commit

Permalink
Change string form of ERecord, EMap, and EList
Browse files Browse the repository at this point in the history
  • Loading branch information
jhnaldo committed Jul 26, 2024
1 parent 8d9d498 commit 0e75f14
Show file tree
Hide file tree
Showing 44 changed files with 133 additions and 118 deletions.
4 changes: 2 additions & 2 deletions src/main/resources/manuals/funcs/HostEnqueuePromiseJob.ir
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ def HostEnqueuePromiseJob(
realm: RealmRecord | Null,
): Enum[~unused~] = {
call %0 = clo<GetActiveScriptOrModule>()
let newJob = (new PendingJob { "Job" : job, "Realm" : realm, "ScriptOrModule" : %0 })
let newJob = (record [PendingJob] { "Job" : job, "Realm" : realm, "ScriptOrModule" : %0 })
push @JOB_QUEUE < newJob
return ~unused~
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
def HostGetImportMetaProperties(
moduleRecord: ModuleRecord,
): List[{ [[Key]]: Symbol | String, [[Value]]: ESValue }] = {
return (new [])
}
return (list [])
}
4 changes: 2 additions & 2 deletions src/main/resources/manuals/funcs/INTRINSICS.EvalError.ir
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def <BUILTIN>:INTRINSICS.EvalError(
} else {
let newTarget = NewTarget
}
call %1 = clo<OrdinaryCreateFromConstructor>(newTarget, "%EvalError.prototype%", (new ["ErrorData"]))
call %1 = clo<OrdinaryCreateFromConstructor>(newTarget, "%EvalError.prototype%", (list ["ErrorData"]))
let O = [? %1]
%2 = (! (= message undefined))
if %2 {
Expand All @@ -23,4 +23,4 @@ def <BUILTIN>:INTRINSICS.EvalError(
call %5 = clo<InstallErrorCause>(O, options)
[? %5]
return O
}
}
4 changes: 2 additions & 2 deletions src/main/resources/manuals/funcs/INTRINSICS.RangeError.ir
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def <BUILTIN>:INTRINSICS.RangeError(
} else {
let newTarget = NewTarget
}
call %1 = clo<OrdinaryCreateFromConstructor>(newTarget, "%RangeError.prototype%", (new ["ErrorData"]))
call %1 = clo<OrdinaryCreateFromConstructor>(newTarget, "%RangeError.prototype%", (list ["ErrorData"]))
let O = [? %1]
%2 = (! (= message undefined))
if %2 {
Expand All @@ -23,4 +23,4 @@ def <BUILTIN>:INTRINSICS.RangeError(
call %5 = clo<InstallErrorCause>(O, options)
[? %5]
return O
}
}
4 changes: 2 additions & 2 deletions src/main/resources/manuals/funcs/INTRINSICS.ReferenceError.ir
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def <BUILTIN>:INTRINSICS.ReferenceError(
} else {
let newTarget = NewTarget
}
call %1 = clo<OrdinaryCreateFromConstructor>(newTarget, "%ReferenceError.prototype%", (new ["ErrorData"]))
call %1 = clo<OrdinaryCreateFromConstructor>(newTarget, "%ReferenceError.prototype%", (list ["ErrorData"]))
let O = [? %1]
%2 = (! (= message undefined))
if %2 {
Expand All @@ -23,4 +23,4 @@ def <BUILTIN>:INTRINSICS.ReferenceError(
call %5 = clo<InstallErrorCause>(O, options)
[? %5]
return O
}
}
4 changes: 2 additions & 2 deletions src/main/resources/manuals/funcs/INTRINSICS.SyntaxError.ir
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def <BUILTIN>:INTRINSICS.SyntaxError(
} else {
let newTarget = NewTarget
}
call %1 = clo<OrdinaryCreateFromConstructor>(newTarget, "%SyntaxError.prototype%", (new ["ErrorData"]))
call %1 = clo<OrdinaryCreateFromConstructor>(newTarget, "%SyntaxError.prototype%", (list ["ErrorData"]))
let O = [? %1]
%2 = (! (= message undefined))
if %2 {
Expand All @@ -23,4 +23,4 @@ def <BUILTIN>:INTRINSICS.SyntaxError(
call %5 = clo<InstallErrorCause>(O, options)
[? %5]
return O
}
}
4 changes: 2 additions & 2 deletions src/main/resources/manuals/funcs/INTRINSICS.TypeError.ir
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def <BUILTIN>:INTRINSICS.TypeError(
} else {
let newTarget = NewTarget
}
call %1 = clo<OrdinaryCreateFromConstructor>(newTarget, "%TypeError.prototype%", (new ["ErrorData"]))
call %1 = clo<OrdinaryCreateFromConstructor>(newTarget, "%TypeError.prototype%", (list ["ErrorData"]))
let O = [? %1]
%2 = (! (= message undefined))
if %2 {
Expand All @@ -23,4 +23,4 @@ def <BUILTIN>:INTRINSICS.TypeError(
call %5 = clo<InstallErrorCause>(O, options)
[? %5]
return O
}
}
4 changes: 2 additions & 2 deletions src/main/resources/manuals/funcs/INTRINSICS.URIError.ir
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def <BUILTIN>:INTRINSICS.URIError(
} else {
let newTarget = NewTarget
}
call %1 = clo<OrdinaryCreateFromConstructor>(newTarget, "%URIError.prototype%", (new ["ErrorData"]))
call %1 = clo<OrdinaryCreateFromConstructor>(newTarget, "%URIError.prototype%", (list ["ErrorData"]))
let O = [? %1]
%2 = (! (= message undefined))
if %2 {
Expand All @@ -23,4 +23,4 @@ def <BUILTIN>:INTRINSICS.URIError(
call %5 = clo<InstallErrorCause>(O, options)
[? %5]
return O
}
}
12 changes: 6 additions & 6 deletions src/main/resources/manuals/funcs/ToObject.ir
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@ def ToObject(
return %3
}
if (= (typeof argument) @Boolean) {
return (new OrdinaryObject { "Prototype" : @EXECUTION_STACK[0].Realm.Intrinsics["%Boolean.prototype%"], "BooleanData" : argument, "Extensible" : true, "__MAP__" : (map) })
return (record [OrdinaryObject] { "Prototype" : @EXECUTION_STACK[0].Realm.Intrinsics["%Boolean.prototype%"], "BooleanData" : argument, "Extensible" : true, "__MAP__" : (map) })
}
if (= (typeof argument) @Number) {
return (new OrdinaryObject { "Prototype" : @EXECUTION_STACK[0].Realm.Intrinsics["%Number.prototype%"], "NumberData" : argument, "Extensible" : true, "__MAP__" : (map) })
return (record [OrdinaryObject] { "Prototype" : @EXECUTION_STACK[0].Realm.Intrinsics["%Number.prototype%"], "NumberData" : argument, "Extensible" : true, "__MAP__" : (map) })
}
if (= (typeof argument) @String) {
let obj = (new StringExoticObject { "Prototype" : @EXECUTION_STACK[0].Realm.Intrinsics["%String.prototype%"], "StringData" : argument, "Extensible" : true, "__MAP__" : (map) })
obj.__MAP__.length = (new PropertyDescriptor { "Value" : ([number] argument.length), "Writable" : false, "Enumerable" : false, "Configurable" : false })
let obj = (record [StringExoticObject] { "Prototype" : @EXECUTION_STACK[0].Realm.Intrinsics["%String.prototype%"], "StringData" : argument, "Extensible" : true, "__MAP__" : (map) })
obj.__MAP__.length = (record [PropertyDescriptor] { "Value" : ([number] argument.length), "Writable" : false, "Enumerable" : false, "Configurable" : false })
return obj
}
if (= (typeof argument) @Symbol) {
let obj = (new OrdinaryObject { "Prototype" : @EXECUTION_STACK[0].Realm.Intrinsics["%Symbol.prototype%"], "SymbolData" : argument, "Extensible" : true, "__MAP__" : (map) })
let obj = (record [OrdinaryObject] { "Prototype" : @EXECUTION_STACK[0].Realm.Intrinsics["%Symbol.prototype%"], "SymbolData" : argument, "Extensible" : true, "__MAP__" : (map) })
return obj
}
if (= (typeof argument) @BigInt) {
let obj = (new OrdinaryObject { "Prototype" : @EXECUTION_STACK[0].Realm.Intrinsics["%BigInt.prototype%"], "BigIntData" : argument, "Extensible" : true, "__MAP__" : (map) })
let obj = (record [OrdinaryObject] { "Prototype" : @EXECUTION_STACK[0].Realm.Intrinsics["%BigInt.prototype%"], "BigIntData" : argument, "Extensible" : true, "__MAP__" : (map) })
return obj
}
if (= (typeof argument) @Object) return argument
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/manuals/funcs/__NEW_ERROR_OBJ__.ir
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
def <AUX>:__NEW_ERROR_OBJ__(
proto: String,
): OrdinaryObject = {
return (new OrdinaryObject { "Prototype" : @EXECUTION_STACK[0].Realm.Intrinsics[proto], "ErrorData" : undefined, "__MAP__" : (map) } )
return (record [OrdinaryObject] { "Prototype" : @EXECUTION_STACK[0].Realm.Intrinsics[proto], "ErrorData" : undefined, "__MAP__" : (map) } )
}
22 changes: 11 additions & 11 deletions src/main/resources/manuals/rule.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/main/scala/esmeta/analyzer/AbsTransfer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ trait AbsTransferDecl { self: Analyzer =>
}
}
case ELexical(name, expr) => notSupported("ELexical")
case e @ ERecord(tname, fields) =>
case e @ ERecord(tnameOpt, fields) =>
val asite = AllocSite(e.asite, np.view)
for {
pairs <- join(fields.map {
Expand All @@ -467,7 +467,7 @@ trait AbsTransferDecl { self: Analyzer =>
v <- transfer(expr)
} yield (f, v)
})
lv <- id(_.allocRecord(asite, tname, pairs))
lv <- id(_.allocRecord(asite, tnameOpt, pairs))
} yield lv
case e @ EMap(pairs) =>
val asite = AllocSite(e.asite, np.view)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,11 @@ trait HeapBasicDomainDecl { self: Self =>
/** allocation of record with address partitions */
def allocRecord(
to: AllocSite,
tname: String,
tnameOpt: Option[String],
pairs: Iterable[(String, AbsValue)],
): Elem =
given CFG = cfg
val newObj = pairs.foldLeft(AbsObj(RecordObj(tname))) {
val newObj = pairs.foldLeft(AbsObj(RecordObj(tnameOpt))) {
case (m, (f, v)) => m.update(AbsValue(Str(f)), v, weak = false)
}
alloc(elem, to, newObj)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ trait HeapDomainDecl { self: Self =>
/** allocation of record with address partitions */
def allocRecord(
to: AllocSite,
tname: String,
tname: Option[String],
pairs: Iterable[(String, AbsValue)] = Nil,
): Elem

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,11 +246,11 @@ trait StateBasicDomainDecl { self: Self =>
/** allocation of record with address partitions */
def allocRecord(
to: AllocSite,
tname: String,
tnameOpt: Option[String],
pairs: Iterable[(String, AbsValue)],
): (AbsValue, Elem) =
val partV = AbsValue(to)
(partV, elem.copy(heap = heap.allocRecord(to, tname, pairs)))
(partV, elem.copy(heap = heap.allocRecord(to, tnameOpt, pairs)))

/** allocation of list with address partitions */
def allocList(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ trait StateDomainDecl { self: Self =>
/** allocation of record with address partitions */
def allocRecord(
to: AllocSite,
tname: String,
tnameOpt: Option[String],
pairs: Iterable[(String, AbsValue)],
): (AbsValue, Elem)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,14 +186,12 @@ trait StateTypeDomainDecl { self: Self =>
/** allocation of record with address partitions */
def allocRecord(
to: AllocSite,
tname: String,
tnameOpt: Option[String],
pairs: Iterable[(String, AbsValue)],
): (AbsValue, Elem) =
val value =
if (tname == "Record") RecordT((for {
(f, v) <- pairs
} yield f -> v.ty).toMap)
else NameT(tname)
val value = tnameOpt match
case None => RecordT(pairs.map { case (f, v) => f -> v.ty }.toMap)
case Some(tname) => NameT(tname)
(AbsValue(value), elem)

/** allocation of list with address partitions */
Expand Down
6 changes: 4 additions & 2 deletions src/main/scala/esmeta/compiler/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -498,8 +498,10 @@ class Compiler(
case (FieldLiteral(f), e) => f -> compile(fb, e)
}
val tname = Type.normalizeName(rawName)
if (hasMap(tname)) ERecord(tname, props :+ (INNER_MAP -> EMap(Nil)))
else ERecord(tname, props)
val updatedProps =
if (hasMap(tname)) props :+ (INNER_MAP -> EMap(Nil))
else props
ERecord(if (tname == "Record") None else Some(tname), updatedProps)
case LengthExpression(ReferenceExpression(ref)) =>
toStrERef(compile(fb, ref), "length")
case LengthExpression(expr) =>
Expand Down
6 changes: 3 additions & 3 deletions src/main/scala/esmeta/interpreter/Interpreter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ class Interpreter(
case ELexical(name, expr) =>
val str = eval(expr).asStr
AstValue(Lexical(name, str))
case ERecord("Completion", fields) =>
case ERecord(Some("Completion"), fields) =>
val map = (for {
(f, expr) <- fields
v = eval(expr)
Expand All @@ -382,8 +382,8 @@ class Interpreter(
case v => throw InvalidCompTarget(v)
Comp(ty, value.toPureValue, targetOpt)
case _ => throw InvalidComp
case ERecord(tname, fields) =>
val addr = st.allocRecord(tname)
case ERecord(tnameOpt, fields) =>
val addr = st.allocRecord(tnameOpt)
for ((f, expr) <- fields) st.update(addr, Str(f), eval(expr))
addr
case EMap(pairs) =>
Expand Down
5 changes: 4 additions & 1 deletion src/main/scala/esmeta/ir/Expr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ case class ELexical(

// allocation expressions
sealed trait AllocExpr extends Expr { var asite: Int = -1 }
case class ERecord(tname: String, pairs: List[(String, Expr)]) extends AllocExpr
case class ERecord(
tnameOpt: Option[String],
pairs: List[(String, Expr)],
) extends AllocExpr
case class EMap(pairs: List[(Expr, Expr)]) extends AllocExpr
case class EList(exprs: List[Expr]) extends AllocExpr
case class EListConcat(exprs: List[Expr]) extends AllocExpr
Expand Down
10 changes: 5 additions & 5 deletions src/main/scala/esmeta/ir/util/Parser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,11 @@ trait Parsers extends TyParsers {

// allocation expressions
lazy val allocExpr: Parser[AllocExpr] = asite(
("(" ~ "new" ~> opt(word) ~ opt(fields) <~ ")") ^^ {
case t ~ fs => ERecord(t.getOrElse("Record"), fs.getOrElse(Nil))
("(" ~ "record" ~> opt("[" ~> word <~ "]") ~ opt(fields) <~ ")") ^^ {
case t ~ fs => ERecord(t, fs.getOrElse(Nil))
} | ("(" ~ "map" ~> opt(pairs) <~ ")") ^^ {
case ps => EMap(ps.getOrElse(Nil))
} | ("(" ~ "new" ~ "[" ~> repsep(expr, ",") <~ "]" ~ ")") ^^ {
} | ("(" ~ "list" ~ "[" ~> repsep(expr, ",") <~ "]" ~ ")") ^^ {
case es => EList(es)
} | ("(" ~ "list-concat" ~> rep(expr) <~ ")") ^^ {
case es => EListConcat(es)
Expand All @@ -198,11 +198,11 @@ trait Parsers extends TyParsers {

// fields
lazy val fields: Parser[List[(String, Expr)]] =
"{" ~> repsep(pair(string ~ (":" ~> expr)), ",") <~ "}"
"{" ~> repsep(pair(string ~ (":" ~> expr)), ",") <~ opt(",") ~ "}"

// key-value pairs
lazy val pairs: Parser[List[(Expr, Expr)]] =
"{" ~> repsep(pair(expr ~ ("->" ~> expr)), ",") <~ "}"
"{" ~> repsep(pair(expr ~ ("->" ~> expr)), ",") <~ opt(",") <~ "}"

// allocation sites
def asite(parser: Parser[AllocExpr]): Parser[AllocExpr] =
Expand Down
21 changes: 11 additions & 10 deletions src/main/scala/esmeta/ir/util/Stringifier.scala
Original file line number Diff line number Diff line change
Expand Up @@ -205,19 +205,20 @@ class Stringifier(detail: Boolean, location: Boolean) {
// allocation expressions
lazy val allocExprRule: Rule[AllocExpr] = (app, expr) =>
expr match {
case ERecord(tname, fields) =>
given Rule[(String, Expr)] = {
case (app, (f, e)) => app >> "\"" >> f >> "\" : " >> e
}
given Rule[Iterable[(String, Expr)]] = iterableRule("{ ", ", ", " }")
app >> "(new " >> tname >> " " >> fields >> ")"
case ERecord(tnameOpt, fields) =>
app >> "(record "
tnameOpt.map(app >> "[" >> _ >> "] ")
app.wrap("{", "}")(for {
(field, expr) <- fields
} app :> "\"" >> field >> "\" : " >> expr >> ",") >> ")"
case EMap(Nil) => app >> "(map)"
case EMap(pairs) =>
given Rule[Iterable[(Expr, Expr)]] = iterableRule("{ ", ", ", " }")
if (pairs.isEmpty) app >> "(map)"
else app >> "(map " >> pairs >> ")"
(app >> "(map ").wrap("{", "}")(for {
(key, value) <- pairs
} app :> key >> " -> " >> value >> ",") >> ")"
case EList(exprs) =>
given Rule[Iterable[Expr]] = iterableRule("[", ", ", "]")
app >> "(new " >> exprs >> ")"
app >> "(list " >> exprs >> ")"
case EListConcat(exprs) =>
given Rule[Iterable[Expr]] = iterableRule(sep = " ")
app >> "(list-concat " >> exprs >> ")"
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/esmeta/ir/util/UnitWalker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ trait UnitWalker extends BasicUnitWalker {

// allocation expressions
def walk(alloc: AllocExpr): Unit = alloc match {
case ERecord(tname, fields) =>
walk(tname)
case ERecord(tnameOpt, fields) =>
walkOpt(tnameOpt, walk)
walkList(fields, { case (f, e) => (walk(f), walk(e)) })
case EMap(pairs) =>
walkList(pairs, { case (k, v) => (walk(k), walk(v)) })
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/esmeta/ir/util/Walker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@ trait Walker extends BasicWalker {

// allocation expressions
def walk(alloc: AllocExpr): AllocExpr = alloc match
case ERecord(tname, fields) =>
case ERecord(tnameOpt, fields) =>
ERecord(
walk(tname),
walkOpt(tnameOpt, walk),
walkList(fields, { case (p, e) => (walk(p), walk(e)) }),
)
case EMap(pairs) =>
Expand Down
7 changes: 4 additions & 3 deletions src/main/scala/esmeta/state/Heap.scala
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,11 @@ case class Heap(
}

/** record allocations */
def allocRecord(tname: String)(using CFG): Addr =
val record = RecordObj(tname)
def allocRecord(tnameOpt: Option[String])(using CFG): Addr =
val record = RecordObj(tnameOpt)
// TODO check it is the best way to handle this
if (isObject(tname)) record.update(Str("PrivateElements"), alloc(ListObj()))
if (isObject(record.tname))
record.update(Str("PrivateElements"), alloc(ListObj()))
alloc(record)

private def isObject(tname: String): Boolean =
Expand Down
Loading

0 comments on commit 0e75f14

Please sign in to comment.