예제 #1
0
        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);
        }
예제 #2
0
        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
            });
        }