// left OPERATOR right style expressions // the most common form of expressions // for things like 1 + 3 #region lValueOperatorrValueCalls internal void genericExpVisitor(YarnSpinnerParser.ExpressionContext left, YarnSpinnerParser.ExpressionContext right, int op) { Visit(left); Visit(right); // TODO: temp operator call // Indicate that we are pushing two items for comparison compiler.Emit(OpCode.PushFloat, new Operand(2)); compiler.Emit(OpCode.CallFunc, new Operand(tokens[op].ToString())); }
// operatorEquals style operators, eg += // these two should only be called during a SET operation // eg << set $var += 1 >> // the left expression has to be a variable // the right value can be anything #region operatorEqualsCalls // generic helper for these types of expressions internal void opEquals(string varName, YarnSpinnerParser.ExpressionContext expression, int op) { // Get the current value of the variable compiler.Emit(OpCode.PushVariable, new Operand(varName)); // run the expression Visit(expression); // Stack now contains [currentValue, expressionValue] // Indicate that we are pushing two items for comparison compiler.Emit(OpCode.PushFloat, new Operand(2)); // now we evaluate the operator // op will match to one of + - / * % compiler.Emit(OpCode.CallFunc, new Operand(tokens[op].ToString())); // Stack now has the destination value // now store the variable and clean up the stack compiler.Emit(OpCode.StoreVariable, new Operand(varName)); compiler.Emit(OpCode.Pop); }
private void GenerateClause(string jumpLabel, ParserRuleContext clauseContext, YarnSpinnerParser.StatementContext[] children, YarnSpinnerParser.ExpressionContext expression) { string endOfClauseLabel = this.compiler.RegisterLabel("skipclause"); // handling the expression (if it has one) will only be called on // ifs and elseifs if (expression != null) { // Code-generate the expression this.Visit(expression); this.compiler.Emit(OpCode.JumpIfFalse, expression.Start, new Operand(endOfClauseLabel)); } // running through all of the children statements foreach (var child in children) { this.Visit(child); } this.compiler.Emit(OpCode.JumpTo, clauseContext.Stop, new Operand(jumpLabel)); if (expression != null) { this.compiler.CurrentNode.Labels.Add(endOfClauseLabel, this.compiler.CurrentNode.Instructions.Count); this.compiler.Emit(OpCode.Pop, clauseContext.Stop); } }
internal void generateClause(string jumpLabel, YarnSpinnerParser.StatementContext[] children, YarnSpinnerParser.ExpressionContext expression) { string endOfClauseLabel = compiler.RegisterLabel("skipclause"); // handling the expression (if it has one) // will only be called on ifs and elseifs if (expression != null) { Visit(expression); compiler.Emit(OpCode.JumpIfFalse, new Operand(endOfClauseLabel)); } // running through all of the children statements foreach (var child in children) { Visit(child); } compiler.Emit(OpCode.JumpTo, new Operand(jumpLabel)); if (expression != null) { compiler.CurrentNode.Labels.Add(endOfClauseLabel, compiler.CurrentNode.Instructions.Count); compiler.Emit(OpCode.Pop); } }