/// <summary>Prepares to adapt a command entry to CIL.</summary> /// <param name="values">The adaptation-relevant values.</param> /// <param name="entry">The present entry ID.</param> public override void PreAdaptToCIL(CILAdaptationValues values, int entry) { CommandEntry cent = values.Entry.Entries[entry]; MapTag mt = MapTag.For(cent.Arguments[0].ToString()); if (mt.Internal.Count == 0) { throw new ErrorInducedException("Empty map input to require!"); } foreach (KeyValuePair <string, TemplateObject> pair in mt.Internal) { TagType tagType; if (pair.Value is TagTypeTag tag) { tagType = tag.Internal; } else if (!cent.System.TagSystem.Types.RegisteredTypes.TryGetValue(pair.Value.ToString(), out tagType)) { throw new ErrorInducedException("Invalid local variable type: " + pair.Value.ToString() + "!"); } int loc = values.LocalVariableLocation(pair.Key); if (loc >= 0) { TagReturnType type = values.LocalVariableType(loc); if (type.Type != tagType) { throw new ErrorInducedException("Required local variable '" + pair.Key + "' already exists, but is of type '" + type.Type.TypeName + "', when '" + pair.Value.ToString() + "' was required!"); } } values.AddVariable(pair.Key, tagType); } }
/// <summary>Prepares to adapt a command entry to CIL.</summary> /// <param name="values">The adaptation-relevant values.</param> /// <param name="entry">The relevant entry ID.</param> public override void PreAdaptToCIL(CILAdaptationValues values, int entry) { CommandEntry cent = values.Entry.Entries[entry]; string larg = cent.Arguments[0].ToString().ToLowerFast(); if (values.LocalVariableLocation(larg) >= 0) { throw new ErrorInducedException("Duplicate local variable: " + larg + "!"); } if (cent.Arguments[1].ToString().ToLowerFast() != "=") { throw new ErrorInducedException("Invalid input to var command: second argument must be '='."); } TagType t; if (cent.Arguments.Length >= 5) { if (cent.Arguments[3].ToString().ToLowerFast() != "as") { throw new ErrorInducedException("Invalid input to var command: fourth argument must be 'as'."); } string tname = cent.Arguments[4].ToString(); if (!cent.System.TagSystem.Types.RegisteredTypes.TryGetValue(tname, out t)) { throw new ErrorInducedException("Invalid local variable type: " + larg + "!"); } } else { t = ArgumentCompiler.ReturnType(cent.Arguments[2], values).Type; } values.AddVariable(larg, t); }
/// <summary>Adapts a command entry to CIL.</summary> /// <param name="values">The adaptation-relevant values.</param> /// <param name="entry">The present entry ID.</param> public override void AdaptToCIL(CILAdaptationValues values, int entry) { CommandEntry cent = values.CommandAt(entry); bool debug = cent.DBMode <= DebugMode.FULL; MapTag mt = MapTag.For(cent.Arguments[0].ToString()); if (mt.Internal.Count == 0) { throw new ErrorInducedException("Empty map input to require!"); } foreach (string varn in mt.Internal.Keys) { values.LoadQueue(); values.LoadEntry(entry); values.LoadLocalVariable(cent.VarLoc(varn)); values.ILGen.Emit(OpCodes.Ldstr, varn); values.ILGen.Emit(OpCodes.Call, REQUIRECOMMAND_CHECKFORVALIDITY); } if (debug) { values.LoadQueue(); values.LoadEntry(entry); values.ILGen.Emit(OpCodes.Call, REQUIRECOMMAND_OUTPUTSUCCESS); } }
/// <summary>Pre-Adapt helper for save targets.</summary> /// <param name="values">The adaptation-relevant values.</param> /// <param name="entry">The relevant entry ID.</param> /// <param name="canPreExist">Whether the variable is allowed to already exist.</param> /// <param name="tagType">The required type.</param> /// <param name="required">Whether a save name *must* be specified by the user.</param> /// <param name="defaultName">The default name (or null if none).</param> public void PreAdaptSaveMode(CILAdaptationValues values, int entry, bool canPreExist, TagType tagType, bool required, string defaultName = null) { CommandEntry cent = values.CommandAt(entry); string saveName = cent.GetSaveNameNoParse(defaultName); if (saveName == null) { if (!required) { return; } throw new ErrorInducedException($"Command '{Meta.Name}' requires a save name, but none was given."); } int preVarLoc = values.LocalVariableLocation(saveName, out TagReturnType preVarType); if (preVarLoc >= 0) { if (!canPreExist) { throw new ErrorInducedException($"Already have a save target var (labeled '{TextStyle.SeparateVal(saveName)}')?!"); } if (preVarType.Type != tagType) { throw new ErrorInducedException($"Already have a save target var (labeled '{TextStyle.SeparateVal(saveName)}', with type " + $"'{TextStyle.SeparateVal(preVarType.Type.TypeName)}') of wrong type (expected '{TextStyle.SeparateVal(tagType.TypeName)}')."); } cent.SaveLoc = preVarLoc; } else { cent.SaveLoc = values.AddVariable(saveName, tagType); } }
/// <summary> /// Gets the save variable location (used in Adapt, after using <see cref="PreAdaptSaveMode(CILAdaptationValues, int, bool, TagType, bool, string)"/> in PreAdapt). /// </summary> /// <param name="values">The adaptation-relevant values.</param> /// <param name="entry">The relevant entry ID.</param> /// <param name="defaultName">The default name (or null if none).</param> public static int GetSaveLoc(CILAdaptationValues values, int entry, string defaultName = null) { CommandEntry cent = values.CommandAt(entry); string sn = values.Entry.Entries[cent.BlockStart - 1].GetSaveNameNoParse(defaultName); return(cent.VarLoc(sn)); }
/// <summary>Prepares to adapt a command entry to CIL.</summary> /// <param name="values">The adaptation-relevant values.</param> /// <param name="entry">The present entry ID.</param> public override void PreAdaptToCIL(CILAdaptationValues values, int entry) { CommandEntry cent = values.Entry.Entries[entry]; if (cent.IsCallback) { values.PopVarSet(); return; } string arg = cent.Arguments[0].ToString(); if (arg == "next" || arg == "stop") { return; } values.PushVarSet(); string sn = cent.GetSaveNameNoParse("while_index"); if (values.LocalVariableLocation(sn) >= 0) { throw new ErrorInducedException("Already have a while_index var (labeled '" + sn + "')?!"); } TagType type = cent.TagSystem.Types.Type_Integer; values.AddVariable(sn, type); }
/// <summary>Adapts a command entry to CIL.</summary> /// <param name="values">The adaptation-relevant values.</param> /// <param name="entry">The present entry ID.</param> public override void AdaptToCIL(CILAdaptationValues values, int entry) { CommandEntry cent = values.Entry.Entries[entry]; if (cent.IsCallback) { values.MarkCommand(entry); // TODO: Debug? int dodgepoint = cent.BlockEnd + 2; while (dodgepoint < values.Entry.Entries.Length) { CommandEntry tent = values.Entry.Entries[dodgepoint]; if (tent.Command is ElseCommand) { dodgepoint = tent.BlockEnd + 2; } else { break; } } values.ILGen.Emit(OpCodes.Br, values.Entry.AdaptedILPoints[dodgepoint]); return; } if (cent.BlockEnd <= 0) { throw new Exception("Incorrectly defined IF command: no block follows!"); } values.MarkCommand(entry); values.LoadQueue(); values.LoadEntry(entry); values.ILGen.Emit(OpCodes.Call, TryIfCILMethod); values.ILGen.Emit(OpCodes.Brfalse, values.Entry.AdaptedILPoints[cent.BlockEnd + 2]); }
// NOTE: Intentionally no meta! /// <summary>Adapts a command entry to CIL.</summary> /// <param name="values">The adaptation-relevant values.</param> /// <param name="entry">The present entry ID.</param> public override void AdaptToCIL(CILAdaptationValues values, int entry) { // TODO: Type verification? (Can this type be modified in the way being attempted?) values.MarkCommand(entry); CommandEntry cent = values.Entry.Entries[entry]; bool debug = cent.DBMode.ShouldShow(DebugMode.FULL); string vn = cent.Arguments[0].ToString().ToLowerFast(); string[] split = vn.Split('.'); string mainVar = split[0]; if (!cent.VarLookup.TryGetValue(mainVar, out SingleCILVariable locVar)) { throw new ErrorInducedException("Unknown variable name '" + mainVar + "' - cannot set its value."); } TagReturnType varType = locVar.Type; string mode = cent.Arguments[1].ToString(); var operationType = mode switch { "=" => ObjectOperation.SET, "+=" => ObjectOperation.ADD, "-=" => ObjectOperation.SUBTRACT, "*=" => ObjectOperation.MULTIPLY, "/=" => ObjectOperation.DIVIDE, _ => throw new ErrorInducedException("That setter mode (" + mode + ") does not exist!"), }; if (split.Length > 1) { values.LoadLocalVariable(locVar.Index); if (locVar.Type.IsRaw) { // TODO: Work directly with raws values.ILGen.Emit(OpCodes.Newobj, locVar.Type.Type.RawInternalConstructor); // Handle raw translation if needed. } if (split.Length == 2) { values.ILGen.Emit(OpCodes.Dup); } values.ILGen.Emit(OpCodes.Ldstr, split[1]); if (varType.Type.Operation_GetSubSettable.Method.GetParameters().Length == 3) { values.LoadQueue(); values.LoadEntry(entry); values.ILGen.Emit(OpCodes.Call, Method_GetOES); } values.ILGen.Emit(OpCodes.Call, varType.Type.Operation_GetSubSettable.Method); for (int i = 2; i < split.Length; i++) { if (i + 1 == split.Length) { values.ILGen.Emit(OpCodes.Dup); } values.LoadEntry(entry); values.LoadQueue(); values.ILGen.Emit(OpCodes.Ldstr, split[i]); values.ILGen.Emit(OpCodes.Call, Method_GetSubObject); } values.LoadArgumentObject(entry, 2); values.ILGen.Emit(OpCodes.Ldstr, split[^ 1]);
/// <summary>Adapts a command entry to CIL.</summary> /// <param name="values">The adaptation-relevant values.</param> /// <param name="entry">The relevant entry ID.</param> public override void AdaptToCIL(CILAdaptationValues values, int entry) { CommandEntry cent = values.CommandAt(entry); if (cent.DBMode == DebugMode.FULL) { values.MarkCommand(entry); values.LoadQueue(); values.LoadEntry(entry); values.ILGen.Emit(OpCodes.Call, Method_DebugOutput); } }
/// <summary>Adapts a command entry to CIL.</summary> /// <param name="values">The adaptation-relevant values.</param> /// <param name="entry">The present entry ID.</param> public override void AdaptToCIL(CILAdaptationValues values, int entry) { CommandEntry cent = values.CommandAt(entry); bool db = cent.DBMode <= DebugMode.FULL; if (db) { values.LoadQueue(); values.LoadEntry(entry); values.ILGen.Emit(OpCodes.Call, DebugStopMethod); } values.ILGen.Emit(OpCodes.Br, values.Entry.AdaptedILPoints[^ 1]);
/// <summary>Prepares to adapt a command entry to CIL.</summary> /// <param name="values">The adaptation-relevant values.</param> /// <param name="entry">The relevant entry ID.</param> public virtual void PreAdaptToCIL(CILAdaptationValues values, int entry) { if (SaveMode != CommandSaveMode.NO_SAVE) { CommandEntry cent = values.CommandAt(entry); TagType saveTagType = cent.System.TagTypes.TypeForName(SaveType); if (saveTagType == null) { throw new ErrorInducedException($"Command '{TextStyle.SeparateVal(Meta.Name)}' specifies a non-existent save tag type '{TextStyle.SeparateVal(SaveType)}'."); } PreAdaptSaveMode(values, entry, true, saveTagType, SaveMode != CommandSaveMode.WHEN_NAME_SPECIFIED, DefaultSaveName); } }
/// <summary>Gets the resultant type of this argument bit.</summary> /// <param name="values">The relevant variable set.</param> /// <returns>The tag type.</returns> public override TagReturnType ReturnType(CILAdaptationValues values) { if (Bits.Length == 1) { // TODO: Generic handler? if (Start is LvarTagBase) { int var = (int)(((Bits[0].Variable.Bits[0]) as TextArgumentBit).InputValue as IntegerTag).Internal; return(values.LocalVariableType(var)); } return(Start.ResultType); } return(Bits[^ 1].TagHandler.Meta.ReturnTypeResult);
/// <summary>Prepares to adapt a command entry to CIL.</summary> /// <param name="values">The adaptation-relevant values.</param> /// <param name="entry">The relevant entry ID.</param> public override void PreAdaptToCIL(CILAdaptationValues values, int entry) { CommandEntry cent = values.Entry.Entries[entry]; string larg = cent.Arguments[0].ToString().ToLowerFast(); values.DBMode = larg switch { "full" => DebugMode.FULL, "minimal" => DebugMode.MINIMAL, "none" => DebugMode.NONE, "default" => values.Entry.Script.Debug, _ => throw new ErrorInducedException("Unknown debug mode: " + TextStyle.Separate + larg + TextStyle.Error + "!"), }; }
/// <summary>Adapts a command entry to CIL.</summary> /// <param name="values">The adaptation-relevant values.</param> /// <param name="entry">The present entry ID.</param> public override void AdaptToCIL(CILAdaptationValues values, int entry) { CommandEntry cent = values.Entry.Entries[entry]; string targ = cent.Arguments[0].ToString(); for (int i = 0; i < values.Entry.Entries.Length; i++) { if (values.Entry.Entries[i].Command is MarkCommand && values.Entry.Entries[i].Arguments[0].ToString() == targ) { // TODO: call Outputter function? values.ILGen.Emit(OpCodes.Br, values.Entry.AdaptedILPoints[i]); return; } } throw new Exception("GOTO command invalid: no matching mark!"); }
/// <summary>Adapts a command entry to CIL.</summary> /// <param name="values">The adaptation-relevant values.</param> /// <param name="entry">The relevant entry ID.</param> public override void AdaptToCIL(CILAdaptationValues values, int entry) { CommandEntry cent = values.CommandAt(entry); bool debug = cent.DBMode.ShouldShow(DebugMode.FULL); values.MarkCommand(entry); TagReturnType returnType = ArgumentCompiler.ReturnType(cent.Arguments[2], values); string lvarname = cent.Arguments[0].ToString().ToLowerFast(); SingleCILVariable locVar = cent.VarLookup[lvarname]; // This method: // runnable.Var = TYPE.CREATE_FOR(tagdata, runnable.entry.arg2()); // or: // runnable.Var = runnable.entry.arg2(); values.LoadRunnable(); values.LoadArgumentObject(entry, 2); if (cent.Arguments.Length > 4) { string type_name = cent.Arguments[4].ToString().ToLowerFast(); TagType specifiedType = cent.System.TagSystem.Types.RegisteredTypes[type_name]; TagReturnType specifiedReturnType = new(specifiedType, specifiedType.Meta.RawInternal); values.EnsureType(returnType, specifiedReturnType); // Ensure the correct object type. returnType = specifiedReturnType; } else { TagReturnType specifiedReturnType = new(returnType.Type, returnType.Type.Meta.RawInternal); values.EnsureType(returnType, specifiedReturnType); // Ensure the correct object type. returnType = specifiedReturnType; } values.ILGen.Emit(OpCodes.Stfld, locVar.Field); // Push the result into the local var if (debug) // If in debug mode... { values.LoadLocalVariable(locVar.Index); // Load variable. if (returnType.IsRaw) { values.ILGen.Emit(OpCodes.Newobj, returnType.Type.RawInternalConstructor); // Handle raw translation if needed. } values.ILGen.Emit(OpCodes.Ldstr, lvarname); // Load the variable name as a string. values.ILGen.Emit(OpCodes.Ldstr, returnType.Type.TypeName); // Load the variable type name as a string. values.LoadQueue(); // Load the queue values.LoadEntry(entry); // Load the entry values.ILGen.Emit(OpCodes.Call, Method_DebugHelper); // Call the debug method } }
/// <summary>Prepares to adapt a command entry to CIL.</summary> /// <param name="values">The adaptation-relevant values.</param> /// <param name="entry">The present entry ID.</param> public override void PreAdaptToCIL(CILAdaptationValues values, int entry) { CommandEntry cent = values.Entry.Entries[entry]; if (cent.IsCallback) { values.PopVarSet(); return; } string arg = cent.Arguments[0].ToString(); if (arg == "next" || arg == "stop") { return; } values.PushVarSet(); // TODO: scope properly! PreAdaptSaveMode(values, entry, false, cent.System.TagSystem.Types.Type_Dynamic, true); }
/// <summary>Prepares to adapt a command entry to CIL.</summary> /// <param name="values">The adaptation-relevant values.</param> /// <param name="entry">The present entry ID.</param> public override void PreAdaptToCIL(CILAdaptationValues values, int entry) { CommandEntry cent = values.Entry.Entries[entry]; if (cent.IsCallback) { values.PopVarSet(); return; } string arg0 = cent.Arguments[0].ToString(); if (arg0 == "define") { values.PushVarSet(); // TODO: Forcibly compress the block to an argument, instead of compiling the sub-block } else if (arg0 != "undefine" && arg0 != "stop") { throw new ErrorInducedException("First argument must be 'define', 'undefine', or 'stop'."); } }
/// <summary>Adapts a command entry to CIL.</summary> /// <param name="values">The adaptation-relevant values.</param> /// <param name="entry">The present entry ID.</param> public override void AdaptToCIL(CILAdaptationValues values, int entry) { CommandEntry cent = values.CommandAt(entry); bool db = cent.DBMode <= DebugMode.FULL; if (cent.IsCallback) { string sn = values.Entry.Entries[cent.BlockStart - 1].GetSaveNameNoParse("while_index"); int lvar_ind_loc = cent.VarLoc(sn); values.LoadQueue(); if (db) { values.LoadEntry(entry); } else { values.ILGen.Emit(OpCodes.Ldc_I4, cent.BlockStart - 1); } values.LoadLocalVariable(lvar_ind_loc); values.ILGen.Emit(OpCodes.Call, db ? TryWhileCILMethod : TryWhileCILMethodNoDebug); values.ILGen.Emit(OpCodes.Brtrue, values.Entry.AdaptedILPoints[cent.BlockStart]); return; } string arg = cent.Arguments[0].ToString(); if (arg == "stop") { for (int i = entry - 1; i >= 0; i--) { CommandEntry nextEntry = values.Entry.Entries[i]; if (nextEntry.Command is not WhileCommand || nextEntry.IsCallback) { continue; } string a0 = nextEntry.Arguments[0].ToString(); if (a0 != "stop" && a0 != "next" && nextEntry.InnerCommandBlock != null) { if (db) { values.LoadQueue(); values.LoadEntry(entry); values.ILGen.Emit(OpCodes.Call, DebugStopMethod); } values.ILGen.Emit(OpCodes.Br, values.Entry.AdaptedILPoints[nextEntry.BlockEnd + 2]); return; } } throw new ErrorInducedException("Invalid 'while stop' command: not inside a while block!"); } else if (arg == "next") { for (int i = entry - 1; i >= 0; i--) { CommandEntry nextEntry = values.Entry.Entries[i]; if (nextEntry.Command is not WhileCommand || nextEntry.IsCallback) { continue; } string a0 = nextEntry.ToString(); if (a0 != "stop" && a0 != "next" && nextEntry.InnerCommandBlock != null) { if (db) { values.LoadQueue(); values.LoadEntry(entry); values.ILGen.Emit(OpCodes.Call, DebugNextMethod); } values.ILGen.Emit(OpCodes.Br, values.Entry.AdaptedILPoints[nextEntry.BlockEnd + 1]); return; } } throw new ErrorInducedException("Invalid 'while next' command: not inside a while block!"); } else { values.LoadQueue(); values.LoadEntry(entry); values.ILGen.Emit(OpCodes.Call, CreateIndexObjectMethod); values.ILGen.Emit(OpCodes.Stfld, cent.VarLookup[cent.GetSaveNameNoParse("while_index")].Field); values.ILGen.Emit(OpCodes.Call, db ? TryWhileNumberedCILMethod : TryWhileNumberedCIL_NoDebugMethod); values.ILGen.Emit(OpCodes.Brfalse, values.Entry.AdaptedILPoints[cent.BlockEnd + 2]); } }
/// <summary>Adapts the tag base to CIL.</summary> /// <param name="ilgen">IL Generator.</param> /// <param name="tab">The TagArgumentBit.</param> /// <param name="values">Related adaptation values.</param> /// <returns>Whether any adaptation was done.</returns> public override bool AdaptToCIL(ILGeneratorTracker ilgen, TagArgumentBit tab, CILAdaptationValues values) { int index = (int)((tab.Bits[0].Variable.Bits[0] as TextArgumentBit).InputValue as IntegerTag).Internal; ilgen.Emit(OpCodes.Ldarg_0); // Load argument: TagData ilgen.Emit(OpCodes.Ldfld, TagData.Field_TagData_Runnable); // Load TagData.Runnable ilgen.Emit(OpCodes.Ldfld, values.LocalVariableData(index).Field); // Load Runnable.Var return(true); }
/// <summary>Adapts a command entry to CIL.</summary> /// <param name="values">The adaptation-relevant values.</param> /// <param name="entry">The relevant entry ID.</param> public virtual void AdaptToCIL(CILAdaptationValues values, int entry) { values.CallExecute(entry, this); }
/// <summary>Adapts a command entry to CIL.</summary> /// <param name="values">The adaptation-relevant values.</param> /// <param name="entry">The present entry ID.</param> public override void AdaptToCIL(CILAdaptationValues values, int entry) { CommandEntry cent = values.CommandAt(entry); bool db = cent.DBMode <= DebugMode.FULL; if (cent.IsCallback) { int lvar_ind_loc = GetSaveLoc(values, entry); values.LoadQueue(); if (db) { values.LoadEntry(entry); } else { values.ILGen.Emit(OpCodes.Ldc_I4, cent.BlockStart - 1); } values.LoadLocalVariable(lvar_ind_loc); values.ILGen.Emit(OpCodes.Call, db ? TryForeachCILMethod : TryForeachCILMethodNoDebug); values.ILGen.Emit(OpCodes.Brtrue, values.Entry.AdaptedILPoints[cent.BlockStart]); return; } string arg = cent.Arguments[0].ToString(); if (arg == "stop") { for (int i = entry - 1; i >= 0; i--) { CommandEntry nextEntry = values.Entry.Entries[i]; if (nextEntry.Command is not ForeachCommand || nextEntry.IsCallback) { continue; } string a0 = nextEntry.Arguments[0].ToString(); if (a0 == "start" && nextEntry.InnerCommandBlock != null) { if (db) { values.LoadQueue(); values.LoadEntry(entry); values.ILGen.Emit(OpCodes.Call, DebugStopMethod); } values.ILGen.Emit(OpCodes.Br, values.Entry.AdaptedILPoints[nextEntry.BlockEnd + 2]); return; } } throw new ErrorInducedException("Invalid 'foreach stop' command: not inside a foreach block!"); } else if (arg == "next") { for (int i = entry - 1; i >= 0; i--) { CommandEntry nextEntry = values.Entry.Entries[i]; if (nextEntry.Command is not ForeachCommand || nextEntry.IsCallback) { continue; } string a0 = nextEntry.Arguments[0].ToString(); if (a0 == "start" && nextEntry.InnerCommandBlock != null) { if (db) { values.LoadQueue(); values.LoadEntry(entry); values.ILGen.Emit(OpCodes.Call, DebugNextMethod); } values.ILGen.Emit(OpCodes.Br, values.Entry.AdaptedILPoints[nextEntry.BlockEnd + 1]); return; } } throw new ErrorInducedException("Invalid 'foreach next' command: not inside a foreach block!"); } else if (arg == "start") { SingleCILVariable locVar = cent.VarLookup[cent.GetSaveNameNoParse("foreach_value")]; values.LoadQueue(); values.LoadEntry(entry); values.LoadRunnable(); values.ILGen.Emit(OpCodes.Call, CreateListItemMethod); values.ILGen.Emit(OpCodes.Stfld, locVar.Field); values.LoadLocalVariable(locVar.Index); values.ILGen.Emit(OpCodes.Call, db ? TryForeachNumberedCILMethod : TryForeachNumberedCIL_NoDebugMethod); values.ILGen.Emit(OpCodes.Brfalse, values.Entry.AdaptedILPoints[cent.BlockEnd + 2]); } else { throw new ErrorInducedException("Invalid 'foreach' command: unknown argument: " + arg); } }
/// <summary>Adapts a command entry to CIL.</summary> /// <param name="values">The adaptation-relevant values.</param> /// <param name="entry">The relevant entry ID.</param> public override void AdaptToCIL(CILAdaptationValues values, int entry) { CommandEntry cent = values.Entry.Entries[entry]; bool db = cent.DBMode <= DebugMode.FULL; if (cent.IsCallback) { if (db) { values.LoadQueue(); values.LoadEntry(entry); values.ILGen.Emit(OpCodes.Call, DebugCallbackMethod); } return; } string arg0 = cent.Arguments[0].ToString(); if (arg0 == "stop") { for (int i = entry - 1; i >= 0; i--) { CommandEntry nextEntry = values.Entry.Entries[i]; if (nextEntry.Command is not FunctionCommand) { continue; } if (nextEntry.IsCallback) { if (db) { values.LoadQueue(); values.LoadEntry(entry); values.ILGen.Emit(OpCodes.Call, DebugStopMethod); } values.ILGen.Emit(OpCodes.Br, values.Entry.AdaptedILPoints[i + 2]); return; } } throw new ErrorInducedException("Invalid 'function stop' command: not inside a function block!"); } else if (arg0 == "undefine") { if (cent.Arguments.Length < 2) { throw new ErrorInducedException("Invalid 'function undefine' command: must label what function to undefine (as an additional argument)!"); } values.LoadEntry(entry); values.LoadQueue(); values.ILGen.Emit(OpCodes.Call, UndefineMethod); } else // "define" { if (cent.Arguments.Length < 2) { throw new ErrorInducedException("Invalid 'function define' command: must name the function to define (as an additional argument)!"); } if (cent.InnerCommandBlock == null) { throw new ErrorInducedException("Invalid 'function define' command: must be followed by a block-function to define!"); } values.LoadEntry(entry); values.LoadQueue(); values.ILGen.Emit(OpCodes.Call, DefineMethod); values.ILGen.Emit(OpCodes.Br, values.Entry.AdaptedILPoints[cent.BlockEnd + 2]); } }
/// <summary>Adapts the template tab base for compiling.</summary> /// <param name="ccse">The compiled CSE.</param> /// <param name="tab">The TagArgumentBit.</param> /// <param name="i">The command index.</param> /// <param name="values">Related adaptation values.</param> public virtual TagReturnType Adapt(CompiledCommandStackEntry ccse, TagArgumentBit tab, int i, CILAdaptationValues values) { return(default);
/// <summary>Gets the resultant type of this argument bit.</summary> /// <param name="values">The relevant variable set.</param> /// <returns>The tag type.</returns> public abstract TagReturnType ReturnType(CILAdaptationValues values);
/// <summary>Adapts the var tag base for compiling.</summary> /// <param name="ccse">The compiled CSE.</param> /// <param name="tab">The TagArgumentBit.</param> /// <param name="i">The command index.</param> /// <param name="values">Related adaptation values.</param> public override TagReturnType Adapt(CompiledCommandStackEntry ccse, TagArgumentBit tab, int i, CILAdaptationValues values) { int index = (int)((tab.Bits[0].Variable.Bits[0] as TextArgumentBit).InputValue as IntegerTag).Internal; return(values.LocalVariableType(index)); }
/// <summary>Adapts the tag base to CIL.</summary> /// <param name="ilgen">IL Generator.</param> /// <param name="tab">The TagArgumentBit.</param> /// <param name="values">Related adaptation values.</param> /// <returns>Whether any adaptation was done.</returns> public virtual bool AdaptToCIL(ILGeneratorTracker ilgen, TagArgumentBit tab, CILAdaptationValues values) { return(false); }
/// <summary>Adapts a command entry to CIL.</summary> /// <param name="values">The adaptation-relevant values.</param> /// <param name="entry">The present entry ID.</param> public override void AdaptToCIL(CILAdaptationValues values, int entry) { base.AdaptToCIL(values, entry); values.ILGen.Emit(OpCodes.Ret); }
/// <summary>Gets the resultant type of this argument bit.</summary> /// <param name="values">The relevant variable set.</param> /// <returns>The tag type.</returns> public override TagReturnType ReturnType(CILAdaptationValues values) { return(new TagReturnType(Engine.TagSystem.Types.RegisteredTypes[ResType], false)); }
/// <summary>Adapts the var tag base for compiling.</summary> /// <param name="ccse">The compiled CSE.</param> /// <param name="tab">The TagArgumentBit.</param> /// <param name="i">The command index.</param> /// <param name="values">Related adaptation values.</param> public override TagReturnType Adapt(CompiledCommandStackEntry ccse, TagArgumentBit tab, int i, CILAdaptationValues values) { string vn = tab.Bits[0].Variable.ToString().ToLowerFast(); CommandEntry entry = ccse.Entries[i]; if (!entry.VarLookup.TryGetValue(vn, out SingleCILVariable locVar)) { throw new ErrorInducedException("Var tag cannot compile: unknown variable name input '" + vn + "' (That variable name cannot be found. Have you declared it in this script section? Consider using the 'require' command.)"); } tab.Start = tab.TagSystem.LVar; tab.Bits[0].Key = "\0lvar"; tab.Bits[0].Handler = null; tab.Bits[0].OriginalInput = "[" + tab.Bits[0].Variable.ToString() + "]"; tab.Bits[0].Variable = new Argument() { WasQuoted = false, Bits = new ArgumentBit[] { new TextArgumentBit(locVar.Index, tab.Engine) } }; return(locVar.Type); }