@@ -75,7 +75,9 @@ int push_vfn_token(estack op, estack out, etoken tok, expr_var_t *vars, int *p_n
7575
7676 for (i = 0 ; i < memory ; i ++ ) {
7777 /* add assignment token */
78- newtok .toktype = (i == 0 ) ? TOK_ASSIGN_USE : TOK_ASSIGN ;
78+ newtok .toktype = TOK_ASSIGN ;
79+ if (i == 0 )
80+ newtok .toktype |= ASSIGN_KEEP_ARG ;
7981 newtok .var .idx = num_var ;
8082#if TRACE_PARSE
8183 printf ("vfn memory: adding assign(vars[%d]) to op stack\n" , num_var );
@@ -215,7 +217,7 @@ int expr_parser_build_stack(mpr_expr expr, const char *str,
215217 goto error ;
216218 }
217219 }
218- switch (tok .toktype ) {
220+ switch (tok .toktype & TOKEN_MASK ) {
219221 case TOK_LITERAL :
220222 /* push to output stack */
221223 estack_push (out , & tok );
@@ -248,6 +250,7 @@ int expr_parser_build_stack(mpr_expr expr, const char *str,
248250#endif
249251 {FAIL_IF (!found_in -> loop_start_pos ,
250252 "local input variable used before lambda token." );}
253+ /* find offset of the value to be copied on the evaluation stack */
251254 i = found_in -> loop_start_pos + 1 ;
252255 while (i < out -> num_tokens ) {
253256 if (out -> tokens [i ].toktype <= TOK_MOVE )
@@ -919,7 +922,7 @@ int expr_parser_build_stack(mpr_expr expr, const char *str,
919922 var_cache -> loop_start_pos = 0 ;
920923
921924 GET_NEXT_TOKEN (tok );
922- if (TOK_ASSIGN == tok .toktype ) {
925+ if (TOK_ASSIGN == ( tok .toktype & TOKEN_MASK ) ) {
923926 /* expression contains accumulator variable initialization */
924927 lambda_allowed = 1 ;
925928 }
@@ -1383,7 +1386,7 @@ int expr_parser_build_stack(mpr_expr expr, const char *str,
13831386 /* move assignment tokens */
13841387 for (; memory > 0 ; memory -- ) {
13851388 etoken tmp = estack_pop (op );
1386- {FAIL_IF (tmp -> toktype != TOK_ASSIGN && tmp -> toktype != TOK_ASSIGN_USE ,
1389+ {FAIL_IF (!( tmp -> toktype & TOK_ASSIGN ) ,
13871390 "VFN missing memory assignment tokens." );}
13881391 /* copy datatype and vector length from vfn token */
13891392 tmp -> gen .datatype = t -> gen .datatype ;
@@ -1431,8 +1434,10 @@ int expr_parser_build_stack(mpr_expr expr, const char *str,
14311434 estack_push (out , & tok );
14321435 reduce_types &= ~(tok .con .flags & REDUCE_TYPE_MASK );
14331436 }
1434- /* special case: if top of stack is tok_assign_use, pop to output */
1435- if (op -> num_tokens && (estack_peek (op , ESTACK_TOP ))-> toktype == TOK_ASSIGN_USE ) {
1437+ /* special case: if top of stack is tok_assign with keep_arg flag, pop to output */
1438+ if (op -> num_tokens
1439+ && (estack_peek (op , ESTACK_TOP ))-> toktype & TOK_ASSIGN
1440+ && (estack_peek (op , ESTACK_TOP ))-> toktype & ASSIGN_KEEP_ARG ) {
14361441 estack_push (out , estack_pop (op ));
14371442 {FAIL_IF (!estack_check_type (out , vars , 1 ), "Malformed expression (16)." );}
14381443 }
@@ -1558,11 +1563,11 @@ int expr_parser_build_stack(mpr_expr expr, const char *str,
15581563 if ((op -> num_tokens == 1 ) && op_top -> toktype < TOK_ASSIGN )
15591564 {FAIL ("Malformed expression (22)" );}
15601565 estack_push (out , estack_pop (op ));
1561- if ( TOK_ASSIGN_USE == ( estack_peek ( out , ESTACK_TOP )) -> toktype
1566+ if ( ASSIGN_KEEP_ARG & op_top -> toktype
15621567 && estack_check_assign_type_and_len (out , vars ) == -1 )
15631568 {FAIL ("Malformed expression (23)" );}
1564- if (!is_const && TOK_ASSIGN_CONST == estack_peek ( out , ESTACK_TOP ) -> toktype )
1565- estack_peek (out , ESTACK_TOP )-> toktype = TOK_ASSIGN ;
1569+ if (!is_const && ASSIGN_CONSTANT & op_top -> toktype )
1570+ estack_peek (out , ESTACK_TOP )-> toktype &= ~ ASSIGN_CONSTANT ;
15661571 }
15671572 /* mark last assignment token to clear eval stack */
15681573 (estack_peek (out , ESTACK_TOP ))-> gen .flags |= CLEAR_STACK ;
@@ -1583,13 +1588,13 @@ int expr_parser_build_stack(mpr_expr expr, const char *str,
15831588 }
15841589 else {
15851590 etoken t = estack_peek (out , ESTACK_TOP - substack_len );
1586- switch (t -> toktype ) {
1591+ switch (t -> toktype & TOKEN_MASK ) {
15871592 case TOK_OP :
15881593 if (t -> op .idx < OP_INCREMENT_PRE || t -> op .idx > OP_DECREMENT_POST )
15891594 {FAIL ("misplaced increment or decrement operator" );}
1595+ break ;
15901596 case TOK_ASSIGN :
15911597 case TOK_ASSIGN_TT :
1592- case TOK_ASSIGN_CONST :
15931598 out_top -> gen .flags |= (TYPE_LOCKED | CLEAR_STACK );
15941599 break ;
15951600 default :
@@ -1721,6 +1726,8 @@ int expr_parser_build_stack(mpr_expr expr, const char *str,
17211726 }
17221727 else {
17231728 /* we are retrieving signal instance index */
1729+ /* evaluator will keep track of local instance being processed, so we don't
1730+ * need to know which variable is being addressed */
17241731 GET_NEXT_TOKEN (tok );
17251732 {FAIL_IF (tok .toktype != TOK_VAR , "Misplaced instance index query." );}
17261733 tok .toktype = TOK_VAR_INST_IDX ;
@@ -1739,8 +1746,7 @@ int expr_parser_build_stack(mpr_expr expr, const char *str,
17391746
17401747 allow_toktype = OBJECT_TOKENS & ~TOK_NEGATE ;
17411748 break ;
1742- case TOK_ASSIGN :
1743- case TOK_ASSIGN_OP : {
1749+ case TOK_ASSIGN : {
17441750 etoken out_top = estack_peek (out , ESTACK_TOP );
17451751 /* assignment to variable */
17461752 {FAIL_IF (!assigning , "Misplaced assignment operator." );}
@@ -1769,12 +1775,13 @@ int expr_parser_build_stack(mpr_expr expr, const char *str,
17691775 vars [var ].flags |= VAR_ASSIGNED ;
17701776 i = estack_get_substack_len (out , ESTACK_TOP );
17711777 /* nothing extraordinary, continue as normal */
1772- if (TOK_ASSIGN_OP == tok .toktype ) {
1773- out_top -> toktype = TOK_ASSIGN_OP ;
1778+ out_top -> toktype = TOK_ASSIGN ;
1779+ if (ASSIGN_COMPOUND & tok .toktype ) {
1780+ out_top -> toktype |= ASSIGN_COMPOUND ;
17741781 out_top -> var .op_idx = tok .var .op_idx ;
17751782 }
1776- else {
1777- out_top -> toktype = is_const ? TOK_ASSIGN_CONST : TOK_ASSIGN ;
1783+ if ( is_const ) {
1784+ out_top -> toktype |= ASSIGN_CONSTANT ;
17781785 }
17791786 out_top -> var .offset = 0 ;
17801787 while (i > 0 ) {
@@ -1791,13 +1798,11 @@ int expr_parser_build_stack(mpr_expr expr, const char *str,
17911798 {FAIL_IF (out_top -> var .idx == VAR_Y && !(out_top -> gen .flags & VAR_HIST_IDX ),
17921799 "Only past samples of output timetag are writable." );}
17931800 i = estack_get_substack_len (out , ESTACK_TOP );
1794- if (TOK_ASSIGN_OP == tok .toktype ) {
1795- out_top -> toktype = TOK_ASSIGN_TT_OP ;
1801+ out_top -> toktype = TOK_ASSIGN_TT ;
1802+ if (ASSIGN_COMPOUND & tok .toktype ) {
1803+ out_top -> toktype |= ASSIGN_COMPOUND ;
17961804 out_top -> var .op_idx = tok .var .op_idx ;
17971805 }
1798- else {
1799- out_top -> toktype = TOK_ASSIGN_TT ;
1800- }
18011806 out_top -> gen .datatype = MPR_DBL ;
18021807 while (i > 0 ) {
18031808 estack_push (op , estack_pop (out ));
@@ -1807,8 +1812,9 @@ int expr_parser_build_stack(mpr_expr expr, const char *str,
18071812 else if (out_top -> toktype == TOK_VECTORIZE ) {
18081813 int var , j , arity = out_top -> fn .arity ;
18091814
1810- /* out token is vectorizer */
1815+ /* remove vectorizer token from output */
18111816 estack_pop (out );
1817+
18121818 out_top = estack_peek (out , ESTACK_TOP );
18131819 {FAIL_IF (out_top -> toktype != TOK_VAR , "Bad token left of assignment. (1)" );}
18141820 var = out_top -> var .idx ;
@@ -1828,12 +1834,13 @@ int expr_parser_build_stack(mpr_expr expr, const char *str,
18281834 else if (out_top -> var .idx != var )
18291835 {FAIL ("Cannot mix variables in vector assignment." );}
18301836 j = estack_get_substack_len (out , ESTACK_TOP );
1831- if (TOK_ASSIGN_OP == tok .toktype ) {
1832- out_top -> toktype = TOK_ASSIGN_OP ;
1837+ out_top -> toktype = TOK_ASSIGN ;
1838+ if (ASSIGN_COMPOUND & tok .toktype ) {
1839+ out_top -> toktype |= ASSIGN_COMPOUND ;
18331840 out_top -> var .op_idx = tok .var .op_idx ;
18341841 }
1835- else {
1836- out_top -> toktype = is_const ? TOK_ASSIGN_CONST : TOK_ASSIGN ;
1842+ if ( is_const ) {
1843+ out_top -> toktype |= ASSIGN_CONSTANT ;
18371844 }
18381845 while (j -- > 0 )
18391846 estack_push (op , estack_pop (out ));
@@ -1883,7 +1890,7 @@ int expr_parser_build_stack(mpr_expr expr, const char *str,
18831890#endif
18841891 for (i = 0 ; i < out -> num_tokens ; i ++ ) {
18851892 etoken t = estack_peek (out , i );
1886- if (TOK_ASSIGN_OP == t -> toktype || TOK_ASSIGN_TT_OP == t -> toktype ) {
1893+ if (( TOK_ASSIGN & t -> toktype ) && ( ASSIGN_COMPOUND & t -> toktype ) ) {
18871894 /* include variable indexes/indexing subexpressions but not the value to be assigned */
18881895 int j , assign_len = 1 , arg_substack_len , var_substack_len = estack_get_substack_len (out , i ) - 1 ;
18891896 etoken_t newtok ;
@@ -1924,10 +1931,7 @@ int expr_parser_build_stack(mpr_expr expr, const char *str,
19241931 etoken a = estack_peek (out , j );
19251932 if (!(TOK_ASSIGN & a -> toktype ))
19261933 break ;
1927- if (TOK_ASSIGN_OP == a -> toktype )
1928- a -> toktype = TOK_ASSIGN ;
1929- else if (TOK_ASSIGN_TT_OP == a -> toktype )
1930- a -> toktype = TOK_ASSIGN_TT ;
1934+ a -> toktype &= ~ASSIGN_COMPOUND ;
19311935 -- j ;
19321936 }
19331937
@@ -1943,10 +1947,11 @@ int expr_parser_build_stack(mpr_expr expr, const char *str,
19431947 /* we have inserted a token but i still points to the old assignment token position */
19441948 for (j = 0 ; j < var_substack_len ; j ++ ) {
19451949 etoken a = estack_peek (out , i - arg_substack_len - j );
1946- if (TOK_ASSIGN == a -> toktype )
1947- a -> toktype = TOK_VAR ;
1948- else if (TOK_ASSIGN_TT == a -> toktype )
1949- a -> toktype = TOK_TT ;
1950+ switch (a -> toktype & TOKEN_MASK ) {
1951+ case TOK_ASSIGN : a -> toktype = TOK_VAR ; break ;
1952+ case TOK_ASSIGN_TT : a -> toktype = TOK_TT ; break ;
1953+ default : break ;
1954+ }
19501955 }
19511956
19521957 /* 6) if there are more than 1 assignment tokens we also need a TOK_VECTORIZE */
@@ -2027,10 +2032,12 @@ int expr_parser_build_stack(mpr_expr expr, const char *str,
20272032 newtok .gen .vec_len = 1 ;
20282033 estack_insert (out , ++ i , 1 , & newtok );
20292034
2030- /* add var substack and convert to assign_use */
2035+ /* add var substack and convert to assign with keep_arg flag */
20312036 t = estack_insert (out , ++ i , substack_len , estack_peek (out , var_idx - substack_len + 1 ));
20322037 {FAIL_IF (t -> toktype != TOK_VAR , "error!" );}
2033- t -> toktype = pre ? TOK_ASSIGN_USE : TOK_ASSIGN ;
2038+ t -> toktype = TOK_ASSIGN ;
2039+ if (pre )
2040+ t -> toktype |= ASSIGN_KEEP_ARG ;
20342041 t -> gen .flags |= flags ;
20352042 if (t -> var .idx < VAR_Y ) {
20362043 vars [t -> var .idx ].flags |= VAR_ASSIGNED ;
@@ -2048,13 +2055,22 @@ int expr_parser_build_stack(mpr_expr expr, const char *str,
20482055 /* run checks on VAR_NOW and VAR_NEXT */
20492056 for (i = 0 ; i < out -> num_tokens ; i ++ ) {
20502057 etoken t = estack_peek (out , i );
2051- {FAIL_IF ( (TOK_VAR == t -> toktype || TOK_ASSIGN == t -> toktype )
2052- && (VAR_NOW == t -> var .idx || VAR_NEXT == t -> var .idx ),
2053- "Illegal variable index." );}
2054- {FAIL_IF (TOK_TT == t -> toktype && VAR_NOW == t -> var .idx && NUM_VAR_IDXS (t -> gen .flags ),
2055- "'now' timestamp does not accept indices." );}
2056- {FAIL_IF (TOK_ASSIGN_TT == t -> toktype && VAR_NOW == t -> var .idx ,
2057- "Cannot assign to 'now' timestamp." );}
2058+ switch (t -> toktype & TOKEN_MASK ) {
2059+ case TOK_VAR :
2060+ case TOK_ASSIGN :
2061+ {FAIL_IF (VAR_NOW == t -> var .idx || VAR_NEXT == t -> var .idx , "Illegal variable index." );}
2062+ break ;
2063+ case TOK_TT :
2064+ {FAIL_IF (VAR_NOW == t -> var .idx && NUM_VAR_IDXS (t -> gen .flags ),
2065+ "'now' timestamp does not accept indices." );}
2066+ break ;
2067+ case TOK_ASSIGN_TT :
2068+ {FAIL_IF (VAR_NOW == t -> var .idx , "Cannot assign to 'now' timestamp." );}
2069+ break ;
2070+ default :
2071+ break ;
2072+
2073+ }
20582074 }
20592075
20602076 /* check that all used-defined variables were assigned */
0 commit comments