Skip to content

Commit

Permalink
Refactor getSdo helper
Browse files Browse the repository at this point in the history
  • Loading branch information
jhnaldo committed Jul 24, 2024
1 parent 8450498 commit eb096bd
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 89 deletions.
44 changes: 6 additions & 38 deletions src/main/scala/esmeta/analyzer/AbsTransfer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ trait AbsTransferDecl { self: Analyzer =>
/** loading monads */
import AbsState.monad.*

/** given instance for CFG */
given CFG = cfg

/** fixpiont computation */
@tailrec
final def fixpoint: Unit = sem.worklist.next match
Expand Down Expand Up @@ -167,43 +170,8 @@ trait AbsTransferDecl { self: Analyzer =>
val st = sem.getState(np)
transfer(expr)(st)._1

/** sdo with default case */
val defaultCases = List(
"Contains",
"AllPrivateIdentifiersValid",
"ContainsArguments",
)

/** get syntax-directed operation (SDO) */
val getSDO = cached[(Ast, String), Option[(Ast, Func)]] {
case (ast, operation) =>
val fnameMap = cfg.fnameMap
ast.chains.foldLeft[Option[(Ast, Func)]](None) {
case (None, ast0) =>
val subIdx = getSubIdx(ast0)
val fname = s"${ast0.name}[${ast0.idx},${subIdx}].$operation"
fnameMap.get(fname) match
case Some(sdo) => Some(ast0, sdo)
case None if defaultCases contains operation =>
Some(ast0, fnameMap(s"<DEFAULT>.$operation"))
case _ => None
case (res: Some[_], _) => res
}
}

/** get sub index of parsed Ast */
val getSubIdx = cached[Ast, Int] {
case lex: Lexical => 0
case Syntactic(name, _, rhsIdx, children) =>
val rhs = cfg.grammar.nameMap(name).rhsList(rhsIdx)
val optionals = (for {
((_, opt), child) <- rhs.ntsWithOptional zip children if opt
} yield !child.isEmpty)
optionals.reverse.zipWithIndex.foldLeft(0) {
case (acc, (true, idx)) => acc + scala.math.pow(2, idx).toInt
case (acc, _) => acc
}
}
val getSdo = cached[(Ast, String), Option[(Ast, Func)]](_.getSdo(_))

/** transfer function for normal instructions */
def transfer(inst: NormalInst)(using np: NodePoint[_]): Updater =
Expand Down Expand Up @@ -291,7 +259,7 @@ trait AbsTransferDecl { self: Analyzer =>
var newV: AbsValue = AbsValue.Bot
bv.getSingle match
case One(AstValue(syn: Syntactic)) =>
getSDO((syn, method)) match
getSdo((syn, method)) match
case Some((ast, sdo)) =>
val callPoint = CallPoint(callerNp, sdo)
val astV = AbsValue(ast)
Expand All @@ -304,7 +272,7 @@ trait AbsTransferDecl { self: Analyzer =>
newV ⊔= bv.getLexical(method)

// syntactic sdo
for ((sdo, ast) <- bv.getSDO(method))
for ((sdo, ast) <- bv.getSdo(method))
val callPoint = CallPoint(callerNp, sdo)
doCall(callPoint, st, args, ast :: vs, method = true)
case _ => /* do nothing */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ trait ValueBasicDomainDecl { self: Self =>
def refineThis(func: Func): Elem = elem

/** get syntactic SDO */
def getSDO(method: String): List[(Func, Elem)] = ???
def getSdo(method: String): List[(Func, Elem)] = ???

/** get lexical result */
def getLexical(method: String): Elem = ???
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ trait ValueDomainDecl { self: Self =>
def refineThis(func: Func): Elem

/** get syntactic SDO */
def getSDO(method: String): List[(Func, Elem)]
def getSdo(method: String): List[(Func, Elem)]

/** get lexical result */
def getLexical(method: String): Elem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ trait ValueTypeDomainDecl { self: Self =>
)

/** get syntactic SDO */
def getSDO(method: String): List[(Func, Elem)] = elem.ty.astValue match
def getSdo(method: String): List[(Func, Elem)] = elem.ty.astValue match
case AstTopTy =>
for {
func <- cfg.funcs if func.isSDO
Expand Down
28 changes: 28 additions & 0 deletions src/main/scala/esmeta/es/Ast.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package esmeta.es

import esmeta.cfg.*
import esmeta.es.util.*
import esmeta.error.InvalidASTItem
import esmeta.ir.Type
Expand Down Expand Up @@ -92,6 +93,33 @@ sealed trait Ast extends ESElem with Locational {
syn.loc = locOpt; syn
case lex: Lexical => lex.loc = locOpt; lex

/** get syntax-directed operation (SDO) */
def getSdo(name: String)(using cfg: CFG): Option[(Ast, Func)] =
val fnameMap = cfg.fnameMap
chains.foldLeft[Option[(Ast, Func)]](None) {
case (None, ast0) =>
val subIdx = ast0.getSubIdx
val fname = s"${ast0.name}[${ast0.idx},${subIdx}].$name"
fnameMap
.get(fname)
.orElse(fnameMap.get(s"<DEFAULT>.$name"))
.map((ast0, _))
case (res: Some[_], _) => res
}

/** get sub index of parsed Ast */
def getSubIdx(using cfg: CFG): Int = this match
case lex: Lexical => 0
case Syntactic(name, _, rhsIdx, children) =>
val rhs = cfg.grammar.nameMap(name).rhsList(rhsIdx)
val optionals = (for {
((_, opt), child) <- rhs.ntsWithOptional zip children if opt
} yield !child.isEmpty)
optionals.reverse.zipWithIndex.foldLeft(0) {
case (acc, (true, idx)) => acc + scala.math.pow(2, idx).toInt
case (acc, _) => acc
}

/** not use case class' hash code */
override def hashCode: Int = super.hashCode
}
Expand Down
41 changes: 3 additions & 38 deletions src/main/scala/esmeta/interpreter/Interpreter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ class Interpreter(
case ISdoCall(lhs, base, method, args) =>
eval(base).asAst match
case syn: Syntactic =>
getSDO((syn, method)) match
getSdo((syn, method)) match
case Some((ast0, sdo)) =>
val vs = args.map(eval)
val newLocals = getLocals(
Expand Down Expand Up @@ -541,13 +541,6 @@ class Interpreter(
st.define(x, value)
st.context.moveNext

/** sdo with default case */
val defaultCases = List(
"Contains",
"AllPrivateIdentifiersValid",
"ContainsArguments",
)

// ---------------------------------------------------------------------------
// private helpers
// ---------------------------------------------------------------------------
Expand All @@ -569,36 +562,8 @@ class Interpreter(
mkdir(logDir)
getPrintWriter(s"$logDir/log")

/** get syntax-directed operation(SDO) */
private val getSDO = cached[(Ast, String), Option[(Ast, Func)]] {
case (ast, operation) =>
val fnameMap = cfg.fnameMap
ast.chains.foldLeft[Option[(Ast, Func)]](None) {
case (None, ast0) =>
val subIdx = getSubIdx(ast0)
val fname = s"${ast0.name}[${ast0.idx},${subIdx}].$operation"
fnameMap.get(fname) match
case Some(sdo) => Some(ast0, sdo)
case None if defaultCases contains operation =>
Some(ast0, fnameMap(s"<DEFAULT>.$operation"))
case _ => None
case (res: Some[_], _) => res
}
}

/** get sub index of parsed Ast */
private val getSubIdx = cached[Ast, Int] {
case lex: Lexical => 0
case Syntactic(name, _, rhsIdx, children) =>
val rhs = cfg.grammar.nameMap(name).rhsList(rhsIdx)
val optionals = (for {
((_, opt), child) <- rhs.ntsWithOptional zip children if opt
} yield !child.isEmpty)
optionals.reverse.zipWithIndex.foldLeft(0) {
case (acc, (true, idx)) => acc + scala.math.pow(2, idx).toInt
case (acc, _) => acc
}
}
/** cache to get syntax-directed operation (SDO) */
private val getSdo = cached[(Ast, String), Option[(Ast, Func)]](_.getSdo(_))
}

/** IR interpreter with a CFG */
Expand Down
13 changes: 3 additions & 10 deletions src/main/scala/esmeta/ir/Inst.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,10 @@ case class IWhile(cond: Expr, body: Inst) extends BranchInst
object BranchInst extends Parser.From(Parser.branchInst)

// call instructions
sealed trait CallInst extends Inst {
val lhs: Local
def fexpr: Expr
}
sealed trait CallInst extends Inst { val lhs: Local }
case class ICall(lhs: Local, fexpr: Expr, args: List[Expr]) extends CallInst
case class ISdoCall(lhs: Local, base: Expr, method: String, args: List[Expr])
extends CallInst {
lazy val fexpr: Expr = base match
case ERef(base) => ERef(Field(base, EStr(method)))
case _ => ??? // XXX error -> see compiler
}
case class ISdoCall(lhs: Local, base: Expr, op: String, args: List[Expr])
extends CallInst

// special instructions
case class ISeq(insts: List[Inst]) extends Inst

0 comments on commit eb096bd

Please sign in to comment.