/// <summary> /// Execute the logical expression. /// exp: (a AND b) /// /// Only bool type are authorized. /// </summary> /// <param name="exprExecResult"></param> /// <param name="exprComparison"></param> /// <param name="exprExecBase"></param> /// <returns></returns> private bool ExecExpressionLogical(ExecResult exprExecResult, ExprLogical exprLogical, out ExpressionExecBase exprExecBase) { exprExecBase = null; //----first step is to execute both operands ExpressionExecBase exprExecBaseLeft; ExecExpression(exprExecResult, exprLogical.ExprLeft, out exprExecBaseLeft); ExpressionExecBase exprExecBaseRight; ExecExpression(exprExecResult, exprLogical.ExprRight, out exprExecBaseRight); //---Are the operands boolean type? ExprExecValueBool exprExecValueLeftBool = exprExecBaseLeft as ExprExecValueBool; if (exprExecValueLeftBool != null) { // decode the right operand, should be a bool value too ExprExecValueBool exprExecValueRightBool = exprExecBaseRight as ExprExecValueBool; if (exprExecValueRightBool == null) { // the type of both operands mismatch! exprExecResult.AddErrorExec(ErrorCode.ExprLogicalOperandsTypeMismatchBoolExpected, "Position", exprLogical.ExprRight.Token.Position.ToString()); return(false); } ExprExecValueBool exprValueBoolResult = new ExprExecValueBool(); // is the operator AND? if (exprLogical.Operator == OperatorLogicalCode.And) { // ok, execute the comparison exprValueBoolResult.Value = exprExecValueLeftBool.Value && exprExecValueRightBool.Value; exprExecBase = exprValueBoolResult; return(true); } // is the operator OR? if (exprLogical.Operator == OperatorLogicalCode.Or) { // ok, execute the comparison exprValueBoolResult.Value = (exprExecValueLeftBool.Value || exprExecValueRightBool.Value); exprExecBase = exprValueBoolResult; return(true); } // is the operator XOR? if (exprLogical.Operator == OperatorLogicalCode.Xor) { // ok, execute the comparison, the operator doesn't exists so do firts a OR exprValueBoolResult.Value = (exprExecValueLeftBool.Value || exprExecValueRightBool.Value); // the xor case: both operands are true so the result is false if (exprExecValueLeftBool.Value && exprExecValueRightBool.Value) { exprValueBoolResult.Value = false; } exprExecBase = exprValueBoolResult; return(true); } // other operators are not allowed on the boolean type (only bool) exprExecResult.AddErrorExec(ErrorCode.ExprLogicalOperatorNotAllowed, "Position", exprLogical.ExprLeft.Token.Position.ToString(), "Operator", exprLogical.Operator.ToString()); return(false); } //---Are the operands others type? -> error exprExecResult.AddErrorExec(ErrorCode.ExprLogicalOperandTypeNotAllowed, "Position", exprLogical.ExprLeft.Token.Position.ToString(), "Token", exprExecBaseLeft.GetType().ToString()); return(false); }
/// <summary> /// analyze and return the list of variables and functionCalls found in the expression to define before execute it. /// Do also some checks. /// </summary> /// <param name="exprParseResult"></param> /// <param name="expr"></param> /// <returns></returns> private bool AnalyzeSyntaxTree(ParseResult result, ExpressionBase expr) { //----is it a final operand? ExprFinalOperand exprFinalOperand = expr as ExprFinalOperand; if (exprFinalOperand != null) { if (exprFinalOperand.ContentType == OperandType.ObjectName) { // save the objectName (variable) result.AddVariable(exprFinalOperand.Operand); } return(true); } //----is it a function call? ExprFunctionCall exprFunctionCall = expr as ExprFunctionCall; if (exprFunctionCall != null) { // scan parameters of the function call foreach (ExpressionBase exprParam in exprFunctionCall.ListExprParameters) { AnalyzeSyntaxTree(result, exprParam); } result.AddFunctionCall(exprFunctionCall.FunctionName, exprFunctionCall.ListExprParameters.Count); return(true); } //----is it an expression comparison? ExprComparison exprComparison = expr as ExprComparison; if (exprComparison != null) { AnalyzeSyntaxTree(result, exprComparison.ExprLeft); AnalyzeSyntaxTree(result, exprComparison.ExprRight); return(true); } //----is it an expression logical? ExprLogical exprLogical = expr as ExprLogical; if (exprLogical != null) { AnalyzeSyntaxTree(result, exprLogical.ExprLeft); AnalyzeSyntaxTree(result, exprLogical.ExprRight); return(true); } //----is it an expression logical NOT? ExprLogicalNot exprLogicalNot = expr as ExprLogicalNot; if (exprLogicalNot != null) { AnalyzeSyntaxTree(result, exprLogicalNot.ExprBase); return(true); } //----is it an expression calculation? ExprCalculation exprCalculation = expr as ExprCalculation; if (exprCalculation != null) { // analyze all operands of the calculation expression bool res = true; foreach (ExpressionBase exprChild in exprCalculation.ListExprOperand) { res = res && AnalyzeSyntaxTree(result, exprChild); } //AnalyzeSyntaxTree(result, exprCalculation.ExprLeft); //AnalyzeSyntaxTree(result, exprCalculation.ExprRight); return(res); } //----is it a set value expression ? // todo: throw new Exception("todo: AnalyzeSyntaxTree(), expression type not yet implemented!"); }
/// <summary> /// start the execution, analyze and return the list of variables to create. /// todo: recréer un syntax tree, avec des valeurs! /// /// -->Doit renvoyer comme résultat un objet de type ExprValueXXX, non?? (si pas d'erreur). /// </summary> /// <returns></returns> private bool ExecExpression(ExecResult exprExecResult, ExpressionBase expr, out ExpressionExecBase exprExecBase) { exprExecBase = null; //----is it a final operand (value, var or call function)? ExprFinalOperand finalOperand = expr as ExprFinalOperand; if (finalOperand != null) { return(ExecExpressionFinalOperand(exprExecResult, finalOperand, out exprExecBase)); } //----is it a comparison expression? ExprComparison exprComparison = expr as ExprComparison; if (exprComparison != null) { // execute the expression, execute the right part, execute the left part, then exec the expr (as 2 value operands) return(ExecExpressionComparison(exprExecResult, exprComparison, out exprExecBase)); } //----is it a logical expression (bin/2 operands)? ExprLogical exprLogical = expr as ExprLogical; if (exprLogical != null) { return(ExecExpressionLogical(exprExecResult, exprLogical, out exprExecBase)); } //----is it a NOT logical expression? ExprLogicalNot exprLogicalNot = expr as ExprLogicalNot; if (exprLogicalNot != null) { return(ExecExpressionLogicalNot(exprExecResult, exprLogicalNot, out exprExecBase)); } //----is it a calculation expression? ExprCalculation exprCalculation = expr as ExprCalculation; if (exprCalculation != null) { // execute the expression, execute the right part, execute the left part, then exec the expr (as 2 value operands) return(ExecExpressionCalculation(exprExecResult, exprCalculation, out exprExecBase)); } //----is it function call? ExprFunctionCall exprFunctionCall = expr as ExprFunctionCall; if (exprFunctionCall != null) { return(ExecExpressionFunctionCall(exprExecResult, exprFunctionCall, out exprExecBase)); } //----is it a setValue expression? // todo: future // todo: error, expression not yet implemented!! exprExecResult.AddErrorExec(ErrorCode.ExpressionTypeNotYetImplemented, "Expr", expr.GetType().ToString()); return(false); }