@@ -1571,19 +1571,27 @@ void cmd_for_in(bcip_t true_ip, bcip_t false_ip, var_p_t var_p) {
15711571 v_detach (new_var );
15721572 return ;
15731573 }
1574- if (new_var -> type != V_ARRAY ) {
1574+
1575+ switch (new_var -> type ) {
1576+ case V_MAP :
1577+ case V_ARRAY :
1578+ break ;
1579+
1580+ default :
15751581 v_free (new_var );
15761582 v_detach (new_var );
15771583 err_typemismatch ();
15781584 return ;
15791585 }
15801586
1581- node .x .vfor .flags = 1 ; // allocated here
1587+ // allocated here
1588+ node .x .vfor .flags = 1 ;
15821589 node .x .vfor .arr_ptr = array_p = new_var ;
15831590 }
15841591
15851592 if (!prog_error ) {
1586- node .x .vfor .step_expr_ip = 0 ; // element-index
1593+ // element-index
1594+ node .x .vfor .step_expr_ip = 0 ;
15871595
15881596 var_p_t var_elem_ptr = 0 ;
15891597 switch (array_p -> type ) {
@@ -1789,6 +1797,107 @@ void cmd_until() {
17891797 v_free (& var );
17901798}
17911799
1800+ //
1801+ // FOR [EACH] v1 IN v2
1802+ //
1803+ void cmd_next_for_in (stknode_t * node , bcip_t next_ip ) {
1804+ var_t * array_p = node -> x .vfor .arr_ptr ;
1805+ var_t * var_elem_ptr = NULL ;
1806+
1807+ bcip_t jump_ip = node -> x .vfor .jump_ip ;
1808+ var_t * var_p = node -> x .vfor .var_ptr ;
1809+
1810+ switch (array_p -> type ) {
1811+ case V_MAP :
1812+ var_elem_ptr = map_elem_key (array_p , ++ node -> x .vfor .step_expr_ip );
1813+ break ;
1814+
1815+ case V_ARRAY :
1816+ if (v_asize (array_p ) > (int ) ++ node -> x .vfor .step_expr_ip ) {
1817+ var_elem_ptr = v_elem (array_p , node -> x .vfor .step_expr_ip );
1818+ }
1819+ break ;
1820+
1821+ default :
1822+ break ;
1823+ }
1824+
1825+ if (var_elem_ptr ) {
1826+ v_set (var_p , var_elem_ptr );
1827+ stknode_t * stknode = code_push (kwFOR );
1828+ stknode -> x .vfor = node -> x .vfor ;
1829+ code_jump (jump_ip );
1830+ } else {
1831+ // end of iteration
1832+ if (node -> x .vfor .flags & 1 ) {
1833+ // allocated in for
1834+ v_free (node -> x .vfor .arr_ptr );
1835+ v_detach (node -> x .vfor .arr_ptr );
1836+ }
1837+ code_jump (next_ip );
1838+ }
1839+ }
1840+
1841+ //
1842+ // FOR v=exp1 TO exp2 [STEP exp3]
1843+ //
1844+ void cmd_next_for_to (stknode_t * node , bcip_t next_ip ) {
1845+ int check = 0 ;
1846+ var_t var_to ;
1847+
1848+ bcip_t jump_ip = node -> x .vfor .jump_ip ;
1849+ var_t * var_p = node -> x .vfor .var_ptr ;
1850+
1851+ prog_ip = node -> x .vfor .to_expr_ip ;
1852+ v_init (& var_to );
1853+ eval (& var_to );
1854+
1855+ if (!prog_error && (var_to .type == V_INT || var_to .type == V_NUM )) {
1856+ // get step val
1857+ var_t var_step ;
1858+ var_step .const_flag = 0 ;
1859+ var_step .type = V_INT ;
1860+ var_step .v .i = 1 ;
1861+
1862+ if (node -> x .vfor .step_expr_ip != INVALID_ADDR ) {
1863+ prog_ip = node -> x .vfor .step_expr_ip ;
1864+ eval (& var_step );
1865+ }
1866+
1867+ if (!prog_error && (var_step .type == V_INT || var_step .type == V_NUM )) {
1868+ v_inc (var_p , & var_step );
1869+ if (v_sign (& var_step ) < 0 ) {
1870+ check = (v_compare (var_p , & var_to ) >= 0 );
1871+ } else {
1872+ check = (v_compare (var_p , & var_to ) <= 0 );
1873+ }
1874+ } else {
1875+ if (!prog_error ) {
1876+ err_typemismatch ();
1877+ }
1878+ }
1879+ v_free (& var_step );
1880+ } else {
1881+ if (!prog_error ) {
1882+ rt_raise ("FOR-TO: TO v IS NOT A NUMBER" );
1883+ }
1884+ }
1885+
1886+ //
1887+ // run
1888+ //
1889+ if (!prog_error ) {
1890+ if (check ) {
1891+ stknode_t * stknode = code_push (kwFOR );
1892+ stknode -> x .vfor = node -> x .vfor ;
1893+ code_jump (jump_ip );
1894+ } else {
1895+ code_jump (next_ip );
1896+ }
1897+ }
1898+ v_free (& var_to );
1899+ }
1900+
17921901/**
17931902 * NEXT
17941903 */
@@ -1813,108 +1922,11 @@ void cmd_next() {
18131922 return ;
18141923 }
18151924
1816- bcip_t jump_ip = node .x .vfor .jump_ip ;
1817- var_t * var_p = node .x .vfor .var_ptr ;
18181925
18191926 if (node .x .vfor .subtype == kwTO ) {
1820- //
1821- // FOR v=exp1 TO exp2 [STEP exp3]
1822- //
1823- int check = 0 ;
1824- var_t var_to ;
1825-
1826- prog_ip = node .x .vfor .to_expr_ip ;
1827- v_init (& var_to );
1828- eval (& var_to );
1829-
1830- if (!prog_error && (var_to .type == V_INT || var_to .type == V_NUM )) {
1831- // get step val
1832- var_t var_step ;
1833- var_step .const_flag = 0 ;
1834- var_step .type = V_INT ;
1835- var_step .v .i = 1 ;
1836-
1837- if (node .x .vfor .step_expr_ip != INVALID_ADDR ) {
1838- prog_ip = node .x .vfor .step_expr_ip ;
1839- eval (& var_step );
1840- }
1841-
1842- if (!prog_error && (var_step .type == V_INT || var_step .type == V_NUM )) {
1843- v_inc (var_p , & var_step );
1844- if (v_sign (& var_step ) < 0 ) {
1845- check = (v_compare (var_p , & var_to ) >= 0 );
1846- } else {
1847- check = (v_compare (var_p , & var_to ) <= 0 );
1848- }
1849- } else {
1850- if (!prog_error ) {
1851- err_typemismatch ();
1852- }
1853- }
1854- v_free (& var_step );
1855- } else {
1856- if (!prog_error ) {
1857- rt_raise ("FOR-TO: TO v IS NOT A NUMBER" );
1858- }
1859- }
1860-
1861- //
1862- // RUN
1863- //
1864- if (!prog_error ) {
1865- if (check ) {
1866- stknode_t * stknode = code_push (kwFOR );
1867- stknode -> x .vfor = node .x .vfor ;
1868- code_jump (jump_ip );
1869- } else {
1870- code_jump (next_ip );
1871- }
1872- }
1873- v_free (& var_to );
1927+ cmd_next_for_to (& node , next_ip );
18741928 } else {
1875- //
1876- // FOR [EACH] v1 IN v2
1877- //
1878- var_t * array_p = node .x .vfor .arr_ptr ;
1879- var_t * var_elem_ptr = 0 ;
1880-
1881- switch (array_p -> type ) {
1882- case V_MAP :
1883- node .x .vfor .step_expr_ip ++ ; // element-index
1884- var_elem_ptr = map_elem_key (array_p , node .x .vfor .step_expr_ip );
1885- break ;
1886-
1887- case V_ARRAY :
1888- node .x .vfor .step_expr_ip ++ ; // element-index
1889-
1890- if (v_asize (array_p ) > (int ) node .x .vfor .step_expr_ip ) {
1891- var_elem_ptr = v_elem (array_p , node .x .vfor .step_expr_ip );
1892- } else {
1893- if (node .x .vfor .flags & 1 ) {
1894- // allocated in for
1895- v_free (node .x .vfor .arr_ptr );
1896- v_detach (node .x .vfor .arr_ptr );
1897- }
1898- }
1899- break ;
1900-
1901- default :
1902- if (node .x .vfor .flags & 1 ) {
1903- // allocated in for
1904- v_free (node .x .vfor .arr_ptr );
1905- v_detach (node .x .vfor .arr_ptr );
1906- }
1907- break ;
1908- }
1909-
1910- if (var_elem_ptr ) {
1911- v_set (var_p , var_elem_ptr );
1912- stknode_t * stknode = code_push (kwFOR );
1913- stknode -> x .vfor = node .x .vfor ;
1914- code_jump (jump_ip );
1915- } else {
1916- code_jump (next_ip );
1917- }
1929+ cmd_next_for_in (& node , next_ip );
19181930 }
19191931}
19201932
0 commit comments