InstructionResult ExecuteInstructionFor(Instruction instruction) { InstructionFor instructionFor = instruction as InstructionFor; ExecuteInstruction(instructionFor.InitInstruction); while (ExecuteInstruction(instructionFor.TestInstruction).Value.BoolValue) { InstructionResult result = ExecuteBloc(instructionFor.BlocInstruction.ToArray()); if (result != null) { if (result.Return) { return(result); } else if (result.Break) { return(new InstructionResult() { Return = false }); } } ExecuteInstruction(instructionFor.IncrementInstruction); } return(new InstructionResult()); }
InstructionResult ExecuteInstructionFunction(Instruction instruction) { InstructionResult result = new InstructionResult(); InstructionFunction instructionFunction = instruction as InstructionFunction; List <Value> values = new List <Value>(); foreach (var parameter in instructionFunction.Parameters) { Value value = CopyValue(ExecuteInstruction(parameter).Value); values.Add(value); } if (_embededFunctions.ContainsKey(instructionFunction.FunctionName)) { FunctionCallArgs functionCallArgs = new FunctionCallArgs() { Interpreter = this, Name = instructionFunction.FunctionName, Values = values }; result.Value = _embededFunctions[instructionFunction.FunctionName](functionCallArgs); } else { Function previousFunction = _currentFunction; _currentFunction = _program.Functions.FirstOrDefault(f => f.Name == instructionFunction.FunctionName); ThrowExceptionOnCondition(_currentFunction == null, instruction, 30002, new string[] { instructionFunction.FunctionName }); _stack.AddRange(values); int numberOfValueToAdd = _currentFunction.Variables.Count - _currentFunction.ParametersCount; for (int i = 0; i < numberOfValueToAdd; i++) { _stack.Add(new Value()); } result = ExecuteBloc(_currentFunction.Instructions.ToArray()); _stack.RemoveRange(_stack.Count - _currentFunction.Variables.Count, _currentFunction.Variables.Count); _currentFunction = previousFunction; } result.Value = ResolvePath(result.Value, instructionFunction.Path); result.Return = false; return(result); }
public Value Execute() { _globalVariables = new Value[_program.Variables.Count]; for (int i = 0; i < _globalVariables.Length; i++) { _globalVariables[i] = new Value(); } _stack = new List <Value>(); foreach (Instruction instruction in _program.Instructions) { InstructionResult result = null; TryToExecute(() => { result = ExecuteInstruction(instruction); }, 30000, instruction.Line, instruction.Position); if (result != null && result.Return) { return(result.Value); } } return(null); }
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 }); }