public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters) { Integer id = parameters[0].Index; Function function = package.Assembly.AllFunctions.Find(p => (Integer)p.UniqueID == id); if (function.IsStatic) { } else { RuntimeOutputCode error; if (!CheckObjectStackItem(package, function.BaseClass, out error)) { return(error); } if (function.IsConstuctor) { package.MemZone.ObjectStackItem.InitClassObject(); } } var result = package.RuntimeMachine.CallFunction(function); if (result != null) { return(result.Code); } return(RuntimeOutputCode.OK); }
public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters) { Field field = package.Assembly.AllFields.Find(p => p.UniqueID == (int)parameters[0].Index); Object obj = GetObject(parameters[1], package); if (obj.Type != field.Type) { return(RuntimeOutputCode.DifferentTypes); } if (field.IsStatic) { field.BaseClass.StaticFields[field.UniqueID] = obj; } else { RuntimeOutputCode error; if (!CheckObjectStackItem(package, field.BaseClass, out error)) { return(error); } package.MemZone.ObjectStackItem.SetClassField(field.UniqueID, obj); } return(RuntimeOutputCode.OK); }
/// <summary> /// Получает числовое значение данного токена, если он является примитивным или значение уже подсчитано /// </summary> private Constant Parse(RuntimeDataPackage package) { if (_valueSet) { return(Value); } if (_referenceSet && Reference.Type == ReferenceType.Define) { return(new Constant(PreprocessorDirective.defines.Exists(p => p.Name == RawValue))); } if (_referenceSet && package != null) { if (Reference.Type == ReferenceType.Variable) { var variable = package.GetVariable(Reference.Index); if (variable.Value.Type.Type != Runtime.Structures.TypeReferenceType.Integer) { throw new Exception("Wrong object type!"); } return(new Constant(variable.Value.IntegerValue)); } else { switch (Reference.Object.Type) { case FlashElementType.Constant: return((Reference.Object as FlashElementConstant).ToConstant()); case FlashElementType.Variable: case FlashElementType.Instruction: case FlashElementType.Expression: case FlashElementType.Undefined: default: throw new Exception("Wrong reference object!"); } } } else { Constant constant; var error = Constant.Parse(RawValue, out constant); if (error != null) { if (error.Type == ParseErrorType.Syntax_Constant_TooLong || error.Type == ParseErrorType.Syntax_Constant_BaseOverflow) { throw new Exception("Wrong const format"); } throw new WrongTokenException(); } else { return(constant); } } }
public Constant GetNumericValue(ObjectReference reference, RuntimeDataPackage package) { switch (reference.Type) { case (ReferenceType.Constant): return(GetConst(reference.Index, package).Constant); case (ReferenceType.Variable): { var var = GetVar(reference.Index, package); if (var.Value.Type.Type != TypeReferenceType.Integer) { return(null); } return(new Constant(var)); } case (ReferenceType.Expression): { Expression expression = package.Expressions.Find(p => p.Index == reference.Index).Expression; Constant constnant = expression.Calculate(package, true); package.RuntimeMachine.Ticks += expression.Steps; return(constnant); } } return(null); }
public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters) { Integer a = GetNumericValue(parameters[0], package).IntValue; Integer b = GetNumericValue(parameters[1], package).IntValue; ComapreResult result = 0; if (a == b) { result |= ComapreResult.Equal; } else { result |= ComapreResult.NotEqual; } if (a > b) { result |= ComapreResult.Greater; } if (a < b) { result |= ComapreResult.Less; } //package.MemZone.Stack.Push(BaseIntegerType.PrimitiveType.Cast((Integer)(int)result)[0]); return(RuntimeOutputCode.OK); }
public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters) { var source = GetNumericValue(parameters[0], package); //package.MemZone.Stack.Push(source.ToPrimitive()[0]); return(RuntimeOutputCode.OK); }
public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters) { Integer position = GetNumericValue(parameters[0], package).IntValue; //RuntimeMachineJump(position, runtimeMachine); return(RuntimeOutputCode.OK); }
/// <summary> /// Расчитывает числовое значение данного выражения /// </summary> /// <returns>Числовое значение выражения</returns> public Constant Calculate(RuntimeDataPackage package = null) { //Пытаемся посчиать его рекурсивно. //Там все ссылочно кладется в токены, так что не нужно ничего возвращать Calculate(package, TokenTree, false); return(TokenTree.Value); }
public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters) { Integer varIndex = parameters[0].Index; package.MemZone.ObjectStackItem = GetVar(varIndex, package).Value; return(RuntimeOutputCode.OK); }
public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters) { var dest = GetVar(parameters[0].Index, package); throw new NotImplementedException(); //dest.Value = memZone.Stack.Pop(); return(RuntimeOutputCode.OK); }
public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters) { var dest = GetVar(parameters[0].Index, package); var source = GetNumericValue(parameters[1], package); throw new NotImplementedException(); //dest.Value = source.Value; return(RuntimeOutputCode.OK); }
public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters) { if (package.CallStackItem.RunningFunction.IsConstuctor) { package.MemZone.ObjectStackItem = package.CallStackItem.Locals[0].Value; //self } package.RuntimeMachine.Return(); return(RuntimeOutputCode.OK); }
public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters) { Integer varIndex = parameters[0].Index; Integer classIndex = parameters[1].Index; TypeReference type = package.Assembly.UsedTypes.Find(p => p.UniqueID == (int)classIndex); package.CallStackItem.Locals.Add(new Variable(type, varIndex)); return(RuntimeOutputCode.OK); }
public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters) { /*ComapreResult result = (ComapreResult)(int)package.MemZone.Stack.Pop(); * * if (result.HasFlag(ComapreResult.Equal)) * { * Integer position = GetNumericValue(parameters[0], package).Value; * * RuntimeMachineJump(position, package.RuntimeMachine); * }*/; return(RuntimeOutputCode.OK); }
public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters) { if (package.CallStackItem.RunningFunction.IsConstuctor) { return(RuntimeOutputCode.ReturnInConstructorsAreNotAllowed); } package.RuntimeMachine.Return(); package.MemZone.ObjectStackItem = GetObject(parameters[0], package); return(RuntimeOutputCode.OK); }
/// <summary> /// Возможно ли расчитать числовое значение данного токена. Если да, то <see cref="Calculate"/> вернет данное значение /// </summary> public bool CanBeCalculated(RuntimeDataPackage package = null) { //Можно посчиатать если: // 1. Значение уже подсчитано // или // 2. Нету дочерных токенов // Если дочерные токены есть, то можно если: // 3. Все значениея дочерных уже подсчиатыны // или // 4. Если ссылки на дочерные установлены // 4.1. И если ссылки - переменные, то если все переменные есть в mz // или // 5. Все дочерные значения примитивные, и их можно подсчитать // // Но подсчитать нельзя если: // Некоторые дочерние токены имеют унарные функции или операторы if (_valueSet) { return(true); } if (Subtokens != null) { bool referenceConditional = true; bool hasRefsToVar = Subtokens.Exists(p => p.Reference != null && p.Reference.Type == ReferenceType.Variable); if (hasRefsToVar) { referenceConditional = package != null && Subtokens .FindAll(p => p.Reference != null && p.Reference.Type == ReferenceType.Variable) .All(p => package.ContainsVarialbe(p.Reference.Index)); } if (!referenceConditional) { return(false); } return((Subtokens.All(p => p._valueSet) || Subtokens.All(p => p.IsSimple)) && (Subtokens.Exists(p => p.UnaryFunction == null) && Subtokens.Exists(p => p.UnaryOperator == null))); } else if (_referenceSet && Reference.Type == ReferenceType.Variable) { return(package != null && package.ContainsVarialbe(Reference.Index)); } else { return(true); } }
public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters) { var dest = GetVar(parameters[0].Index, package); var source = GetNumericValue(parameters[1], package); if (dest.Value.Type.Type != Structures.TypeReferenceType.Integer) { return(RuntimeOutputCode.ExpectedIntegerVariable); } dest.Value.IntegerValue += source.IntValue; return(RuntimeOutputCode.OK); }
/// <summary> /// Расчитывает числовое значение данного выражения /// </summary> /// <param name="clearCache">Стоит ли чистить числовыые значения токенов независящих от переменных</param> /// <param name="isProbe">Указывает на то что данный запуск пробный, и не должен гарантировать получение результата</param> /// <returns>Числовое значение выражения</returns> public Constant Calculate(RuntimeDataPackage package = null, bool clearCache = false, bool isProbe = false) { Steps = 0; //Пытаемся посчиать его рекурсивно. //Там все ссылочно кладется в токены, так что не нужно ничего возвращать Calculate(package, TokenTree, isProbe); var value = TokenTree.Value; //Чистим расчитаные значения для тех токенов, которые зависят от переменных. if (clearCache) { ClearCache(TokenTree); } return(value); }
/// <summary> /// Рекурсивный метод расчета значения токенов /// </summary> /// <param name="token">Токен, который будет расчитываться</param> private void Calculate(RuntimeDataPackage package, Token token, bool isProbe) { //Если токен можно посчитать сходу то делаем это if (token.CanBeCalculated(package)) { token.Calculate(package); Steps += token.Steps; return; } if (token.Subtokens == null) { if (!isProbe) { throw new Exception(); } else { return; } } //Рекурсивно считаем все дочерные токены, вплоть до самых последних, //Которые обязаны считаться! foreach (Token subToken in token.Subtokens) { Calculate(package, subToken, isProbe); Steps += subToken.Steps; } //Если после пересчета возможно посчитать, то считаем if (token.CanBeCalculated(package)) { token.Calculate(package); Steps += token.Steps; return; } //Ну тут уже безысходность if (!isProbe) { throw new Exception(); } }
public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters) { var value = GetNumericValue(parameters[0], package); if (value == null) { return(RuntimeOutputCode.ExpectedIntegerVariable); } if (value.Type == Structures.TypeReferenceType.Integer) { package.RuntimeMachine.OutBytes("stdout", value.ToPrimitiveInt()); } else { package.RuntimeMachine.OutBytes("stdout", value.ToPrimitiveArray()); } return(RuntimeOutputCode.OK); }
public Object GetObject(ObjectReference reference, RuntimeDataPackage package) { switch (reference.Type) { case ReferenceType.Variable: return(GetVar(reference.Index, package).Value); case ReferenceType.Constant: case ReferenceType.Expression: return(new Object(GetNumericValue(reference, package).IntValue, package.Assembly)); case ReferenceType.Define: case ReferenceType.Type: case ReferenceType.Function: case ReferenceType.Field: default: return(null); } }
public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters) { Integer varIndex = parameters[0].Index; var variable = GetVar(varIndex, package); if (package.MemZone.ObjectStackItem == null) { return(RuntimeOutputCode.ObjectStackIsEmpty); } if (package.MemZone.ObjectStackItem.Type != variable.Value.Type) { return(RuntimeOutputCode.DifferentTypes); } variable.Value = package.MemZone.ObjectStackItem; return(RuntimeOutputCode.OK); }
public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters) { Field field = package.Assembly.AllFields.Find(p => p.UniqueID == (int)parameters[0].Index); if (field.IsStatic) { package.MemZone.ObjectStackItem = field.BaseClass.StaticFields[field.UniqueID]; } else { RuntimeOutputCode error; if (!CheckObjectStackItem(package, field.BaseClass, out error)) { return(error); } package.MemZone.ObjectStackItem = package.MemZone.ObjectStackItem.GetClassField(field.UniqueID); } return(RuntimeOutputCode.OK); }
protected bool CheckObjectStackItem(RuntimeDataPackage package, Class baseClass, out RuntimeOutputCode error) { if (package.MemZone.ObjectStackItem == null) { error = RuntimeOutputCode.ObjectStackIsEmpty; return(false); } if (package.MemZone.ObjectStackItem.Type.Type != TypeReferenceType.Class) { error = RuntimeOutputCode.ClassTypeExpected; return(false); } if (package.MemZone.ObjectStackItem.Type.ClassType != baseClass) { error = RuntimeOutputCode.DifferentClasses; return(false); } error = RuntimeOutputCode.OK; return(true); }
public abstract RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters);
public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters) { package.MemZone.ParamStack.Push(GetObject(parameters[0], package)); return(RuntimeOutputCode.OK); }
protected Variable GetVar(Integer index, RuntimeDataPackage package) { return(package.GetVariable(index)); }
public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters) { return(RuntimeOutputCode.OK); }
protected ConstantMark GetConst(Integer index, RuntimeDataPackage package) { return(package.Constants[(int)index]); }
/// <summary> /// Расчитывает числовое значение данного токена. Возможно только в случае если <see cref="CanBeCalculated"/> <see cref="true"/> /// </summary> /// <returns></returns> public Constant Calculate(RuntimeDataPackage package) { Steps = 0; if (_valueSet) { return(Value); } if (IsSimple) { CalculateValue(Parse(package), this); _valueSet = true; return(Value); } //1. Найти пару с найбольшим приоритетом //2. Удалить ее, заменив ее решением //Посторять 1-2 пункты пока не останится последний токен //3. Применить унарный оператор //Создаем копию саб токенов. Нам не нужно портить изначальный массив. var subTokens = Subtokens.Select(p => (Token)p.Clone()).ToList(); while (subTokens.Count != 1) { //Индексы в массиве операнов при самом приоритетном операторе int maxLeftIndex = -1; int maxRightIndex = -1; //Приоритет самого приоритетного оператора int maxPriority = 0; //Самый приоритетный оператор Operator op = null; //Ищем оператор for (int i = 0; i < subTokens.Count; i++) { //Ищем по левому, бикоз вай нот if (subTokens[i].LeftSideOperator != null) { if (subTokens[i].LeftSideOperator.Priority > maxPriority) { //Запоминаем наши индексы и прочее maxLeftIndex = i - 1; maxRightIndex = i; maxPriority = subTokens[i].LeftSideOperator.Priority; op = subTokens[i].LeftSideOperator; } } } //Хз, можно убрать наверное /*if (!subTokens[maxLeftIndex].IsPrimitive) * throw new Exception("Token must be primitive"); * * if (!subTokens[maxRightIndex].IsPrimitive) * throw new Exception("Token must be primitive");*/ //Получаем числовые значение //Учитываем, что операнды могут иметь свои унарные операции и функции. //Их приоритет всегда выше бинарных, потому сразу выполняем их CalculateValue(subTokens[maxLeftIndex].Parse(package), subTokens[maxLeftIndex]); CalculateValue(subTokens[maxRightIndex].Parse(package), subTokens[maxRightIndex]); var value = op.BinaryFunc(subTokens[maxLeftIndex].Value, subTokens[maxRightIndex].Value); Steps += op.OperatorSteps; //Дебага ради создаем новое строковое значение var newRawValue = value.ToString(); //Важно грамотно сохранить левые и правые токены var newToken = new Token(newRawValue) { LeftSideOperator = subTokens[maxLeftIndex].LeftSideOperator, LeftSideToken = subTokens[maxLeftIndex].LeftSideToken, RightSideOperator = subTokens[maxRightIndex].RightSideOperator, RightSideToken = subTokens[maxRightIndex].RightSideToken, Value = value, _valueSet = true }; //Подставляем в существующие токены наш новы if (maxLeftIndex - 1 >= 0) { subTokens[maxLeftIndex - 1].RightSideToken = newToken; } if (maxRightIndex + 1 < subTokens.Count) { subTokens[maxRightIndex + 1].LeftSideToken = newToken; } //Удаляем 2 старых subTokens.RemoveAt(maxRightIndex); subTokens.RemoveAt(maxLeftIndex); //Заменяя его на новый subTokens.Insert(maxLeftIndex, newToken); } CalculateValue(subTokens[0].Value, this); return(Value); }