@@ -111,7 +111,9 @@ impl Value {
111111 Self :: DExp ( DExp { mut result, lines } ) => {
112112 if result. is_empty ( ) {
113113 result = meta. get_tmp_var ( ) ; /* init tmp_var */
114- } else if let Some ( ( _, _, value) ) = meta. get_const_value ( & result) {
114+ } else if let
115+ Some ( ( _, _, value) )
116+ = meta. get_const_value_and_add ( & result) {
115117 // 对返回句柄使用常量值的处理
116118 if let Some ( dexp) = value. as_dexp ( ) {
117119 err ! (
@@ -646,7 +648,6 @@ pub enum LogicLine {
646648 Other ( Vec < Value > ) ,
647649 Expand ( Expand ) ,
648650 Select ( Select ) ,
649- End ,
650651 NoOp ,
651652 /// 空语句, 什么也不生成
652653 Ignore ,
@@ -656,7 +657,6 @@ pub enum LogicLine {
656657impl Compile for LogicLine {
657658 fn compile ( self , meta : & mut CompileMeta ) {
658659 match self {
659- Self :: End => meta. push ( "end" . into ( ) ) ,
660660 Self :: NoOp => meta. push ( "noop" . into ( ) ) ,
661661 Self :: Label ( mut lab) => {
662662 // 如果在常量展开中, 尝试将这个标记替换
@@ -915,23 +915,46 @@ impl CompileMeta {
915915 self . const_var_namespace . pop ( ) . unwrap ( )
916916 }
917917
918- /// 获取一个常量到值的使用次数与映射与其内部标记 ,
918+ /// 获取一个常量到值的使用次数与映射与其内部标记的引用 ,
919919 /// 从当前作用域往顶层作用域一层层找, 都没找到就返回空
920- pub fn get_const_value ( & mut self , name : & Var ) -> Option < ( usize , & Vec < Var > , & Value ) > {
920+ pub fn get_const_value ( & self , name : & Var ) -> Option < & ( usize , Vec < Var > , Value ) > {
921+ self . const_var_namespace
922+ . iter ( )
923+ . rev ( )
924+ . find_map ( |namespace| {
925+ namespace. get ( name)
926+ } )
927+ }
928+
929+ /// 获取一个常量到值的使用次数与映射与其内部标记的可变引用,
930+ /// 从当前作用域往顶层作用域一层层找, 都没找到就返回空
931+ pub fn get_const_value_mut ( & mut self , name : & Var )
932+ -> Option < & mut ( usize , Vec < Var > , Value ) > {
921933 self . const_var_namespace
922934 . iter_mut ( )
923935 . rev ( )
924936 . find_map ( |namespace| {
925- namespace
926- . get_mut ( name)
927- . map ( |( count, labels, value) | {
928- let this_count = * count;
929- * count += 1 ;
930- ( this_count, & * labels, & * value)
931- } )
937+ namespace. get_mut ( name)
932938 } )
933939 }
934940
941+ /// 调用[`Self::get_const_value_mut_and_add`]
942+ /// 并将返回结果转换为不可变引用
943+ pub fn get_const_value_and_add ( & mut self , name : & Var )
944+ -> Option < & ( usize , Vec < Var > , Value ) > {
945+ self . get_const_value_mut_and_add ( name)
946+ . map ( |x| & * x)
947+ }
948+
949+ /// 调用[`Self::get_const_value_mut`], 但是非空情况会给使用计数加一
950+ pub fn get_const_value_mut_and_add ( & mut self , name : & Var )
951+ -> Option < & mut ( usize , Vec < Var > , Value ) > {
952+ self . get_const_value_mut ( name) . map ( |x| {
953+ x. 0 += 1 ;
954+ x
955+ } )
956+ }
957+
935958 /// 新增一个常量到值的映射, 如果当前作用域已有此映射则返回旧的值并插入新值
936959 pub fn add_const_value ( & mut self , Const ( var, value, labels) : Const )
937960 -> Option < ( usize , Vec < Var > , Value ) > {
@@ -995,10 +1018,22 @@ impl CompileMeta {
9951018 /// 这个函数会直接调用获取函数将标记映射完毕, 然后返回其值
9961019 /// 如果不是一个宏则直接返回None, 也不会进入无需清理
9971020 pub fn const_expand_enter ( & mut self , name : & Var ) -> Option < Value > {
998- let ( count, labels, value) = self . get_const_value ( name) ?;
1021+ let label_count = self . get_const_value ( name) ?. 1 . len ( ) ;
1022+ let mut tmp_tags = Vec :: with_capacity ( label_count) ;
1023+ tmp_tags. extend ( repeat_with ( || self . get_tmp_tag ( ) )
1024+ . take ( label_count) ) ;
1025+
1026+ let ( count, labels, value)
1027+ = self . get_const_value_and_add ( name) . unwrap ( ) ;
9991028 let mut labels_map = HashMap :: with_capacity ( labels. len ( ) ) ;
1000- for label in labels. iter ( ) . cloned ( ) {
1001- let maped_label = format ! ( "__const_{}_{}_{}" , & name, count, & label) ;
1029+ for ( tmp_tag, label) in zip ( tmp_tags, labels. iter ( ) . cloned ( ) ) {
1030+ let maped_label = format ! (
1031+ "{}_const_{}_{}_{}" ,
1032+ tmp_tag,
1033+ & name,
1034+ count,
1035+ & label
1036+ ) ;
10021037 labels_map. insert ( label, maped_label) ;
10031038 }
10041039 let res = value. clone ( ) ;
@@ -1726,4 +1761,27 @@ mod tests {
17261761 "print R" ,
17271762 ] ) ;
17281763 }
1764+
1765+ #[ test]
1766+ fn in_const_const_label_rename_test ( ) {
1767+ let parser = ExpandParser :: new ( ) ;
1768+
1769+ let ast = parse ! ( parser, r#"
1770+ const X = (
1771+ const X = (
1772+ i = 0;
1773+ do {
1774+ op i i + 1;
1775+ } while i < 10;
1776+ );
1777+ take __ = X;
1778+ take __ = X;
1779+ );
1780+ take __ = X;
1781+ take __ = X;
1782+ "# ) . unwrap ( ) ;
1783+ let meta = CompileMeta :: new ( ) ;
1784+ let mut tag_codes = meta. compile ( ast) ;
1785+ let _logic_lines = tag_codes. compile ( ) . unwrap ( ) ;
1786+ }
17291787}
0 commit comments