Instruction AnalyseOperation(Tokenizer.Token[] tokens, int index, out int tokenCount) { InstructionOperation instructionOperation = new InstructionOperation(); Tokenizer.Token[][] tokensOperands = SplitTokens(tokens, t => t.TokenType == Tokenizer.TokenType.Operator); foreach (Tokenizer.Token[] operand in tokensOperands) { int tc = 0; Instruction instruction = AnalyseInstruction(operand, 0, out tc); instructionOperation.ValuesInstructions.Add(instruction); } int currentIndex = tokensOperands[0].Length; for (int i = 1; i < tokensOperands.Length; i++) { InstructionOperation.OperatorType ope = TokenNameTooperatorType[tokens[currentIndex].TokenName]; instructionOperation.Operators.Add(ope); currentIndex += 1 + tokensOperands[i].Length; } //Sort operators priorities foreach (InstructionOperation.OperatorType[] operatorPriority in InstructionOperation.OperatorsPriority) { if (!instructionOperation.Operators.Exists(o => !operatorPriority.Contains(o))) { //All operators have the same priority break; } InstructionOperation subInstruction = null; for (int i = 0; i < instructionOperation.Operators.Count; i++) { if (operatorPriority.Contains(instructionOperation.Operators[i])) { if (subInstruction == null) { subInstruction = new InstructionOperation(); subInstruction.ValuesInstructions.Add(instructionOperation.ValuesInstructions[i]); instructionOperation.ValuesInstructions.RemoveAt(i); } subInstruction.Operators.Add(instructionOperation.Operators[i]); instructionOperation.Operators.RemoveAt(i); subInstruction.ValuesInstructions.Add(instructionOperation.ValuesInstructions[i]); instructionOperation.ValuesInstructions.RemoveAt(i); i--; } else { if (subInstruction != null) { instructionOperation.ValuesInstructions.Insert(i, subInstruction); subInstruction = null; } } } if (subInstruction != null) { instructionOperation.ValuesInstructions.Add(subInstruction); } } tokenCount = tokens.Length; return(instructionOperation); }
InstructionResult ExecuteInstructionOperation(Instruction instruction) { InstructionOperation instructionOperation = instruction as InstructionOperation; InstructionResult r = ExecuteInstruction(instructionOperation.ValuesInstructions.First()); Value leftValue = CopyValue(r.Value); for (int i = 0; i < instructionOperation.Operators.Count; i++) { InstructionOperation.OperatorType ope = instructionOperation.Operators[i]; if (ope == InstructionOperation.OperatorType.And && leftValue.BoolValue == false) { break; } if (ope == InstructionOperation.OperatorType.Or && leftValue.BoolValue == true) { break; } r = ExecuteInstruction(instructionOperation.ValuesInstructions[i + 1]); Value rightValue = CopyValue(r.Value); switch (ope) { case InstructionOperation.OperatorType.Addition: if (leftValue.Type == Value.DataType.String && rightValue.Type == Value.DataType.String) { leftValue.StringValue = leftValue.StringValue + rightValue.StringValue; } else if (leftValue.Type == Value.DataType.Numeric && rightValue.Type == Value.DataType.String) { leftValue.StringValue = leftValue.NumericValue.ToString() + rightValue.StringValue; } else if (leftValue.Type == Value.DataType.String && rightValue.Type == Value.DataType.Numeric) { leftValue.StringValue = leftValue.StringValue + rightValue.NumericValue.ToString(); } else if (leftValue.Type == Value.DataType.Numeric) { leftValue.NumericValue = leftValue.NumericValue + rightValue.NumericValue; } break; case InstructionOperation.OperatorType.Substraction: if (leftValue.Type == Value.DataType.Numeric) { leftValue.NumericValue = leftValue.NumericValue - rightValue.NumericValue; } else if (leftValue.Type == Value.DataType.DateTime && rightValue.Type == Value.DataType.DateTime) { leftValue.Type = Value.DataType.TimeSpan; leftValue.TimeSpanValue = leftValue.DateTimeValue - rightValue.DateTimeValue; } break; case InstructionOperation.OperatorType.Multiplication: leftValue.NumericValue = leftValue.NumericValue * rightValue.NumericValue; break; case InstructionOperation.OperatorType.Division: leftValue.NumericValue = leftValue.NumericValue / rightValue.NumericValue; break; case InstructionOperation.OperatorType.Modulo: leftValue.NumericValue = leftValue.NumericValue % rightValue.NumericValue; break; case InstructionOperation.OperatorType.Or: leftValue.BoolValue = leftValue.BoolValue || rightValue.BoolValue; break; case InstructionOperation.OperatorType.And: leftValue.BoolValue = leftValue.BoolValue && rightValue.BoolValue; break; case InstructionOperation.OperatorType.TestEqual: switch (leftValue.Type) { case Value.DataType.String: leftValue.BoolValue = leftValue.StringValue == rightValue.StringValue; break; case Value.DataType.Numeric: leftValue.BoolValue = leftValue.NumericValue == rightValue.NumericValue; break; case Value.DataType.Boolean: leftValue.BoolValue = leftValue.BoolValue == rightValue.BoolValue; break; case Value.DataType.Undefined: leftValue.BoolValue = rightValue.Type == Value.DataType.Undefined; break; } leftValue.Type = Value.DataType.Boolean; break; case InstructionOperation.OperatorType.TestNotEqual: switch (leftValue.Type) { case Value.DataType.String: leftValue.BoolValue = leftValue.StringValue != rightValue.StringValue; break; case Value.DataType.Numeric: leftValue.BoolValue = leftValue.NumericValue != rightValue.NumericValue; break; case Value.DataType.Boolean: leftValue.BoolValue = leftValue.BoolValue != rightValue.BoolValue; break; case Value.DataType.Undefined: leftValue.BoolValue = rightValue.Type != Value.DataType.Undefined; break; } leftValue.Type = Value.DataType.Boolean; break; case InstructionOperation.OperatorType.GreaterThan: leftValue.BoolValue = leftValue.NumericValue > rightValue.NumericValue; leftValue.Type = Value.DataType.Boolean; break; case InstructionOperation.OperatorType.LessThan: leftValue.BoolValue = leftValue.NumericValue < rightValue.NumericValue; leftValue.Type = Value.DataType.Boolean; break; case InstructionOperation.OperatorType.GreaterThanOrEqual: leftValue.BoolValue = leftValue.NumericValue >= rightValue.NumericValue; leftValue.Type = Value.DataType.Boolean; break; case InstructionOperation.OperatorType.LessThanOrEqual: leftValue.BoolValue = leftValue.NumericValue <= rightValue.NumericValue; leftValue.Type = Value.DataType.Boolean; break; } } return(new InstructionResult() { Value = leftValue, Return = true }); }