@@ -457,11 +457,11 @@ export class Parser {
457
457
return this ;
458
458
}
459
459
460
- skip ( length : number , options ?: ParserOptions ) {
460
+ skip ( length : ParserOptions [ 'length' ] , options ?: ParserOptions ) {
461
461
return this . seek ( length , options ) ;
462
462
}
463
463
464
- seek ( relOffset : number , options ?: ParserOptions ) {
464
+ seek ( relOffset : ParserOptions [ 'length' ] , options ?: ParserOptions ) {
465
465
if ( options && options . assert ) {
466
466
throw new Error ( 'assert option on seek is not allowed.' ) ;
467
467
}
@@ -571,7 +571,7 @@ export class Parser {
571
571
return this . setNextParser ( 'choice' , varName as string , options ) ;
572
572
}
573
573
574
- nest ( varName : string | ParserOptions , options : ParserOptions ) {
574
+ nest ( varName : string | ParserOptions , options ? : ParserOptions ) {
575
575
if ( typeof options !== 'object' && typeof varName === 'object' ) {
576
576
options = varName ;
577
577
varName = null ;
@@ -670,34 +670,38 @@ export class Parser {
670
670
671
671
private addRawCode ( ctx : Context ) {
672
672
ctx . pushCode ( 'var offset = 0;' ) ;
673
-
674
- if ( this . constructorFn ) {
675
- ctx . pushCode ( 'var vars = new constructorFn();' ) ;
676
- } else {
677
- ctx . pushCode ( 'var vars = {};' ) ;
678
- }
673
+ ctx . pushCode (
674
+ `var vars = ${ this . constructorFn ? 'new constructorFn()' : '{}' } ;`
675
+ ) ;
676
+ ctx . pushCode ( 'vars.$parent = null;' ) ;
677
+ ctx . pushCode ( 'vars.$root = vars;' ) ;
679
678
680
679
this . generate ( ctx ) ;
681
680
682
681
this . resolveReferences ( ctx ) ;
683
682
683
+ ctx . pushCode ( 'delete vars.$parent;' ) ;
684
+ ctx . pushCode ( 'delete vars.$root;' ) ;
684
685
ctx . pushCode ( 'return vars;' ) ;
685
686
}
686
687
687
688
private addAliasedCode ( ctx : Context ) {
688
- ctx . pushCode ( `function ${ FUNCTION_PREFIX + this . alias } (offset) {` ) ;
689
-
690
- if ( this . constructorFn ) {
691
- ctx . pushCode ( 'var vars = new constructorFn();' ) ;
692
- } else {
693
- ctx . pushCode ( 'var vars = {};' ) ;
694
- }
689
+ ctx . pushCode (
690
+ `function ${ FUNCTION_PREFIX + this . alias } (offset, parent, root) {`
691
+ ) ;
692
+ ctx . pushCode (
693
+ `var vars = ${ this . constructorFn ? 'new constructorFn()' : '{}' } ;`
694
+ ) ;
695
+ ctx . pushCode ( 'vars.$parent = parent || null;' ) ;
696
+ ctx . pushCode ( 'vars.$root = root || vars;' ) ;
695
697
696
698
this . generate ( ctx ) ;
697
699
698
700
ctx . markResolved ( this . alias ) ;
699
701
this . resolveReferences ( ctx ) ;
700
702
703
+ ctx . pushCode ( 'delete vars.$parent;' ) ;
704
+ ctx . pushCode ( 'delete vars.$root;' ) ;
701
705
ctx . pushCode ( 'return { offset: offset, result: vars };' ) ;
702
706
ctx . pushCode ( '}' ) ;
703
707
@@ -1088,18 +1092,28 @@ export class Parser {
1088
1092
) ;
1089
1093
ctx . pushCode ( `offset += ${ PRIMITIVE_SIZES [ type as PrimitiveTypes ] } ;` ) ;
1090
1094
} else {
1095
+ const parentVar = ctx . generateVariable ( ) ;
1091
1096
const tempVar = ctx . generateTmpVariable ( ) ;
1092
- ctx . pushCode ( `var ${ tempVar } = ${ FUNCTION_PREFIX + type } (offset);` ) ;
1097
+ ctx . pushCode (
1098
+ `var ${ tempVar } = ${
1099
+ FUNCTION_PREFIX + type
1100
+ } (offset, ${ parentVar } , ${ parentVar } .$root);`
1101
+ ) ;
1093
1102
ctx . pushCode (
1094
1103
`var ${ item } = ${ tempVar } .result; offset = ${ tempVar } .offset;`
1095
1104
) ;
1096
1105
if ( type !== this . alias ) ctx . addReference ( type ) ;
1097
1106
}
1098
1107
} else if ( type instanceof Parser ) {
1108
+ const parentVar = ctx . generateVariable ( ) ;
1099
1109
ctx . pushCode ( `var ${ item } = {};` ) ;
1100
1110
1101
1111
ctx . pushScope ( item ) ;
1112
+ ctx . pushCode ( `${ item } .$parent = ${ parentVar } ;` ) ;
1113
+ ctx . pushCode ( `${ item } .$root = ${ parentVar } .$root;` ) ;
1102
1114
type . generate ( ctx ) ;
1115
+ ctx . pushCode ( `delete ${ item } .$parent` ) ;
1116
+ ctx . pushCode ( `delete ${ item } .$root` ) ;
1103
1117
ctx . popScope ( ) ;
1104
1118
}
1105
1119
@@ -1136,7 +1150,11 @@ export class Parser {
1136
1150
ctx . pushCode ( `offset += ${ PRIMITIVE_SIZES [ type as PrimitiveTypes ] } ` ) ;
1137
1151
} else {
1138
1152
const tempVar = ctx . generateTmpVariable ( ) ;
1139
- ctx . pushCode ( `var ${ tempVar } = ${ FUNCTION_PREFIX + type } (offset);` ) ;
1153
+ ctx . pushCode (
1154
+ `var ${ tempVar } = ${
1155
+ FUNCTION_PREFIX + type
1156
+ } (offset, ${ varName } .$parent, ${ varName } .$root);`
1157
+ ) ;
1140
1158
ctx . pushCode (
1141
1159
`${ varName } = ${ tempVar } .result; offset = ${ tempVar } .offset;`
1142
1160
) ;
@@ -1151,8 +1169,14 @@ export class Parser {
1151
1169
1152
1170
private generateChoice ( ctx : Context ) {
1153
1171
const tag = ctx . generateOption ( this . options . tag ) ;
1172
+ const nestVar = ctx . generateVariable ( this . varName ) ;
1173
+
1154
1174
if ( this . varName ) {
1155
- ctx . pushCode ( `${ ctx . generateVariable ( this . varName ) } = {};` ) ;
1175
+ ctx . pushCode ( `${ nestVar } = {};` ) ;
1176
+
1177
+ const parentVar = ctx . generateVariable ( ) ;
1178
+ ctx . pushCode ( `${ nestVar } .$parent = ${ parentVar } ;` ) ;
1179
+ ctx . pushCode ( `${ nestVar } .$root = ${ parentVar } .$root;` ) ;
1156
1180
}
1157
1181
ctx . pushCode ( `switch(${ tag } ) {` ) ;
1158
1182
Object . keys ( this . options . choices ) . forEach ( ( tag ) => {
@@ -1169,22 +1193,37 @@ export class Parser {
1169
1193
ctx . generateError ( `"Met undefined tag value " + ${ tag } + " at choice"` ) ;
1170
1194
}
1171
1195
ctx . pushCode ( '}' ) ;
1196
+
1197
+ if ( this . varName ) {
1198
+ ctx . pushCode ( `delete ${ nestVar } .$parent` ) ;
1199
+ ctx . pushCode ( `delete ${ nestVar } .$root` ) ;
1200
+ }
1172
1201
}
1173
1202
1174
1203
private generateNest ( ctx : Context ) {
1175
1204
const nestVar = ctx . generateVariable ( this . varName ) ;
1176
1205
1177
1206
if ( this . options . type instanceof Parser ) {
1178
1207
if ( this . varName ) {
1208
+ const parentVar = ctx . generateVariable ( ) ;
1179
1209
ctx . pushCode ( `${ nestVar } = {};` ) ;
1210
+ ctx . pushCode ( `${ nestVar } .$parent = ${ parentVar } ;` ) ;
1211
+ ctx . pushCode ( `${ nestVar } .$root = ${ parentVar } .$root;` ) ;
1180
1212
}
1181
1213
ctx . pushPath ( this . varName ) ;
1182
1214
this . options . type . generate ( ctx ) ;
1183
1215
ctx . popPath ( this . varName ) ;
1216
+ if ( this . varName ) {
1217
+ ctx . pushCode ( `delete ${ nestVar } .$parent` ) ;
1218
+ ctx . pushCode ( `delete ${ nestVar } .$root` ) ;
1219
+ }
1184
1220
} else if ( aliasRegistry [ this . options . type ] ) {
1221
+ const parentVar = ctx . generateVariable ( ) ;
1185
1222
const tempVar = ctx . generateTmpVariable ( ) ;
1186
1223
ctx . pushCode (
1187
- `var ${ tempVar } = ${ FUNCTION_PREFIX + this . options . type } (offset);`
1224
+ `var ${ tempVar } = ${
1225
+ FUNCTION_PREFIX + this . options . type
1226
+ } (offset, ${ parentVar } , ${ parentVar } .$root);`
1188
1227
) ;
1189
1228
ctx . pushCode (
1190
1229
`${ nestVar } = ${ tempVar } .result; offset = ${ tempVar } .offset;`
@@ -1285,14 +1324,22 @@ export class Parser {
1285
1324
ctx . pushCode ( `offset = ${ offset } ;` ) ;
1286
1325
1287
1326
if ( this . options . type instanceof Parser ) {
1327
+ const parentVar = ctx . generateVariable ( ) ;
1288
1328
ctx . pushCode ( `${ nestVar } = {};` ) ;
1329
+ ctx . pushCode ( `${ nestVar } .$parent = ${ parentVar } ;` ) ;
1330
+ ctx . pushCode ( `${ nestVar } .$root = ${ parentVar } .$root;` ) ;
1289
1331
ctx . pushPath ( this . varName ) ;
1290
1332
this . options . type . generate ( ctx ) ;
1291
1333
ctx . popPath ( this . varName ) ;
1334
+ ctx . pushCode ( `delete ${ nestVar } .$parent` ) ;
1335
+ ctx . pushCode ( `delete ${ nestVar } .$root` ) ;
1292
1336
} else if ( aliasRegistry [ this . options . type ] ) {
1337
+ const parentVar = ctx . generateVariable ( ) ;
1293
1338
const tempVar = ctx . generateTmpVariable ( ) ;
1294
1339
ctx . pushCode (
1295
- `var ${ tempVar } = ${ FUNCTION_PREFIX + this . options . type } (offset);`
1340
+ `var ${ tempVar } = ${
1341
+ FUNCTION_PREFIX + this . options . type
1342
+ } (offset, ${ parentVar } , ${ parentVar } .$root);`
1296
1343
) ;
1297
1344
ctx . pushCode (
1298
1345
`${ nestVar } = ${ tempVar } .result; offset = ${ tempVar } .offset;`
0 commit comments