@@ -102,7 +102,13 @@ impl Value {
102102 Self :: Var ( var) => {
103103 if let Some ( value) = meta. const_expand_enter ( & var) {
104104 // 是一个常量
105- let res = value. take ( meta) ;
105+ let res = if let Value :: Var ( var) = value {
106+ // 只进行单步常量追溯
107+ // 因为常量定义时已经完成了原有的多步
108+ var
109+ } else {
110+ value. take ( meta)
111+ } ;
106112 meta. const_expand_exit ( ) ;
107113 res
108114 } else {
@@ -113,8 +119,8 @@ impl Value {
113119 if result. is_empty ( ) {
114120 result = meta. get_tmp_var ( ) ; /* init tmp_var */
115121 } else if let
116- Some ( ( _, _ , value) )
117- = meta. get_const_value_and_add ( & result) {
122+ Some ( ( _, value) )
123+ = meta. get_const_value ( & result) {
118124 // 对返回句柄使用常量值的处理
119125 if let Some ( dexp) = value. as_dexp ( ) {
120126 err ! (
@@ -860,8 +866,8 @@ pub struct CompileMeta {
860866 /// 块中常量, 且带有展开次数与内部标记
861867 /// 并且存储了需要泄露的常量
862868 ///
863- /// `Vec<(leaks, HashMap<name, (count, Vec<Label>, Value)>)>`
864- const_var_namespace : Vec < ( Vec < Var > , HashMap < Var , ( usize , Vec < Var > , Value ) > ) > ,
869+ /// `Vec<(leaks, HashMap<name, (Vec<Label>, Value)>)>`
870+ const_var_namespace : Vec < ( Vec < Var > , HashMap < Var , ( Vec < Var > , Value ) > ) > ,
865871 /// 每层DExp所使用的句柄, 末尾为当前层
866872 dexp_result_handles : Vec < Var > ,
867873 tmp_tag_count : usize ,
@@ -963,7 +969,7 @@ impl CompileMeta {
963969 /// 退出一个子块, 弹出最顶层命名空间
964970 /// 如果无物可弹说明逻辑出现了问题, 所以内部处理为unwrap
965971 /// 一个enter对应一个exit
966- pub fn block_exit ( & mut self ) -> HashMap < Var , ( usize , Vec < Var > , Value ) > {
972+ pub fn block_exit ( & mut self ) -> HashMap < Var , ( Vec < Var > , Value ) > {
967973 // this is poped block
968974 let ( leaks, mut res)
969975 = self . const_var_namespace . pop ( ) . unwrap ( ) ;
@@ -994,7 +1000,7 @@ impl CompileMeta {
9941000
9951001 /// 获取一个常量到值的使用次数与映射与其内部标记的引用,
9961002 /// 从当前作用域往顶层作用域一层层找, 都没找到就返回空
997- pub fn get_const_value ( & self , name : & Var ) -> Option < & ( usize , Vec < Var > , Value ) > {
1003+ pub fn get_const_value ( & self , name : & Var ) -> Option < & ( Vec < Var > , Value ) > {
9981004 self . const_var_namespace
9991005 . iter ( )
10001006 . rev ( )
@@ -1006,7 +1012,7 @@ impl CompileMeta {
10061012 /// 获取一个常量到值的使用次数与映射与其内部标记的可变引用,
10071013 /// 从当前作用域往顶层作用域一层层找, 都没找到就返回空
10081014 pub fn get_const_value_mut ( & mut self , name : & Var )
1009- -> Option < & mut ( usize , Vec < Var > , Value ) > {
1015+ -> Option < & mut ( Vec < Var > , Value ) > {
10101016 self . const_var_namespace
10111017 . iter_mut ( )
10121018 . rev ( )
@@ -1015,31 +1021,29 @@ impl CompileMeta {
10151021 } )
10161022 }
10171023
1018- /// 调用[`Self::get_const_value_mut_and_add`]
1019- /// 并将返回结果转换为不可变引用
1020- pub fn get_const_value_and_add ( & mut self , name : & Var )
1021- -> Option < & ( usize , Vec < Var > , Value ) > {
1022- self . get_const_value_mut_and_add ( name)
1023- . map ( |x| & * x)
1024- }
1025-
1026- /// 调用[`Self::get_const_value_mut`], 但是非空情况会给使用计数加一
1027- pub fn get_const_value_mut_and_add ( & mut self , name : & Var )
1028- -> Option < & mut ( usize , Vec < Var > , Value ) > {
1029- self . get_const_value_mut ( name) . map ( |x| {
1030- x. 0 += 1 ;
1031- x
1032- } )
1033- }
1034-
10351024 /// 新增一个常量到值的映射, 如果当前作用域已有此映射则返回旧的值并插入新值
1036- pub fn add_const_value ( & mut self , Const ( var, value, labels) : Const )
1037- -> Option < ( usize , Vec < Var > , Value ) > {
1025+ pub fn add_const_value ( & mut self , Const ( var, mut value, mut labels) : Const )
1026+ -> Option < ( Vec < Var > , Value ) > {
1027+ // TODO
1028+ // 去掉调用次数 (*)
1029+ // 将定义常量映射到常量改为直接把常量对应的值拿过来
1030+ // 防止`const A = 1;const B = A;const A = 2;print B;`输出2
1031+ // 这还需考虑const注册标签
1032+ if let Some ( var_1) = value. as_var ( ) {
1033+ // 如果const的映射目标值是一个var
1034+ if let Some ( ( labels_1, value_1) )
1035+ = self . get_const_value ( var_1) . cloned ( ) {
1036+ // 且它是一个常量, 则将它直接克隆过来.
1037+ // 防止直接映射到另一常量,
1038+ // 但是另一常量被覆盖导致这在覆盖之前映射的常量结果也发生改变
1039+ ( labels, value) = ( labels_1, value_1)
1040+ }
1041+ }
10381042 self . const_var_namespace
10391043 . last_mut ( )
10401044 . unwrap ( )
10411045 . 1
1042- . insert ( var, ( 0 , labels, value) )
1046+ . insert ( var, ( labels, value) )
10431047 }
10441048
10451049 /// 新增一层DExp, 并且传入它使用的返回句柄
@@ -1096,20 +1100,19 @@ impl CompileMeta {
10961100 /// 这个函数会直接调用获取函数将标记映射完毕, 然后返回其值
10971101 /// 如果不是一个宏则直接返回None, 也不会进入无需清理
10981102 pub fn const_expand_enter ( & mut self , name : & Var ) -> Option < Value > {
1099- let label_count = self . get_const_value ( name) ?. 1 . len ( ) ;
1103+ let label_count = self . get_const_value ( name) ?. 0 . len ( ) ;
11001104 let mut tmp_tags = Vec :: with_capacity ( label_count) ;
11011105 tmp_tags. extend ( repeat_with ( || self . get_tmp_tag ( ) )
11021106 . take ( label_count) ) ;
11031107
1104- let ( count , labels, value)
1105- = self . get_const_value_and_add ( name) . unwrap ( ) ;
1108+ let ( labels, value)
1109+ = self . get_const_value ( name) . unwrap ( ) ;
11061110 let mut labels_map = HashMap :: with_capacity ( labels. len ( ) ) ;
11071111 for ( tmp_tag, label) in zip ( tmp_tags, labels. iter ( ) . cloned ( ) ) {
11081112 let maped_label = format ! (
1109- "{}_const_{}_{}_{} " ,
1113+ "{}_const_{}_{}" ,
11101114 tmp_tag,
11111115 & name,
1112- count,
11131116 & label
11141117 ) ;
11151118 labels_map. insert ( label, maped_label) ;
@@ -2060,4 +2063,111 @@ mod tests {
20602063 = 1 2;
20612064 "# ) . is_err( ) ) ;
20622065 }
2066+
2067+ #[ test]
2068+ fn const_value_clone_test ( ) {
2069+ let parser = ExpandParser :: new ( ) ;
2070+
2071+ let logic_lines = CompileMeta :: new ( ) . compile ( parse ! ( parser, r#"
2072+ const A = 1;
2073+ const B = A;
2074+ const A = 2;
2075+ print A B;
2076+ "# ) . unwrap ( ) ) . compile ( ) . unwrap ( ) ;
2077+ assert_eq ! ( logic_lines, vec![
2078+ "print 2" ,
2079+ "print 1" ,
2080+ ] ) ;
2081+
2082+ let logic_lines = CompileMeta :: new ( ) . compile ( parse ! ( parser, r#"
2083+ const A = 1;
2084+ const B = A;
2085+ const A = 2;
2086+ const C = B;
2087+ const B = 3;
2088+ const B = B;
2089+ print A B C;
2090+ "# ) . unwrap ( ) ) . compile ( ) . unwrap ( ) ;
2091+ assert_eq ! ( logic_lines, vec![
2092+ "print 2" ,
2093+ "print 3" ,
2094+ "print 1" ,
2095+ ] ) ;
2096+
2097+ let logic_lines = CompileMeta :: new ( ) . compile ( parse ! ( parser, r#"
2098+ const A = B;
2099+ const B = 2;
2100+ print A;
2101+ "# ) . unwrap ( ) ) . compile ( ) . unwrap ( ) ;
2102+ assert_eq ! ( logic_lines, vec![
2103+ "print B" ,
2104+ ] ) ;
2105+
2106+ let logic_lines = CompileMeta :: new ( ) . compile ( parse ! ( parser, r#"
2107+ const A = B;
2108+ const B = 2;
2109+ const A = A;
2110+ print A;
2111+ "# ) . unwrap ( ) ) . compile ( ) . unwrap ( ) ;
2112+ assert_eq ! ( logic_lines, vec![
2113+ "print B" ,
2114+ ] ) ;
2115+
2116+ let logic_lines = CompileMeta :: new ( ) . compile ( parse ! ( parser, r#"
2117+ const A = B;
2118+ const B = 2;
2119+ {
2120+ const A = A;
2121+ print A;
2122+ }
2123+ "# ) . unwrap ( ) ) . compile ( ) . unwrap ( ) ;
2124+ assert_eq ! ( logic_lines, vec![
2125+ "print B" ,
2126+ ] ) ;
2127+
2128+ let logic_lines = CompileMeta :: new ( ) . compile ( parse ! ( parser, r#"
2129+ const A = B;
2130+ {
2131+ const B = 2;
2132+ const A = A;
2133+ print A;
2134+ }
2135+ "# ) . unwrap ( ) ) . compile ( ) . unwrap ( ) ;
2136+ assert_eq ! ( logic_lines, vec![
2137+ "print B" ,
2138+ ] ) ;
2139+
2140+ let logic_lines = CompileMeta :: new ( ) . compile ( parse ! ( parser, r#"
2141+ const A = B;
2142+ {
2143+ const B = 2;
2144+ print A;
2145+ }
2146+ "# ) . unwrap ( ) ) . compile ( ) . unwrap ( ) ;
2147+ assert_eq ! ( logic_lines, vec![
2148+ "print B" ,
2149+ ] ) ;
2150+
2151+ let logic_lines = CompileMeta :: new ( ) . compile ( parse ! ( parser, r#"
2152+ const A = B;
2153+ const B = C;
2154+ const C = A;
2155+ print C;
2156+ "# ) . unwrap ( ) ) . compile ( ) . unwrap ( ) ;
2157+ assert_eq ! ( logic_lines, vec![
2158+ "print B" ,
2159+ ] ) ;
2160+
2161+ let logic_lines = CompileMeta :: new ( ) . compile ( parse ! ( parser, r#"
2162+ const A = C;
2163+ const C = 2;
2164+ const B = A;
2165+ const A = 3;
2166+ const C = B;
2167+ print C;
2168+ "# ) . unwrap ( ) ) . compile ( ) . unwrap ( ) ;
2169+ assert_eq ! ( logic_lines, vec![
2170+ "print C" ,
2171+ ] ) ;
2172+ }
20632173}
0 commit comments