@@ -100,24 +100,27 @@ export class Variable {
100
100
101
101
102
102
interface IExpressionPart {
103
- toString ( variable : Variable ) : string ;
103
+ toString ( variable : Variable , parameter : number | undefined ) : string ;
104
104
}
105
105
class ExpressionString implements IExpressionPart {
106
106
constructor ( private _str : string ) { }
107
- toString ( variable : Variable ) : string { return this . _str ; }
107
+ toString ( variable : Variable , parameter : number | undefined ) : string { return this . _str ; }
108
108
}
109
109
class ExpressionThis implements IExpressionPart {
110
- toString ( variable : Variable ) : string { return '(' + variable . name + ')' ; }
110
+ toString ( variable : Variable , parameter : number | undefined ) : string { return '(' + variable . name + ')' ; }
111
111
}
112
112
class ExpressionNParam implements IExpressionPart {
113
113
constructor ( protected _i : number ) { }
114
- toString ( variable : Variable ) : string { return variable . nparam ( this . _i ) ; }
114
+ toString ( variable : Variable , parameter : number | undefined ) : string { return variable . nparam ( this . _i ) ; }
115
115
}
116
116
class ExpressionTParam extends ExpressionNParam {
117
- toString ( variable : Variable ) : string { return variable . tparam ( this . _i ) ; }
117
+ toString ( variable : Variable , parameter : number | undefined ) : string { return variable . tparam ( this . _i ) ; }
118
118
}
119
119
class ExpressionType implements IExpressionPart {
120
- toString ( variable : Variable ) : string { return variable . type ; }
120
+ toString ( variable : Variable , parameter : number | undefined ) : string { return variable . type ; }
121
+ }
122
+ class ExpressionIndex implements IExpressionPart {
123
+ toString ( variable : Variable , parameter : number | undefined ) : string { return parameter !== undefined ? parameter . toString ( ) : "0" ; }
121
124
}
122
125
export class Expression
123
126
{
@@ -148,17 +151,21 @@ export class Expression
148
151
this . _parts . push ( new ExpressionNParam ( parseInt ( match [ 0 ] . substr ( 2 ) ) ) ) ;
149
152
index = match . index + match [ 0 ] . length ;
150
153
}
154
+ else if ( match [ 0 ] === '$i' ) {
155
+ this . _parts . push ( new ExpressionIndex ( ) ) ;
156
+ index = match . index + 2 ;
157
+ }
151
158
}
152
159
}
153
160
if ( index < expression . length ) {
154
161
this . _parts . push ( new ExpressionString ( expression . substr ( index ) ) ) ;
155
162
}
156
163
}
157
164
158
- toString ( variable : Variable ) : string {
165
+ toString ( variable : Variable , parameter : number | undefined = undefined ) : string {
159
166
let result : string = '' ;
160
167
for ( let part of this . _parts ) {
161
- result += part . toString ( variable ) ;
168
+ result += part . toString ( variable , parameter ) ;
162
169
}
163
170
// TODO: do this only for C++ ?
164
171
// It is possible that this should depend on the debugger
@@ -197,6 +204,15 @@ async function evaluateExpression(dbg: debug.Debugger, variable: Variable, expre
197
204
return new EvaluatedExpression ( expr , str , vt [ 1 ] ) ;
198
205
}
199
206
207
+ async function evaluateIndexedExpression ( dbg : debug . Debugger , variable : Variable , expressionName : string , parameter : number ) : Promise < EvaluatedExpression | undefined > {
208
+ const expr = new Expression ( expressionName ) ;
209
+ const str = expr . toString ( variable , parameter ) ;
210
+ let vt = await dbg . getValueAndRawType ( str ) ;
211
+ if ( vt === undefined )
212
+ return undefined ;
213
+ return new EvaluatedExpression ( expr , str , vt [ 1 ] ) ;
214
+ }
215
+
200
216
function getValueFromExpressionStr ( dbg : debug . Debugger , str : string ) : number | boolean | undefined {
201
217
const language = dbg . language ( ) ;
202
218
if ( language != undefined ) {
@@ -240,10 +256,9 @@ export class Container {
240
256
}
241
257
242
258
export class RandomAccessContainer extends Container { }
243
-
244
259
export class ContiguousContainer extends RandomAccessContainer { }
245
260
246
- // Static array
261
+ // Indexed array
247
262
export class Array extends ContiguousContainer
248
263
{
249
264
constructor ( private _start : Expression , private _size : Expression ) {
@@ -276,8 +291,8 @@ export class Array extends ContiguousContainer
276
291
}
277
292
}
278
293
279
- // Dynamic array
280
- export class DArray extends RandomAccessContainer {
294
+ // Indexed array with size defined by two pointers
295
+ export class DArray extends ContiguousContainer {
281
296
constructor ( private _start : Expression , private _finish : Expression ) {
282
297
super ( ) ;
283
298
}
@@ -303,6 +318,38 @@ export class DArray extends RandomAccessContainer {
303
318
}
304
319
}
305
320
321
+ export class IArray extends RandomAccessContainer
322
+ {
323
+ constructor ( private _element : Expression , private _size : Expression ) {
324
+ super ( ) ;
325
+ }
326
+
327
+ element ( variable : Variable ) : string | undefined {
328
+ return this . _element . toString ( variable , 0 ) ;
329
+ }
330
+
331
+ async size ( dbg : debug . Debugger , variable : Variable ) : Promise < number > {
332
+ const sizeStr = this . _size . toString ( variable ) ;
333
+ // TODO: Check if it's possible to parse size at this point
334
+ const sizeVal = await dbg . getValue ( sizeStr ) ;
335
+ return sizeVal !== undefined ? parseInt ( sizeVal ) : 0 ;
336
+ }
337
+
338
+ async * elements ( dbg : debug . Debugger , variable : Variable ) : AsyncGenerator < string , void , unknown > {
339
+ const size = await this . size ( dbg , variable ) ;
340
+ if ( ! ( size > 0 ) ) // also handle NaN
341
+ return ;
342
+ // NOTE: This loop could be done asynchroniously with await Promise.all()
343
+ // but an array can potentially store great number of objects so there
344
+ // would be great number of promises. And it will not be possible to
345
+ // end fast in case of error because the program would wait for all.
346
+ for ( let i = 0 ; i < size ; ++ i ) {
347
+ const elStr = this . _element . toString ( variable , i ) ;
348
+ yield elStr ;
349
+ }
350
+ }
351
+ }
352
+
306
353
// TODO: Later when direct memory access is implemented allow passing pointers
307
354
export class LinkedList extends Container
308
355
{
@@ -1262,6 +1309,12 @@ async function _getContainer(dbg: debug.Debugger, variable: Variable, entry: any
1262
1309
if ( start && finish ) {
1263
1310
return new DArray ( start . expression , finish . expression ) ;
1264
1311
}
1312
+ } else if ( entry . iarray && entry . iarray . element && entry . iarray . size ) {
1313
+ const element = await evaluateIndexedExpression ( dbg , variable , entry . iarray . element , 0 ) ;
1314
+ const size = await evaluateExpression ( dbg , variable , entry . iarray . size ) ;
1315
+ if ( element && size ) {
1316
+ return new IArray ( element . expression , size . expression ) ;
1317
+ }
1265
1318
} else if ( entry . linkedlist && entry . linkedlist . size && entry . linkedlist . value ) {
1266
1319
if ( entry . linkedlist . head && entry . linkedlist . next ) {
1267
1320
const size = await evaluateExpression ( dbg , variable , entry . linkedlist . size ) ;
0 commit comments