public static void UpdateUsing(CSTranslationContext context, VMVariableScope scope)
        {
            var csClass = context.CurrentClass;

            if (!csClass.UseLocals &&
                (scope == VMVariableScope.Local || scope == VMVariableScope.LocalByTemp))
            {
                csClass.UseLocals = true;
            }

            if (!csClass.UseTemps &&
                (scope == VMVariableScope.Temps || scope == VMVariableScope.TempByTemp || scope == VMVariableScope.DynSpriteFlagForTempOfStackObject ||
                 scope == VMVariableScope.LocalByTemp || scope == VMVariableScope.MyPersonDataByTemp || scope == VMVariableScope.RoomByTemp0 ||
                 scope == VMVariableScope.StackObjectAttributeByTemp || scope == VMVariableScope.StackObjectMotiveByTemp || scope == VMVariableScope.StackObjectPersonDataByTemp ||
                 scope == VMVariableScope.StackObjectTemp || scope == VMVariableScope.TempXL || scope == VMVariableScope.JobData || scope == VMVariableScope.MyList ||
                 scope == VMVariableScope.StackObjectList))
            {
                csClass.UseTemps = true;
            }

            if (!csClass.UseParams &&
                (scope == VMVariableScope.Parameters || scope == VMVariableScope.StackObjectAttributeByParameter))
            {
                csClass.UseParams = true;
            }
        }
        public void InitInfo(CSTranslationContext ctx)
        {
            var info = GetInfoFromId(ctx, Instruction.Opcode);

            _CanYield = info.Item1;
            FuncFile  = info.Item2;
            FuncClass = info.Item3;
            FuncArgs  = info.Item4;
        }
        private static Tuple <bool, string, string, int> GetInfoFromId(CSTranslationContext ctx, ushort call)
        {
            SimAnticsModule      module;
            CSTranslationContext ctx2;

            //find the bhav.
            if (call < 4096)
            {
                //global
                module = ctx.GlobalModule;
                ctx2   = ctx.GlobalContext as CSTranslationContext;
            }
            else if (call < 8192)
            {
                //local (can only be us)
                module = null;
                ctx2   = null;
            }
            else
            {
                //semiglobal
                module = ctx.SemiGlobalModule;
                ctx2   = ctx.SemiGlobalContext as CSTranslationContext;
            }

            if (ctx2 != null)
            {
                //in previously compiled context
                StructuredBHAV newBHAV;
                if (ctx2.BHAVInfo.TryGetValue(call, out newBHAV))
                {
                    return(new Tuple <bool, string, string, int>(newBHAV.Yields, ctx2.NamespaceName, CSTranslationContext.FormatName(newBHAV.Source.ChunkLabel) + "_" + newBHAV.Source.ChunkID, Math.Max(4, (int)newBHAV.Source.Args)));
                }
                return(new Tuple <bool, string, string, int>(true, null, null, 4));
            }
            if (module != null)
            {
                //in compiled module
                var func = module.GetFunction(call);
                if (func == null)
                {
                    return(new Tuple <bool, string, string, int>(true, null, null, 4));
                }
                return(new Tuple <bool, string, string, int>(func is IBHAV, module.GetType().Namespace, func.GetType().Name, (func as IInlineBHAV)?.ArgCount ?? 4));
            }
            else
            {
                StructuredBHAV newBHAV;
                if (ctx.BHAVInfo.TryGetValue(call, out newBHAV))
                {
                    return(new Tuple <bool, string, string, int>(newBHAV.Yields, null, CSTranslationContext.FormatName(newBHAV.Source.ChunkLabel) + "_" + newBHAV.Source.ChunkID, Math.Max(4, (int)newBHAV.Source.Args)));
                }
                return(new Tuple <bool, string, string, int>(true, null, null, 4));
            }
        }
        public static string GetConstant(CSTranslationContext context, VMVariableScope scope, short data)
        {
            switch (scope)
            {
            case VMVariableScope.Literal:
                return(data.ToString());

            case VMVariableScope.Tuning:
                return(GetTuningVariable(context, (ushort)data).ToString());
            }
            throw new Exception("Scope " + scope.ToString() + " not supported as Constant.");
        }
 public RoslynSimanticsModule(RoslynSimanticsContext context, GameIffResource file)
 {
     Context = context;
     File    = file;
     if (file is GameGlobalResource)
     {
         if (file.MainIff.Filename == "global.iff")
         {
             IsGlobal = true;
         }
         else
         {
             IsSemiGlobal = true;
         }
     }
     Name     = CSTranslationContext.FormatName(File.MainIff.Filename.Replace(".iff", ""));
     FilePath = Path.Combine(Context.CacheDirectory, Name);
 }
Exemple #6
0
        public RoslynSimanticsModule GetModuleFor(GameIffResource res)
        {
            var source = res.MainIff;
            var name   = CSTranslationContext.FormatName(source.Filename.Substring(0, source.Filename.Length - 4));
            RoslynSimanticsModule result;

            lock (FormattedNameToRoslynModule) {
                if (FormattedNameToRoslynModule.TryGetValue(name, out result))
                {
                    return(result);
                }
                else
                {
                    //try to create one!
                    result = new RoslynSimanticsModule(Context, res);
                    FormattedNameToRoslynModule[name] = result;
                    return(result);
                }
            }
        }
Exemple #7
0
        public SimAnticsModule GetModuleFor(IffFile source)
        {
            if (source.CachedJITModule != null)
            {
                return((SimAnticsModule)source.CachedJITModule);
            }
            var             name = CSTranslationContext.FormatName(source.Filename.Substring(0, source.Filename.Length - 4));
            SimAnticsModule result;

            if (FormattedNameToModule.TryGetValue(name, out result))
            {
                //TODO: checksum
                if (!result.Inited)
                {
                    result.Init();
                }
                source.CachedJITModule = result;
                return(result);
            }
            return(null);
        }
        public void ConversionAction()
        {
            int i = 0;

            while (i++ < 1)
            {
                var translator = new CSTranslator();
                var globalRes  = Content.Content.Get().WorldObjectGlobals.Get("global").Resource;

                var iff = globalRes.MainIff;
                iff.Filename = "global.iff";
                translator.Context.GlobalRes = globalRes;
                var globalText = translator.TranslateIff(iff);
                using (var file = System.IO.File.Open(Path.Combine(DestPath, "Global.cs"), System.IO.FileMode.Create))
                {
                    using (var writer = new System.IO.StreamWriter(file))
                    {
                        writer.Write(globalText);
                    }
                }

                if (Abort)
                {
                    break;
                }

                var globalContext = (CSTranslationContext)translator.Context;

                var compiledSG   = new Dictionary <GameGlobalResource, CSTranslationContext>();
                var objs         = Content.Content.Get().WorldObjects.Entries.Where(x => User || (x.Value.Source != GameObjectSource.User)).ToList();
                var fileComplete = new HashSet <string>();
                var objPct       = 0;
                foreach (var obj in objs)
                {
                    var r = obj.Value;
                    if (!fileComplete.Contains(r.FileName))
                    {
                        Invoke(new Action(() => {
                            AOTProgress.Value = 10 + (objPct * 90) / objs.Count;
                        }));
                        fileComplete.Add(r.FileName);
                        var objRes = r.Get();

                        CSTranslationContext sg = null;
                        if (objRes.Resource.SemiGlobal != null)
                        {
                            if (!compiledSG.TryGetValue(objRes.Resource.SemiGlobal, out sg))
                            {
                                //compile semiglobals
                                translator = new CSTranslator();
                                var sgIff = objRes.Resource.SemiGlobal.MainIff;
                                translator.Context.ObjectRes     = objRes.Resource; //pass this in as occasionally *local* tuning constants are used in *semiglobal* functions.
                                translator.Context.GlobalRes     = globalRes;
                                translator.Context.SemiGlobalRes = objRes.Resource.SemiGlobal;
                                translator.Context.GlobalContext = globalContext;
                                Invoke(new Action(() => {
                                    AOTStatus.Text = $"Translating Semi-Global {sgIff.Filename}";
                                }));
                                var semiglobalText = translator.TranslateIff(sgIff);
                                using (var file = System.IO.File.Open(Path.Combine(DestPath, translator.Context.Filename + ".cs"), System.IO.FileMode.Create))
                                {
                                    using (var writer = new System.IO.StreamWriter(file))
                                    {
                                        writer.Write(semiglobalText);
                                    }
                                }
                                sg = (CSTranslationContext)translator.Context;
                                compiledSG[objRes.Resource.SemiGlobal] = sg;
                            }
                        }

                        translator = new CSTranslator();
                        var objIff = objRes.Resource.MainIff;
                        translator.Context.GlobalRes         = globalRes;
                        translator.Context.SemiGlobalRes     = objRes.Resource.SemiGlobal;
                        translator.Context.ObjectRes         = objRes.Resource;
                        translator.Context.GlobalContext     = globalContext;
                        translator.Context.SemiGlobalContext = sg;
                        Invoke(new Action(() => {
                            AOTStatus.Text = $"Translating {objIff.Filename}";
                        }));
                        var objText = translator.TranslateIff(objIff);
                        using (var file = System.IO.File.Open(Path.Combine(DestPath, translator.Context.Filename + ".cs"), System.IO.FileMode.Create))
                        {
                            using (var writer = new System.IO.StreamWriter(file))
                            {
                                writer.Write(objText);
                            }
                        }
                    }
                    objPct++;
                }

                if (!Abort)
                {
                    Invoke(new Action(() => {
                        AOTStatus.Text    = $"Completed! {objs.Count} objects converted.";
                        AOTProgress.Value = 100;
                    }));
                }
            }
            if (Abort)
            {
                Invoke(new Action(() => {
                    AOTStatus.Text = "Aborted.";
                }));
            }

            Invoke(new Action(() => {
                AOTToggle.Text    = "Begin";
                AOTToggle.Enabled = true;
            }));
            Abort            = false;
            ConversionThread = null;
        }
        public static string SetStatement(CSTranslationContext context, VMVariableScope scope, short data, string op, string value, bool big)
        {
            UpdateUsing(context, scope);
            if (big && !IsBig(scope))
            {
                value = $"(short)({value})";
            }

            if (ScopeMutable(scope))
            {
                //the GetVariable version is mutable, meaning we can use +=, %= etc.
                var exp = GetExpression(context, scope, data, big);
                return($"{exp} {op} {value};");
            }
            else
            {
                if (op != "=")
                {
                    op = op.Substring(0, 1);
                    var exp = GetExpression(context, scope, data, big);
                    value = $"(short)({exp} {op} {value})"; //eg. "x[0] += 1" becomes "x[0] = x[0] + 1";
                }
                switch (scope)
                {
                case VMVariableScope.MyObjectAttributes:     //0
                    return($"context.Caller.SetAttribute({(ushort)data}, {value});");

                case VMVariableScope.StackObjectAttributes:     //1
                    return($"context.StackObject.SetAttribute({(ushort)data}, {value});");

                case VMVariableScope.TargetObjectAttributes:     //2
                    throw new Exception("Target Object is Deprecated!");

                case VMVariableScope.MyObject:     //3
                    return($"context.Caller.SetValue({EnumValueName((VMStackObjectVariable)data)}, {value});");

                case VMVariableScope.StackObject:     //4
                    return($"context.StackObject.SetValue({EnumValueName((VMStackObjectVariable)data)}, {value});");

                case VMVariableScope.TargetObject:     //5
                    throw new Exception("Target Object is Deprecated!");

                case VMVariableScope.Global:     //6
                    return($"context.VM.SetGlobalValue({(ushort)data}, {value});");

                case VMVariableScope.Literal:     //7
                    /** Huh? **/
                    return($"");

                case VMVariableScope.TreeAdRange:     //12
                    return($"");                      //can't set this!

                case VMVariableScope.StackObjectTemp: //13
                    break;

                case VMVariableScope.MyMotives:     //14
                    return($"((VMAvatar)context.Caller).SetMotiveData({EnumValueName((VMMotive)data)}, {value});");

                case VMVariableScope.StackObjectMotives:     //15
                    return($"(context.StackObject as VMAvatar)?.SetMotiveData({EnumValueName((VMMotive)data)}, {value});");

                case VMVariableScope.StackObjectSlot:                         //16
                    return($"/* attempting to assign stack object slot? */"); //can't set this!

                //throw new Exception("Not implemented...");

                case VMVariableScope.StackObjectMotiveByTemp:     //17
                    return($"((VMAvatar)context.StackObject).SetMotiveData((VMMotive)temps[{data}], {value});");

                case VMVariableScope.MyPersonData:     //18
                    return($"((VMAvatar)context.Caller).SetPersonData({EnumValueName((VMPersonDataVariable)data)}, {value});");

                case VMVariableScope.StackObjectPersonData:     //19
                    return($"((VMAvatar)context.StackObject).SetPersonData({EnumValueName((VMPersonDataVariable)data)}, {value});");

                case VMVariableScope.MySlot:     //20
                    throw new Exception("Not implemented...");

                case VMVariableScope.StackObjectDefinition:           //21
                    return($"");                                      //you can't set this!

                case VMVariableScope.StackObjectAttributeByParameter: //22
                    return($"context.StackObject.SetAttribute((ushort)args[{data}], {value});");

                //23: room by temp 0
                //24: neighbor in stack object

                case VMVariableScope.Tuning:                            //26
                    return($"");                                        //you can't set this!

                case VMVariableScope.DynSpriteFlagForTempOfStackObject: //27
                    return($"context.StackObject.SetDynamicSpriteFlag((ushort)temps[{data}], {value} > 0);");

                case VMVariableScope.TreeAdPersonalityVar: //28
                    return($"");                           //you can't set this!

                case VMVariableScope.TreeAdMin:            //29
                    return($"");                           //you can't set this!

                case VMVariableScope.MyPersonDataByTemp:   //30
                    return($"((VMAvatar)context.Caller).SetPersonData((VMPersonDataVariable)temps[{data}], {value});");

                case VMVariableScope.StackObjectPersonDataByTemp:     //31
                    return($"((VMAvatar)context.StackObject).SetPersonData((VMPersonDataVariable)temps[{data}], {value});");

                case VMVariableScope.NeighborPersonData:     //32
                    throw new Exception("Not implemented...");

                case VMVariableScope.JobData:     //33
                    throw new Exception("Not implemented...");

                case VMVariableScope.NeighborhoodData:     //34
                    throw new Exception("Not implemented...");

                case VMVariableScope.StackObjectFunction: //35
                    return($"");                          //you can't set this!

                case VMVariableScope.MyTypeAttr:          //36
                    if (context.TS1)
                    {
                        return($"Content.Content.Get().Neighborhood.SetTATT((context.Caller.MasterDefinition ?? context.Caller.Object.OBJ).TypeAttrGUID, {data}, {value});");
                    }
                    return($"");

                case VMVariableScope.StackObjectTypeAttr:     //37
                    if (context.TS1)
                    {
                        return($"Content.Content.Get().Neighborhood.SetTATT((context.StackObject.MasterDefinition ?? context.StackObject.Object.OBJ).TypeAttrGUID, {data}, {value});");
                    }
                    return($"");

                case VMVariableScope.NeighborsObjectDefinition:  //38
                    return($"");                                 //you can't set this!

                case VMVariableScope.StackObjectAttributeByTemp: //41
                    return($"context.StackObject.SetAttribute((ushort)temps[{data}], {value});");

                case VMVariableScope.CityTime:        //43
                case VMVariableScope.TSOStandardTime: //44
                case VMVariableScope.GameTime:        //45
                    return($"");                      //you can't set this!

                case VMVariableScope.MyList:          //46
                    return($"/** Set My List **/");

                //throw new Exception("Not implemented...");

                case VMVariableScope.StackObjectList:      //47
                    return($"/** Set Stack Obj List **/"); //you can't set this!

                //throw new Exception("Not implemented...");

                case VMVariableScope.MoneyOverHead32Bit:     //48
                    return($"((VMAvatar)context.Caller).ShowMoneyHeadline({value});");

                case VMVariableScope.MyLeadTileAttribute:     //49
                    return($"context.Caller.MultitileGroup.BaseObject.SetAttribute({(ushort)data}, {value});");

                case VMVariableScope.StackObjectLeadTileAttribute:     //50
                    return($"context.StackObject.MultitileGroup.BaseObject.SetAttribute({(ushort)data}, {value});");

                case VMVariableScope.MyLeadTile:     //51
                    return($"context.Caller.MultitileGroup.BaseObject.SetValue({EnumValueName((VMStackObjectVariable)data)}, {value});");

                case VMVariableScope.StackObjectLeadTile:     //52
                    return($"context.StackObject.MultitileGroup.BaseObject.SetValue({EnumValueName((VMStackObjectVariable)data)}, {value});");

                case VMVariableScope.StackObjectMasterDef:     //53
                    return($"");

                case VMVariableScope.FeatureEnableLevel:     //54
                    throw new Exception("Not implemented...");

                case VMVariableScope.MyAvatarID: //59
                    return($"");                 //you can't set this!
                }
            }
            return($"VMMemory.SetVariable(context, {EnumValueName(scope)}, {data}, {value});");
        }
        public static string GetExpression(CSTranslationContext context, VMVariableScope scope, short data, bool big)
        {
            UpdateUsing(context, scope);

            switch (scope)
            {
            case VMVariableScope.MyObjectAttributes:     //0
                return(Exp($"context.Caller.GetAttribute({(ushort)data})"));

            case VMVariableScope.StackObjectAttributes:     //1
                return(Exp($"context.StackObject.GetAttribute({(ushort)data})"));

            case VMVariableScope.TargetObjectAttributes:     //2
                throw new Exception("Target Object is Deprecated!");

            case VMVariableScope.MyObject:     //3
                return(Exp($"context.Caller.GetValue({EnumValueName((VMStackObjectVariable)data)})"));

            case VMVariableScope.StackObject:     //4
                return(Exp($"context.StackObject.GetValue({EnumValueName((VMStackObjectVariable)data)})"));

            case VMVariableScope.TargetObject:     //5
                throw new Exception("Target Object is Deprecated!");

            case VMVariableScope.Global:     //6
                return(Exp($"context.VM.GetGlobalValue({(ushort)data})"));

            case VMVariableScope.Literal:     //7
                return(Exp(data.ToString()));

            case VMVariableScope.Temps:     //8
                return(Exp($"temps[{data}]"));

            case VMVariableScope.Parameters:     //9
                return(Exp($"args[{data}]"));

            case VMVariableScope.StackObjectID:     //10
                return(Exp($"context.StackObjectID"));

            case VMVariableScope.TempByTemp:     //11
                return(Exp($"temps[temps[{data}]]"));

            case VMVariableScope.TreeAdRange:     //12
                return(Exp($"0"));

            //throw new VMSimanticsException("Not implemented...", context);

            case VMVariableScope.StackObjectTemp:     //13
                return(Exp($"context.StackObject.Thread.TempRegisters[{data}]"));

            case VMVariableScope.MyMotives:     //14
                return(Exp($"((VMAvatar)context.Caller).GetMotiveData({EnumValueName((VMMotive)data)})"));

            case VMVariableScope.StackObjectMotives:     //15
                return(Exp($"((context.StackObject as VMAvatar)?.GetMotiveData({EnumValueName((VMMotive)data)}) ?? 0)"));

            case VMVariableScope.StackObjectSlot:     //16
                return(Exp($"(context.StackObject.GetSlot({data})?.ObjectID ?? 0)"));

            case VMVariableScope.StackObjectMotiveByTemp:     //17
                return(Exp($"((VMAvatar)context.StackObject).GetMotiveData((VMMotive)temps[{data}])"));

            case VMVariableScope.MyPersonData:     //18
                return(Exp($"((VMAvatar)context.Caller).GetPersonData({EnumValueName((VMPersonDataVariable)data)})"));

            case VMVariableScope.StackObjectPersonData:     //19
                return(Exp($"((VMAvatar)context.StackObject).GetPersonData({EnumValueName((VMPersonDataVariable)data)})"));

            case VMVariableScope.MySlot:     //20
                return(Exp($"(context.Caller.GetSlot({data})?.ObjectID ?? 0)"));

            case VMVariableScope.StackObjectDefinition:     //21
                return(Exp($"VMMemory.GetEntityDefinitionVar(context.StackObject.Object.OBJ, {EnumValueName((VMOBJDVariable)data)}, context)"));

            case VMVariableScope.StackObjectAttributeByParameter:     //22
                return(Exp($"context.StackObject.GetAttribute((ushort)args[{data}])"));

            //23 : room, fallback
            //24 : nhood, fallback

            case VMVariableScope.Local:     //25
                return(Exp($"locals[{data}]"));

            case VMVariableScope.Tuning:     //26
                return(Exp($"VMMemory.GetTuningVariable(context.Callee, {(ushort)data}, context)"));

            case VMVariableScope.DynSpriteFlagForTempOfStackObject:     //27
                return(Exp($"(context.StackObject.IsDynamicSpriteFlagSet((ushort)temps[{data}]) ? (short)1 : (short)0)"));

            case VMVariableScope.TreeAdPersonalityVar:     //28
                throw new Exception("Not implemented...");

            case VMVariableScope.TreeAdMin:     //29
                throw new Exception("Not implemented...");

            case VMVariableScope.MyPersonDataByTemp:     //30
                return(Exp($"((VMAvatar)context.Caller).GetPersonData((VMPersonDataVariable)(temps[{data}]))"));

            case VMVariableScope.StackObjectPersonDataByTemp:     //31
                return(Exp($"((VMAvatar)context.StackObject).GetPersonData((VMPersonDataVariable)(temps[{data}]))"));

            case VMVariableScope.NeighborPersonData:     //32
                if (!context.TS1)
                {
                    throw new Exception("Only valid in TS1.");
                }
                return(Exp($"(Content.Content.Get().Neighborhood.GetNeighborByID(context.StackObjectID)?.PersonData?.ElementAt({data}) ?? 0)"));

            case VMVariableScope.JobData:     //33 jobdata(temp0, temp1), used a few times to test if a person is at work but that isn't relevant for tso...
                if (!context.TS1)
                {
                    throw new Exception("Only valid in TS1.");
                }
                return(Exp($"Content.Content.Get().Jobs.GetJobData((ushort)temps[0], temps[1], {data})"));

            case VMVariableScope.NeighborhoodData:    //34
                return(Exp($"0"));                    //tutorial values only

            case VMVariableScope.StackObjectFunction: //35
                return(Exp($"(short)context.StackObject.EntryPoints[{data}].ActionFunction"));

            case VMVariableScope.MyTypeAttr:     //36
                if (context.TS1)
                {
                    return(Exp($"Content.Content.Get().Neighborhood.GetTATT((context.Caller.MasterDefinition ?? context.Caller.Object.OBJ).TypeAttrGUID, {data})"));
                }
                return(Exp($"0"));

            case VMVariableScope.StackObjectTypeAttr:     //37
                if (context.TS1)
                {
                    return(Exp($"Content.Content.Get().Neighborhood.GetTATT((context.StackObject.MasterDefinition ?? context.StackObject.Object.OBJ).TypeAttrGUID, {data})"));
                }
                return(Exp($"0"));

            //38 neighbor object definition: fallback

            case VMVariableScope.Unused:
                return(Exp($"context.VM.TuningCache.GetLimit({EnumValueName((VMMotive)data)})"));

            case VMVariableScope.LocalByTemp:     //40
                return(Exp($"locals[temps[{data}]]"));

            case VMVariableScope.StackObjectAttributeByTemp:     //41
                return(Exp($"context.StackObject.GetAttribute((ushort)temps[{data}])"));

            case VMVariableScope.TempXL:     //42
                if (big)
                {
                    return(Exp($"context.Thread.TempXL[{data}]"));
                }
                else
                {
                    return(Exp($"(short)context.Thread.TempXL[{data}]"));
                }

            case VMVariableScope.TSOStandardTime:     //44
                //return GetTSOStandardTime(data)
                var time = "context.VM.Context.Clock.UTCNow";

                switch (data)
                {
                case 0:
                    return(Exp($"(short){time}.Second"));

                case 1:
                    return(Exp($"(short){time}.Minute"));

                case 2:
                    return(Exp($"(short){time}.Hour"));

                case 3:
                    return(Exp($"(short){time}.Day"));

                case 4:
                    return(Exp($"(short){time}.Month"));

                case 5:
                    return(Exp($"(short){time}.Year"));
                }
                ;
                return(Exp($"0"));

            case VMVariableScope.CityTime:     //43
            case VMVariableScope.GameTime:     //45
                var timeN = "context.VM.Context.Clock";
                switch (data)
                {
                case 0:
                    return(Exp($"(short){timeN}.Seconds"));

                case 1:
                    return(Exp($"(short){timeN}.Minutes"));

                case 2:
                    return(Exp($"(short){timeN}.Hours"));

                case 3:
                    return(Exp($"(short){timeN}.TimeOfDay"));

                case 4:
                    return(Exp($"(short){timeN}.DayOfMonth"));

                case 5:
                    return(Exp($"(short){timeN}.Month"));

                case 6:
                    return(Exp($"(short){timeN}.Year"));
                }
                ;
                break;

            case VMVariableScope.MyList:     //46 (man if only i knew what this meant)
                switch (data)
                {
                case 0: return(Exp($"context.Caller.MyList.First.Value"));        //is this allowed?

                case 1: return(Exp($"context.Caller.MyList.Last.Value"));

                case 2: return(Exp($"(short)context.Caller.MyList.Count"));

                default: return(Exp($"context.Caller.MyList.ElementAt(temps[0])"));
                }

            case VMVariableScope.StackObjectList:     //47
                //if (context.StackObject == null) return 0; (this hack is probably needed by something)
                switch (data)
                {
                case 0: return(Exp($"context.StackObject.MyList.First.Value"));

                case 1: return(Exp($"context.StackObject.MyList.Last.Value"));

                case 2: return(Exp($"(short)context.StackObject.MyList.Count"));

                default: return(Exp($"context.StackObject.MyList.ElementAt(temps[0])"));
                }

            case VMVariableScope.MoneyOverHead32Bit:     //48
                //we're poor... will need special case for this in expression like TempXL
                if (big)
                {
                    Exp($"0");
                }
                return(Exp($"0"));

            case VMVariableScope.MyLeadTileAttribute:     //49
                return(Exp($"context.Caller.MultitileGroup.BaseObject.GetAttribute({(ushort)data})"));

            case VMVariableScope.StackObjectLeadTileAttribute:     //50
                return(Exp($"context.StackObject.MultitileGroup.BaseObject.GetAttribute({(ushort)data})"));

            case VMVariableScope.MyLeadTile:     //51
                return($"context.Caller.MultitileGroup.BaseObject.GetValue({EnumValueName((VMStackObjectVariable)data)})");

            case VMVariableScope.StackObjectLeadTile:     //52
                return($"context.StackObject.MultitileGroup.BaseObject.GetValue({EnumValueName((VMStackObjectVariable)data)})");

            //throw new Exception("Not implemented...");

            case VMVariableScope.StackObjectMasterDef:     //53
                //gets definition of the master tile of a multi tile object in the stack object.
                return(Exp($"GetEntityDefinitionVar(context.StackObject.MasterDefinition ?? context.StackObject.Object.OBJ, {EnumValueName((VMOBJDVariable)data)}, context)"));

            case VMVariableScope.FeatureEnableLevel:     //54
                return(Exp($"1"));
                //all of them are enabled, dont really care right now

                //59: MyAvatarID, fallback
            }

            return(Exp($"VMMemory.GetVariable(context, {EnumValueName(scope)}, {data})"));
        }