Exemple #1
0
        static void Main(string[] args)
        {
            CommandsResolver commands = new CommandsResolver();

            CalculatorCommands.Register(commands);
            CalculatorCommands.RegisterConstants(commands);

            Stack <double> stack = new Stack <double>();

            AssemblyName asm = typeof(Program).Assembly.GetName();

            bool cont = true;

            Console.WriteLine($"{asm.Name} {asm.Version}, by Bytewave");
            Console.WriteLine();
            Console.WriteLine("h/help for help");
            Console.WriteLine();

            while (cont)
            {
                string input = Prompt();

                if (Double.TryParse(input, out double inputNumber))
                {
                    if (Double.IsNaN(inputNumber))
                    {
                        Console.Error.WriteLine("Invalid number.");
                    }
                    else
                    {
                        stack.Push(inputNumber);
                    }
                }
                else
                {
                    Func <Stack <double>, Stack <double> > resolvedCommand = commands.ResolveCommand(input);

                    if (resolvedCommand == null)
                    {
                        Console.Error.WriteLine($"{input} is not a command, constant, or valid number.");
                    }
                    else
                    {
                        stack = resolvedCommand(stack);

                        if (stack == null)
                        {
                            cont = false;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Reigsters the commands for RPNCalc.
        /// </summary>
        /// <param name="commands">The current CommandsResolver object.</param>
        public static void Register(CommandsResolver commands)
        {
            commands.RegisterCommand("rot", "r", (stack) => {
                if (stack.Count < 2)
                {
                    Console.Error.WriteLine("Not enough elements to rotate stack.");
                    return(stack);
                }

                Stack <double> newStack = new Stack <double>();

                newStack.Push(stack.Pop());

                foreach (double num in stack.Reverse())
                {
                    newStack.Push(num);
                }

                return(newStack);
            });

            commands.RegisterCommand("swp", "s", (stack) => {
                if (stack.Count < 2)
                {
                    Console.Error.WriteLine("Cannot swap items without 2 items to swap.");
                    return(stack);
                }

                double[] nums = GetOperands(stack);

                stack.Push(nums[1]);
                stack.Push(nums[0]);

                return(stack);
            });

            commands.RegisterCommand("dup", "d", (stack) => {
                if (stack.Count < 1)
                {
                    Console.Error.WriteLine("Cannot duplicate items from an empty stack.");
                    return(stack);
                }

                stack.Push(stack.Peek());

                return(stack);
            });

            commands.RegisterCommand("print", "p", (stack) => {
                if (stack.Count == 0)
                {
                    Console.WriteLine("Empty stack.");
                    return(stack);
                }

                int counter = stack.Count - 1;

                foreach (double num in stack.Reverse())
                {
                    Console.WriteLine($"{counter} : {num:0.##########}");
                    counter--;
                }

                return(stack);
            });

            commands.RegisterCommand("pop", "x", (stack) => {
                if (stack.Count == 0)
                {
                    Console.Error.WriteLine("Cannot pop from an empty stack.");
                    return(stack);
                }

                stack.Pop();

                return(stack);
            });

            commands.RegisterCommand("clear", "c", (stack) => {
                stack.Clear();

                return(stack);
            });

            commands.RegisterCommand("add", "+", (stack) => {
                double[] nums = GetOperands(stack);

                if (nums == null)
                {
                    return(stack);
                }

                stack.Push(nums[0] + nums[1]);

                return(stack);
            });

            commands.RegisterCommand("mul", "*", (stack) => {
                double[] nums = GetOperands(stack);

                if (nums == null)
                {
                    return(stack);
                }

                stack.Push(nums[0] * nums[1]);

                return(stack);
            });

            commands.RegisterCommand("sub", "-", (stack) => {
                double[] nums = GetOperands(stack);

                if (nums == null)
                {
                    return(stack);
                }

                stack.Push(nums[0] - nums[1]);

                return(stack);
            });

            commands.RegisterCommand("div", "/", (stack) => {
                double[] nums = GetOperands(stack);

                if (nums == null)
                {
                    return(stack);
                }

                stack.Push(nums[0] / nums[1]);

                return(stack);
            });

            commands.RegisterCommand("pow", "^", (stack) => {
                double[] nums = GetOperands(stack);

                if (nums == null)
                {
                    return(stack);
                }

                stack.Push(Math.Pow(nums[0], nums[1]));

                return(stack);
            });

            commands.RegisterCommand("sin", (stack) => {
                double[] nums = GetOperands(stack, 1);

                if (nums == null)
                {
                    return(stack);
                }

                stack.Push(Math.Sin(nums[0]));

                return(stack);
            });

            commands.RegisterCommand("cos", (stack) => {
                double[] nums = GetOperands(stack, 1);

                if (nums == null)
                {
                    return(stack);
                }

                stack.Push(Math.Cos(nums[0]));

                return(stack);
            });

            commands.RegisterCommand("tan", (stack) => {
                double[] nums = GetOperands(stack, 1);

                if (nums == null)
                {
                    return(stack);
                }

                stack.Push(Math.Tan(nums[0]));

                return(stack);
            });

            commands.RegisterCommand("cls", "z", (stack) => {
                try {
                    Console.Clear();
                } catch {
                    Console.WriteLine("cls is not supported here");
                }

                return(stack);
            });

            commands.RegisterCommand("log10", "log", (stack) => {
                double[] nums = GetOperands(stack, 1);

                if (nums == null)
                {
                    return(stack);
                }

                stack.Push(Math.Log10(nums[0]));

                return(stack);
            });

            commands.RegisterCommand("loge", "ln", (stack) => {
                double[] nums = GetOperands(stack, 1);

                if (nums == null)
                {
                    return(stack);
                }

                stack.Push(Math.Log(nums[0]));

                return(stack);
            });

            commands.RegisterCommand("logbase", "lb", (stack) => {
                double[] nums = GetOperands(stack, 2);

                if (nums == null)
                {
                    return(stack);
                }

                stack.Push(Math.Log(nums[1], nums[0]));

                return(stack);
            });

            commands.RegisterCommand("help", "h", (stack) => {
                Console.WriteLine("STACK OPERATIONS");
                Console.WriteLine("[number] - push a number onto the stack");
                Console.WriteLine("rot, r - rotate the stack (pop top off, move to bottom)");
                Console.WriteLine("swp, s - swap the top two elements on the stack");
                Console.WriteLine("dup, d - duplicate the top number on the stack");
                Console.WriteLine("print, p - show the current stack contents");
                Console.WriteLine("pop, x - pop the last element off the stack");
                Console.WriteLine("clear, c - clear the stack");
                Console.WriteLine();
                Console.WriteLine("ARITHMETIC AND FUNCTIONS");
                Console.WriteLine("mul, * - multiply the top two numbers on the stack; push result");
                Console.WriteLine("add, + - add the top two numbers on the stack");
                Console.WriteLine("div, / - divide the top two numbers (1 / 0)");
                Console.WriteLine("sub, - - subtract the top two numbers (1 - 0)");
                Console.WriteLine("pow, ^ - raise the second top number to the top number (1 ^ 0)");
                Console.WriteLine("sin, cos, tan - trig functions");
                Console.WriteLine("log10, log - take the log base 10 of the top number");
                Console.WriteLine("loge, ln - take the natural log of the top number");
                Console.WriteLine("logbase, lb - take the log base (1) of (0)");
                Console.WriteLine();
                Console.WriteLine("CALCULATOR COMMANDS");
                Console.WriteLine("cls, z - clear the screen");
                Console.WriteLine("help, h - show this help");
                Console.WriteLine("exit - exit the calculator");
                Console.WriteLine();
                Console.WriteLine("CONSTANTS");
                Console.WriteLine("pi, e");

                return(stack);
            });

            commands.RegisterCommand("exit", (stack) => {
                return(null);
            });
        }
 /// <summary>
 /// Registers the constants used in RPNCalc.
 /// </summary>
 /// <param name="commands">The current CommandsResolver object.</param>
 public static void RegisterConstants(CommandsResolver commands)
 {
     commands.RegisterConstant("pi", Math.PI);
     commands.RegisterConstant("e", Math.E);
 }