/// <summary>Constructs a single CIL adapter variable.</summary> /// <param name="_index">The variable index.</param> /// <param name="_name">The variable name.</param> /// <param name="_type">The variable type.</param> /// <param name="_field">The field for this variable.</param> public SingleCILVariable(int _index, string _name, TagReturnType _type, FieldInfo _field) { Index = _index; Name = _name; Type = _type; Field = _field; }
/// <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); } }
// 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>Prepares the tag meta.</summary> /// <param name="tags">The tag parser.</param> public void Ready(TagHandler tags) { ActualType = TagType == null ? null : tags.Types.RegisteredTypes[TagType]; if (ReturnType == null || !tags.Types.RegisteredTypes.TryGetValue(ReturnType, out TagType returnedTagType)) { ReturnTypeResult = default; } else { ReturnTypeResult = new TagReturnType(returnedTagType, false); } ModifierType = new TagReturnType(Modifier == null ? null : tags.Types.RegisteredTypes[Modifier], false); }
/// <summary> /// Returns the location of a local variable, by name. /// Returns -1 if not found. /// </summary> /// <param name="name">The name.</param> /// <param name="type">The type of the local variable.</param> /// <returns>The location.</returns> public int LocalVariableLocation(string name, out TagReturnType type) { foreach (int i in LVarIDs) { foreach (SingleCILVariable locVar in CLVariables[i]) { if (locVar.Name == name) { type = locVar.Type; return(locVar.Index); } } } type = default; return(-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); 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 } }
public static TagReturnType Compiler_Tag_As(ILGeneratorTracker ilgen, TagArgumentBit tab, int bit, TagReturnType prevType) { ilgen.Emit(OpCodes.Ldfld, Field_DynamicTag_Internal); // Load field "Internal" on the input DynamicTag instance. ilgen.Emit(OpCodes.Ldarg_0); // Load argument: TagData. string type_name = tab.Bits[bit].Variable.ToString(); TagType varType = tab.Engine.TagSystem.Types.RegisteredTypes[type_name.ToLowerFast()]; ilgen.Emit(OpCodes.Call, varType.CreatorMethod); // Run the creator method for the type on the input tag. return(new TagReturnType(varType, false)); }