public override void GenerateIntoContainer(Runtime.Container container) { if (value is int) { container.AddContent (new Runtime.IntValue ((int)value)); } else if (value is float) { container.AddContent (new Runtime.FloatValue ((float)value)); } }
public override void GenerateIntoContainer (Runtime.Container container) { container.AddContent (Runtime.ControlCommand.BeginString()); foreach (var c in content) { container.AddContent (c.runtimeObject); } container.AddContent (Runtime.ControlCommand.EndString()); }
public override void GenerateIntoContainer(Runtime.Container container) { leftExpression.GenerateIntoContainer (container); rightExpression.GenerateIntoContainer (container); opName = NativeNameForOp (opName); container.AddContent(Runtime.NativeFunctionCall.CallWithName(opName)); }
// When generating the value of a constant expression, // we can't just keep generating the same constant expression into // different places where the constant value is referenced, since then // the same runtime objects would be used in multiple places, which // is impossible since each runtime object should have one parent. // Instead, we generate a prototype of the runtime object(s), then // copy them each time they're used. public void GenerateConstantIntoContainer(Runtime.Container container) { if( _prototypeRuntimeConstantExpression == null ) { _prototypeRuntimeConstantExpression = new Runtime.Container (); GenerateIntoContainer (_prototypeRuntimeConstantExpression); } foreach (var runtimeObj in _prototypeRuntimeConstantExpression.content) { container.AddContent (runtimeObj.Copy()); } }
public override void GenerateIntoContainer(Runtime.Container container) { divert.GenerateRuntimeObject(); _runtimeDivert = (Runtime.Divert) divert.runtimeDivert; _runtimeDivertTargetValue = new Runtime.DivertTargetValue (); if (divert.arguments != null && divert.arguments.Count > 0) { Error ("Can't use a divert target as a variable if it has parameters"); return; } container.AddContent (_runtimeDivertTargetValue); }
public override void GenerateIntoContainer (Runtime.Container container) { Expression constantValue = null; // Name can be null if it's actually a path to a knot/stitch etc for a read count var varName = name; // If it's a constant reference, just generate the literal expression value if ( varName != null && story.constants.TryGetValue (varName, out constantValue) ) { constantValue.GenerateConstantIntoContainer (container); isConstantReference = true; } else { _runtimeVarRef = new Runtime.VariableReference (name); container.AddContent(_runtimeVarRef); } }
public override void GenerateIntoContainer(Runtime.Container container) { // A && B && C && D // => (((A B &&) C &&) D &&) etc bool isFirst = true; foreach (var conditionExpr in subExpressions) { conditionExpr.GenerateIntoContainer (container); if (!isFirst) { container.AddContent (Runtime.NativeFunctionCall.CallWithName ("&&")); } isFirst = false; } }
public override void GenerateIntoContainer(Runtime.Container container) { // x = x + 1 // ^^^ ^ ^ ^ // 4 1 3 2 // Reverse polish notation: (x 1 +) (assign to x) // 1. container.AddContent (new Runtime.VariableReference (varName)); // 2. container.AddContent (new Runtime.IntValue (isInc ? 1 : -1)); // 3. container.AddContent (Runtime.NativeFunctionCall.CallWithName ("+")); // 4. container.AddContent (new Runtime.VariableAssignment (varName, false)); // Finally, leave the variable on the stack so it can be used as a sub-expression container.AddContent (new Runtime.VariableReference (varName)); }
public override void GenerateIntoContainer(Runtime.Container container) { innerExpression.GenerateIntoContainer (container); container.AddContent(Runtime.NativeFunctionCall.CallWithName(nativeNameForOp)); }
void GenerateArgumentVariableAssignments(Runtime.Container container) { if (this.arguments == null || this.arguments.Count == 0) { return; } // Assign parameters in reverse since they'll be popped off the evaluation stack // No need to generate EvalStart and EvalEnd since there's nothing being pushed // back onto the evaluation stack. for (int i = arguments.Count - 1; i >= 0; --i) { var paramName = arguments [i].name; var assign = new Runtime.VariableAssignment (paramName, isNewDeclaration:true); container.AddContent (assign); } }
public override void GenerateIntoContainer (Runtime.Container container) { if (isChoiceCount) { if (arguments.Count > 0) Error ("The CHOICE_COUNT() function shouldn't take any arguments"); container.AddContent (Runtime.ControlCommand.ChoiceCount ()); } else if (isTurnsSince) { var divertTarget = arguments [0] as DivertTarget; var variableDivertTarget = arguments [0] as VariableReference; if (arguments.Count != 1 || (divertTarget == null && variableDivertTarget == null)) { Error ("The TURNS_SINCE() function should take one argument: a divert target to the target knot, stitch, gather or choice you want to check. e.g. TURNS_SINCE(-> myKnot)"); return; } if (divertTarget) { _turnCountDivertTarget = divertTarget; AddContent (_turnCountDivertTarget); _turnCountDivertTarget.GenerateIntoContainer (container); } else { _turnCountVariableReference = variableDivertTarget; AddContent (_turnCountVariableReference); _turnCountVariableReference.GenerateIntoContainer (container); if (!story.countAllVisits) { Error ("Attempting to get TURNS_SINCE for a variable target without -c compiler option. You need the compiler switch turned on so that it can track turn counts for everything, not just those you directly reference."); } } container.AddContent (Runtime.ControlCommand.TurnsSince ()); } else if (isRandom) { if (arguments.Count != 2) Error ("RANDOM should take 2 parameters: a minimum and a maximum integer"); // We can type check single values, but not complex expressions for (int arg = 0; arg < arguments.Count; arg++) { if (arguments [arg] is Number) { var num = arguments [arg] as Number; if (!(num.value is int)) { string paramName = arg == 0 ? "minimum" : "maximum"; Error ("RANDOM's "+paramName+" parameter should be an integer"); } } arguments[arg].GenerateIntoContainer (container); } container.AddContent (Runtime.ControlCommand.Random ()); } else if (isSeedRandom) { if (arguments.Count != 1) Error ("SEED_RANDOM should take 1 parameter - an integer seed"); var num = arguments [0] as Number; if (num && !(num.value is int)) { Error ("SEED_RANDOM's parameter should be an integer seed"); } arguments [0].GenerateIntoContainer (container); container.AddContent (Runtime.ControlCommand.SeedRandom ()); } // Normal function call else { container.AddContent (_proxyDivert.runtimeObject); } // Function calls that are used alone on a tilda-based line: // ~ func() // Should tidy up any returned value from the evaluation stack, // since it's unused. if (shouldPopReturnedValue) container.AddContent (Runtime.ControlCommand.PopEvaluatedValue ()); }