Skip to content

Commit

Permalink
Rename EnumById & Co to EnumCast and document them
Browse files Browse the repository at this point in the history
  • Loading branch information
Mingun committed Apr 19, 2024
1 parent fd58889 commit ab4116e
Show file tree
Hide file tree
Showing 20 changed files with 52 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,8 @@ class GraphvizClassCompiler(classSpecs: ClassSpecs, topClass: ClassSpec) extends
List()
case _: Ast.expr.EnumVariant =>
List()
case Ast.expr.EnumById(_, id, _) =>
affectedVars(id)
case Ast.expr.EnumCast(_, value, _) =>
affectedVars(value)
case Ast.expr.Attribute(value, attr) =>
val targetClass = translator.detectType(value)
targetClass match {
Expand Down
8 changes: 7 additions & 1 deletion shared/src/main/scala/io/kaitai/struct/exprlang/Ast.scala
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,13 @@ object Ast {
* KSY file.
*/
case class EnumVariant(enumName: identifier, variant: identifier, inType: typeId = EmptyTypeId) extends expr
case class EnumById(enumName: identifier, id: expr, inType: typeId = EmptyTypeId) extends expr
/**
* Transformation of the `value` expression into the `enumName` type,
* defined in the type `inType`. Unlike other nodes this node never
* parsed from the expression language, because at parse time any
* identifier can represent an enum and actual resolution performed later
*/
case class EnumCast(enumName: identifier, value: expr, inType: typeId = EmptyTypeId) extends expr

case class Attribute(value: expr, attr: identifier) extends expr
case class CastToType(value: expr, typeName: typeId) extends expr
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ object InstanceSpec {
// value instance
ParseUtils.ensureLegalKeys(srcMap, LEGAL_KEYS_VALUE_INST, path, Some("value instance"))

// Wrap everything in EnumById if "enum" is used
// Wrap everything in EnumCast if "enum" is used
val value2 = ParseUtils.getOptValueStr(srcMap, "enum", path) match {
case None =>
value
case Some(enumName) =>
Ast.expr.EnumById(Ast.identifier(enumName), value)
Ast.expr.EnumCast(Ast.identifier(enumName), value)
}

val ifExpr = ParseUtils.getOptValueExpression(srcMap, "if", path)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ trait EveryReadIsExpression
val expr = translator.bytesToStr(parseExprBytes(t.bytes, io), t.encoding)
handleAssignment(id, expr, rep, isRaw)
case t: EnumType =>
val expr = translator.doEnumById(t.enumSpec.get, parseExpr(t.basedOn, t.basedOn, io, defEndian))
val expr = translator.doEnumCast(t.enumSpec.get, parseExpr(t.basedOn, t.basedOn, io, defEndian))
handleAssignment(id, expr, rep, isRaw)
case _ =>
val expr = parseExpr(dataType, assignType, io, defEndian)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ trait GoReads extends CommonReads with ObjectOrientedLanguage with GoSwitchOps {
case t: EnumType =>
val r1 = translator.outVarCheckRes(parseExpr(t.basedOn, io, defEndian))
val enumSpec = t.enumSpec.get
val expr = translator.trEnumById(enumSpec.name, translator.resToStr(r1))
val expr = translator.trEnumCast(enumSpec.name, translator.resToStr(r1))
handleAssignment(id, expr, rep, isRaw)
case _: BitsType1 =>
val expr = parseExpr(dataType, io, defEndian)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ abstract class BaseTranslator(val provider: TypeProvider)
doInterpolatedStringLiteral(s)
case Ast.expr.Bool(n) =>
doBoolLiteral(n)
case Ast.expr.EnumById(enumType, id, inType) =>
case Ast.expr.EnumCast(enumType, value, inType) =>
val enumSpec = provider.resolveEnum(inType, enumType.name)
doEnumById(enumSpec, translate(id))
doEnumCast(enumSpec, translate(value))
case Ast.expr.EnumVariant(enumType, variant, inType) =>
val enumSpec = provider.resolveEnum(inType, enumType.name)
doEnumVariant(enumSpec, variant.name)
Expand Down Expand Up @@ -195,7 +195,15 @@ abstract class BaseTranslator(val provider: TypeProvider)
* @return String in the target language with reference to the enum variant
*/
def doEnumVariant(enumSpec: EnumSpec, variant: String): String
def doEnumById(enumSpec: EnumSpec, id: String): String
/**
* Translates cast of expression to the enumeration type.
*
* @param enumSpec An enum definition
* @param value Translated expression which should have enum type
*
* @return String in the target language transformation of the expression result into enumeration type
*/
def doEnumCast(enumSpec: EnumSpec, value: String): String

// Predefined methods of various types
def strConcat(left: Ast.expr, right: Ast.expr, extPrec: Int) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ class CSharpTranslator(provider: TypeProvider, importList: ImportList) extends B

override def doEnumVariant(enumSpec: EnumSpec, variant: String): String =
s"${enumClass(enumSpec.name)}.${Utils.upperCamelCase(variant)}"
override def doEnumById(enumSpec: EnumSpec, id: String): String =
s"((${enumClass(enumSpec.name)}) $id)"
override def doEnumCast(enumSpec: EnumSpec, value: String): String =
s"((${enumClass(enumSpec.name)}) $value)"

def enumClass(enumTypeAbs: List[String]): String = {
val enumTypeRel = Utils.relClass(enumTypeAbs, provider.nowClass.name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ class CppTranslator(provider: TypeProvider, importListSrc: CppImportList, import
CppCompiler.types2class(enumSpec.name.dropRight(1)) + "::" +
Utils.upperUnderscoreCase(enumSpec.name.last + "_" + variant)
}
override def doEnumById(enumSpec: EnumSpec, id: String): String =
s"static_cast<${CppCompiler.types2class(enumSpec.name)}>($id)"
override def doEnumCast(enumSpec: EnumSpec, value: String): String =
s"static_cast<${CppCompiler.types2class(enumSpec.name)}>($value)"

override def doStrCompareOp(left: Ast.expr, op: Ast.cmpop, right: Ast.expr) = {
if (op == Ast.cmpop.Eq) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ class ExpressionValidator(val provider: TypeProvider)
_: Ast.expr.FloatNum |
_: Ast.expr.Str |
_: Ast.expr.Bool => // all simple literals are good and valid
case Ast.expr.EnumById(enumType, id, inType) =>
case Ast.expr.EnumCast(enumType, value, inType) =>
provider.resolveEnum(inType, enumType.name)
validate(id)
validate(value)
case Ast.expr.EnumVariant(enumType, variant, inType) =>
val enumSpec = provider.resolveEnum(inType, enumType.name)
if (!enumSpec.map.values.exists(_.name == variant.name)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ class GoTranslator(out: StringLanguageOutputWriter, provider: TypeProvider, impo
trInterpolatedStringLiteral(s)
case Ast.expr.Bool(n) =>
trBoolLiteral(n)
case Ast.expr.EnumById(enumType, id, inType) =>
case Ast.expr.EnumCast(enumType, value, inType) =>
val enumSpec = provider.resolveEnum(inType, enumType.name)
trEnumById(enumSpec.name, translate(id))
trEnumCast(enumSpec.name, translate(value))
case Ast.expr.EnumVariant(enumType, variant, inType) =>
val enumSpec = provider.resolveEnum(inType, enumType.name)
trEnumVariant(enumSpec.name, variant.name)
Expand Down Expand Up @@ -260,8 +260,8 @@ class GoTranslator(out: StringLanguageOutputWriter, provider: TypeProvider, impo

def trEnumVariant(enumTypeAbs: List[String], variant: String) =
ResultString(GoCompiler.enumToStr(enumTypeAbs, variant))
def trEnumById(enumTypeAbs: List[String], id: String) =
ResultString(s"${types2class(enumTypeAbs)}($id)")
def trEnumCast(enumTypeAbs: List[String], value: String) =
ResultString(s"${types2class(enumTypeAbs)}($value)")

override def doBytesCompareOp(left: Ast.expr, op: Ast.cmpop, right: Ast.expr): String = {
op match {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ class JavaScriptTranslator(provider: TypeProvider, importList: ImportList) exten
}
s"${JavaScriptCompiler.types2class(enumSpec.name, isExternal)}.${Utils.upperUnderscoreCase(variant)}"
}
override def doEnumById(enumSpec: EnumSpec, id: String): String =
override def doEnumCast(enumSpec: EnumSpec, value: String): String =
// Just an integer, without any casts / resolutions - one would have to look up constants manually
id
value

override def doBytesCompareOp(left: Ast.expr, op: Ast.cmpop, right: Ast.expr): String =
s"(${JavaScriptCompiler.kstreamName}.byteArrayCompare(${translate(left)}, ${translate(right)}) ${cmpOp(op)} 0)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ class JavaTranslator(provider: TypeProvider, importList: ImportList) extends Bas

override def doEnumVariant(enumSpec: EnumSpec, variant: String): String =
s"${enumClass(enumSpec.name)}.${Utils.upperUnderscoreCase(variant)}"
override def doEnumById(enumSpec: EnumSpec, id: String): String =
s"${enumClass(enumSpec.name)}.byId($id)"
override def doEnumCast(enumSpec: EnumSpec, value: String): String =
s"${enumClass(enumSpec.name)}.byId($value)"

def enumClass(enumTypeAbs: List[String]): String = {
val enumTypeRel = Utils.relClass(enumTypeAbs, provider.nowClass.name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ class LuaTranslator(provider: TypeProvider, importList: ImportList) extends Base

override def doEnumVariant(enumSpec: EnumSpec, variant: String): String =
s"${LuaCompiler.types2class(enumSpec.name)}.$variant"
override def doEnumById(enumSpec: EnumSpec, id: String): String =
s"${LuaCompiler.types2class(enumSpec.name)}($id)"
override def doEnumCast(enumSpec: EnumSpec, value: String): String =
s"${LuaCompiler.types2class(enumSpec.name)}($value)"

override def strConcat(left: Ast.expr, right: Ast.expr, extPrec: Int): String =
s"${translate(left)} .. ${translate(right)}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class NimTranslator(provider: TypeProvider, importList: ImportList) extends Base
override def bytesToStr(bytesExpr: String, encoding: String): String = {
s"""encode($bytesExpr, "$encoding")"""
}
override def doEnumById(enumSpec: EnumSpec, id: String): String = s"${namespaced(enumSpec.name)}($id)"
override def doEnumCast(enumSpec: EnumSpec, value: String): String = s"${namespaced(enumSpec.name)}($value)"
// override def doEnumVariant(enumSpec: EnumSpec, variant: String): String = s"${namespaced(enumSpec.name)}($variant)"
override def doEnumVariant(enumSpec: EnumSpec, variant: String): String = s"${enumSpec.name.head}.$variant"
override def doName(s: String): String =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ class PHPTranslator(provider: TypeProvider, config: RuntimeConfig) extends BaseT
val enumClass = types2classAbs(enumSpec.name)
s"$enumClass::${Utils.upperUnderscoreCase(variant)}"
}
override def doEnumById(enumSpec: EnumSpec, id: String): String =
override def doEnumCast(enumSpec: EnumSpec, value: String): String =
// Just an integer, without any casts / resolutions - one would have to look up constants manually
id
value

override def arraySubscript(container: expr, idx: expr): String =
s"${translate(container)}[${translate(idx)}]"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ class PerlTranslator(provider: TypeProvider, importList: ImportList) extends Bas
val enumName = Utils.upperUnderscoreCase(enumSpec.name.last)
s"$$$enumClassWithScope${enumName}_${Utils.upperUnderscoreCase(variant)}"
}
override def doEnumById(enumSpec: EnumSpec, id: String): String =
override def doEnumCast(enumSpec: EnumSpec, value: String): String =
// Just an integer, without any casts / resolutions - one would have to look up constants manually
id
value

def enumClass(enumTypeAbs: List[String]): String = {
val enumTypeRel = Utils.relClass(enumTypeAbs, provider.nowClass.name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ class PythonTranslator(provider: TypeProvider, importList: ImportList, config: R
}
s"${PythonCompiler.types2class(enumSpec.name, isExternal)}.$variant"
}
override def doEnumById(enumSpec: EnumSpec, id: String): String =
s"${PythonCompiler.kstreamName}.resolve_enum(${PythonCompiler.types2class(enumSpec.name, enumSpec.isExternal(provider.nowClass))}, $id)"
override def doEnumCast(enumSpec: EnumSpec, value: String): String =
s"${PythonCompiler.kstreamName}.resolve_enum(${PythonCompiler.types2class(enumSpec.name, enumSpec.isExternal(provider.nowClass))}, $value)"

override def booleanOp(op: Ast.boolop) = op match {
case Ast.boolop.Or => "or"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ class RubyTranslator(provider: TypeProvider) extends BaseTranslator(provider)

override def doEnumVariant(enumSpec: EnumSpec, variant: String): String =
RubyCompiler.enumValue(enumSpec.name.last, variant)
override def doEnumById(enumSpec: EnumSpec, id: String): String =
s"${RubyCompiler.kstreamName}::resolve_enum(${enumDirectMap(enumSpec.name)}, $id)"
override def doEnumCast(enumSpec: EnumSpec, value: String): String =
s"${RubyCompiler.kstreamName}::resolve_enum(${enumDirectMap(enumSpec.name)}, $value)"

def enumDirectMap(enumTypeAndName: List[String]): String = {
val enumTypeAbs = enumTypeAndName.dropRight(1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ class RustTranslator(provider: TypeProvider, config: RuntimeConfig) extends Base
val enumClass = types2classAbs(enumSpec.name)
s"$enumClass::${Utils.upperUnderscoreCase(variant)}"
}
override def doEnumById(enumSpec: EnumSpec, id: String): String =
override def doEnumCast(enumSpec: EnumSpec, value: String): String =
// Just an integer, without any casts / resolutions - one would have to look up constants manually
id
value

override def arraySubscript(container: expr, idx: expr): String =
s"${translate(container)}[${translate(idx)}]"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class TypeDetector(provider: TypeProvider) {
val t = EnumType(inType.names.toList :+ enumType.name, CalcIntType)
t.enumSpec = Some(provider.resolveEnum(inType, enumType.name))
t
case Ast.expr.EnumById(enumType, _, inType) =>
case Ast.expr.EnumCast(enumType, _, inType) =>
val t = EnumType(List(enumType.name), CalcIntType)
t.enumSpec = Some(provider.resolveEnum(inType, enumType.name))
t
Expand Down

0 comments on commit ab4116e

Please sign in to comment.