@@ -413,12 +413,29 @@ const char* basic_get_string_variable(const char* var, struct basic_ctx* ctx)
413413 }
414414 list [0 ] = ctx -> str_variables ;
415415 size_t len = strlen (var );
416+
416417 for (j = ctx -> call_stack_ptr ; j >= 0 ; -- j ) {
417418 struct ub_var_string * cur = list [j ];
418- for (; cur ; cur = cur -> next ) {
419+ struct ub_var_string * prev = NULL ;
420+ while (cur ) {
419421 if (len == cur -> name_length && !strcmp (var , cur -> varname )) {
422+ /* move-to-front optimisation */
423+ if (prev ) {
424+ /* unlink */
425+ prev -> next = cur -> next ;
426+ /* relink at head */
427+ if (j == 0 ) {
428+ cur -> next = ctx -> str_variables ;
429+ ctx -> str_variables = cur ;
430+ } else {
431+ cur -> next = ctx -> local_string_variables [j ];
432+ ctx -> local_string_variables [j ] = cur ;
433+ }
434+ }
420435 return cur -> value ;
421436 }
437+ prev = cur ;
438+ cur = cur -> next ;
422439 }
423440 }
424441
@@ -492,7 +509,7 @@ int64_t basic_get_int_variable(const char* var, struct basic_ctx* ctx)
492509 if (basic_builtin_int_fn (var , ctx , & retv )) {
493510 return retv ;
494511 }
495-
512+
496513 if (varname_is_function (var )) {
497514 return basic_eval_int_fn (var , ctx );
498515 }
@@ -507,18 +524,36 @@ int64_t basic_get_int_variable(const char* var, struct basic_ctx* ctx)
507524 list [j ] = ctx -> local_int_variables [j ];
508525 }
509526 list [0 ] = ctx -> int_variables ;
527+
510528 size_t len = strlen (var );
511529 for (j = ctx -> call_stack_ptr ; j >= 0 ; -- j ) {
512530 struct ub_var_int * cur = list [j ];
513- for (; cur ; cur = cur -> next ) {
531+ struct ub_var_int * prev = NULL ;
532+ while (cur ) {
514533 if (len == cur -> name_length && !strcmp (var , cur -> varname )) {
515- int64_t v = cur -> value ;
516534 /* If ERROR is read, it resets its value */
535+ int64_t v = cur -> value ;
517536 if (len == 5 && !strcmp (var , "ERROR" )) {
518537 basic_set_int_variable ("ERROR" , 0 , ctx , false, false);
519538 }
539+
540+ /* move-to-front optimisation */
541+ if (prev ) {
542+ /* unlink */
543+ prev -> next = cur -> next ;
544+ /* relink at head */
545+ if (j == 0 ) {
546+ cur -> next = ctx -> int_variables ;
547+ ctx -> int_variables = cur ;
548+ } else {
549+ cur -> next = ctx -> local_int_variables [j ];
550+ ctx -> local_int_variables [j ] = cur ;
551+ }
552+ }
520553 return v ;
521554 }
555+ prev = cur ;
556+ cur = cur -> next ;
522557 }
523558 }
524559
@@ -531,7 +566,7 @@ bool basic_get_double_variable(const char* var, struct basic_ctx* ctx, double* r
531566 if (basic_builtin_double_fn (var , ctx , res )) {
532567 return true;
533568 }
534-
569+
535570 if (varname_is_double_function (var )) {
536571 basic_eval_double_fn (var , ctx , res );
537572 return true;
@@ -541,25 +576,40 @@ bool basic_get_double_variable(const char* var, struct basic_ctx* ctx, double* r
541576 return basic_get_double_array_variable (var , arr_variable_index (ctx ), ctx , res );
542577 }
543578
544-
545579 struct ub_var_double * list [ctx -> call_stack_ptr + 1 ];
546580 int64_t j ;
547581 for (j = ctx -> call_stack_ptr ; j > 0 ; -- j ) {
548582 list [j ] = ctx -> local_double_variables [j ];
549583 }
550584 list [0 ] = ctx -> double_variables ;
585+
551586 size_t len = strlen (var );
552587 for (j = ctx -> call_stack_ptr ; j >= 0 ; -- j ) {
553588 struct ub_var_double * cur = list [j ];
554- for (; cur ; cur = cur -> next ) {
589+ struct ub_var_double * prev = NULL ;
590+ while (cur ) {
555591 if (len == cur -> name_length && !strcmp (var , cur -> varname )) {
556592 * res = cur -> value ;
593+ /* move-to-front optimisation */
594+ if (prev ) {
595+ /* unlink */
596+ prev -> next = cur -> next ;
597+ /* relink at head */
598+ if (j == 0 ) {
599+ cur -> next = ctx -> double_variables ;
600+ ctx -> double_variables = cur ;
601+ } else {
602+ cur -> next = ctx -> local_double_variables [j ];
603+ ctx -> local_double_variables [j ] = cur ;
604+ }
605+ }
557606 return true;
558607 }
608+ prev = cur ;
609+ cur = cur -> next ;
559610 }
560611 }
561612
562-
563613 if (var [len - 1 ] == '#' ) {
564614 tokenizer_error_printf (ctx , "No such real variable '%s'" , var );
565615 }
0 commit comments