@@ -290,6 +290,14 @@ impl DExp {
290290 lines
291291 }
292292 }
293+
294+ pub fn result ( & self ) -> & str {
295+ self . result . as_ref ( )
296+ }
297+
298+ pub fn lines ( & self ) -> & Expand {
299+ & self . lines
300+ }
293301}
294302impl TakeHandle for DExp {
295303 fn take_handle ( self , meta : & mut CompileMeta ) -> Var {
@@ -351,6 +359,7 @@ impl DisplaySource for DExp {
351359 meta. push ( ")" ) ;
352360 }
353361}
362+ impl_derefs ! ( impl for DExp => ( self : self . lines) : Expand ) ;
354363
355364/// 将一个Value与一个Var以特定格式组合起来,
356365/// 可完成如属性调用的功能
@@ -442,15 +451,9 @@ impl Meta {
442451 /// 如果只有一个值与被赋值则与之前行为一致
443452 /// 如果值与被赋值数量不匹配则返回错误
444453 /// 如果值与被赋值数量匹配且大于一对就返回Expand中多个set
445- pub fn build_sets ( & self , loc : [ Location ; 2 ] , mut vars : Vec < Value > , mut values : Vec < Value > )
454+ pub fn build_sets ( loc : [ Location ; 2 ] , mut vars : Vec < Value > , mut values : Vec < Value > )
446455 -> Result < LogicLine , Error > {
447- fn build_set ( var : Value , value : Value ) -> LogicLine {
448- LogicLine :: Other ( vec ! [
449- Value :: ReprVar ( "set" . into( ) ) ,
450- var,
451- value,
452- ] )
453- }
456+ let build_set = Self :: build_set;
454457 if vars. len ( ) != values. len ( ) {
455458 // 接受与值数量不匹配
456459 return Err ( (
@@ -475,6 +478,15 @@ impl Meta {
475478 Ok ( Expand ( expand) . into ( ) )
476479 }
477480 }
481+
482+ /// 单纯的构建一个set语句
483+ pub fn build_set ( var : Value , value : Value ) -> LogicLine {
484+ LogicLine :: Other ( vec ! [
485+ Value :: ReprVar ( "set" . into( ) ) ,
486+ var,
487+ value,
488+ ] )
489+ }
478490}
479491
480492pub trait FromMdtArgs
@@ -1018,6 +1030,50 @@ impl Op {
10181030 }
10191031 }
10201032
1033+ pub fn get_result ( & self ) -> & Value {
1034+ macro_rules! build_match {
1035+ {
1036+ $(
1037+ $variant: ident
1038+ ) ,* $( , ) ?
1039+ } => {
1040+ match self {
1041+ $( Self :: $variant( res, ..) => res ) ,*
1042+ }
1043+ } ;
1044+ }
1045+ build_match ! {
1046+ Add , Sub , Mul , Div , Idiv , Mod , Pow ,
1047+ Equal , NotEqual , Land , LessThan , LessThanEq , GreaterThan , GreaterThanEq ,
1048+ StrictEqual , Shl , Shr , Or , And , Xor , Not ,
1049+ Max , Min , Angle , Len , Noise , Abs , Log ,
1050+ Log10 , Floor , Ceil , Sqrt , Rand , Sin , Cos ,
1051+ Tan , Asin , Acos , Atan ,
1052+ }
1053+ }
1054+
1055+ pub fn get_result_mut ( & mut self ) -> & mut Value {
1056+ macro_rules! build_match {
1057+ {
1058+ $(
1059+ $variant: ident
1060+ ) ,* $( , ) ?
1061+ } => {
1062+ match self {
1063+ $( Self :: $variant( res, ..) => res ) ,*
1064+ }
1065+ } ;
1066+ }
1067+ build_match ! {
1068+ Add , Sub , Mul , Div , Idiv , Mod , Pow ,
1069+ Equal , NotEqual , Land , LessThan , LessThanEq , GreaterThan , GreaterThanEq ,
1070+ StrictEqual , Shl , Shr , Or , And , Xor , Not ,
1071+ Max , Min , Angle , Len , Noise , Abs , Log ,
1072+ Log10 , Floor , Ceil , Sqrt , Rand , Sin , Cos ,
1073+ Tan , Asin , Acos , Atan ,
1074+ }
1075+ }
1076+
10211077 pub fn oper_symbol_str ( & self ) -> & ' static str {
10221078 macro_rules! build_match {
10231079 {
@@ -1651,6 +1707,14 @@ impl LogicLine {
16511707 }
16521708 }
16531709
1710+ pub fn as_op_mut ( & mut self ) -> Option < & mut Op > {
1711+ if let Self :: Op ( v) = self {
1712+ Some ( v)
1713+ } else {
1714+ None
1715+ }
1716+ }
1717+
16541718 /// Returns `true` if the logic line is [`Label`].
16551719 ///
16561720 /// [`Label`]: LogicLine::Label
@@ -2201,6 +2265,14 @@ pub fn mdt_logic_split(s: &str) -> Result<Vec<&str>, usize> {
22012265 Ok ( res)
22022266}
22032267
2268+ pub type OpExprInfo = ( bool , Value ) ;
2269+
2270+ pub fn op_expr_do < F > ( f : F ) -> OpExprInfo
2271+ where F : FnOnce ( ) -> Op
2272+ {
2273+ ( true , DExp :: new_nores ( vec ! [ f( ) . into( ) ] . into ( ) ) . into ( ) )
2274+ }
2275+
22042276#[ cfg( test) ]
22052277mod tests {
22062278 use std:: str:: FromStr ;
@@ -4322,4 +4394,58 @@ mod tests {
43224394 ) ;
43234395 }
43244396 }
4397+
4398+ #[ test]
4399+ fn op_expr_test ( ) {
4400+ let parser = ExpandParser :: new ( ) ;
4401+
4402+ assert_eq ! (
4403+ parse!( parser, r#"
4404+ x = max(1, 2);
4405+ y = max(max(1, 2), max(3, max(4, 5)));
4406+ "# ) . unwrap( ) ,
4407+ parse!( parser, r#"
4408+ op x max 1 2;
4409+ op y max (op $ max 1 2;) (op $ max 3 (op $ max 4 5;););
4410+ "# ) . unwrap( ) ,
4411+ ) ;
4412+
4413+ assert_eq ! (
4414+ parse!( parser, r#"
4415+ x = 1+2*3;
4416+ y = (1+2)*3;
4417+ z = 1+2+3;
4418+ "# ) . unwrap( ) ,
4419+ parse!( parser, r#"
4420+ op x 1 + (op $ 2 * 3;);
4421+ op y (op $ 1 + 2;) * 3;
4422+ op z (op $ 1 + 2;) + 3;
4423+ "# ) . unwrap( ) ,
4424+ ) ;
4425+
4426+ assert_eq ! (
4427+ parse!( parser, r#"
4428+ x = 1*max(2, 3);
4429+ y = a & b | c & d & e | f;
4430+ "# ) . unwrap( ) ,
4431+ parse!( parser, r#"
4432+ op x 1 * (op $ max 2 3;);
4433+ op y (op $ (op $ a & b;) | (op $ (op $ c & d;) & e;);) | f;
4434+ "# ) . unwrap( ) ,
4435+ ) ;
4436+
4437+ assert_eq ! (
4438+ parse!( parser, r#"
4439+ x = a**b**c; # pow的右结合
4440+ y = -x;
4441+ z = ~y;
4442+ "# ) . unwrap( ) ,
4443+ parse!( parser, r#"
4444+ op x a ** (op $ b ** c;);
4445+ op y `0` - x;
4446+ op z ~y;
4447+ "# ) . unwrap( ) ,
4448+ ) ;
4449+
4450+ }
43254451}
0 commit comments