示例#1
0
        public override bool Equals(object o)
        {
            if (o.GetType() != GetType())
            {
                return(false);
            }
            ExtendedChar other = (ExtendedChar)o;

            return((Number != null && other.Number != null) ? Number == other.Number : Value == other.Value);
        }
示例#2
0
        static void Main(string[] args)
        {
            bool   asciiMode = false, strictMode = false, breakMode = false, fileMode = false, commentMode = false;
            string command;

            if (args.Contains("--help") || args.Contains("-h"))
            {
                Console.WriteLine("\nInterprets a Defunc program.\n\n  --help    -h Displays this help message.\n  --ascii   -a Converts ASCII input to integers and outputs as ASCII characters.\n  --strict  -s Makes minor errors halt execution.\n  --break   -b Gives option to break during a long execution cycle.\n  --file    -f Use F\"Filename\" to run a premade file.\n  --comment -c Allows | to be used to toggle between comments and code. (Always on for loaded files.)\n\nPress any key to exit."); Console.ReadKey(); return;
            }
            if (args.Contains("--ascii") || args.Contains("-a"))
            {
                asciiMode = true;
            }
            if (args.Contains("--strict") || args.Contains("-s"))
            {
                strictMode = true;
            }
            if (args.Contains("--break") || args.Contains("-b"))
            {
                breakMode = true;
            }
            if (args.Contains("--file") || args.Contains("-f"))
            {
                fileMode = true;
            }
            if (args.Contains("--comment") || args.Contains("-c"))
            {
                commentMode = true;
            }

            List <OpInfo> Functions = OpInfo.GetDefault(asciiMode);

            if (fileMode)
            {
                Functions.Add(new OpInfo('F'));
            }
            if (commentMode)
            {
                Functions.Add(new OpInfo('|'));
            }

            List <string> commands = new List <string>();

            while (true)
            {
                if (commands.Count == 0)
                {
                    commands.AddRange(Console.ReadLine().Split(new char[] { '\n' }));
                    if (commands[0] == "")
                    {
                        break;
                    }
                }
                command = commands[0];

                #region Read From File

                Regex regex = new Regex("^F\".*\"$");

                if (fileMode && regex.IsMatch(command))
                {
                    string   path  = command.Substring(2, command.Length - 3);
                    string[] lines = new string[0];
                    try
                    {
                        lines = File.ReadAllLines(path);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Error reading file: " + e.ToString());
                    }

                    //Strip comments.
                    string[] strippedLines = new string[lines.Length];
                    foreach (string line in lines)
                    {
                        string strippedLine = "";
                        string tempLine     = line;
                        while (tempLine.Length > 0)
                        {
                            if (tempLine[0] == '|')
                            {
                                tempLine = tempLine.Substring(1);
                                while (tempLine[0] != '|' && tempLine.Length > 0)
                                {
                                    tempLine = tempLine.Substring(1);
                                }
                                tempLine = tempLine.Substring(1);
                                continue;
                            }
                            strippedLine += tempLine[0];
                            tempLine      = tempLine.Substring(1);
                        }
                        strippedLines[Array.IndexOf(lines, line)] = strippedLine;
                    }

                    commands.AddRange(strippedLines);

                    commands = commands.Skip(1).ToList();
                    continue;
                }
                #endregion

                #region Strip Comments
                string strippedCommand = "";
                string tempCommand     = command;
                while (tempCommand.Length > 0)
                {
                    if (tempCommand[0] == '|')
                    {
                        tempCommand = tempCommand.Substring(1);
                        while (tempCommand[0] != '|' && tempCommand.Length > 0)
                        {
                            tempCommand = tempCommand.Substring(1);
                        }
                        tempCommand = tempCommand.Substring(1);
                        continue;
                    }
                    strippedCommand += tempCommand[0];
                    tempCommand      = tempCommand.Substring(1);
                }
                if (commentMode)
                {
                    command = strippedCommand;
                }
                #endregion

                #region New Function Definition

                if (!Functions.Select(x => x.Name).Contains(command[0]))
                {
                    // Scan for the function name, and any local variables.
                    char name = command[0];
                    command = command.Substring(1);
                    Dictionary <char, int> locals = new Dictionary <char, int>();
                    while (!Functions.Select(x => x.Name).Contains(command[0]) && !locals.Select(x => x.Key).Contains(command[0]))
                    {
                        locals.Add(command[0], locals.Count);
                        command = command.Substring(1);
                    }

                    //Create the function itself.
                    char[] innerCommand = command.ToCharArray();
                    Functions.Add(new OpInfo(name, locals.Count, x => {
                        x.Stack.Push(y => y.MoveNext());
                        x.Stack.Push(y => {
                            List <ReturnValue> returned = y.ReturnValues.Pop();
                            ExtendedChar[] modCommand   = new ExtendedChar[innerCommand.Length];
                            innerCommand.Select(z => (ExtendedChar)z).ToArray().CopyTo(modCommand, 0);
                            //Substitute in passed values.
                            foreach (KeyValuePair <char, int> kvp in locals)
                            {
                                modCommand = modCommand.Select(z => z.Equals((ExtendedChar)kvp.Key) ? new ExtendedChar(returned[kvp.Value].Value) : z).ToArray();
                            }
                            List <ExtendedChar> trimmed = new List <ExtendedChar>();
                            //Trim any excess commands.
                            int count = 1;
                            while (count > 0)
                            {
                                if (modCommand[0].Number == null)
                                {
                                    count += y.Funcs.Where(z => z.Name == modCommand[0].Value).GetFunction().ParamCount;
                                }
                                count--;
                                trimmed.AddRange(modCommand.Take(1));
                                modCommand = modCommand.Skip(1).ToArray();
                            }
                            if (strictMode && modCommand.Length > 0)
                            {
                                throw new ArgumentCountException();
                            }
                            //Add to unanalyzed program.
                            y.Program = trimmed.Concat(y.Program).ToArray();
                            return(y);
                        });
                        x.Await(locals.Count);
                        return(x);
                    }));

                    commands = commands.Skip(1).ToList();
                    continue;
                }
                #endregion

                #region Execute Function

                //Initialize the program's state.
                State CurrentState = new State();
                CurrentState.Funcs        = Functions;
                CurrentState.ReturnValues = new Stack <List <ReturnValue> >();
                CurrentState.Stack        = new Stack <Func <State, State> >(new Func <State, State>[] {
                    new Func <State, State>(x => x.MoveNext())
                });
                CurrentState.Program = command.ToCharArray().Select(x => (ExtendedChar)x).ToArray();

                ulong cycles = 0ul;
                ulong max    = 100_000_000ul;
                while (CurrentState.Stack.Count > 0)
                {
                    try
                    {
                        //Runs the current command.
                        CurrentState = CurrentState.Stack.Pop()(CurrentState);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("There was an error: " + e.ToString());
                        break;
                    }
                    if (breakMode && cycles++ >= max)
                    {
                        Console.Write("\nContinue execution? Y/N : ");
                        string response = Console.ReadLine();
                        if (response.Length == 0 || (response[0] != 'y' && response[0] != 'Y'))
                        {
                            break;
                        }
                        max *= 10;
                    }
                }
                Console.WriteLine();
                if (CurrentState.Program.Count() > 0 && strictMode)
                {
                    throw new ArgumentCountException();
                }
                commands = commands.Skip(1).ToList();
                #endregion
            }
        }