예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
파일: Token.cs 프로젝트: Coestaris/hasm
        /// <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);
                }
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters)
        {
            Integer position = GetNumericValue(parameters[0], package).IntValue;

            //RuntimeMachineJump(position, runtimeMachine);

            return(RuntimeOutputCode.OK);
        }
예제 #8
0
        /// <summary>
        /// Расчитывает числовое значение данного выражения
        /// </summary>
        /// <returns>Числовое значение выражения</returns>
        public Constant Calculate(RuntimeDataPackage package = null)
        {
            //Пытаемся посчиать его рекурсивно.
            //Там все ссылочно кладется в токены, так что не нужно ничего возвращать
            Calculate(package, TokenTree, false);

            return(TokenTree.Value);
        }
예제 #9
0
        public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters)
        {
            Integer varIndex = parameters[0].Index;

            package.MemZone.ObjectStackItem = GetVar(varIndex, package).Value;

            return(RuntimeOutputCode.OK);
        }
예제 #10
0
        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);
        }
예제 #11
0
        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);
        }
예제 #12
0
        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);
        }
예제 #13
0
        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);
        }
예제 #14
0
        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);
        }
예제 #15
0
        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);
        }
예제 #16
0
파일: Token.cs 프로젝트: Coestaris/hasm
        /// <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);
            }
        }
예제 #17
0
        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);
        }
예제 #18
0
        /// <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);
        }
예제 #19
0
        /// <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();
            }
        }
예제 #20
0
        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);
        }
예제 #21
0
        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);
            }
        }
예제 #22
0
        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);
        }
예제 #23
0
        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);
        }
예제 #24
0
        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);
        }
예제 #25
0
 public abstract RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters);
예제 #26
0
        public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters)
        {
            package.MemZone.ParamStack.Push(GetObject(parameters[0], package));

            return(RuntimeOutputCode.OK);
        }
예제 #27
0
 protected Variable GetVar(Integer index, RuntimeDataPackage package)
 {
     return(package.GetVariable(index));
 }
예제 #28
0
 public override RuntimeOutputCode Apply(RuntimeDataPackage package, List <ObjectReference> parameters)
 {
     return(RuntimeOutputCode.OK);
 }
예제 #29
0
 protected ConstantMark GetConst(Integer index, RuntimeDataPackage package)
 {
     return(package.Constants[(int)index]);
 }
예제 #30
0
파일: Token.cs 프로젝트: Coestaris/hasm
        /// <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);
        }