Example #1
0
        void CheckAllFiles(GUICallback callback = null)
        {
            // The shared context for all script analysis.
            var analysisContext = new Yarn.Analysis.Context();

            // We shouldn't try to perform program analysis if
            // any of the files fails to compile, because that
            // analysis would be performed on incomplete data.
            bool shouldPerformAnalysis = true;

            // How many files have we finished checking?
            int complete = 0;

            // Let's get started!

            // First, ensure that we're looking at all of the scripts.
            UpdateYarnScriptList();

            // Next, compile each one.
            foreach (var result in checkResults)
            {
                // Attempt to compile the file. Record any compiler messages.
                CheckerResult.State state;

                var messages = ValidateFile(result.script, analysisContext, out state);

                result.state    = state;
                result.messages = messages;

                // Don't perform whole-program analysis if any file failed to compile
                if (result.state != CheckerResult.State.Passed)
                {
                    shouldPerformAnalysis = false;
                }

                // We're done with it; if we have a callback to call after
                // each file is validated, do so.
                complete++;

                if (callback != null)
                {
                    callback(complete, checkResults.Count);
                }
            }

            var results = new List <Yarn.Analysis.Diagnosis>();

            if (shouldPerformAnalysis)
            {
                var scriptAnalyses = analysisContext.FinishAnalysis();
                results.AddRange(scriptAnalyses);
            }


            var environmentAnalyses = AnalyseEnvironment();

            results.AddRange(environmentAnalyses);

            diagnoses = results;
        }
Example #2
0
        public void TestAnalysis()
        {
            ICollection <Yarn.Analysis.Diagnosis> diagnoses;

            Yarn.Analysis.Context context;

            // this script has the following variables:
            // $foo is read from and written to
            // $bar is written to but never read
            // $bas is read from but never written to
            // this means that there should be two diagnosis results
            var script = "// testing\n<<set $foo to 1>><<set $bar to $foo>><<set $bar to $bas>>";

            context = new Yarn.Analysis.Context(typeof(Yarn.Analysis.UnusedVariableChecker));
            dialogue.LoadString(script);
            dialogue.Analyse(context);
            diagnoses = new List <Yarn.Analysis.Diagnosis>(context.FinishAnalysis());

            Assert.AreEqual(2, diagnoses.Count);

            dialogue.UnloadAll();

            context = new Yarn.Analysis.Context(typeof(Yarn.Analysis.UnusedVariableChecker));

            dialogue.LoadFile(Path.Combine(UnityDemoScriptsPath, "Ship.yarn.txt"));
            dialogue.LoadFile(Path.Combine(UnityDemoScriptsPath, "Sally.yarn.txt"));
            dialogue.Analyse(context);
            diagnoses = new List <Yarn.Analysis.Diagnosis>(context.FinishAnalysis());

            // This script should contain no unused variables
            Assert.IsEmpty(diagnoses);
        }
Example #3
0
        public void TestAnalysis()
        {
            ICollection <Yarn.Analysis.Diagnosis> diagnoses;

            Yarn.Analysis.Context context;


            // this script has the following variables:
            // $foo is read from and written to
            // $bar is written to but never read
            // $bas is read from but never written to
            // this means that there should be two diagnosis results
            var script = "// testing\n<<set $foo to 1>><<set $bar to $foo>><<set $bar to $bas>>";

            context = new Yarn.Analysis.Context();
            dialogue.LoadString(script);
            dialogue.Analyse(context);
            diagnoses = new List <Yarn.Analysis.Diagnosis>(context.FinishAnalysis());

            Assert.IsTrue(diagnoses.Count == 2);

            dialogue.UnloadAll();

            context = new Yarn.Analysis.Context();
            dialogue.LoadFile("../Unity/Assets/Yarn Spinner/Examples/Demo Assets/Space/Ship.json");
            dialogue.LoadFile("../Unity/Assets/Yarn Spinner/Examples/Demo Assets/Space/Sally.json");
            dialogue.Analyse(context);
            diagnoses = new List <Yarn.Analysis.Diagnosis>(context.FinishAnalysis());

            // This script should contain no unused variables
            Assert.IsEmpty(diagnoses);
        }
Example #4
0
        static int Verify(VerifyOptions options)
        {
            CheckFileList(options.files, ALLOWED_EXTENSIONS);

            Dialogue dialogue;

            try
            {
                dialogue = CreateDialogue(options, null);
            }
#pragma warning disable CA1031 // Do not catch general exception types
            catch
            {
                return(1);
            }
#pragma warning restore CA1031 // Do not catch general exception types

            if (options.compileAndExit)
            {
                var result = dialogue.GetByteCode();
                Console.WriteLine(result);
                return(0);
            }

            var context = new Yarn.Analysis.Context();

            dialogue.Analyse(context);

            foreach (var diagnosis in context.FinishAnalysis())
            {
                switch (diagnosis.severity)
                {
                case Analysis.Diagnosis.Severity.Error:
                    Error(diagnosis.ToString(showSeverity: false));
                    break;

                case Analysis.Diagnosis.Severity.Warning:
                    Warn(diagnosis.ToString(showSeverity: false));
                    break;

                case Analysis.Diagnosis.Severity.Note:
                    Note(diagnosis.ToString(showSeverity: false));
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            return(0);
        }
Example #5
0
        public void TestAnalysis()
        {
            ICollection <Yarn.Analysis.Diagnosis> diagnoses;

            Yarn.Analysis.Context context;

            // this script has the following variables:
            // $foo is read from and written to
            // $bar is written to but never read
            // this means that there should be one diagnosis result
            context = new Yarn.Analysis.Context(typeof(Yarn.Analysis.UnusedVariableChecker));

            var path = Path.Combine(TestDataPath, "AnalysisTest.yarn");

            CompilationJob compilationJob = CompilationJob.CreateFromFiles(path);

            compilationJob.Library = dialogue.Library;

            var result = Compiler.Compile(compilationJob);

            Assert.Empty(result.Diagnostics);

            stringTable = result.StringTable;

            dialogue.SetProgram(result.Program);
            dialogue.Analyse(context);
            diagnoses = new List <Yarn.Analysis.Diagnosis>(context.FinishAnalysis());

            Assert.Equal(1, diagnoses.Count);
            Assert.Contains("Variable $bar is assigned, but never read from", diagnoses.First().message);

            dialogue.UnloadAll();

            context = new Yarn.Analysis.Context(typeof(Yarn.Analysis.UnusedVariableChecker));

            result = Compiler.Compile(CompilationJob.CreateFromFiles(new[] {
                Path.Combine(SpaceDemoScriptsPath, "Ship.yarn"),
                Path.Combine(SpaceDemoScriptsPath, "Sally.yarn"),
            }, dialogue.Library));

            Assert.Empty(result.Diagnostics);

            dialogue.SetProgram(result.Program);

            dialogue.Analyse(context);
            diagnoses = new List <Yarn.Analysis.Diagnosis>(context.FinishAnalysis());

            // This script should contain no unused variables
            Assert.Empty(diagnoses);
        }
Example #6
0
        public void TestAnalysis()
        {
            ICollection <Yarn.Analysis.Diagnosis> diagnoses;

            Yarn.Analysis.Context context;

            // this script has the following variables:
            // $foo is read from and written to
            // $bar is written to but never read
            // $bas is read from but never written to
            // this means that there should be two diagnosis results
            context = new Yarn.Analysis.Context(typeof(Yarn.Analysis.UnusedVariableChecker));

            var path = Path.Combine(TestDataPath, "AnalysisTest.yarn");

            Compiler.CompileFile(path, out var program, out stringTable);

            dialogue.SetProgram(program);
            dialogue.Analyse(context);
            diagnoses = new List <Yarn.Analysis.Diagnosis>(context.FinishAnalysis());

            Assert.Equal(2, diagnoses.Count);

            dialogue.UnloadAll();

            context = new Yarn.Analysis.Context(typeof(Yarn.Analysis.UnusedVariableChecker));

            string shipPath = Path.Combine(SpaceDemoScriptsPath, "Ship.yarn");

            Compiler.CompileFile(shipPath, out var shipProgram, out var shipStringTable);

            string sallyPath = Path.Combine(SpaceDemoScriptsPath, "Sally.yarn");

            Compiler.CompileFile(sallyPath, out var sallyProgram, out var sallyStringTable);

            stringTable = shipStringTable.Union(sallyStringTable).ToDictionary(k => k.Key, v => v.Value);

            var combinedProgram = Program.Combine(shipProgram, sallyProgram);

            dialogue.SetProgram(combinedProgram);

            dialogue.Analyse(context);
            diagnoses = new List <Yarn.Analysis.Diagnosis>(context.FinishAnalysis());

            // This script should contain no unused variables
            Assert.Empty(diagnoses);
        }
        // Finds all .JSON files, and validates them.
        void Validate()
        {
            UpdateJSONList();

            var analysisContext = new Yarn.Analysis.Context();

            bool shouldPerformAnalysis = true;

            foreach (var result in checkResults)
            {
                CheckerResult.State state;

                var messages = ValidateFile(result.script, analysisContext, out state);

                result.state    = state;
                result.messages = messages;

                // Don't perform whole-program analysis if any file failed to compile
                if (result.state != CheckerResult.State.Passed)
                {
                    shouldPerformAnalysis = false;
                }
            }

            var results = new List <Yarn.Analysis.Diagnosis>();


            if (shouldPerformAnalysis)
            {
                results.AddRange(analysisContext.FinishAnalysis());
            }

            results.AddRange(AnalyseEnvironment());

            diagnoses = results;
        }
Example #8
0
        public static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                ShowHelpAndExit();
            }

            bool   showTokens            = false;
            bool   showParseTree         = false;
            bool   waitForLines          = false;
            string onlyConsiderNode      = null;
            bool   showDebugging         = false;
            int    runTimes              = 1;
            bool   compileToBytecodeOnly = false;
            bool   verifyOnly            = false;
            bool   autoSelectFirstOption = false;
            bool   analyseOnly           = false;
            string outputFile            = null;

            var    inputFiles = new List <string> ();
            string startNode  = Dialogue.DEFAULT_START;

            string[] allowedExtensions = { ".node", ".json" };

            var defaultVariables = new Dictionary <string, float> ();

            foreach (var arg in args)
            {
                // Handle 'start' parameter
                if (arg.IndexOf("-s=") != -1)
                {
                    var startArray = arg.Split(new char[] { '=' });
                    if (startArray.Length != 2)
                    {
                        ShowHelpAndExit();
                    }
                    else
                    {
                        startNode = startArray [1];
                        continue;
                    }
                }

                // Handle variable input
                if (arg.IndexOf("-v") != -1)
                {
                    var variable      = arg.Substring(2);
                    var variableArray = variable.Split(new char[] { '=' });
                    if (variableArray.Length != 2)
                    {
                        ShowHelpAndExit();
                    }
                    else
                    {
                        var varName  = "$" + variableArray [0];
                        var varValue = float.Parse(variableArray [1]);
                        defaultVariables [varName] = varValue;
                        continue;
                    }
                }

                // Handle 'only this node' parameter
                if (arg.IndexOf("-o=") != -1)
                {
                    var startArray = arg.Split(new char[] { '=' });
                    if (startArray.Length != 2)
                    {
                        ShowHelpAndExit();
                    }
                    else
                    {
                        onlyConsiderNode = startArray [1];
                        continue;
                    }
                }

                // Handle 'run times' parameter
                if (arg.IndexOf("-r=") != -1)
                {
                    var argArray = arg.Split('=');
                    if (argArray.Length != 2)
                    {
                        ShowHelpAndExit();
                    }
                    else
                    {
                        runTimes = int.Parse(argArray [1]);
                        continue;
                    }
                }

                // Handle 'output file' parameter
                if (arg.IndexOf("-f=") != -1)
                {
                    var argArray = arg.Split('=');
                    if (argArray.Length != 2)
                    {
                        ShowHelpAndExit();
                    }
                    else
                    {
                        outputFile = argArray[1];
                        continue;
                    }
                }

                switch (arg)
                {
                case "-V":
                    verifyOnly = true;
                    break;

                case "-t":
                    showTokens    = true;
                    showDebugging = true;
                    break;

                case "-p":
                    showParseTree = true;
                    showDebugging = true;
                    break;

                case "-w":
                    waitForLines = true;
                    break;

                case "-d":
                    showDebugging = true;
                    break;

                case "-c":
                    compileToBytecodeOnly = true;
                    break;

                case "-1":
                    autoSelectFirstOption = true;
                    break;

                case "-h":
                    ShowHelpAndExit();
                    break;

                case "-a":
                    analyseOnly = true;
                    break;

                default:

                    // only allow one file
                    if (inputFiles.Count > 0)
                    {
                        Console.Error.WriteLine("Error: Too many files specified.");
                        Environment.Exit(1);
                    }

                    var extension = System.IO.Path.GetExtension(arg);
                    if (Array.IndexOf(allowedExtensions, extension) != -1)
                    {
                        inputFiles.Add(arg);
                    }
                    break;
                }
            }

            if (inputFiles.Count == 0)
            {
                Console.Error.WriteLine("Error: No files specified.");
                Environment.Exit(1);
            }

            // Create the object that handles callbacks
            var impl = new ConsoleRunnerImplementation(waitForLines: waitForLines);

            // load the default variables we got on the command line
            foreach (var variable in defaultVariables)
            {
                impl.SetNumber(variable.Key, variable.Value);
            }

            // Load nodes
            var dialogue = new Dialogue(impl);


            // Add some methods for testing
            dialogue.library.RegisterFunction("add_three_operands", 3, delegate(Value[] parameters) {
                return(parameters[0] + parameters[1] + parameters[2]);
            });

            dialogue.library.RegisterFunction("last_value", -1, delegate(Value[] parameters) {
                // return the last value
                return(parameters[parameters.Length - 1]);
            });

            dialogue.library.RegisterFunction("is_even", 1, delegate(Value[] parameters) {
                return((int)parameters[0].AsNumber % 2 == 0);
            });

            // Register the "assert" function, which stops execution if its parameter evaluates to false
            dialogue.library.RegisterFunction("assert", -1, delegate(Value[] parameters) {
                if (parameters[0].AsBool == false)
                {
                    // TODO: Include file, node and line number
                    if (parameters.Length > 1 && parameters[1].AsBool)
                    {
                        dialogue.LogErrorMessage("ASSERTION FAILED: " + parameters[1].AsString);
                    }
                    else
                    {
                        dialogue.LogErrorMessage("ASSERTION FAILED");
                    }
                    Environment.Exit(1);
                }
            });


            // Register a function to let test scripts register how many
            // options they expect to send
            dialogue.library.RegisterFunction("prepare_for_options", 2, delegate(Value[] parameters) {
                impl.numberOfExpectedOptions = (int)parameters [0].AsNumber;
                impl.autoSelectOptionNumber  = (int)parameters[1].AsNumber;
            });

            dialogue.library.RegisterFunction("expect_line", 1, delegate(Value[] parameters) {
                impl.expectedNextLine = parameters[0].AsString;
            });

            dialogue.library.RegisterFunction("expect_command", 1, delegate(Value[] parameters) {
                impl.expectedNextCommand = parameters[0].AsString;
            });

            if (autoSelectFirstOption == true)
            {
                impl.autoSelectFirstOption = true;
            }

            // If debugging is enabled, log debug messages; otherwise, ignore them
            if (showDebugging)
            {
                dialogue.LogDebugMessage = delegate(string message) {
                    Console.WriteLine("Debug: " + message);
                };
            }
            else
            {
                dialogue.LogDebugMessage = delegate(string message) {};
            }

            dialogue.LogErrorMessage = delegate(string message) {
                Console.WriteLine("ERROR: " + message);
            };

            if (verifyOnly)
            {
                try {
                    dialogue.LoadFile(inputFiles [0], showTokens, showParseTree, onlyConsiderNode);
                } catch (Exception e) {
                    Console.WriteLine("Error: " + e.Message);
                }
                return;
            }

            dialogue.LoadFile(inputFiles [0], showTokens, showParseTree, onlyConsiderNode);

            if (outputFile != null)
            {
                var result = dialogue.GetByteCode();
                System.Text.UTF8Encoding utf8 = new System.Text.UTF8Encoding();
                using (System.IO.StreamWriter file = new System.IO.StreamWriter(outputFile, false, utf8)) {
                    file.Write(result);
                }
                return;
            }

            if (compileToBytecodeOnly)
            {
                var result = dialogue.GetByteCode();
                Console.WriteLine(result);
                return;
            }

            if (analyseOnly)
            {
                var context = new Yarn.Analysis.Context();

                dialogue.Analyse(context);

                foreach (var diagnosis in context.FinishAnalysis())
                {
                    Console.WriteLine(diagnosis.ToString(showSeverity: true));
                }
                return;
            }

            // Only run the program when we're not emitting debug output of some kind
            var runProgram =
                showTokens == false &&
                showParseTree == false &&
                compileToBytecodeOnly == false &&
                analyseOnly == false;

            if (runProgram)
            {
                // Run the conversation

                for (int run = 0; run < runTimes; run++)
                {
                    foreach (var step in dialogue.Run(startNode))
                    {
                        // It can be one of three types: a line to show, options
                        // to present to the user, or an internal command to run

                        if (step is Dialogue.LineResult)
                        {
                            var lineResult = step as Dialogue.LineResult;
                            impl.RunLine(lineResult.line);
                        }
                        else if (step is Dialogue.OptionSetResult)
                        {
                            var optionsResult = step as Dialogue.OptionSetResult;
                            impl.RunOptions(optionsResult.options, optionsResult.setSelectedOptionDelegate);
                        }
                        else if (step is Dialogue.CommandResult)
                        {
                            var commandResult = step as Dialogue.CommandResult;
                            impl.RunCommand(commandResult.command.text);
                        }
                    }
                    impl.DialogueComplete();
                }
            }
        }
        // Finds all .JSON files, and validates them.
        void Validate()
        {
            UpdateJSONList();

            var analysisContext = new Yarn.Analysis.Context();

            bool shouldPerformAnalysis = true;

            foreach (var result in checkResults) {

                CheckerResult.State state;

                var messages = ValidateFile(result.script, analysisContext, out state);

                result.state = state;
                result.messages = messages;

                // Don't perform whole-program analysis if any file failed to compile
                if (result.state != CheckerResult.State.Passed) {
                    shouldPerformAnalysis = false;
                }

            }

            var results = new List<Yarn.Analysis.Diagnosis>();

            if (shouldPerformAnalysis)
                results.AddRange(analysisContext.FinishAnalysis());

            results.AddRange(AnalyseEnvironment());

            diagnoses = results;
        }
Example #10
0
        public static void Main(string[] args)
        {
            if (args.Length == 0) {
                ShowHelpAndExit ();
            }

            bool showTokens = false;
            bool showParseTree = false;
            bool waitForLines = false;
            string onlyConsiderNode = null;
            bool showDebugging = false;
            int runTimes = 1;
            bool compileToBytecodeOnly = false;
            bool verifyOnly = false;
            bool autoSelectFirstOption = false;
            bool analyseOnly = false;

            var inputFiles = new List<string> ();
            string startNode = Dialogue.DEFAULT_START;

            string[] allowedExtensions = {".node", ".json" };

            var defaultVariables = new Dictionary<string,float> ();

            foreach (var arg in args) {

                // Handle 'start' parameter
                if (arg.IndexOf("-s=") != -1) {
                    var startArray = arg.Split (new char[]{ '=' });
                    if (startArray.Length != 2) {
                        ShowHelpAndExit ();
                    } else {
                        startNode = startArray [1];
                        continue;
                    }
                }

                // Handle variable input
                if (arg.IndexOf("-v") != -1) {
                    var variable = arg.Substring (2);
                    var variableArray = variable.Split (new char[]{ '=' });
                    if (variableArray.Length != 2) {
                        ShowHelpAndExit ();
                    } else {
                        var varName = "$" + variableArray [0];
                        var varValue = float.Parse (variableArray [1]);
                        defaultVariables [varName] = varValue;
                        continue;
                    }

                }

                // Handle 'only this node' parameter
                if (arg.IndexOf("-o=") != -1) {
                    var startArray = arg.Split (new char[]{ '=' });
                    if (startArray.Length != 2) {
                        ShowHelpAndExit ();
                    } else {
                        onlyConsiderNode = startArray [1];
                        continue;
                    }
                }

                // Handle 'run times' parameter
                if (arg.IndexOf("-r=") != -1) {
                    var argArray = arg.Split ('=');
                    if (argArray.Length != 2) {
                        ShowHelpAndExit ();
                    } else {
                        runTimes = int.Parse (argArray [1]);
                        continue;
                    }

                }

                switch (arg) {
                case "-V":
                    verifyOnly = true;
                    break;
                case "-t":
                    showTokens = true;
                    showDebugging = true;
                    break;
                case "-p":
                    showParseTree = true;
                    showDebugging = true;
                    break;
                case "-w":
                    waitForLines = true;
                    break;
                case "-d":
                    showDebugging = true;
                    break;
                case "-c":
                    compileToBytecodeOnly = true;
                    break;
                case "-1":
                    autoSelectFirstOption = true;
                    break;
                case "-h":
                    ShowHelpAndExit ();
                    break;
                case "-a":
                    analyseOnly = true;
                    break;
                default:

                    // only allow one file
                    if (inputFiles.Count > 0) {
                        Console.Error.WriteLine ("Error: Too many files specified.");
                        Environment.Exit (1);
                    }

                    var extension = System.IO.Path.GetExtension (arg);
                    if (Array.IndexOf(allowedExtensions, extension) != -1) {
                        inputFiles.Add (arg);
                    }
                    break;
                }
            }

            if (inputFiles.Count == 0) {
                Console.Error.WriteLine ("Error: No files specified.");
                Environment.Exit (1);
            }

            // Create the object that handles callbacks
            var impl = new ConsoleRunnerImplementation (waitForLines:waitForLines);

            // load the default variables we got on the command line
            foreach (var variable in defaultVariables) {

                impl.SetNumber (variable.Key, variable.Value);
            }

            // Load nodes
            var dialogue = new Dialogue(impl);

            // Add some methods for testing
            dialogue.library.RegisterFunction ("add_three_operands", 3, delegate(Value[] parameters) {
                return parameters[0]+parameters[1]+parameters[2];
            });

            dialogue.library.RegisterFunction ("last_value", -1, delegate(Value[] parameters) {
                // return the last value
                return parameters[parameters.Length-1];
            });

            dialogue.library.RegisterFunction ("is_even", 1, delegate(Value[] parameters) {
                return (int)parameters[0].AsNumber % 2 == 0;
            });

            // Register the "assert" function, which stops execution if its parameter evaluates to false
            dialogue.library.RegisterFunction ("assert", -1, delegate(Value[] parameters) {
                if (parameters[0].AsBool == false) {

                    // TODO: Include file, node and line number
                    if( parameters.Length > 1 && parameters[1].AsBool ) {
                        dialogue.LogErrorMessage ("ASSERTION FAILED: " + parameters[1].AsString);
                    } else {
                        dialogue.LogErrorMessage ("ASSERTION FAILED");
                    }
                    Environment.Exit(1);
                }
            });

            // Register a function to let test scripts register how many
            // options they expect to send
            dialogue.library.RegisterFunction ("prepare_for_options", 2, delegate(Value[] parameters) {
                impl.numberOfExpectedOptions = (int)parameters [0].AsNumber;
                impl.autoSelectOptionNumber = (int)parameters[1].AsNumber;
            });

            dialogue.library.RegisterFunction ("expect_line", 1, delegate(Value[] parameters) {
                impl.expectedNextLine = parameters[0].AsString;
            });

            dialogue.library.RegisterFunction ("expect_command", 1, delegate(Value[] parameters) {
                impl.expectedNextCommand = parameters[0].AsString;
            });

            if (autoSelectFirstOption == true) {
                impl.autoSelectFirstOption = true;
            }

            // If debugging is enabled, log debug messages; otherwise, ignore them
            if (showDebugging) {
                dialogue.LogDebugMessage = delegate(string message) {
                    Console.WriteLine ("Debug: " + message);
                };
            } else {
                dialogue.LogDebugMessage = delegate(string message) {};
            }

            dialogue.LogErrorMessage = delegate(string message) {
                Console.WriteLine ("ERROR: " + message);
            };

            if (verifyOnly) {
                try {
                    dialogue.LoadFile (inputFiles [0],showTokens, showParseTree, onlyConsiderNode);
                } catch (Exception e) {
                    Console.WriteLine ("Error: " + e.Message);
                }
                return;
            }

            dialogue.LoadFile (inputFiles [0],showTokens, showParseTree, onlyConsiderNode);

            if (compileToBytecodeOnly) {
                var result = dialogue.GetByteCode ();
                Console.WriteLine (result);
                return;
            }

            if (analyseOnly) {

                var context = new Yarn.Analysis.Context ();

                dialogue.Analyse (context);

                foreach (var diagnosis in context.FinishAnalysis()) {
                    Console.WriteLine (diagnosis.ToString(showSeverity:true));
                }
                return;
            }

            // Only run the program when we're not emitting debug output of some kind
            var runProgram =
                showTokens == false &&
                showParseTree == false &&
                compileToBytecodeOnly == false &&
                analyseOnly == false;

            if (runProgram) {
                // Run the conversation

                for (int run = 0; run < runTimes; run++) {
                    foreach (var step in dialogue.Run (startNode)) {

                        // It can be one of three types: a line to show, options
                        // to present to the user, or an internal command to run

                        if (step is Dialogue.LineResult) {
                            var lineResult = step as Dialogue.LineResult;
                            impl.RunLine (lineResult.line);
                        } else if (step is Dialogue.OptionSetResult) {
                            var optionsResult = step as Dialogue.OptionSetResult;
                            impl.RunOptions (optionsResult.options, optionsResult.setSelectedOptionDelegate);
                        } else if (step is Dialogue.CommandResult) {
                            var commandResult = step as Dialogue.CommandResult;
                            impl.RunCommand (commandResult.command.text);
                        }
                    }
                    impl.DialogueComplete ();
                }

            }
        }
Example #11
0
        public void TestAnalysis()
        {
            ICollection<Yarn.Analysis.Diagnosis> diagnoses;
            Yarn.Analysis.Context context;

            // this script has the following variables:
            // $foo is read from and written to
            // $bar is written to but never read
            // $bas is read from but never written to
            // this means that there should be two diagnosis results
            var script = "// testing\n<<set $foo to 1>><<set $bar to $foo>><<set $bar to $bas>>";

            context = new Yarn.Analysis.Context ();
            dialogue.LoadString (script);
            dialogue.Analyse (context);
            diagnoses = new List<Yarn.Analysis.Diagnosis>(context.FinishAnalysis ());

            Assert.IsTrue (diagnoses.Count == 2);

            dialogue.UnloadAll ();

            context = new Yarn.Analysis.Context ();
            dialogue.LoadFile ("../Unity/Assets/Yarn Spinner/Examples/Demo Assets/Space/Ship.json");
            dialogue.LoadFile ("../Unity/Assets/Yarn Spinner/Examples/Demo Assets/Space/Sally.json");
            dialogue.Analyse (context);
            diagnoses = new List<Yarn.Analysis.Diagnosis>(context.FinishAnalysis ());

            // This script should contain no unused variables
            Assert.IsEmpty (diagnoses);
        }