コード例 #1
0
 private void Run()
 {
     while (ExecutionStack.Count > 0)
     {
         var objectBase = ExecutionStack.Pop();
         if (objectBase is ExecutableName executableName)
         {
             if (!DictionaryStack.ContainsKey(executableName.Value))
             {
                 throw new Exception("Command not found");
             }
             ExecutionStack.Push(DictionaryStack[executableName.Value]);
         }
         else if (objectBase is OperandObject operandObject)
         {
             operandObject.Value();
         }
         else if (objectBase is ProcedureObject procedureObject)
         {
             foreach (var item in procedureObject.Value)
             {
                 ExecutionStack.Push(item);
             }
         }
         else
         {
             OperandStack.Push(objectBase);
         }
     }
 }
コード例 #2
0
        public void PushOneTest()
        {
            DictionaryStack <int, string> dictStack = new DictionaryStack <int, string>();

            try
            {
                dictStack.Push(0, "name1");

                string expectedValue = "name1";
                string actualValue1  = dictStack.Peek();
                string actualValue2  = dictStack[0];
                Assert.IsTrue(expectedValue == actualValue1, $"Peek values did not match. Expected {expectedValue}, actually {actualValue1}");
                Assert.IsTrue(expectedValue == actualValue2, $"Indexing  values did not match. Expected {expectedValue}, actually {actualValue2}");
            }
            catch (Exception e)
            {
                Assert.Fail("Test failed: " + e);
            }
        }
コード例 #3
0
        public Dictionary <string, OperandObject> CreateSystemDictionary()
        {
            var systemDictionary = new Dictionary <string, OperandObject>();

            systemDictionary.Add("gt", new OperandObject(() =>
            {
                var second = OperandStack.Pop() as NumericalObject;
                var first  = OperandStack.Pop() as NumericalObject;
                OperandStack.Push(new BooleanObject(first.Value > second.Value));
            }));

            systemDictionary.Add("ifelse", new OperandObject(() =>
            {
                var third  = OperandStack.Pop() as ProcedureObject;
                var second = OperandStack.Pop() as ProcedureObject;
                var first  = OperandStack.Pop() as BooleanObject;
                ExecutionStack.Push(first.Value ? second : third);
            }));

            systemDictionary.Add("pop", new OperandObject(() =>
            {
                OperandStack.Pop();
            }));

            systemDictionary.Add("exch", new OperandObject(() =>
            {
                var second = OperandStack.Pop();
                var first  = OperandStack.Pop();
                OperandStack.Push(second);
                OperandStack.Push(first);
            }));

            systemDictionary.Add("dup", new OperandObject(() =>
            {
                OperandStack.Push(OperandStack.Top());
            }));

            systemDictionary.Add("copy", new OperandObject(() =>
            {
                var count   = OperandStack.Pop() as NumericalObject;
                var objects = OperandStack.Pop((int)count.Value);
                objects     = objects.Reverse().ToArray();
                OperandStack.Push(objects);
                OperandStack.Push(objects);
                //TODO not accurate to spec
            }));

            systemDictionary.Add("clear", new OperandObject(() =>
            {
                OperandStack.Clear();
            }));

            systemDictionary.Add("count", new OperandObject(() =>
            {
                var item = new NumericalObject(OperandStack.Count);
                OperandStack.Push(item);
            }));

            systemDictionary.Add("def", new OperandObject(() =>
            {
                var first  = OperandStack.Pop() as ProcedureObject;
                var second = OperandStack.Pop() as LiteralName;

                if (DictionaryStack.ContainsKey(second.Value))
                {
                    DictionaryStack[second.Value] = first;
                }
                else
                {
                    DictionaryStack.Add(second.Value, first);
                }
            }));

            systemDictionary.Add("add", new OperandObject(() =>
            {
                var first  = OperandStack.Pop() as NumericalObject;
                var second = OperandStack.Pop() as NumericalObject;
                var result = second.Value + first.Value;
                OperandStack.Push(new NumericalObject(result));
            }));

            systemDictionary.Add("div", new OperandObject(() =>
            {
                var first  = OperandStack.Pop() as NumericalObject;
                var second = OperandStack.Pop() as NumericalObject;
                var result = second.Value / first.Value;
                OperandStack.Push(new NumericalObject(result));
            }));

            systemDictionary.Add("idiv", new OperandObject(() =>
            {
                var first  = OperandStack.Pop() as NumericalObject;
                var second = OperandStack.Pop() as NumericalObject;
                var result = (long)second.Value / (long)first.Value;
                OperandStack.Push(new NumericalObject(result));
            }));

            systemDictionary.Add("mod", new OperandObject(() =>
            {
                var first  = OperandStack.Pop() as NumericalObject;
                var second = OperandStack.Pop() as NumericalObject;
                var result = second.Value % first.Value;
                OperandStack.Push(new NumericalObject(result));
            }));

            systemDictionary.Add("mul", new OperandObject(() =>
            {
                var first  = OperandStack.Pop() as NumericalObject;
                var second = OperandStack.Pop() as NumericalObject;
                var result = second.Value * first.Value;
                OperandStack.Push(new NumericalObject(result));
            }));

            systemDictionary.Add("sub", new OperandObject(() =>
            {
                var first  = OperandStack.Pop() as NumericalObject;
                var second = OperandStack.Pop() as NumericalObject;
                var result = second.Value + first.Value;
                OperandStack.Push(new NumericalObject(result));
            }));

            systemDictionary.Add("abs", new OperandObject(() =>
            {
                var first  = OperandStack.Pop() as NumericalObject;
                var result = Math.Abs(first.Value);
                OperandStack.Push(new NumericalObject(result));
            }));

            systemDictionary.Add("neg", new OperandObject(() =>
            {
                var first  = OperandStack.Pop() as NumericalObject;
                var result = -first.Value;
                OperandStack.Push(new NumericalObject(result));
            }));

            return(systemDictionary);
        }
コード例 #4
0
        private void Parser_OnToken(TokenType tokenType, string value)
        {
            _log.AppendLine($"{tokenType} - {value}");

            try
            {
                if (tokenType == TokenType.Real)
                {
                    OperandStack.Push(new NumericalObject(double.Parse(value)));
                }
                else if (tokenType == TokenType.Integer)
                {
                    OperandStack.Push(new NumericalObject(double.Parse(value)));
                }
                else if (tokenType == TokenType.Name)
                {
                    if (value.StartsWith("//"))
                    {
                        var name = value.Substring(2);
                        if (!DictionaryStack.ContainsKey(name))
                        {
                            throw new Exception($"Key '{name}' not found in DictionaryStack.");
                        }
                        OperandStack.Push(DictionaryStack[name]);
                    }
                    else if (value.StartsWith("/"))
                    {
                        var name = value.Substring(1);
                        OperandStack.Push(new LiteralName(name));
                    }
                    else
                    {
                        OperandStack.Push(new ExecutableName(value));
                    }
                }
                else if (tokenType == TokenType.BeginProcedure)
                {
                    _procedureCount++;
                    OperandStack.Push(new SymbolObject(SymbolEnum.Procedure));
                }
                else if (tokenType == TokenType.EndProcedure)
                {
                    var items = new List <ObjectBase>();
                    while (true)
                    {
                        var currentOperand = OperandStack.Pop();
                        if (currentOperand is SymbolObject symbolObject)
                        {
                            if (symbolObject.Value != SymbolEnum.Procedure)
                            {
                                throw new Exception("Unexpected symbol type");
                            }
                            break;
                        }
                        items.Add(currentOperand);
                    }
                    OperandStack.Push(new ProcedureObject(items.ToArray()));
                    _procedureCount--;
                }
                else if (tokenType == TokenType.BeginArray)
                {
                    OperandStack.Push(new SymbolObject(SymbolEnum.Array));
                }
                else if (tokenType == TokenType.EndArray)
                {
                    var items = new List <ObjectBase>();
                    while (true)
                    {
                        var currentOperand = OperandStack.Pop();
                        if (currentOperand is SymbolObject symbolObject)
                        {
                            if (symbolObject.Value != SymbolEnum.Array)
                            {
                                throw new Exception("Unexpected symbol type");
                            }
                            break;
                        }
                        items.Add(currentOperand);
                    }
                    OperandStack.Push(new ArrayObject(items.ToArray()));
                }
                else if (tokenType == TokenType.BeginDictionary)
                {
                    OperandStack.Push(new SymbolObject(SymbolEnum.Dictionary));
                }
                else if (tokenType == TokenType.EndDictionary)
                {
                    var items = new Dictionary <LiteralName, ObjectBase>();
                    while (true)
                    {
                        var currentOperand = OperandStack.Pop();
                        if (currentOperand is SymbolObject symbolObject)
                        {
                            if (symbolObject.Value != SymbolEnum.Array)
                            {
                                throw new Exception("Unexpected symbol type");
                            }
                            break;
                        }
                        var literal = OperandStack.Pop() as LiteralName;
                        items.Add(literal, currentOperand);
                    }
                    OperandStack.Push(new DictionaryObject(items));
                }

                if (ShouldRun(OperandStack.Top()))
                {
                    ExecutionStack.Push(OperandStack.Pop());
                    Run();
                }
            }
            catch (Exception ex)
            {
                _log.AppendLine($"Exception: {ex}");
                throw;
            }
        }