@@ -100,24 +100,27 @@ export class Variable {
100100
101101
102102interface IExpressionPart {
103- toString ( variable : Variable ) : string ;
103+ toString ( variable : Variable , parameter : number | undefined ) : string ;
104104}
105105class ExpressionString implements IExpressionPart {
106106 constructor ( private _str : string ) { }
107- toString ( variable : Variable ) : string { return this . _str ; }
107+ toString ( variable : Variable , parameter : number | undefined ) : string { return this . _str ; }
108108}
109109class ExpressionThis implements IExpressionPart {
110- toString ( variable : Variable ) : string { return '(' + variable . name + ')' ; }
110+ toString ( variable : Variable , parameter : number | undefined ) : string { return '(' + variable . name + ')' ; }
111111}
112112class ExpressionNParam implements IExpressionPart {
113113 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 ) ; }
115115}
116116class 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 ) ; }
118118}
119119class 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" ; }
121124}
122125export class Expression
123126{
@@ -148,17 +151,21 @@ export class Expression
148151 this . _parts . push ( new ExpressionNParam ( parseInt ( match [ 0 ] . substr ( 2 ) ) ) ) ;
149152 index = match . index + match [ 0 ] . length ;
150153 }
154+ else if ( match [ 0 ] === '$i' ) {
155+ this . _parts . push ( new ExpressionIndex ( ) ) ;
156+ index = match . index + 2 ;
157+ }
151158 }
152159 }
153160 if ( index < expression . length ) {
154161 this . _parts . push ( new ExpressionString ( expression . substr ( index ) ) ) ;
155162 }
156163 }
157164
158- toString ( variable : Variable ) : string {
165+ toString ( variable : Variable , parameter : number | undefined = undefined ) : string {
159166 let result : string = '' ;
160167 for ( let part of this . _parts ) {
161- result += part . toString ( variable ) ;
168+ result += part . toString ( variable , parameter ) ;
162169 }
163170 // TODO: do this only for C++ ?
164171 // It is possible that this should depend on the debugger
@@ -197,6 +204,15 @@ async function evaluateExpression(dbg: debug.Debugger, variable: Variable, expre
197204 return new EvaluatedExpression ( expr , str , vt [ 1 ] ) ;
198205}
199206
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+
200216function getValueFromExpressionStr ( dbg : debug . Debugger , str : string ) : number | boolean | undefined {
201217 const language = dbg . language ( ) ;
202218 if ( language != undefined ) {
@@ -240,10 +256,9 @@ export class Container {
240256}
241257
242258export class RandomAccessContainer extends Container { }
243-
244259export class ContiguousContainer extends RandomAccessContainer { }
245260
246- // Static array
261+ // Indexed array
247262export class Array extends ContiguousContainer
248263{
249264 constructor ( private _start : Expression , private _size : Expression ) {
@@ -276,8 +291,8 @@ export class Array extends ContiguousContainer
276291 }
277292}
278293
279- // Dynamic array
280- export class DArray extends RandomAccessContainer {
294+ // Indexed array with size defined by two pointers
295+ export class DArray extends ContiguousContainer {
281296 constructor ( private _start : Expression , private _finish : Expression ) {
282297 super ( ) ;
283298 }
@@ -303,6 +318,38 @@ export class DArray extends RandomAccessContainer {
303318 }
304319}
305320
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+
306353// TODO: Later when direct memory access is implemented allow passing pointers
307354export class LinkedList extends Container
308355{
@@ -1262,6 +1309,12 @@ async function _getContainer(dbg: debug.Debugger, variable: Variable, entry: any
12621309 if ( start && finish ) {
12631310 return new DArray ( start . expression , finish . expression ) ;
12641311 }
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+ }
12651318 } else if ( entry . linkedlist && entry . linkedlist . size && entry . linkedlist . value ) {
12661319 if ( entry . linkedlist . head && entry . linkedlist . next ) {
12671320 const size = await evaluateExpression ( dbg , variable , entry . linkedlist . size ) ;
0 commit comments