@@ -121,6 +121,62 @@ void cmd_packed_let() {
121121 }
122122}
123123
124+ unsigned get_dimensions (int32_t * * lbound , int32_t * * ubound ) {
125+ unsigned count = 0 ;
126+ if (code_peek () == kwTYPE_LEVEL_BEGIN ) {
127+ code_skipnext ();
128+ while (code_peek () != kwTYPE_LEVEL_END && !prog_error ) {
129+ if (count == MAXDIM ) {
130+ err_matdim ();
131+ break ;
132+ }
133+ var_t arg ;
134+ v_init (& arg );
135+ eval (& arg );
136+ if (prog_error ) {
137+ break ;
138+ }
139+ int dim = v_getint (& arg );
140+ v_free (& arg );
141+
142+ if (count ) {
143+ // allocate for extra dimension
144+ * lbound = (int32_t * )realloc (* lbound , (sizeof (int32_t ) * (count + 1 )));
145+ * ubound = (int32_t * )realloc (* ubound , (sizeof (int32_t ) * (count + 1 )));
146+ } else {
147+ // allocate for first dimension
148+ * lbound = (int32_t * )malloc (sizeof (int32_t ));
149+ * ubound = (int32_t * )malloc (sizeof (int32_t ));
150+ }
151+
152+ if (code_peek () == kwTO ) {
153+ (* lbound )[count ] = dim ;
154+ code_skipnext ();
155+ eval (& arg );
156+ (* ubound )[count ] = v_getint (& arg );
157+ v_free (& arg );
158+ } else {
159+ (* lbound )[count ] = opt_base ;
160+ (* ubound )[count ] = dim ;
161+ }
162+
163+ count ++ ;
164+
165+ // skip separator
166+ if (code_peek () == kwTYPE_SEP ) {
167+ code_skipnext ();
168+ if (code_getnext () != ',' ) {
169+ err_missing_comma ();
170+ break ;
171+ }
172+ }
173+ }
174+ // skip end separator
175+ code_skipnext ();
176+ }
177+ return count ;
178+ }
179+
124180/**
125181 * DIM var([lower TO] uppper [, ...])
126182 */
@@ -131,95 +187,51 @@ void cmd_dim(int preserve) {
131187 byte code = code_peek ();
132188 if (code == kwTYPE_LINE || code == kwTYPE_EOC ) {
133189 exitf = 1 ;
134- } else {
135- var_t array ;
136- array .v .a .maxdim = 0 ;
137- if (code_peek () == kwTYPE_SEP ) {
138- code_skipnext ();
139- if (code_getnext () != ',' ) {
140- err_missing_comma ();
141- }
190+ break ;
191+ }
192+ if (code_peek () == kwTYPE_SEP ) {
193+ code_skipnext ();
194+ if (code_getnext () != ',' ) {
195+ err_missing_comma ();
196+ return ;
142197 }
198+ }
143199
144- var_t * var_p = code_getvarptr_parens (1 );
145- byte zero_length = 1 ;
200+ var_t * var_p = code_getvarptr_parens (1 );
201+ if (prog_error ) {
202+ break ;
203+ }
146204
147- if (!prog_error ) {
148- if (code_peek () == kwTYPE_LEVEL_BEGIN ) {
149- code_skipnext ();
150- while (code_peek () != kwTYPE_LEVEL_END ) {
151- zero_length = 0 ;
152- var_t arg ;
153- v_init (& arg );
154- eval (& arg );
155- if (prog_error ) {
156- return ;
157- }
158- if (code_peek () == kwTO ) {
159- array .v .a .lbound [array .v .a .maxdim ] = v_getint (& arg );
160- code_skipnext ();
161- eval (& arg );
162- if (prog_error ) {
163- return ;
164- }
165- array .v .a .ubound [array .v .a .maxdim ] = v_getint (& arg );
166- } else {
167- array .v .a .lbound [array .v .a .maxdim ] = opt_base ;
168- array .v .a .ubound [array .v .a .maxdim ] = v_getint (& arg );
169- }
170- v_free (& arg );
171- array .v .a .maxdim ++ ;
172-
173- // skip separator
174- if (code_peek () == kwTYPE_SEP ) {
175- code_skipnext ();
176- if (code_getnext () != ',' ) {
177- err_missing_comma ();
178- }
179- }
180- }
181- // skip end separator
182- code_skipnext ();
183- } else {
184- zero_length = 1 ;
185- }
205+ int32_t * lbound = NULL ;
206+ int32_t * ubound = NULL ;
207+ unsigned dimensions = get_dimensions (& lbound , & ubound );
208+ if (!prog_error ) {
209+ if (!dimensions ) {
210+ v_toarray1 (var_p , 0 );
186211 } else {
187- rt_raise (ERR_SYNTAX );
188- }
189-
190- //
191- // run...
192- //
193- if (!prog_error ) {
194- if (zero_length ) {
195- v_toarray1 (var_p , 0 );
212+ int size = 1 ;
213+ for (int i = 0 ; i < dimensions ; i ++ ) {
214+ size = size * (ABS (ubound [i ] - lbound [i ]) + 1 );
215+ }
216+ if (!preserve ) {
217+ v_new_array (var_p , size );
196218 } else {
197- int i ;
198- int size = 1 ;
199- for (i = 0 ; i < array .v .a .maxdim ; i ++ ) {
200- size = size * (ABS (array .v .a .ubound [i ] - array .v .a .lbound [i ]) + 1 );
201- }
202- if (!preserve ) {
203- v_toarray1 (var_p , size );
219+ if (var_p -> type == V_ARRAY ) {
220+ v_resize_array (var_p , size );
204221 } else {
205- if (var_p -> type == V_ARRAY ) {
206- v_resize_array (var_p , size );
207- } else {
208- v_toarray1 (var_p , size );
209- }
210- }
211-
212- // dim
213- var_p -> v .a .maxdim = array .v .a .maxdim ;
214- for (i = 0 ; i < array .v .a .maxdim ; i ++ ) {
215- var_p -> v .a .lbound [i ] = array .v .a .lbound [i ];
216- var_p -> v .a .ubound [i ] = array .v .a .ubound [i ];
222+ v_new_array (var_p , size );
217223 }
218224 }
219- } else {
220- exitf = 1 ;
225+ // dim
226+ v_maxdim (var_p ) = dimensions ;
227+ for (int i = 0 ; i < dimensions ; i ++ ) {
228+ v_lbound (var_p , i ) = lbound [i ];
229+ v_ubound (var_p , i ) = ubound [i ];
230+ }
221231 }
222232 }
233+ free (lbound );
234+ free (ubound );
223235 } while (!exitf && !prog_error );
224236}
225237
@@ -328,7 +340,7 @@ void cmd_lins() {
328340 if (prog_error ) {
329341 return ;
330342 }
331- idx -= var_p -> v . a . lbound [ 0 ] ;
343+ idx -= v_lbound ( var_p , 0 ) ;
332344
333345 par_getcomma ();
334346 if (prog_error ) {
@@ -412,7 +424,7 @@ void cmd_ldel() {
412424 if (prog_error ) {
413425 return ;
414426 }
415- idx -= var_p -> v . a . lbound [ 0 ] ;
427+ idx -= v_lbound ( var_p , 0 ) ;
416428 if ((idx >= size ) || (idx < 0 )) {
417429 err_out_of_range ();
418430 return ;
@@ -2520,7 +2532,7 @@ void cmd_sort() {
25202532 if (!errf ) {
25212533 if (v_asize (var_p ) > 1 ) {
25222534 static_qsort_last_use_ip = use_ip ;
2523- qsort (var_p -> v . a . data , v_asize (var_p ), sizeof (var_t ), qs_cmp );
2535+ qsort (v_data ( var_p ) , v_asize (var_p ), sizeof (var_t ), qs_cmp );
25242536 }
25252537 }
25262538 // NO RTE anymore... there is no meaning on this because of empty
@@ -2585,12 +2597,12 @@ void cmd_search() {
25852597 }
25862598 // search
25872599 if (!errf ) {
2588- rv_p -> v .i = var_p -> v . a . lbound [ 0 ] - 1 ;
2600+ rv_p -> v .i = v_lbound ( var_p , 0 ) - 1 ;
25892601 for (int i = 0 ; i < v_asize (var_p ); i ++ ) {
25902602 var_t * elem_p = v_elem (var_p , i );
25912603 int bcmp = sb_qcmp (elem_p , & vkey , use_ip );
25922604 if (bcmp == 0 ) {
2593- rv_p -> v .i = i + var_p -> v . a . lbound [ 0 ] ;
2605+ rv_p -> v .i = i + v_lbound ( var_p , 0 ) ;
25942606 break ;
25952607 }
25962608 }
0 commit comments