Exemple #1
0
        /// <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);
            }
        }
Exemple #2
0
        /// <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);
        }
Exemple #3
0
        /// <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);
            }
        }
Exemple #4
0
        /// <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);
            }
        }
Exemple #5
0
        /// <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]);
        }
Exemple #8
0
        // 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);
            }
        }
Exemple #10
0
        /// <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]);
Exemple #11
0
 /// <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!");
        }
Exemple #15
0
        /// <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);
        }
Exemple #17
0
        /// <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]);
            }
        }
Exemple #19
0
        /// <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);
        }
Exemple #20
0
 /// <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);
            }
        }
Exemple #22
0
        /// <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);
Exemple #25
0
        /// <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);
 }
Exemple #27
0
 /// <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);
        }