Esempio n. 1
0
        // a regular ol' line of text
        public override int VisitLine_statement(YarnSpinnerParser.Line_statementContext context)
        {
            // TODO: add support for line conditions:
            //
            // Mae: here's a line <<if true>>
            //
            // is identical to
            //
            // <<if true>>
            // Mae: here's a line
            // <<endif>>

            // Convert the formatted string into a string with
            // placeholders, and evaluate the inline expressions and push
            // the results onto the stack.
            GenerateFormattedText(context.line_formatted_text().children, out var composedString, out var expressionCount);

            // Get the lineID for this string from the hashtags if it has one; otherwise, a new one will be created
            string lineID = compiler.GetLineID(context.hashtag());

            var hashtagText = GetHashtagTexts(context.hashtag());

            int lineNumber = context.Start.Line;

            string stringID = compiler.RegisterString(
                composedString.ToString(),
                compiler.CurrentNode.Name,
                lineID,
                lineNumber,
                hashtagText);

            compiler.Emit(OpCode.RunLine, new Operand(stringID), new Operand(expressionCount));

            return(0);
        }
        // a regular ol' line of text
        public override int VisitLine_statement(YarnSpinnerParser.Line_statementContext context)
        {
            // TODO: add support for line conditions:
            //
            // Mae: here's a line <<if true>>
            //
            // is identical to
            //
            // <<if true>> Mae: here's a line <<endif>>

            // Evaluate the inline expressions and push the results onto
            // the stack.
            var expressionCount = GenerateCodeForExpressionsInFormattedText(context.line_formatted_text().children);

            // Get the lineID for this string from the hashtags
            string lineID = Compiler.GetLineID(context.hashtag());

            if (lineID == null)
            {
                throw new ParseException("No line ID specified");
            }

            compiler.Emit(OpCode.RunLine, new Operand(lineID), new Operand(expressionCount));

            return(0);
        }
        public override int VisitLine_statement([NotNull] YarnSpinnerParser.Line_statementContext context)
        {
            int lineNumber = context.Start.Line;

            string lineID = Compiler.GetLineID(context.hashtag());

            var hashtagText = GetHashtagTexts(context.hashtag());

            GenerateFormattedText(context.line_formatted_text().children, out var composedString, out var expressionCount);

            string stringID = stringTableManager.RegisterString(
                composedString.ToString(),
                fileName,
                currentNodeName,
                lineID,
                lineNumber,
                hashtagText);

            if (lineID == null)
            {
                var hashtag = new YarnSpinnerParser.HashtagContext(context, 0);
                hashtag.text = new CommonToken(YarnSpinnerLexer.HASHTAG_TEXT, stringID);
                context.AddChild(hashtag);
            }

            return(0);
        }
Esempio n. 4
0
        // a regular ol' line of text
        public override int VisitLine_statement(YarnSpinnerParser.Line_statementContext context)
        {
            // grabbing the line of text and stripping off any "'s if they had them
            string lineText = context.text().GetText().Trim('"');

            // getting the lineID from the hashtags if it has one
            string lineID = compiler.GetLineID(context.hashtag_block());

            // technically this only gets the line the statement started on
            int lineNumber = context.Start.Line;

            string stringID = compiler.RegisterString(lineText, compiler.currentNode.Name, lineID, lineNumber);

            compiler.Emit(OpCode.RunLine, new Operand(stringID));

            return(0);
        }
        // for the shortcut options (-> line of text <<if expression>>
        // indent statements dedent)+
        public override int VisitShortcut_option_statement(YarnSpinnerParser.Shortcut_option_statementContext context)
        {
            string endOfGroupLabel = compiler.RegisterLabel("group_end");

            var labels = new List <string>();

            int optionCount = 0;

            // For each option, create an internal destination label that,
            // if the user selects the option, control flow jumps to. Then,
            // evaluate its associated line_statement, and use that as the
            // option text. Finally, add this option to the list of
            // upcoming options.
            foreach (var shortcut in context.shortcut_option())
            {
                // Generate the name of internal label that we'll jump to
                // if this option is selected. We'll emit the label itself
                // later.
                string optionDestinationLabel = compiler.RegisterLabel($"shortcutoption_{compiler.CurrentNode.Name ?? "node"}_{optionCount + 1}");
                labels.Add(optionDestinationLabel);

                // This line statement may have a condition on it. If it
                // does, emit code that evaluates the condition, and add a
                // flag on the 'Add Option' instruction that indicates that
                // a condition exists.

                bool hasLineCondition = false;
                if (shortcut.line_statement().line_condition() != null)
                {
                    // Evaluate the condition, and leave it on the stack
                    Visit(shortcut.line_statement().line_condition().expression());

                    hasLineCondition = true;
                }

                // We can now prepare and add the option.

                // Start by figuring out the text that we want to add. This
                // will involve evaluating any inline expressions.
                var expressionCount = GenerateCodeForExpressionsInFormattedText(shortcut.line_statement().line_formatted_text().children);

                // Get the line ID from the hashtags if it has one
                string lineID = Compiler.GetLineID(shortcut.line_statement().hashtag());

                if (lineID == null)
                {
                    throw new ParseException("No line ID provided");
                }

                // And add this option to the list.
                compiler.Emit(
                    OpCode.AddOption,
                    new Operand(lineID),
                    new Operand(optionDestinationLabel),
                    new Operand(expressionCount),
                    new Operand(hasLineCondition));

                optionCount++;
            }

            // All of the options that we intend to show are now ready to
            // go.
            compiler.Emit(OpCode.ShowOptions);

            // The top of the stack now contains the name of the label we
            // want to jump to. Jump to it now.
            compiler.Emit(OpCode.Jump);

            // We'll now emit the labels and code associated with each
            // option.
            optionCount = 0;
            foreach (var shortcut in context.shortcut_option())
            {
                // Emit the label for this option's code
                compiler.CurrentNode.Labels.Add(labels[optionCount], compiler.CurrentNode.Instructions.Count);

                // Run through all the children statements of the shortcut
                // option.
                foreach (var child in shortcut.statement())
                {
                    Visit(child);
                }

                // Jump to the end of this shortcut option group.
                compiler.Emit(OpCode.JumpTo, new Operand(endOfGroupLabel));

                optionCount++;
            }

            // We made it to the end! Mark the end of the group, so we can
            // jump to it.
            compiler.CurrentNode.Labels.Add(endOfGroupLabel, compiler.CurrentNode.Instructions.Count);
            compiler.Emit(OpCode.Pop);

            return(0);
        }