Ejemplo n.º 1
0
        // this combine method is for multi-level macros
        public GenericScriptItem[] Combine(ScriptMacro macro, int depth)
        {
            // if null, we dont even need to bother
            if (macro == null)
            {
                return(Optimized);
            }
            // if too deep, just return normally

            // combine this layer
            int RangeStart, RangeEnd;

            if (!macro.GetRange(depth, out RangeStart, out RangeEnd))
            {
                // if too deep, just return normally
                return(Optimized);
            }

            // loop for all
            for (int i = RangeStart; i <= RangeEnd; i++)
            {
                if (Optimized[i] == null)
                {
                    // nothing here
                    if (depth < macro.pre.Length - 1)
                    {
                        Optimized[i] = new ScriptArrayItem(parent);
                        (Optimized[i] as ScriptArrayItem).Combine(macro, depth + 1);
                    }
                    else
                    {
                        // if last level, just put macro in there
                        Optimized[i] = macro;
                    }
                }
                else if (Optimized[i].type == ScriptItemType.ArrayItem)
                {
                    // if another array, see if we can insert us there
                    (Optimized[i] as ScriptArrayItem).Combine(macro, depth + 1);
                }
            }

            // and finally at the end of the day, we can rest assured everything is sorted. Phew.
            return(Optimized);
        }
Ejemplo n.º 2
0
        // function to calculate the optimized arrays of items or array items to quickly return items for certain types of requests
        public GenericScriptItem[] Optimize()
        {
            Optimized = new GenericScriptItem[0x100];

            foreach (GenericScriptItem entry in Items)
            {
                switch (entry.type)
                {
                case ScriptItemType.NULL:
                    screrr(entry.line, "Type of item is NULL! This is most likely a programming error in SMPS2ASM!");
                    break;

                case ScriptItemType.Equate:
                    ScriptEquate eq = (entry as ScriptEquate);
                    // only pre-calculated equates are possible to be used
                    if (!eq.CheckEvaluate())
                    {
                        S2AScript.screrr(entry.line, "Equates that are being optimized into a look-up-table must be possible to be pre-calculated! Equate with contents '" + eq.val + "' failed to be pre-calculated.");
                    }
                    // get offset
                    int v;
                    if (!Parse.DoubleToInt(GetEquate(eq.equ).value, out v))
                    {
                        screrr(entry.line, "Equate value can not be accurately converted from double floating point to int! Equate with contents '" + eq.val + "' failed to be conveted to 32-bit signed integer.");
                    }

                    // save entry or throw error.
                    if (Optimized[v] == null)
                    {
                        Optimized[v] = entry;
                    }
                    else
                    {
                        screrr(entry.line, "Entity " + entry.identifier + " conflicts with " + Optimized[v].identifier + " at line " + Optimized[v].line +
                               ", both trying to occupy the value " + v + " (0x" + v.ToString("X2") + ")! Optimization requires no such conflicts.");
                    }
                    break;

                case ScriptItemType.Macro:
                    ScriptMacro ma = (entry as ScriptMacro);
                    // collect range
                    int rangeStart, rangeEnd;
                    if (!ma.GetRange(0, out rangeStart, out rangeEnd))
                    {
                        S2AScript.screrr(entry.line, "Unable to parse first level macro range. Macro range of '" + (ma.pre.Length > 0 ? ma.pre[0] : "") + "' is not valid.");
                    }

                    // if true, there is only 1 level to this macro
                    bool onlylevel = ma.pre.Length == 1;
                    for (int i = rangeStart; i <= rangeEnd; i++)
                    {
                        if (onlylevel)
                        {
                            if (Optimized[i] == null)
                            {
                                Optimized[i] = ma;
                            }

                            else if (Optimized[i].type == ScriptItemType.ArrayItem)
                            {
                                (Optimized[i] as ScriptArrayItem).CombineFree(ma);
                            }

                            else
                            {
                                screrr(entry.line, "Entity " + entry.identifier + " conflicts with " + Optimized[i].identifier + " at line " + Optimized[i].line +
                                       ", both trying to occupy the value " + i + " (0x" + i.ToString("X2") + ")! Optimization requires no such conflicts.");
                            }
                        }
                        else
                        {
                            if (Optimized[i] == null)
                            {
                                Optimized[i] = new ScriptArrayItem(parent);
                                (Optimized[i] as ScriptArrayItem).Combine(ma, 1);
                            }
                            else if (Optimized[i].type == ScriptItemType.ArrayItem)
                            {
                                (Optimized[i] as ScriptArrayItem).Combine(ma, 1);
                            }

                            else
                            {
                                screrr(entry.line, "Entity " + entry.identifier + " conflicts with " + Optimized[i].identifier + " at line " + Optimized[i].line +
                                       ", both trying to occupy the value " + i + " (0x" + i.ToString("X2") + ")! Optimization requires no such conflicts.");
                            }
                        }
                    }
                    break;

                case ScriptItemType.ArrayItem:
                    screrr(entry.line, "Unoptimized list contains a pre-occupied technical element that may not be interpreted. This is likely a programming error, please report to devs!");
                    break;

                case ScriptItemType.Import:
                    ScriptArray sc = context.GetSubscript((entry as ScriptImport).name);
                    if (sc.Optimized == null)
                    {
                        sc.Optimize();
                    }
                    Optimized = ConvertSMPS.context.Combine(new GenericScriptItem[][] { Optimized, sc.Optimized });
                    break;

                // all these items are invalid inside the LUT.
                default:
                    screrr(entry.line, "Optimized look-up-table may only contain unoptimizable elements! Look-up-tables may contain either Equates, or macros.");
                    break;
                }
            }
            return(Optimized);
        }