diff --git a/shared/src/main/scala/io/kaitai/struct/languages/CSharpCompiler.scala b/shared/src/main/scala/io/kaitai/struct/languages/CSharpCompiler.scala index 88060c2c4..b5d2e3de7 100644 --- a/shared/src/main/scala/io/kaitai/struct/languages/CSharpCompiler.scala +++ b/shared/src/main/scala/io/kaitai/struct/languages/CSharpCompiler.scala @@ -274,15 +274,17 @@ class CSharpCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) override def condIfFooter(expr: expr): Unit = fileFooter(null) - override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw): Unit = { + override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = { importList.add("System.Collections.Generic") if (needRaw.level >= 1) out.puts(s"${privateMemberName(RawIdentifier(id))} = new List();") if (needRaw.level >= 2) out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = new List();") - out.puts(s"${privateMemberName(id)} = new ${kaitaiType2NativeType(ArrayTypeInStream(dataType))}();") + } + + override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType): Unit = { out.puts("{") out.inc out.puts("var i = 0;") @@ -302,33 +304,18 @@ class CSharpCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.puts("}") } - override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, repeatExpr: expr): Unit = { - importList.add("System.Collections.Generic") - - if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = new List((int) (${expression(repeatExpr)}));") - if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = new List((int) (${expression(repeatExpr)}));") - out.puts(s"${privateMemberName(id)} = new ${kaitaiType2NativeType(ArrayTypeInStream(dataType))}((int) (${expression(repeatExpr)}));") + override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, repeatExpr: expr): Unit = { out.puts(s"for (var i = 0; i < ${expression(repeatExpr)}; i++)") out.puts("{") out.inc } - override def handleAssignmentRepeatExpr(id: Identifier, expr: String): Unit = { - out.puts(s"${privateMemberName(id)}.Add($expr);") - } + override def handleAssignmentRepeatExpr(id: Identifier, expr: String): Unit = + handleAssignmentRepeatEos(id, expr) override def condRepeatExprFooter: Unit = fileFooter(null) - override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, untilExpr: expr): Unit = { - importList.add("System.Collections.Generic") - - if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = new List();") - if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = new List();") - out.puts(s"${privateMemberName(id)} = new ${kaitaiType2NativeType(ArrayTypeInStream(dataType))}();") + override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, untilExpr: expr): Unit = { out.puts("{") out.inc out.puts("var i = 0;") @@ -347,7 +334,7 @@ class CSharpCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.puts(s"${privateMemberName(id)}.Add($tempVar);") } - override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, untilExpr: expr): Unit = { + override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, untilExpr: expr): Unit = { typeProvider._currentIteratorType = Some(dataType) out.puts("i++;") out.dec diff --git a/shared/src/main/scala/io/kaitai/struct/languages/CppCompiler.scala b/shared/src/main/scala/io/kaitai/struct/languages/CppCompiler.scala index e6361cff5..c62311146 100644 --- a/shared/src/main/scala/io/kaitai/struct/languages/CppCompiler.scala +++ b/shared/src/main/scala/io/kaitai/struct/languages/CppCompiler.scala @@ -619,7 +619,7 @@ class CppCompiler( outSrc.puts("}") } - override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw): Unit = { + override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = { importListHdr.addSystem("vector") if (needRaw.level >= 1) { @@ -632,6 +632,9 @@ class CppCompiler( outSrc.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = ${newVector(CalcBytesType)};") } outSrc.puts(s"${privateMemberName(id)} = ${newVector(dataType)};") + } + + override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType): Unit = { outSrc.puts("{") outSrc.inc outSrc.puts("int i = 0;") @@ -651,54 +654,22 @@ class CppCompiler( outSrc.puts("}") } - override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, repeatExpr: Ast.expr): Unit = { - importListHdr.addSystem("vector") - + override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, repeatExpr: Ast.expr): Unit = { val lenVar = s"l_${idToStr(id)}" - outSrc.puts(s"int $lenVar = ${expression(repeatExpr)};") - if (needRaw.level >= 1) { - val rawId = privateMemberName(RawIdentifier(id)) - outSrc.puts(s"$rawId = ${newVector(CalcBytesType)};") - outSrc.puts(s"$rawId->reserve($lenVar);") - if (needRaw.hasIO) { - val ioId = privateMemberName(IoStorageIdentifier(RawIdentifier(id))) - outSrc.puts(s"$ioId = ${newVector(OwnedKaitaiStreamType)};") - outSrc.puts(s"$ioId->reserve($lenVar);") - } - } - if (needRaw.level >= 2) { - val rawId = privateMemberName(RawIdentifier(RawIdentifier(id))) - outSrc.puts(s"$rawId = ${newVector(CalcBytesType)};") - outSrc.puts(s"$rawId->reserve($lenVar);") - } - outSrc.puts(s"${privateMemberName(id)} = ${newVector(dataType)};") - outSrc.puts(s"${privateMemberName(id)}->reserve($lenVar);") + outSrc.puts(s"const int $lenVar = ${expression(repeatExpr)};") outSrc.puts(s"for (int i = 0; i < $lenVar; i++) {") outSrc.inc } - override def handleAssignmentRepeatExpr(id: Identifier, expr: String): Unit = { - outSrc.puts(s"${privateMemberName(id)}->push_back(${stdMoveWrap(expr)});") - } + override def handleAssignmentRepeatExpr(id: Identifier, expr: String): Unit = + handleAssignmentRepeatEos(id, expr) override def condRepeatExprFooter: Unit = { outSrc.dec outSrc.puts("}") } - override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, untilExpr: expr): Unit = { - importListHdr.addSystem("vector") - - if (needRaw.level >= 1) { - outSrc.puts(s"${privateMemberName(RawIdentifier(id))} = ${newVector(CalcBytesType)};") - if (needRaw.hasIO) { - outSrc.puts(s"${privateMemberName(IoStorageIdentifier(RawIdentifier(id)))} = ${newVector(OwnedKaitaiStreamType)};") - } - } - if (needRaw.level >= 2) { - outSrc.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = ${newVector(CalcBytesType)};") - } - outSrc.puts(s"${privateMemberName(id)} = ${newVector(dataType)};") + override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, untilExpr: expr): Unit = { outSrc.puts("{") outSrc.inc outSrc.puts("int i = 0;") @@ -732,7 +703,7 @@ class CppCompiler( outSrc.puts(s"${privateMemberName(id)}->push_back($wrappedTempVar);") } - override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, untilExpr: expr): Unit = { + override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, untilExpr: expr): Unit = { typeProvider._currentIteratorType = Some(dataType) outSrc.puts("i++;") outSrc.dec diff --git a/shared/src/main/scala/io/kaitai/struct/languages/GoCompiler.scala b/shared/src/main/scala/io/kaitai/struct/languages/GoCompiler.scala index eb40352eb..ad9514fb6 100644 --- a/shared/src/main/scala/io/kaitai/struct/languages/GoCompiler.scala +++ b/shared/src/main/scala/io/kaitai/struct/languages/GoCompiler.scala @@ -293,12 +293,12 @@ class GoCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.inc } - override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw): Unit = { - if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = make([][]byte, 0);") - if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = make([][]byte, 0);") - //out.puts(s"${privateMemberName(id)} = make(${kaitaiType2NativeType(ArrayType(dataType))})") + override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = { + // slices don't have to be manually initialized in Go: the built-in append() + // function works even on `nil` slices (https://go.dev/tour/moretypes/15) + } + + override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType): Unit = { out.puts(s"for i := 1;; i++ {") out.inc @@ -318,27 +318,21 @@ class GoCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.puts(s"$name = append($name, $expr)") } - override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, repeatExpr: Ast.expr): Unit = { - if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = make([][]byte, ${expression(repeatExpr)})") - if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = make([][]byte, ${expression(repeatExpr)})") - out.puts(s"${privateMemberName(id)} = make(${kaitaiType2NativeType(ArrayTypeInStream(dataType))}, ${expression(repeatExpr)})") - out.puts(s"for i := range ${privateMemberName(id)} {") + override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, repeatExpr: Ast.expr): Unit = { + out.puts(s"for i := 0; i < int(${expression(repeatExpr)}); i++ {") out.inc + // FIXME: Go throws a fatal compile error when the `i` variable is not used (unused variables + // can only use the blank identifier `_`, see https://go.dev/doc/effective_go#blank), so we have + // to silence it like this. It would be nice to be able to analyze all expressions that appear + // in the loop body to decide whether to generate `for _ := range` or `for i := range` here, but + // that would be really difficult to do properly in KSC with the current architecture. + out.puts("_ = i") } - override def handleAssignmentRepeatExpr(id: Identifier, r: TranslatorResult): Unit = { - val name = privateMemberName(id) - val expr = translator.resToStr(r) - out.puts(s"$name[i] = $expr") - } + override def handleAssignmentRepeatExpr(id: Identifier, r: TranslatorResult): Unit = + handleAssignmentRepeatEos(id, r) - override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, untilExpr: Ast.expr): Unit = { - if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = make([][]byte, 0);") - if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = make([][]byte, 0);") + override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, untilExpr: Ast.expr): Unit = { out.puts(s"for i := 1;; i++ {") out.inc } @@ -350,7 +344,7 @@ class GoCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.puts(s"${privateMemberName(id)} = append(${privateMemberName(id)}, $tempVar)") } - override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, untilExpr: Ast.expr): Unit = { + override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, untilExpr: Ast.expr): Unit = { typeProvider._currentIteratorType = Some(dataType) out.puts(s"if ${expression(untilExpr)} {") out.inc diff --git a/shared/src/main/scala/io/kaitai/struct/languages/JavaCompiler.scala b/shared/src/main/scala/io/kaitai/struct/languages/JavaCompiler.scala index e200c52f0..75449b6f9 100644 --- a/shared/src/main/scala/io/kaitai/struct/languages/JavaCompiler.scala +++ b/shared/src/main/scala/io/kaitai/struct/languages/JavaCompiler.scala @@ -356,12 +356,15 @@ class JavaCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.inc } - override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw): Unit = { + override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = { if (needRaw.level >= 1) out.puts(s"${privateMemberName(RawIdentifier(id))} = new ArrayList();") if (needRaw.level >= 2) out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = new ArrayList();") out.puts(s"${privateMemberName(id)} = new ${kaitaiType2JavaType(ArrayTypeInStream(dataType))}();") + } + + override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType): Unit = { out.puts("{") out.inc out.puts("int i = 0;") @@ -383,28 +386,17 @@ class JavaCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.puts("}") } - override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, repeatExpr: expr): Unit = { - if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = new ArrayList(((Number) (${expression(repeatExpr)})).intValue());") - if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = new ArrayList(((Number) (${expression(repeatExpr)})).intValue());") - out.puts(s"${idToStr(id)} = new ${kaitaiType2JavaType(ArrayTypeInStream(dataType))}(((Number) (${expression(repeatExpr)})).intValue());") + override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, repeatExpr: expr): Unit = { out.puts(s"for (int i = 0; i < ${expression(repeatExpr)}; i++) {") out.inc importList.add("java.util.ArrayList") } - override def handleAssignmentRepeatExpr(id: Identifier, expr: String): Unit = { - out.puts(s"${privateMemberName(id)}.add($expr);") - } + override def handleAssignmentRepeatExpr(id: Identifier, expr: String): Unit = + handleAssignmentRepeatEos(id, expr) - override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, untilExpr: expr): Unit = { - if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = new ArrayList();") - if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = new ArrayList();") - out.puts(s"${privateMemberName(id)} = new ${kaitaiType2JavaType(ArrayTypeInStream(dataType))}();") + override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, untilExpr: expr): Unit = { out.puts("{") out.inc out.puts(s"${kaitaiType2JavaType(dataType)} ${translator.doName("_")};") @@ -425,7 +417,7 @@ class JavaCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.puts(s"${privateMemberName(id)}.add($tempVar);") } - override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, untilExpr: expr): Unit = { + override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, untilExpr: expr): Unit = { typeProvider._currentIteratorType = Some(dataType) out.puts("i++;") out.dec diff --git a/shared/src/main/scala/io/kaitai/struct/languages/JavaScriptCompiler.scala b/shared/src/main/scala/io/kaitai/struct/languages/JavaScriptCompiler.scala index dea900c08..1bfd6ccdd 100644 --- a/shared/src/main/scala/io/kaitai/struct/languages/JavaScriptCompiler.scala +++ b/shared/src/main/scala/io/kaitai/struct/languages/JavaScriptCompiler.scala @@ -291,12 +291,13 @@ class JavaScriptCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.inc } + // TODO: replace this with UniversalFooter override def condIfFooter(expr: expr): Unit = { out.dec out.puts("}") } - override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw): Unit = { + override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = { if (needRaw.level >= 1) out.puts(s"${privateMemberName(RawIdentifier(id))} = [];") if (needRaw.level >= 2) @@ -304,6 +305,9 @@ class JavaScriptCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.puts(s"${privateMemberName(id)} = [];") if (config.readStoresPos) out.puts(s"this._debug.${idToStr(id)}.arr = [];") + } + + override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType): Unit = { out.puts("var i = 0;") out.puts(s"while (!$io.isEof()) {") out.inc @@ -319,35 +323,20 @@ class JavaScriptCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.puts("}") } - override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, repeatExpr: expr): Unit = { - if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = new Array(${expression(repeatExpr)});") - if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = new Array(${expression(repeatExpr)});") - out.puts(s"${privateMemberName(id)} = new Array(${expression(repeatExpr)});") - if (config.readStoresPos) - out.puts(s"this._debug.${idToStr(id)}.arr = new Array(${expression(repeatExpr)});") + override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, repeatExpr: expr): Unit = { out.puts(s"for (var i = 0; i < ${expression(repeatExpr)}; i++) {") out.inc } - override def handleAssignmentRepeatExpr(id: Identifier, expr: String): Unit = { - out.puts(s"${privateMemberName(id)}[i] = $expr;") - } + override def handleAssignmentRepeatExpr(id: Identifier, expr: String): Unit = + handleAssignmentRepeatEos(id, expr) override def condRepeatExprFooter: Unit = { out.dec out.puts("}") } - override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, untilExpr: expr): Unit = { - if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = []") - if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = [];") - out.puts(s"${privateMemberName(id)} = []") - if (config.readStoresPos) - out.puts(s"this._debug.${idToStr(id)}.arr = [];") + override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, untilExpr: expr): Unit = { out.puts("var i = 0;") out.puts("do {") out.inc @@ -359,7 +348,7 @@ class JavaScriptCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.puts(s"${privateMemberName(id)}.push($tmpName);") } - override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, untilExpr: expr): Unit = { + override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, untilExpr: expr): Unit = { typeProvider._currentIteratorType = Some(dataType) out.puts("i++;") out.dec diff --git a/shared/src/main/scala/io/kaitai/struct/languages/LuaCompiler.scala b/shared/src/main/scala/io/kaitai/struct/languages/LuaCompiler.scala index edefa442f..21047bc1b 100644 --- a/shared/src/main/scala/io/kaitai/struct/languages/LuaCompiler.scala +++ b/shared/src/main/scala/io/kaitai/struct/languages/LuaCompiler.scala @@ -162,12 +162,15 @@ class LuaCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.puts("end") } - override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw): Unit = { + override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = { if (needRaw.level >= 1) out.puts(s"${privateMemberName(RawIdentifier(id))} = {}") if (needRaw.level >= 2) out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = {}") out.puts(s"${privateMemberName(id)} = {}") + } + + override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType): Unit = { out.puts("local i = 0") out.puts(s"while not $io:is_eof() do") out.inc @@ -178,12 +181,7 @@ class LuaCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.puts("end") } - override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, repeatExpr: Ast.expr): Unit = { - if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = {}") - if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = {}") - out.puts(s"${privateMemberName(id)} = {}") + override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, repeatExpr: Ast.expr): Unit = { out.puts(s"for i = 0, ${expression(repeatExpr)} - 1 do") out.inc } @@ -192,17 +190,12 @@ class LuaCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.puts("end") } - override def condRepeatUntilHeader(id: Identifier, io: String, datatype: DataType, needRaw: NeedRaw, repeatExpr: Ast.expr): Unit = { - if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = {}") - if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = {}") - out.puts(s"${privateMemberName(id)} = {}") + override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, repeatExpr: Ast.expr): Unit = { out.puts("local i = 0") out.puts("while true do") out.inc } - override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, untilExpr: Ast.expr): Unit = { + override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, untilExpr: Ast.expr): Unit = { typeProvider._currentIteratorType = Some(dataType) out.puts(s"if ${expression(untilExpr)} then") out.inc diff --git a/shared/src/main/scala/io/kaitai/struct/languages/NimCompiler.scala b/shared/src/main/scala/io/kaitai/struct/languages/NimCompiler.scala index aaa253f57..50da6636a 100644 --- a/shared/src/main/scala/io/kaitai/struct/languages/NimCompiler.scala +++ b/shared/src/main/scala/io/kaitai/struct/languages/NimCompiler.scala @@ -143,7 +143,13 @@ class NimCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) } universalFooter } - override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw): Unit = { + + override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = { + // sequences don't have to be manually initialized in Nim - they're automatically initialized as + // empty sequences (see https://narimiran.github.io/nim-basics/#_result_variable) + } + + override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType): Unit = { out.puts("block:") out.inc out.puts("var i: int") @@ -155,18 +161,18 @@ class NimCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.dec out.dec } - override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, repeatExpr: Ast.expr): Unit = { + override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, repeatExpr: Ast.expr): Unit = { out.puts(s"for i in 0 ..< int(${expression(repeatExpr)}):") out.inc } - override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, repeatExpr: Ast.expr): Unit = { + override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, repeatExpr: Ast.expr): Unit = { out.puts("block:") out.inc out.puts("var i: int") out.puts("while true:") out.inc } - override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, repeatExpr: Ast.expr): Unit = { + override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, repeatExpr: Ast.expr): Unit = { typeProvider._currentIteratorType = Some(dataType) out.puts(s"if ${expression(repeatExpr)}:") out.inc diff --git a/shared/src/main/scala/io/kaitai/struct/languages/PHPCompiler.scala b/shared/src/main/scala/io/kaitai/struct/languages/PHPCompiler.scala index 26086cebd..03e896db4 100644 --- a/shared/src/main/scala/io/kaitai/struct/languages/PHPCompiler.scala +++ b/shared/src/main/scala/io/kaitai/struct/languages/PHPCompiler.scala @@ -267,12 +267,15 @@ class PHPCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.inc } - override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw): Unit = { + override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = { if (needRaw.level >= 1) out.puts(s"${privateMemberName(RawIdentifier(id))} = [];") if (needRaw.level >= 2) out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = [];") out.puts(s"${privateMemberName(id)} = [];") + } + + override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType): Unit = { out.puts("$i = 0;") out.puts(s"while (!$io->isEof()) {") out.inc @@ -287,27 +290,16 @@ class PHPCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) super.condRepeatEosFooter } - override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, repeatExpr: Ast.expr): Unit = { - if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = [];") - if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = [];") - out.puts(s"${privateMemberName(id)} = [];") + override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, repeatExpr: Ast.expr): Unit = { out.puts(s"$$n = ${expression(repeatExpr)};") out.puts("for ($i = 0; $i < $n; $i++) {") out.inc } - override def handleAssignmentRepeatExpr(id: Identifier, expr: String): Unit = { - out.puts(s"${privateMemberName(id)}[] = $expr;") - } + override def handleAssignmentRepeatExpr(id: Identifier, expr: String): Unit = + handleAssignmentRepeatEos(id, expr) - override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, untilExpr: Ast.expr): Unit = { - if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = [];") - if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = [];") - out.puts(s"${privateMemberName(id)} = [];") + override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, untilExpr: Ast.expr): Unit = { out.puts("$i = 0;") out.puts("do {") out.inc @@ -319,7 +311,7 @@ class PHPCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.puts(s"${privateMemberName(id)}[] = $tmpName;") } - override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, untilExpr: Ast.expr): Unit = { + override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, untilExpr: Ast.expr): Unit = { typeProvider._currentIteratorType = Some(dataType) out.puts("$i++;") out.dec diff --git a/shared/src/main/scala/io/kaitai/struct/languages/PerlCompiler.scala b/shared/src/main/scala/io/kaitai/struct/languages/PerlCompiler.scala index 1e3258d55..5bd3aaa72 100644 --- a/shared/src/main/scala/io/kaitai/struct/languages/PerlCompiler.scala +++ b/shared/src/main/scala/io/kaitai/struct/languages/PerlCompiler.scala @@ -236,12 +236,15 @@ class PerlCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.inc } - override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw): Unit = { + override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = { if (needRaw.level >= 1) out.puts(s"${privateMemberName(RawIdentifier(id))} = ();") if (needRaw.level >= 2) out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = ();") out.puts(s"${privateMemberName(id)} = ();") + } + + override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType): Unit = { out.puts(s"while (!$io->is_eof()) {") out.inc } @@ -249,12 +252,7 @@ class PerlCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) override def handleAssignmentRepeatEos(id: Identifier, expr: String): Unit = out.puts(s"push @{${privateMemberName(id)}}, $expr;") - override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, repeatExpr: expr): Unit = { - if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = ();") - if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = ();") - out.puts(s"${privateMemberName(id)} = ();") + override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, repeatExpr: expr): Unit = { val nVar = s"$$n_${idToStr(id)}" out.puts(s"my $nVar = ${expression(repeatExpr)};") out.puts(s"for (my $$i = 0; $$i < $nVar; $$i++) {") @@ -262,14 +260,9 @@ class PerlCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) } override def handleAssignmentRepeatExpr(id: Identifier, expr: String): Unit = - out.puts(s"${privateMemberName(id)}[$$i] = $expr;") + handleAssignmentRepeatEos(id, expr) - override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, untilExpr: expr): Unit = { - if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = ();") - if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = ();") - out.puts(s"${privateMemberName(id)} = ();") + override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, untilExpr: expr): Unit = { out.puts("do {") out.inc } @@ -284,7 +277,7 @@ class PerlCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.puts(s"push @{${privateMemberName(id)}}, $tmpName;") } - override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, untilExpr: expr): Unit = { + override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, untilExpr: expr): Unit = { typeProvider._currentIteratorType = Some(dataType) out.dec out.puts(s"} until (${expression(untilExpr)});") diff --git a/shared/src/main/scala/io/kaitai/struct/languages/PythonCompiler.scala b/shared/src/main/scala/io/kaitai/struct/languages/PythonCompiler.scala index 181e9de97..5a02b1a97 100644 --- a/shared/src/main/scala/io/kaitai/struct/languages/PythonCompiler.scala +++ b/shared/src/main/scala/io/kaitai/struct/languages/PythonCompiler.scala @@ -274,6 +274,8 @@ class PythonCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) case NoRepeat => out.puts(s"self._debug['$name']['start'] = $io.pos()") case _: RepeatExpr | RepeatEos | _: RepeatUntil => + /** TODO: move array initialization to [[condRepeatCommonInit]] - see + * [[JavaScriptCompiler.condRepeatCommonInit]] for inspiration */ out.puts(s"if not 'arr' in self._debug['$name']:") out.inc out.puts(s"self._debug['$name']['arr'] = []") @@ -303,41 +305,35 @@ class PythonCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.inc } - override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw): Unit = { + override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = { if (needRaw.level >= 1) out.puts(s"${privateMemberName(RawIdentifier(id))} = []") if (needRaw.level >= 2) out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = []") out.puts(s"${privateMemberName(id)} = []") + } + + override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType): Unit = { out.puts("i = 0") out.puts(s"while not $io.is_eof():") out.inc } override def handleAssignmentRepeatEos(id: Identifier, expr: String): Unit = out.puts(s"${privateMemberName(id)}.append($expr)") + override def condRepeatEosFooter: Unit = { out.puts("i += 1") universalFooter } - override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, repeatExpr: expr): Unit = { - if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = [None] * (${expression(repeatExpr)})") - if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = [None] * (${expression(repeatExpr)})") - out.puts(s"${privateMemberName(id)} = [None] * (${expression(repeatExpr)})") + override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, repeatExpr: expr): Unit = { out.puts(s"for i in range(${expression(repeatExpr)}):") out.inc } override def handleAssignmentRepeatExpr(id: Identifier, expr: String): Unit = - out.puts(s"${privateMemberName(id)}[i] = $expr") + handleAssignmentRepeatEos(id, expr) - override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, untilExpr: expr): Unit = { - if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = []") - if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = []") - out.puts(s"${privateMemberName(id)} = []") + override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, untilExpr: expr): Unit = { out.puts("i = 0") out.puts("while True:") out.inc @@ -349,7 +345,7 @@ class PythonCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.puts(s"${privateMemberName(id)}.append($tmpName)") } - override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, untilExpr: expr): Unit = { + override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, untilExpr: expr): Unit = { typeProvider._currentIteratorType = Some(dataType) out.puts(s"if ${expression(untilExpr)}:") out.inc diff --git a/shared/src/main/scala/io/kaitai/struct/languages/RubyCompiler.scala b/shared/src/main/scala/io/kaitai/struct/languages/RubyCompiler.scala index e9abac312..e1f103a0d 100644 --- a/shared/src/main/scala/io/kaitai/struct/languages/RubyCompiler.scala +++ b/shared/src/main/scala/io/kaitai/struct/languages/RubyCompiler.scala @@ -278,46 +278,40 @@ class RubyCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.inc } - override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw): Unit = { + override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = { if (needRaw.level >= 1) out.puts(s"${privateMemberName(RawIdentifier(id))} = []") if (needRaw.level >= 2) out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = []") - out.puts(s"${privateMemberName(id)} = []") + } + + override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType): Unit = { out.puts("i = 0") out.puts(s"while not $io.eof?") out.inc } override def handleAssignmentRepeatEos(id: Identifier, expr: String): Unit = out.puts(s"${privateMemberName(id)} << $expr") + override def condRepeatEosFooter: Unit = { out.puts("i += 1") super.condRepeatEosFooter } - override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, repeatExpr: expr): Unit = { - if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = Array.new(${expression(repeatExpr)})") - if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = Array.new(${expression(repeatExpr)})") - out.puts(s"${privateMemberName(id)} = Array.new(${expression(repeatExpr)})") + override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, repeatExpr: expr): Unit = { out.puts(s"(${expression(repeatExpr)}).times { |i|") out.inc } override def handleAssignmentRepeatExpr(id: Identifier, expr: String): Unit = - out.puts(s"${privateMemberName(id)}[i] = $expr") + handleAssignmentRepeatEos(id, expr) + override def condRepeatExprFooter: Unit = { out.dec out.puts("}") } - override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, untilExpr: expr): Unit = { - if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = []") - if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = []") - out.puts(s"${privateMemberName(id)} = []") + override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, untilExpr: expr): Unit = { out.puts("i = 0") out.puts("begin") out.inc @@ -329,7 +323,7 @@ class RubyCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.puts(s"${privateMemberName(id)} << $tmpName") } - override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, untilExpr: expr): Unit = { + override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, untilExpr: expr): Unit = { typeProvider._currentIteratorType = Some(dataType) out.puts("i += 1") out.dec diff --git a/shared/src/main/scala/io/kaitai/struct/languages/RustCompiler.scala b/shared/src/main/scala/io/kaitai/struct/languages/RustCompiler.scala index 5325310ef..2a460879a 100644 --- a/shared/src/main/scala/io/kaitai/struct/languages/RustCompiler.scala +++ b/shared/src/main/scala/io/kaitai/struct/languages/RustCompiler.scala @@ -253,44 +253,36 @@ class RustCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) out.inc } - override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw): Unit = { + override def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit = { if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = [];") + out.puts(s"${privateMemberName(RawIdentifier(id))} = vec!();") if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = [];") - out.puts(s"${privateMemberName(id)} = [];") + out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = vec!();") + out.puts(s"${privateMemberName(id)} = vec!();") + } + + override def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType): Unit = { out.puts(s"while !$io.isEof() {") out.inc } override def handleAssignmentRepeatEos(id: Identifier, expr: String): Unit = { - out.puts(s"${privateMemberName(id)}.push($expr);") + out.puts(s"${privateMemberName(id)}.append($expr);") } override def condRepeatEosFooter: Unit = { super.condRepeatEosFooter } - override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, repeatExpr: Ast.expr): Unit = { - if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = vec!();") - if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = vec!();") - out.puts(s"${privateMemberName(id)} = vec!();") + override def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, repeatExpr: Ast.expr): Unit = { out.puts(s"for i in 0..${expression(repeatExpr)} {") out.inc } - override def handleAssignmentRepeatExpr(id: Identifier, expr: String): Unit = { - out.puts(s"${privateMemberName(id)}.push($expr);") - } + override def handleAssignmentRepeatExpr(id: Identifier, expr: String): Unit = + handleAssignmentRepeatEos(id, expr) - override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, untilExpr: Ast.expr): Unit = { - if (needRaw.level >= 1) - out.puts(s"${privateMemberName(RawIdentifier(id))} = vec!();") - if (needRaw.level >= 2) - out.puts(s"${privateMemberName(RawIdentifier(RawIdentifier(id)))} = vec!();") - out.puts(s"${privateMemberName(id)} = vec!();") + override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, untilExpr: Ast.expr): Unit = { out.puts("while {") out.inc } @@ -302,10 +294,10 @@ class RustCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) translator.doLocalName(Identifier.ITERATOR) } out.puts(s"let $tempVar = $expr;") - out.puts(s"${privateMemberName(id)}.append($expr);") + out.puts(s"${privateMemberName(id)}.append($tempVar);") } - override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, untilExpr: Ast.expr): Unit = { + override def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, untilExpr: Ast.expr): Unit = { typeProvider._currentIteratorType = Some(dataType) out.puts(s"!(${expression(untilExpr)})") out.dec diff --git a/shared/src/main/scala/io/kaitai/struct/languages/components/CommonReads.scala b/shared/src/main/scala/io/kaitai/struct/languages/components/CommonReads.scala index ed36b47d7..899585e67 100644 --- a/shared/src/main/scala/io/kaitai/struct/languages/components/CommonReads.scala +++ b/shared/src/main/scala/io/kaitai/struct/languages/components/CommonReads.scala @@ -63,21 +63,26 @@ trait CommonReads extends LanguageCompiler { } def attrParse0(id: Identifier, attr: AttrLikeSpec, io: String, defEndian: Option[FixedEndian]): Unit = { + if (attr.cond.repeat != NoRepeat) + condRepeatCommonInit(id, attr.dataType, needRaw(attr.dataType)) attr.cond.repeat match { case RepeatEos => - condRepeatEosHeader(id, io, attr.dataType, needRaw(attr.dataType)) - attrParse2(id, attr.dataType, io, attr.cond.repeat, false, defEndian) - condRepeatEosFooter + condRepeatEosHeader(id, io, attr.dataType) case RepeatExpr(repeatExpr: Ast.expr) => - condRepeatExprHeader(id, io, attr.dataType, needRaw(attr.dataType), repeatExpr) - attrParse2(id, attr.dataType, io, attr.cond.repeat, false, defEndian) + condRepeatExprHeader(id, io, attr.dataType, repeatExpr) + case RepeatUntil(untilExpr: Ast.expr) => + condRepeatUntilHeader(id, io, attr.dataType, untilExpr) + case NoRepeat => + } + attrParse2(id, attr.dataType, io, attr.cond.repeat, false, defEndian) + attr.cond.repeat match { + case RepeatEos => + condRepeatEosFooter + case _: RepeatExpr => condRepeatExprFooter case RepeatUntil(untilExpr: Ast.expr) => - condRepeatUntilHeader(id, io, attr.dataType, needRaw(attr.dataType), untilExpr) - attrParse2(id, attr.dataType, io, attr.cond.repeat, false, defEndian) - condRepeatUntilFooter(id, io, attr.dataType, needRaw(attr.dataType), untilExpr) + condRepeatUntilFooter(id, io, attr.dataType, untilExpr) case NoRepeat => - attrParse2(id, attr.dataType, io, attr.cond.repeat, false, defEndian) } } diff --git a/shared/src/main/scala/io/kaitai/struct/languages/components/LanguageCompiler.scala b/shared/src/main/scala/io/kaitai/struct/languages/components/LanguageCompiler.scala index 09847c878..2edeadc5e 100644 --- a/shared/src/main/scala/io/kaitai/struct/languages/components/LanguageCompiler.scala +++ b/shared/src/main/scala/io/kaitai/struct/languages/components/LanguageCompiler.scala @@ -103,14 +103,16 @@ abstract class LanguageCompiler( def condIfHeader(expr: Ast.expr): Unit def condIfFooter(expr: Ast.expr): Unit - def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw): Unit + def condRepeatCommonInit(id: Identifier, dataType: DataType, needRaw: NeedRaw): Unit + + def condRepeatEosHeader(id: Identifier, io: String, dataType: DataType): Unit def condRepeatEosFooter: Unit - def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, repeatExpr: Ast.expr): Unit + def condRepeatExprHeader(id: Identifier, io: String, dataType: DataType, repeatExpr: Ast.expr): Unit def condRepeatExprFooter: Unit - def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, repeatExpr: Ast.expr): Unit - def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, needRaw: NeedRaw, repeatExpr: Ast.expr): Unit + def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, untilExpr: Ast.expr): Unit + def condRepeatUntilFooter(id: Identifier, io: String, dataType: DataType, repeatExpr: Ast.expr): Unit def attrProcess(proc: ProcessExpr, varSrc: Identifier, varDest: Identifier, rep: RepeatSpec): Unit