public static Expression AnalyzeBinaryExpr(SymplBinaryExpr expr, AnalysisScope scope) { // The language has the following special logic to handle And and Or // x And y == if x then y // x Or y == if x then x else (if y then y) if (expr.Operation == ExpressionType.And) { return(AnalyzeIfExpr( new SymplIfExpr( expr.Left, expr.Right, null), scope)); } else if (expr.Operation == ExpressionType.Or) { // Use (LetStar (tmp expr) (if tmp tmp)) to represent (if expr expr) // to remore duplicate evaluation. // So x Or y is translated into // (Let* (tmp1 x) // (If tmp1 tmp1 // (Let* (tmp2 y) (If tmp2 tmp2)))) // IdOrKeywordToken tmp2 = new IdOrKeywordToken( // Real implementation needs to ensure unique ID in scope chain. "__tmpLetVariable2"); var tmpExpr2 = new SymplIdExpr(tmp2); var binding2 = new LetBinding(tmp2, expr.Right);; var ifExpr2 = new SymplIfExpr( tmpExpr2, tmpExpr2, null); var letExpr2 = new SymplLetStarExpr( new[] { binding2 }, new[] { ifExpr2 }); IdOrKeywordToken tmp1 = new IdOrKeywordToken( // Real implementation needs to ensure unique ID in scope chain. "__tmpLetVariable1"); var tmpExpr1 = new SymplIdExpr(tmp1); LetBinding binding1 = new LetBinding(tmp1, expr.Left);; SymplExpr ifExpr1 = new SymplIfExpr( tmpExpr1, tmpExpr1, letExpr2); return(AnalyzeLetStarExpr( new SymplLetStarExpr( new[] { binding1 }, new[] { ifExpr1 } ), scope )); } return(Expression.Dynamic( scope.GetRuntime().GetBinaryOperationBinder(expr.Operation), typeof(object), AnalyzeExpr(expr.Left, scope), AnalyzeExpr(expr.Right, scope) )); }
public static Expression AnalyzeBinaryExpr(SymplBinaryExpr expr, AnalysisScope scope) { // The language has the following special logic to handle And and Or // x And y == if x then y // x Or y == if x then x else (if y then y) if (expr.Operation == ExpressionType.And) { return AnalyzeIfExpr( new SymplIfExpr( expr.Left, expr.Right, null), scope); } else if (expr.Operation == ExpressionType.Or) { // Use (LetStar (tmp expr) (if tmp tmp)) to represent (if expr expr) // to remore duplicate evaluation. // So x Or y is translated into // (Let* (tmp1 x) // (If tmp1 tmp1 // (Let* (tmp2 y) (If tmp2 tmp2)))) // IdOrKeywordToken tmp2 = new IdOrKeywordToken( // Real implementation needs to ensure unique ID in scope chain. "__tmpLetVariable2"); var tmpExpr2 = new SymplIdExpr(tmp2); var binding2 = new LetBinding(tmp2, expr.Right); ; var ifExpr2 = new SymplIfExpr( tmpExpr2, tmpExpr2, null); var letExpr2 = new SymplLetStarExpr( new[] { binding2 }, new[] { ifExpr2 }); IdOrKeywordToken tmp1 = new IdOrKeywordToken( // Real implementation needs to ensure unique ID in scope chain. "__tmpLetVariable1"); var tmpExpr1 = new SymplIdExpr(tmp1); LetBinding binding1 = new LetBinding(tmp1, expr.Left); ; SymplExpr ifExpr1 = new SymplIfExpr( tmpExpr1, tmpExpr1, letExpr2); return AnalyzeLetStarExpr( new SymplLetStarExpr( new[] { binding1 }, new[] { ifExpr1 } ), scope ); } return Expression.Dynamic( scope.GetRuntime().GetBinaryOperationBinder(expr.Operation), typeof(object), AnalyzeExpr(expr.Left, scope), AnalyzeExpr(expr.Right, scope) ); }