@@ -43,6 +43,8 @@ int v_isempty(var_t *var) {
4343 return (var -> v .n == 0.0 );
4444 case V_ARRAY :
4545 return (var -> v .a .size == 0 );
46+ case V_REF :
47+ return v_isempty (var -> v .ref );
4648 }
4749
4850 return 1 ;
@@ -70,6 +72,8 @@ int v_length(var_t *var) {
7072 return strlen (tmpsb );
7173 case V_ARRAY :
7274 return var -> v .a .size ;
75+ case V_REF :
76+ return v_length (var -> v .ref );
7377 }
7478
7579 return 1 ;
@@ -257,6 +261,8 @@ int v_is_nonzero(var_t *v) {
257261 return (v -> v .ap .p != 0 );
258262 case V_ARRAY :
259263 return (v -> v .a .size != 0 );
264+ case V_REF :
265+ return v_is_nonzero (v -> v .ref );
260266 };
261267 return 0 ;
262268}
@@ -349,6 +355,11 @@ int v_compare(var_t *a, var_t *b) {
349355 return hash_compare (a , b );
350356 }
351357
358+ if (a -> type == V_REF || b -> type == V_REF ) {
359+ return v_compare (a -> type == V_REF ? a -> v .ref : a ,
360+ b -> type == V_REF ? b -> v .ref : b );
361+ }
362+
352363 err_evtype ();
353364 return 1 ;
354365}
@@ -407,11 +418,11 @@ void v_add(var_t *result, var_t *a, var_t *b) {
407418 } else if ((a -> type == V_INT || a -> type == V_NUM ) && b -> type == V_STR ) {
408419 if (is_number ((char * ) b -> v .p .ptr )) {
409420 result -> type = V_NUM ;
410- if (a -> type == V_INT
411- )
421+ if (a -> type == V_INT ) {
412422 result -> v .n = a -> v .i + v_getval (b );
413- else
423+ } else {
414424 result -> v .n = a -> v .n + v_getval (b );
425+ }
415426 } else {
416427 result -> type = V_STR ;
417428 result -> v .p .ptr = (byte * ) tmp_alloc (strlen ((char * )b -> v .p .ptr ) + 64 );
@@ -424,6 +435,9 @@ void v_add(var_t *result, var_t *a, var_t *b) {
424435 strcat ((char * ) result -> v .p .ptr , (char * ) b -> v .p .ptr );
425436 result -> v .p .size = strlen ((char * ) result -> v .p .ptr ) + 1 ;
426437 }
438+ } else if (a -> type == V_REF || b -> type == V_REF ) {
439+ v_add (result , a -> type == V_REF ? a -> v .ref : a ,
440+ b -> type == V_REF ? b -> v .ref : b );
427441 }
428442}
429443
@@ -556,6 +570,10 @@ void v_tostr(var_t *arg) {
556570 case V_NUM :
557571 ftostr (arg -> v .n , tmp );
558572 break ;
573+ case V_REF :
574+ v_tostr (arg -> v .ref );
575+ tmp_free (tmp );
576+ return ;
559577 default :
560578 err_varisarray ();
561579 tmp_free (tmp );
@@ -753,3 +771,39 @@ void v_eval_str(var_p_t v) {
753771 prog_ip += len ;
754772}
755773
774+ /*
775+ * evaluate variable reference assignment
776+ */
777+ void v_eval_ref (var_t * v_left ) {
778+ var_t * v_right = NULL ;
779+ // can only reference regular non-dynamic variable
780+ if (code_peek () == kwTYPE_VAR ) {
781+ code_skipnext ();
782+ v_right = tvar [code_getaddr ()];
783+ switch (v_right -> type ) {
784+ case V_REF :
785+ // multiple levels not supported
786+ v_right = NULL ;
787+ break ;
788+ case V_ARRAY :
789+ case V_HASH :
790+ switch (code_peek ()) {
791+ case kwTYPE_LEVEL_BEGIN :
792+ case kwTYPE_UDS_EL :
793+ // base variable only supported
794+ v_right = NULL ;
795+ break ;
796+ }
797+ break ;
798+ default :
799+ break ;
800+ }
801+ }
802+ if (v_right == NULL ) {
803+ rt_raise ("Invalid variable reference" );
804+ } else {
805+ v_free (v_left );
806+ v_left -> type = V_REF ;
807+ v_left -> v .ref = v_right ;
808+ }
809+ }
0 commit comments