Esempio n. 1
0
        /// <summary>
        /// Adds a variable to the global directory.
        /// Called when a new variable ID is read in global scope.
        /// </summary>
        /// <param name="newGlobalVariable"></param>
        /// <returns>The variable address in the global directory where the variable was stored.</returns>
        public static int AddGlobalVariable(Variable newGlobalVariable)
        {
            // retrieve the memory address where the variable will live
            int memorySpace = GetNextAvailable(MemoryScope.global, newGlobalVariable.GetDataType());

            // if memory space is insufficient, throw and exception
            if (memorySpace == -1)
            {
                throw new Exception("Out of global memory");
            }

            // pass on the memory address meant for the variable
            newGlobalVariable.SetMemoryAddress(memorySpace);

            // try to add variable to global directory
            try
            {
                FunctionDirectory.GlobalFunction().AddGlobalVariable(newGlobalVariable);
                if (newGlobalVariable.GetDataType() == SemanticCubeUtilities.DataTypes.number)
                {
                    try { memorySpace = SetMemory(memorySpace, 0); }
                    catch (Exception e) { throw new Exception(e.Message); }
                }
                else if (newGlobalVariable.GetDataType() == SemanticCubeUtilities.DataTypes.text)
                {
                    try { memorySpace = SetMemory(memorySpace, ""); }
                    catch (Exception e) { throw new Exception(e.Message); }
                }
                else if (newGlobalVariable.GetDataType() == SemanticCubeUtilities.DataTypes.boolean)
                {
                    try { memorySpace = SetMemory(memorySpace, false); }
                    catch (Exception e) { throw new Exception(e.Message); }
                }
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
            return(memorySpace);
        }
Esempio n. 2
0
        /// <summary>
        /// Loads an asset into memory.
        /// Called by <see cref="Parser"/> when an Asset is read.
        /// </summary>
        /// <param name="memoryAddress"></param>
        /// <param name="asset"></param>
        /// <returns>The memory address where the asset was set.</returns>
        public static int SetAssetInMemory(Asset asset)
        {
            int memoryAddress = GetNextAssetAvailable();

            if (memoryAddress == -1)
            {
                throw new Exception("Out of asset memory");
            }
            asset.SetMemoryAddress(memoryAddress);

            // try to add asset to global asset directory
            try
            {
                if (currentAssetAddress + Enum.GetNames(typeof(AssetAttributes)).Length <= highestAssetAddress)
                {
                    FunctionDirectory.GlobalFunction().AddAssetVariable(asset);

                    // add attribute values to memory
                    memoryGlobalAssets[memoryAddress + (int)AssetAttributes.id]       = asset.GetID();
                    memoryGlobalAssets[memoryAddress + (int)AssetAttributes.x]        = asset.GetX();
                    memoryGlobalAssets[memoryAddress + (int)AssetAttributes.y]        = asset.GetY();
                    memoryGlobalAssets[memoryAddress + (int)AssetAttributes.width]    = asset.GetWidth();
                    memoryGlobalAssets[memoryAddress + (int)AssetAttributes.height]   = asset.GetHeight();
                    memoryGlobalAssets[memoryAddress + (int)AssetAttributes.rotation] = asset.GetRotation();
                    memoryGlobalAssets[memoryAddress + (int)AssetAttributes.number]   = asset.GetNumber();
                    memoryGlobalAssets[memoryAddress + (int)AssetAttributes.label]    = asset.GetLabel();

                    currentAssetAddress += Enum.GetNames(typeof(AssetAttributes)).Length;
                }

                return(memoryAddress);
            }
            catch (Exception)
            {
                throw;
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Executes the instruction at position currentInstruction.
        /// For instructions that involve animations, the animation is awaited until completed.
        /// </summary>
        private static async Task ExecuteInstruction()
        {
            Quadruple quadruple = quadruples[currentInstruction];

            Utilities.QuadrupleAction action = quadruple.GetAction();

            if (action == Utilities.QuadrupleAction.plus)
            {
                int num1 = (int)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandOne()));
                int num2 = (int)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandTwo()));

                int result = num1 + num2;

                MemoryManager.SetMemory(MapAddressToLocalMemory(quadruple.GetAssignee()), result);
            }
            else if (action == Utilities.QuadrupleAction.minus)
            {
                int num1 = (int)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandOne()));
                int num2 = (int)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandTwo()));

                int result = num1 - num2;

                MemoryManager.SetMemory(MapAddressToLocalMemory(quadruple.GetAssignee()), result);
            }
            else if (action == Utilities.QuadrupleAction.multiply)
            {
                int num1 = (int)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandOne()));
                int num2 = (int)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandTwo()));

                int result = num1 * num2;

                MemoryManager.SetMemory(MapAddressToLocalMemory(quadruple.GetAssignee()), result);
            }
            else if (action == Utilities.QuadrupleAction.negative)
            {
                int numMemAddress = quadruple.GetOperandOne();
                int num1          = (int)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(numMemAddress));
                if (numMemAddress < MemoryManager.lowestConstantIntAddress)
                {
                    num1 *= -1;
                }

                MemoryManager.SetMemory(MapAddressToLocalMemory(quadruple.GetAssignee()), num1);
            }
            else if (action == Utilities.QuadrupleAction.divide)
            {
                int num1 = (int)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandOne()));
                int num2 = (int)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandTwo()));

                if (num2 == 0)
                {
                    throw new DivideByZeroException();
                }

                int result = num1 / num2;

                MemoryManager.SetMemory(MapAddressToLocalMemory(quadruple.GetAssignee()), result);
            }
            else if (action == Utilities.QuadrupleAction.greaterThan)
            {
                int num1 = (int)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandOne()));
                int num2 = (int)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandTwo()));

                bool result = num1 > num2;

                MemoryManager.SetMemory(MapAddressToLocalMemory(quadruple.GetAssignee()), result);
            }
            else if (action == Utilities.QuadrupleAction.lessThan)
            {
                int num1 = (int)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandOne()));
                int num2 = (int)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandTwo()));

                bool result = num1 < num2;

                MemoryManager.SetMemory(MapAddressToLocalMemory(quadruple.GetAssignee()), result);
            }
            else if (action == Utilities.QuadrupleAction.greaterThanOrEqualTo)
            {
                int num1 = (int)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandOne()));
                int num2 = (int)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandTwo()));

                bool result = num1 >= num2;

                MemoryManager.SetMemory(MapAddressToLocalMemory(quadruple.GetAssignee()), result);
            }
            else if (action == Utilities.QuadrupleAction.lessThanOrEqualTo)
            {
                int num1 = (int)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandOne()));
                int num2 = (int)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandTwo()));

                bool result = num1 <= num2;

                MemoryManager.SetMemory(MapAddressToLocalMemory(quadruple.GetAssignee()), result);
            }
            else if (action == Utilities.QuadrupleAction.equalEqual)
            {
                var num1 = MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandOne()));
                var num2 = MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandTwo()));

                bool result = ((IComparable)num1).CompareTo((IComparable)num2) == 0;

                MemoryManager.SetMemory(MapAddressToLocalMemory(quadruple.GetAssignee()), result);
            }
            else if (action == Utilities.QuadrupleAction.notEqual)
            {
                var num1 = MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandOne()));
                var num2 = MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandTwo()));

                bool result = ((IComparable)num1).CompareTo((IComparable)num2) != 0;

                MemoryManager.SetMemory(MapAddressToLocalMemory(quadruple.GetAssignee()), result);
            }
            else if (action == Utilities.QuadrupleAction.and)
            {
                bool cond1 = (bool)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandOne()));
                bool cond2 = (bool)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandTwo()));

                bool result = cond1 && cond2;

                MemoryManager.SetMemory(MapAddressToLocalMemory(quadruple.GetAssignee()), result);
            }
            else if (action == Utilities.QuadrupleAction.or)
            {
                bool cond1 = (bool)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandOne()));
                bool cond2 = (bool)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandTwo()));

                bool result = cond1 || cond2;

                MemoryManager.SetMemory(MapAddressToLocalMemory(quadruple.GetAssignee()), result);
            }
            else if (action == Utilities.QuadrupleAction.equals)
            {
                int    cc            = currentInstruction;
                int    targetAddress = quadruple.GetAssignee();
                object value         = MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandOne()));
                if (targetAddress < 1000) // assignment was to an asset attribute
                {
                    int    assetAttributesCount = Enum.GetNames(typeof(MemoryManager.AssetAttributes)).Length;
                    string assetID = (string)MemoryManager.GetValueFromAddress(targetAddress - (targetAddress % assetAttributesCount));
                    Asset  caller  = Utilities.FindAssetFromID(assetID);

                    if (targetAddress % assetAttributesCount == (int)MemoryManager.AssetAttributes.width)
                    {
                        await caller.SetWidth((int)value);
                    }
                    else if (targetAddress % assetAttributesCount == (int)MemoryManager.AssetAttributes.height)
                    {
                        await caller.SetHeight((int)value);
                    }
                    else if (targetAddress % assetAttributesCount == (int)MemoryManager.AssetAttributes.x)
                    {
                        await caller.SetPositionXAttribute((int)value);
                    }
                    else if (targetAddress % assetAttributesCount == (int)MemoryManager.AssetAttributes.y)
                    {
                        await caller.SetPositionYAttribute((int)value);
                    }
                    else if (targetAddress % assetAttributesCount == (int)MemoryManager.AssetAttributes.number)
                    {
                        await caller.SetNumber((int)value);
                    }
                    else if (targetAddress % assetAttributesCount == (int)MemoryManager.AssetAttributes.label)
                    {
                        await caller.SetLabel((string)value);
                    }
                }

                MemoryManager.SetMemory(MapAddressToLocalMemory(quadruple.GetAssignee()), value);
            }
            else if (action == Utilities.QuadrupleAction.Goto)
            {
                currentInstruction = quadruple.GetAssignee();
            }
            else if (action == Utilities.QuadrupleAction.GotoV)
            {
                if ((bool)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandOne())))
                {
                    currentInstruction = quadruple.GetAssignee();
                }
            }
            else if (action == Utilities.QuadrupleAction.GotoF)
            {
                if (!((bool)MemoryManager.GetValueFromAddress(MapAddressToLocalMemory(quadruple.GetOperandOne()))))
                {
                    currentInstruction = quadruple.GetAssignee();
                }
            }
            else if (action == Utilities.QuadrupleAction.era)
            {
                int functionSize       = quadruple.GetOperandOne();
                int functionMemAddress = quadruple.GetOperandTwo();

                LastFunctionCalled.Push(FunctionDirectory.GetFunctionWithAddress(functionMemAddress));

                // Indicates the address in local memory where the function is loaded.
                int functionAddressInMemory = MemoryManager.AllocateLocalMemory(LastFunctionCalled.Peek()); // this can throw - but VM caller will catch it
                funcToAdd.Push(new Tuple <string, int>(LastFunctionCalled.Peek().GetName(), functionAddressInMemory));
            }
            else if (action == Utilities.QuadrupleAction.param)
            {
                int paramValueAddress = MapAddressToLocalMemory(quadruple.GetOperandOne());

                int paramIndex = quadruple.GetAssignee();
                int pAddr      = FunctionDirectory.GetFunction(funcToAdd.Peek().Item1).GetParameters()[paramIndex].GetMemoryAddress();

                CallStack.Push(funcToAdd.Peek());

                int destinationAddress = MapAddressToLocalMemory(pAddr);

                CallStack.Pop();

                MemoryManager.SetMemory(destinationAddress, MemoryManager.GetValueFromAddress(paramValueAddress));
            }
            else if (action == Utilities.QuadrupleAction.gosub)
            {
                savedInstructionPointer.Push(currentInstruction + 1);
                currentInstruction = quadruple.GetOperandOne();

                CallStack.Push(funcToAdd.Peek());
                LastFunctionCalled.Pop();
                funcToAdd.Pop();
            }
            else if (action == Utilities.QuadrupleAction.retorno)
            {
                int localResultValueAddress       = MapAddressToLocalMemory(quadruple.GetOperandOne());
                int functionAddressInGlobalMemory = quadruple.GetAssignee();

                object resultValue = MemoryManager.GetValueFromAddress(localResultValueAddress);

                // save result in global memory
                try { MemoryManager.SetMemory(functionAddressInGlobalMemory, resultValue); }
                catch (Exception e) { throw new Exception(e.Message); }

                currentInstruction = savedInstructionPointer.Pop();

                if (CallStack.Count == 0)
                {
                    throw new Exception("Call stack is empty.");
                }

                MemoryManager.DeallocateLocalMemory(FunctionDirectory.GetFunction(CallStack.Pop().Item1).GetFunctionSize());
            }
            else if (action == Utilities.QuadrupleAction.endProc)
            {
                currentInstruction = savedInstructionPointer.Pop();

                if (CallStack.Count == 0)
                {
                    throw new Exception("Call stack is empty.");
                }

                MemoryManager.DeallocateLocalMemory(FunctionDirectory.GetFunction(CallStack.Pop().Item1).GetFunctionSize());
                throw new Exception("Function codepath did not contain return statement.");
            }
            else if (action == Utilities.QuadrupleAction.set_position)
            {
                string assetID = (string)MemoryManager.GetValueFromAddress(quadruple.GetOperandOne());
                Asset  caller  = Utilities.FindAssetFromID(assetID);

                int x = (int)MemoryManager.GetValueFromAddress(quadruple.GetOperandTwo());
                int y = (int)MemoryManager.GetValueFromAddress(quadruple.GetAssignee());

                await caller.SetPosition(x, y);

                int xAttrAddress = quadruple.GetOperandOne() + (int)MemoryManager.AssetAttributes.x;
                MemoryManager.SetMemory(xAttrAddress, x);

                int yAttrAddress = quadruple.GetOperandOne() + (int)MemoryManager.AssetAttributes.y;
                MemoryManager.SetMemory(yAttrAddress, y);
            }
            else if (action == Utilities.QuadrupleAction.move_x)
            {
                string assetID = (string)MemoryManager.GetValueFromAddress(quadruple.GetOperandOne());
                Asset  caller  = Utilities.FindAssetFromID(assetID);

                int displacement = (int)MemoryManager.GetValueFromAddress(quadruple.GetOperandTwo());

                await caller.MoveX(displacement);

                int xAttrAddress = quadruple.GetOperandOne() + (int)MemoryManager.AssetAttributes.x;
                MemoryManager.SetMemory(xAttrAddress, (int)MemoryManager.GetValueFromAddress(xAttrAddress) + displacement);
            }
            else if (action == Utilities.QuadrupleAction.move_y)
            {
                string assetID = (string)MemoryManager.GetValueFromAddress(quadruple.GetOperandOne());
                Asset  caller  = Utilities.FindAssetFromID(assetID);

                int displacement = (int)MemoryManager.GetValueFromAddress(quadruple.GetOperandTwo());

                await caller.MoveY(displacement);

                int yAttrAddress = quadruple.GetOperandOne() + (int)MemoryManager.AssetAttributes.y;
                MemoryManager.SetMemory(yAttrAddress, (int)MemoryManager.GetValueFromAddress(yAttrAddress) + displacement);
            }
            else if (action == Utilities.QuadrupleAction.spin)
            {
                string assetID = (string)MemoryManager.GetValueFromAddress(quadruple.GetOperandOne());
                Asset  caller  = Utilities.FindAssetFromID(assetID);

                await caller.Spin();
            }
            else if (action == Utilities.QuadrupleAction.rotate)
            {
                string assetID = (string)MemoryManager.GetValueFromAddress(quadruple.GetOperandOne());
                Asset  caller  = Utilities.FindAssetFromID(assetID);

                int degrees = (int)MemoryManager.GetValueFromAddress(quadruple.GetOperandTwo());

                await caller.Turn(degrees);

                int rotationAttrAddress = quadruple.GetOperandOne() + (int)MemoryManager.AssetAttributes.rotation;
                MemoryManager.SetMemory(rotationAttrAddress, ((int)MemoryManager.GetValueFromAddress(rotationAttrAddress) + degrees) % 360);
            }
            else if (action == Utilities.QuadrupleAction.stop)
            {
                // Go to the end of execution
                currentInstruction = quadruples.Count - 1;
            }
            else if (action == Utilities.QuadrupleAction.end)
            {
                // Finish execution
                endExecution = true;
            }
            else
            {
                throw new Exception("Invalid quadruple action: " + action.ToString());
            }
        }
Esempio n. 4
0
        /// <summary>
        /// This event is invoked when the user clicks the Compile button.
        /// The function prepares to compile by resetting all necessary values back
        /// to default and then begins compilation.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CompileButton_Click(object sender, RoutedEventArgs e)
        {
            Utilities.linesOfCodeCount = 0;
            Utilities.linesOfCode      = new List <CodeLine>();
            ErrorPrinter.errorCount    = 0;
            ErrorPrinter.errorList     = new Dictionary <int, List <string> >();
            FunctionDirectory.Reset();
            MemoryManager.Reset();
            QuadrupleManager.Reset();
            UserControl main = new UserControl();

            ///*
            Utilities.BlockToLineErrors.Clear();
            BlocksWithErrorsInOrder.Clear();
            Utilities.errorsInLines.Clear();

            AssetListViewContainer.PrintCode();
            VariableListViewContainer.PrintCode();
            FunctionListViewContainer.PrintCode();

            Utilities.linesOfCode.Add(new CodeLine("instructions {", main, Utilities.linesOfCodeCount + 1));
            Utilities.linesOfCodeCount++;

            InstructionListViewContainer.PrintCode();

            Utilities.linesOfCode.Add(new CodeLine("}", main, Utilities.linesOfCodeCount + 1));
            Utilities.linesOfCodeCount++;

            WriteCodeToFile(out string filePath);
            //*/

            /*
             * string directoryPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "MarblesOutput");
             * Directory.CreateDirectory(directoryPath);
             * string filePath = Path.Combine(directoryPath, "testMarblesCode2.txt");
             */

            AnalyzeCode(filePath);

            MemoryManager.PrintMemory();
            QuadrupleManager.PrintQuadruples();

            Debug.WriteLine(ErrorPrinter.errorCount + " error(s) found.");
            ErrorPrinter.PrintErrors();

            if (ErrorPrinter.errorCount == 0)
            {
                Utilities.GreenCompile();
                Utilities.EnableRunButton();
                CompileButton.Background = Utilities.CompileButtonColor;
                CompileButton.IsEnabled  = Utilities.CompileButtonEnabled;
            }
            else
            {
                Utilities.RedCompile();
                Utilities.DisableRunButton();

                FillErrorsDictionary();
                SetErrorsInUI();

                CompileButton.Background = Utilities.CompileButtonColor;
                CompileButton.IsEnabled  = Utilities.CompileButtonEnabled;
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Retrieves the offset we try to access in local memory.
        /// Called by <see cref="VirtualMachine.MapAddressToLocalMemory(int)"/>.
        /// </summary>
        /// <param name="functionId"></param>
        /// <param name="address"></param>
        /// <returns>The memory address of an object in local memory.</returns>
        public static int FunctionMemoryToMemoryManager(string functionId, int address)
        {
            Function currentFunctionInCallStack = FunctionDirectory.GetFunction(functionId);

            return(currentFunctionInCallStack.memory.GetIndexFromMemoryList(address));
        }