// have entered the body // the header should have finished being parsed and currentNode ready // all we do is set up a body visitor and tell it to run through all the statements // it handles everything from that point onwards public override void EnterBody(YarnSpinnerParser.BodyContext context) { // if it is a regular node if (!rawTextNode) { BodyVisitor visitor = new BodyVisitor(this); foreach (var statement in context.statement()) { visitor.Visit(statement); } } // we are a rawText node // turn the body into text // save that into the node // perform no compilation // TODO: oh glob! there has to be a better way else { // moving in by 4 from the end to cut off the ---/=== delimiters // and their associated /n's int start = context.Start.StartIndex + 4; int end = context.Stop.StopIndex - 4; string body = context.Start.InputStream.GetText(new Interval(start, end)); currentNode.sourceTextStringID = program.RegisterString(body, currentNode.name, "line:" + currentNode.name, context.Start.Line, true); } }
// have entered the body // the header should have finished being parsed and currentNode ready // all we do is set up a body visitor and tell it to run through all the statements // it handles everything from that point onwards public override void EnterBody(YarnSpinnerParser.BodyContext context) { // if it is a regular node if (!RawTextNode) { // This is the start of a node that we can jump to. Add a label at this point. CurrentNode.Labels.Add(RegisterLabel(), CurrentNode.Instructions.Count); BodyVisitor visitor = new BodyVisitor(this); foreach (var statement in context.statement()) { visitor.Visit(statement); } } // we are a rawText node // turn the body into text // save that into the node // perform no compilation // TODO: oh glob! there has to be a better way else { CurrentNode.SourceTextStringID = RegisterString(context.GetText(), CurrentNode.Name, "line:" + CurrentNode.Name, context.Start.Line, null); } }
// exiting the body of the node, time for last minute work // before moving onto the next node // Does this node end after emitting AddOptions codes // without calling ShowOptions? public override void ExitBody(YarnSpinnerParser.BodyContext context) { // if it is a regular node if (!rawTextNode) { // Note: this only works when we know that we don't have // AddOptions and then Jump up back into the code to run them. // TODO: A better solution would be for the parser to flag // whether a node has Options at the end. var hasRemainingOptions = false; foreach (var instruction in currentNode.instructions) { if (instruction.operation == ByteCode.AddOption) { hasRemainingOptions = true; } if (instruction.operation == ByteCode.ShowOptions) { hasRemainingOptions = false; } } // If this compiled node has no lingering options to show at the end of the node, then stop at the end if (hasRemainingOptions == false) { Emit(currentNode, ByteCode.Stop); } else { // Otherwise, show the accumulated nodes and then jump to the selected node Emit(currentNode, ByteCode.ShowOptions); if (flags.DisableShuffleOptionsAfterNextSet == true) { Emit(currentNode, ByteCode.PushBool, false); Emit(currentNode, ByteCode.StoreVariable, VirtualMachine.SpecialVariables.ShuffleOptions); Emit(currentNode, ByteCode.Pop); flags.DisableShuffleOptionsAfterNextSet = false; } Emit(currentNode, ByteCode.RunNode); } } }
// have entered the body the header should have finished being // parsed and currentNode ready all we do is set up a body visitor // and tell it to run through all the statements it handles // everything from that point onwards public override void EnterBody(YarnSpinnerParser.BodyContext context) { // if it is a regular node if (!RawTextNode) { // This is the start of a node that we can jump to. Add a // label at this point. CurrentNode.Labels.Add(RegisterLabel(), CurrentNode.Instructions.Count); CodeGenerationVisitor visitor = new CodeGenerationVisitor(this); foreach (var statement in context.statement()) { visitor.Visit(statement); } } // We are a rawText node. Don't compile it; instead, note the string else { CurrentNode.SourceTextStringID = Compiler.GetLineIDForNodeName(CurrentNode.Name); } }
// exiting the body of the node, time for last minute work // before moving onto the next node // Does this node end after emitting AddOptions codes // without calling ShowOptions? public override void ExitBody(YarnSpinnerParser.BodyContext context) { // if it is a regular node if (!RawTextNode) { // Note: this only works when we know that we don't have // AddOptions and then Jump up back into the code to run them. // TODO: A better solution would be for the parser to flag // whether a node has Options at the end. var hasRemainingOptions = false; foreach (var instruction in CurrentNode.Instructions) { if (instruction.Opcode == OpCode.AddOption) { hasRemainingOptions = true; } if (instruction.Opcode == OpCode.ShowOptions) { hasRemainingOptions = false; } } // If this compiled node has no lingering options to show at the end of the node, then stop at the end if (hasRemainingOptions == false) { Emit(CurrentNode, OpCode.Stop); } else { // Otherwise, show the accumulated nodes and then jump to the selected node Emit(CurrentNode, OpCode.ShowOptions); // Showing options will make the execution stop; the // user will have invoked code that pushes the name of // a node onto the stack, which RunNode handles Emit(CurrentNode, OpCode.RunNode); } } }
/// <summary> /// Visit a parse tree produced by <see cref="YarnSpinnerParser.body"/>. /// <para> /// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/> /// on <paramref name="context"/>. /// </para> /// </summary> /// <param name="context">The parse tree.</param> /// <return>The visitor result.</return> public virtual Result VisitBody([NotNull] YarnSpinnerParser.BodyContext context) { return(VisitChildren(context)); }
/// <summary> /// Exit a parse tree produced by <see cref="YarnSpinnerParser.body"/>. /// <para>The default implementation does nothing.</para> /// </summary> /// <param name="context">The parse tree.</param> public virtual void ExitBody([NotNull] YarnSpinnerParser.BodyContext context) { }