@@ -121,6 +121,62 @@ void cmd_packed_let() {
121121 }
122122}
123123
124+ uint8_t get_dimensions (int32_t * * lbound , int32_t * * ubound ) {
125+ uint8_t 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,52 @@ 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+ break ;
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- }
186- } else {
187- rt_raise (ERR_SYNTAX );
205+ int32_t * lbound = NULL ;
206+ int32_t * ubound = NULL ;
207+ uint8_t dimensions = get_dimensions (& lbound , & ubound );
208+ if (!prog_error ) {
209+ if (!preserve || var_p -> type != V_ARRAY ) {
210+ v_free (var_p );
188211 }
189-
190- //
191- // run...
192- //
193- if (!prog_error ) {
194- if (zero_length ) {
195- v_toarray1 (var_p , 0 );
196- } 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 );
204- } 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 ];
217- }
218- }
212+ if (!dimensions ) {
213+ v_toarray1 (var_p , 0 );
214+ continue ;
215+ }
216+ uint32_t size = 1 ;
217+ for (int i = 0 ; i < dimensions ; i ++ ) {
218+ size = size * (ABS (ubound [i ] - lbound [i ]) + 1 );
219+ }
220+ if (!preserve || var_p -> type != V_ARRAY ) {
221+ v_new_array (var_p , size );
222+ } else if (v_maxdim (var_p ) != dimensions ) {
223+ err_matdim ();
219224 } else {
220- exitf = 1 ;
225+ // preserve previous array contents
226+ v_resize_array (var_p , size );
227+ }
228+ v_maxdim (var_p ) = dimensions ;
229+ for (int i = 0 ; i < dimensions ; i ++ ) {
230+ v_lbound (var_p , i ) = lbound [i ];
231+ v_ubound (var_p , i ) = ubound [i ];
221232 }
222233 }
234+ free (lbound );
235+ free (ubound );
223236 } while (!exitf && !prog_error );
224237}
225238
@@ -328,7 +341,7 @@ void cmd_lins() {
328341 if (prog_error ) {
329342 return ;
330343 }
331- idx -= var_p -> v . a . lbound [ 0 ] ;
344+ idx -= v_lbound ( var_p , 0 ) ;
332345
333346 par_getcomma ();
334347 if (prog_error ) {
@@ -412,7 +425,7 @@ void cmd_ldel() {
412425 if (prog_error ) {
413426 return ;
414427 }
415- idx -= var_p -> v . a . lbound [ 0 ] ;
428+ idx -= v_lbound ( var_p , 0 ) ;
416429 if ((idx >= size ) || (idx < 0 )) {
417430 err_out_of_range ();
418431 return ;
@@ -513,7 +526,7 @@ void cmd_print(int output) {
513526 byte last_op = 0 ;
514527 byte exitf = 0 ;
515528 byte use_format = 0 ;
516- int handle = 0 ;
529+ intptr_t handle = 0 ;
517530 var_t var ;
518531
519532 // prefix - # (file)
@@ -654,7 +667,7 @@ void cmd_input(int input) {
654667 byte print_crlf = 1 ;
655668 var_t prompt ;
656669 var_t * vuser_p = NULL ;
657- int handle = 0 ;
670+ intptr_t handle = 0 ;
658671 char * inps = NULL ;
659672
660673 v_init (& prompt );
@@ -2520,7 +2533,7 @@ void cmd_sort() {
25202533 if (!errf ) {
25212534 if (v_asize (var_p ) > 1 ) {
25222535 static_qsort_last_use_ip = use_ip ;
2523- qsort (var_p -> v . a . data , v_asize (var_p ), sizeof (var_t ), qs_cmp );
2536+ qsort (v_data ( var_p ) , v_asize (var_p ), sizeof (var_t ), qs_cmp );
25242537 }
25252538 }
25262539 // NO RTE anymore... there is no meaning on this because of empty
@@ -2585,12 +2598,12 @@ void cmd_search() {
25852598 }
25862599 // search
25872600 if (!errf ) {
2588- rv_p -> v .i = var_p -> v . a . lbound [ 0 ] - 1 ;
2601+ rv_p -> v .i = v_lbound ( var_p , 0 ) - 1 ;
25892602 for (int i = 0 ; i < v_asize (var_p ); i ++ ) {
25902603 var_t * elem_p = v_elem (var_p , i );
25912604 int bcmp = sb_qcmp (elem_p , & vkey , use_ip );
25922605 if (bcmp == 0 ) {
2593- rv_p -> v .i = i + var_p -> v . a . lbound [ 0 ] ;
2606+ rv_p -> v .i = i + v_lbound ( var_p , 0 ) ;
25942607 break ;
25952608 }
25962609 }
0 commit comments