Пример #1
0
        /// <summary>
        /// Runs Algo in "inline" mode (no package manager, etc). Returns an exit code.
        /// </summary>
        private static int RunAlgoInline(InlineCLIOptions opts, string[] originalArgs)
        {
            //Set developer mode on if necessary.
            if (opts.DeveloperMode)
            {
                AlgoRuntimeInformation.DeveloperMode = true;
            }
            if (opts.TestMode)
            {
                AlgoRuntimeInformation.UnitTestMode = true;
            }

            //Displaying any generic info and then shutting off?
            if (opts.ShowVersionOnly)
            {
                PrintVersionInfo(); return(0);
            }

            //Compiling a file?
            if (opts.Compile != null)
            {
                //Attempt to compile.
                ALEC.Compile(opts.Compile);
                return(0);
            }

            //Running the script interpreter, or the live interpreter?
            if (opts.ScriptFile == null)
            {
                //Run live.
                //Print version info. If --nohead is on, then the header info for the interpreter is skipped.
                if (!opts.NoHeader)
                {
                    PrintVersionInfo();
                    Console.WriteLine("Starting interpreter...\n");
                }

                //Create a visitor.
                if (visitor == null)
                {
                    visitor = new algoVisitor();

                    //Load core library.
                    visitor.LoadCoreLibrary();
                }

                //Interactive interpreter.
                while (true)
                {
                    Console.Write(">> ");
                    string line = Console.ReadLine();

                    //Catch keywords and null strings.
                    if (line == "quit" || line == "exit" || line == "stop")
                    {
                        break;
                    }
                    if (line == "help")
                    {
                        PrintHelp(); continue;
                    }
                    if (line == "clear")
                    {
                        Console.Clear(); continue;
                    }
                    if (line == "")
                    {
                        continue;
                    }

                    //Parse line.
                    var s_chars  = new AntlrInputStream(line);
                    var s_lexer  = new algoLexer(s_chars);
                    var s_tokens = new CommonTokenStream(s_lexer);
                    var s_parse  = new algoParser(s_tokens);

                    //Turn on continuous mode.
                    AlgoRuntimeInformation.ContinuousMode = true;

                    //Execute.
                    s_parse.BuildParseTree = true;
                    var s_tree = s_parse.compileUnit();

                    try
                    {
                        visitor.VisitCompileUnit(s_tree);
                    }
                    catch (Exception e)
                    {
                        //Internal exception.
                        if (!AlgoRuntimeInformation.UnitTestMode)
                        {
                            Error.Internal(e.Message);
                        }
                        else
                        {
                            throw e;
                        }
                    }
                }

                return(0);
            }
            else
            {
                //Run normal script.
                //Does the given file location exist?
                string fullPath = CPFilePath.GetPlatformFilePath(new string[] { Environment.CurrentDirectory, opts.ScriptFile });
                if (!File.Exists(fullPath))
                {
                    Error.FatalNoContext("No file with the name '" + opts.ScriptFile + "' exists relative to your current directory.");
                    return(-1);
                }

                //Loading in the file arguments.
                List <string> args = originalArgs.ToList();
                args.RemoveAll(x => x.StartsWith("-"));
                algoVisitor.SetConsoleArguments(args.Skip(1).ToArray());

                //Read in the input.
                AlgoRuntimeInformation.FileLoaded = opts.ScriptFile;
                string input  = File.ReadAllText(fullPath);
                var    chars  = new AntlrInputStream(input);
                var    lexer  = new algoLexer(chars);
                var    tokens = new CommonTokenStream(lexer);

                //Debug print.
                if (AlgoRuntimeInformation.DeveloperMode)
                {
                    ANTLRDebug.PrintTokens(lexer);
                }

                //Debug print tree.
                var parser = new algoParser(tokens);
                parser.BuildParseTree = true;
                var tree = parser.compileUnit();
                if (AlgoRuntimeInformation.DeveloperMode)
                {
                    ANTLRDebug.PrintParseList(tree, parser);

                    //Add a gap.
                    Console.WriteLine(" --------------------\n | BEGIN EVALUATION |\n --------------------\n");
                }

                //Walking the tree.
                visitor = new algoVisitor();
                visitor.LoadCoreLibrary();
                visitor.VisitCompileUnit(tree);

                if (AlgoRuntimeInformation.DeveloperMode)
                {
                    Console.ForegroundColor = ConsoleColor.Gray;
                    Console.WriteLine("\n ------------------\n | END EVALUATION |\n ------------------\n");

                    //Print variables.
                    ANTLRDebug.PrintScopes();
                }

                return(0);
            }
        }
Пример #2
0
        /// <summary>
        /// Get a result from this particle block (null if none).
        /// </summary>
        public static AlgoValue ParseParticleBlock(algoVisitor visitor, ParserRuleContext ctx, ITerminalNode firstIdentifier, algoParser.ParticleContext[] particleContext)
        {
            //Is it a user created variable?
            if (algoVisitor.Scopes.VariableExists(firstIdentifier.GetText()))
            {
                //Yes, get the value and evaluate the particles.
                var value = algoVisitor.Scopes.GetVariable(firstIdentifier.GetText());
                if (particleContext != null)
                {
                    //Set particle input as the current value.
                    SetParticleInput(value);

                    foreach (var particle in particleContext)
                    {
                        //Evaluate all the particles, get the final result.
                        visitor.VisitParticle(particle);
                    }

                    value = GetParticleResult();
                }

                //Return the value.
                return(value);
            }
            //Is it a library?
            else if (algoVisitor.Scopes.LibraryExists(firstIdentifier.GetText()))
            {
                //If it's a library, you've got to have a particle access.
                if (particleContext == null || particleContext.Length == 0)
                {
                    Error.Fatal(ctx, "Cannot use a library directly as a value.");
                    return(null);
                }

                //It's a library, prepare for a scope switch.
                var scopes_local             = algoVisitor.Scopes.GetLibrary(firstIdentifier.GetText());
                AlgoScopeCollection oldScope = algoVisitor.Scopes;

                //First, get the first particle to set as the particle input.
                var toEval = particleContext[0]; AlgoValue particleVal = null;

                //Is the first particle an identifier?
                if (toEval.IDENTIFIER() != null)
                {
                    particleVal = scopes_local.GetVariable(toEval.IDENTIFIER().GetText());
                    if (particleVal == null)
                    {
                        Error.Fatal(toEval, "No variable exists in library '" + firstIdentifier.GetText() + "' named '" + toEval.IDENTIFIER().GetText() + "'.");
                        return(null);
                    }
                }
                else if (toEval.functionCall_particle() != null)
                {
                    //Not an identifier, a function. Attempt to call with the correct scopes.
                    SetFunctionArgumentScopes(algoVisitor.Scopes);
                    algoVisitor.Scopes = scopes_local;
                    var funcParticle = toEval.functionCall_particle();

                    //Attempt to get the function from the library.
                    if (!scopes_local.VariableExists(funcParticle.IDENTIFIER().GetText()))
                    {
                        Error.Fatal(funcParticle, "No function exists named '" + funcParticle.IDENTIFIER().GetText() + " in library '" + firstIdentifier.GetText() + "'.");
                        return(null);
                    }

                    //Is it a valid function?
                    var funcVal = scopes_local.GetVariable(funcParticle.IDENTIFIER().GetText());
                    if (funcVal.Type != AlgoValueType.EmulatedFunction && funcVal.Type != AlgoValueType.Function)
                    {
                        Error.Fatal(funcParticle, "Cannot call a value that is not a function ('" + funcParticle.IDENTIFIER().GetText() + " in library '" + firstIdentifier.GetText() + "').");
                        return(null);
                    }

                    SetParticleInput(funcVal);
                    var returned = visitor.VisitFunctionCall_particle(toEval.functionCall_particle());
                    if (returned != null)
                    {
                        particleVal = (AlgoValue)returned;
                    }
                    else
                    {
                        particleVal = null;
                    }

                    //Reset scopes.
                    algoVisitor.Scopes = oldScope;
                    ResetFunctionArgumentScopes();
                    ResetParticleInput();
                }
                else
                {
                    //Not a function call or child.
                    Error.Fatal(toEval, "Cannot index directly into a library.");
                    return(null);
                }

                //Do more particle values need to be gathered?
                if (particleContext.Length > 1)
                {
                    //If particle value is null, throw an error.
                    if (particleVal == null)
                    {
                        Error.Fatal(toEval, "No value returned to perform further operations on.");
                        return(null);
                    }

                    //Swap out the scopes, set the argument evaluation scope.
                    SetFunctionArgumentScopes(algoVisitor.Scopes);
                    SetParticleInput(particleVal);
                    algoVisitor.Scopes = scopes_local;

                    //Execute all the particles past the first one.
                    for (int i = 1; i < particleContext.Length; i++)
                    {
                        visitor.VisitParticle(particleContext[i]);
                        particleVal = GetParticleResult();
                    }

                    //Switch back to the original scope, reset the arg eval scope.
                    ResetFunctionArgumentScopes();
                    ResetParticleInput();
                    algoVisitor.Scopes = oldScope;
                }

                return(particleVal);
            }
            else
            {
                Error.Fatal(ctx, "No variable or library exists with name '" + firstIdentifier.GetText() + "'.");
                return(null);
            }
        }