@@ -668,6 +668,7 @@ x*/ static REBINT Do_Args_Light(REBVAL *func, REBVAL *path, REBSER *block, REBCN
668
668
REBINT dsf = dsp - DSF_BIAS ;
669
669
REBVAL * tos ;
670
670
REBVAL * func ;
671
+ REBOOL useArgs = TRUE; // can be used by get-word function refinements to ignore values
671
672
672
673
if ((dsp + 100 ) > (REBINT )SERIES_REST (DS_Series )) {
673
674
Expand_Stack (STACK_MIN );
@@ -716,7 +717,7 @@ x*/ static REBINT Do_Args_Light(REBVAL *func, REBVAL *path, REBSER *block, REBCN
716
717
index = Do_Next (block , index , IS_OP (func ));
717
718
// THROWN is handled after the switch.
718
719
if (index == END_FLAG ) Trap2 (RE_NO_ARG , Func_Word (dsf ), args );
719
- DS_Base [ds ] = * DS_POP ;
720
+ if ( useArgs ) DS_Base [ds ] = * DS_POP ; else DS_DROP ;
720
721
break ;
721
722
722
723
case REB_LIT_WORD : // 'WORD - Just get next value
@@ -725,34 +726,30 @@ x*/ static REBINT Do_Args_Light(REBVAL *func, REBVAL *path, REBSER *block, REBCN
725
726
if (IS_PAREN (value ) || IS_GET_WORD (value ) || IS_GET_PATH (value )) {
726
727
index = Do_Next (block , index , IS_OP (func ));
727
728
// THROWN is handled after the switch.
728
- DS_Base [ds ] = * DS_POP ;
729
+ if ( useArgs ) DS_Base [ds ] = * DS_POP ; else DS_DROP ;
729
730
}
730
731
else {
731
732
index ++ ;
732
- DS_Base [ds ] = * value ;
733
+ if ( useArgs ) DS_Base [ds ] = * value ;
733
734
}
734
735
} else
735
736
SET_UNSET (& DS_Base [ds ]); // allowed to be none
736
737
break ;
737
738
738
739
case REB_GET_WORD : // :WORD - Get value
739
740
if (index < BLK_LEN (block )) {
740
- DS_Base [ds ] = * BLK_SKIP (block , index );
741
+ if ( useArgs ) DS_Base [ds ] = * BLK_SKIP (block , index );
741
742
index ++ ;
742
743
} else
743
744
SET_UNSET (& DS_Base [ds ]); // allowed to be none
744
745
break ;
745
- /*
746
- value = BLK_SKIP(block, index);
747
- index++;
748
- if (IS_WORD(value) && VAL_WORD_FRAME(value)) value = Get_Var(value);
749
- DS_Base[ds] = *value;
750
- */
746
+
751
747
case REB_REFINEMENT : // /WORD - Function refinement
752
748
if (!path || IS_END (path )) return index ;
753
749
if (IS_WORD (path )) {
754
750
// Optimize, if the refinement is the next arg:
755
751
if (SAME_SYM (path , args )) {
752
+ useArgs = TRUE;
756
753
SET_TRUE (DS_VALUE (ds )); // set refinement stack value true
757
754
path ++ ; // remove processed refinement
758
755
continue ;
@@ -763,6 +760,7 @@ x*/ static REBINT Do_Args_Light(REBVAL *func, REBVAL *path, REBSER *block, REBCN
763
760
args = BLK_SKIP (words , 1 );
764
761
for (; NOT_END (args ); args ++ , ds ++ ) {
765
762
if (IS_REFINEMENT (args ) && VAL_WORD_CANON (args ) == VAL_WORD_CANON (path )) {
763
+ useArgs = TRUE;
766
764
SET_TRUE (DS_VALUE (ds )); // set refinement stack value true
767
765
path ++ ; // remove processed refinement
768
766
break ;
@@ -772,6 +770,34 @@ x*/ static REBINT Do_Args_Light(REBVAL *func, REBVAL *path, REBSER *block, REBCN
772
770
if (IS_END (args )) Trap2 (RE_NO_REFINE , Func_Word (dsf ), path );
773
771
continue ;
774
772
}
773
+ else if (IS_GET_WORD (path )) {
774
+ // This branch is almost same like the above one, but better to have it
775
+ // separated not to slow down regular refinements.
776
+ // Optimize, if the refinement is the next arg:
777
+ if (SAME_SYM (path , args )) {
778
+ value = Get_Var (path );
779
+ useArgs = IS_TRUE (value );
780
+ SET_LOGIC (DS_VALUE (ds ), useArgs );
781
+ path ++ ; // remove processed refinement
782
+ continue ;
783
+ }
784
+ // Refinement out of sequence, resequence arg order:
785
+ more_get_path :
786
+ ds = dsp ;
787
+ args = BLK_SKIP (words , 1 );
788
+ for (; NOT_END (args ); args ++ , ds ++ ) {
789
+ if (IS_REFINEMENT (args ) && VAL_WORD_CANON (args ) == VAL_WORD_CANON (path )) {
790
+ value = Get_Var (path );
791
+ useArgs = IS_TRUE (value );
792
+ SET_LOGIC (DS_VALUE (ds ), useArgs );
793
+ path ++ ; // remove processed refinement
794
+ break ;
795
+ }
796
+ }
797
+ // Was refinement found? If not, error:
798
+ if (IS_END (args )) Trap2 (RE_NO_REFINE , Func_Word (dsf ), path );
799
+ continue ;
800
+ }
775
801
else Trap1 (RE_BAD_REFINE , path );
776
802
break ;
777
803
@@ -789,14 +815,15 @@ x*/ static REBINT Do_Args_Light(REBVAL *func, REBVAL *path, REBSER *block, REBCN
789
815
}
790
816
791
817
// If word is typed, verify correct argument datatype:
792
- if (!TYPE_CHECK (args , VAL_TYPE (DS_VALUE (ds ))))
818
+ if (!TYPE_CHECK (args , VAL_TYPE (DS_VALUE (ds ))) && useArgs )
793
819
Trap3 (RE_EXPECT_ARG , Func_Word (dsf ), args , Of_Type (DS_VALUE (ds )));
794
820
}
795
821
796
822
// Hack to process remaining path:
797
823
if (path && NOT_END (path )) {
798
- if (!IS_WORD (path )) Trap1 (RE_BAD_REFINE , path );
799
- goto more_path ;
824
+ if (IS_WORD (path )) goto more_path ;
825
+ if (IS_GET_WORD (path )) goto more_get_path ;
826
+ Trap1 (RE_BAD_REFINE , path );
800
827
}
801
828
802
829
return index ;
0 commit comments