Пример #1
0
        public void Convert(string Script, out string CompiledScript,
                            out object PositionMap)
        {
            // Its LSL, convert it to C#
            Dictionary <int, int> map     = new Dictionary <int, int>();
            List <string>         csClass = new List <string>();

            Script = Script.Replace("\n", "\r\n");

            List <string> GlobalFunctions;

            string[] lineSplit = ConvertLSLTypes(Script, out GlobalFunctions);
            Dictionary <string, string[]> EnumerableFunctionInfos = new Dictionary <string, string[]>();

            foreach (string function in GlobalFunctions)
            {
                string[] func = GetInfo(function);
                EnumerableFunctionInfos[func[1]] = func;
            }
            List <string> splits      = new List <string>();
            List <string> breaksplits = new List <string>();

            foreach (string s in lineSplit)
            {
                splits.AddRange(s.Trim().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
                breaksplits.AddRange(s.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
            }
            breaksplits.RemoveAll(RemoveR);
            string[]   split                      = splits.ToArray();
            string[]   breaksplit                 = breaksplits.ToArray();
            int        i                          = 0;
            string     currentState               = "";
            bool       InState                    = false;
            bool       inMethod                   = false;
            int        skipUntil                  = 0;
            int        bracketInsideMethod        = 0;
            List <int> ProtectedBracketLoops      = new List <int>();
            bool       AddBracketAfterNextCommand = false;

            foreach (string wword in split)
            {
                if (i < skipUntil)
                {
                    i++;
                    continue;
                }
                string word = wword.Replace("\r", "");
                if (word.StartsWith("//"))
                {
                    GetUntilBreak(split, breaksplit, i, out skipUntil);
                }
                else if (word.StartsWith("/*"))
                {
                    GetUntil(split, "*/", i, out skipUntil);
                }
                else if (word == "default")
                {
                    currentState = "default";
                    InState      = true;
                }
                else if (word == "state")
                {
                    if (inMethod)
                    {
                        currentState = GetUntilBreak(split, breaksplit, i, out skipUntil).Replace(";", "").Trim();
                        AddToClass(csClass, string.Format(
                                       "((ILSL_Api)m_apis[\"ll\"]).state(\"{0}\");",
                                       currentState), split, breaksplit, lineSplit, i, ref map);
                    }
                    else
                    {
                        currentState = GetNextWord(split, i);
                        skipUntil    = i + 2;
                        InState      = true;
                    }
                }
                else if (word.IndexOf("(") != -1 &&
                         Events.Contains(word.Substring(0, word.IndexOf("("))))
                {
                    if (!InState)
                    {
                        throw new ParseException("Event is not in a state");
                    }
                    else
                    {
                        AddToClass(csClass, GenerateEvent(currentState, split, breaksplit, i, out skipUntil),
                                   split, breaksplit, lineSplit, i, ref map);
                        inMethod = true;
                    }
                }
                else if (word == "{" || word == "}")
                {
                    bool addToClass = !(word == "{" && bracketInsideMethod == 0 && InState) &&
                                      !(word == "}" && bracketInsideMethod == 1 && InState);
                    if (word == "{")
                    {
                        bracketInsideMethod++;
                    }
                    else
                    {
                        bracketInsideMethod--;
                        if (ProtectedBracketLoops.Contains(bracketInsideMethod))
                        {
                            ProtectedBracketLoops.Remove(bracketInsideMethod);
                            AddToClass(csClass, GenerateTimeCheck("", true), split, breaksplit, lineSplit, i, ref map);
                        }
                        if (bracketInsideMethod == (InState ? 1 : 0))
                        {
                            //We're inside an enumerable function, add the yield return/break
                            AddToClass(csClass, GenerateReturn(""), split, breaksplit, lineSplit, i, ref map);
                            inMethod = false;
                        }
                        if (bracketInsideMethod == 0)
                        {
                            InState = false;
                        }
                    }
                    if (addToClass)
                    {
                        AddToClass(csClass, word,
                                   split, breaksplit, lineSplit, i, ref map);
                    }
                }
                else if (inMethod)
                {
                    bool   wasSemicolan = false;
                    string csLine       = split[i].StartsWith("for") ?
                                          GetUntilBreak(split, breaksplit, i, out skipUntil)
                        :
                                          GetUntilSemicolanOrBreak(split, breaksplit, i, out skipUntil, out wasSemicolan);
                    if (wasSemicolan && csLine.StartsWith("return"))
                    {
                        csLine = GenerateReturn(csLine);
                    }
                    AddDefaultInitializers(ref csLine);
                    if (AddBracketAfterNextCommand)
                    {
                        AddBracketAfterNextCommand = false;
                        csLine += "\n }";
                    }

                    foreach (string call in ProtectedCalls)
                    {
                        if (csLine.StartsWith(call))
                        {
                            if (!GetNextWord(split, skipUntil - 1).StartsWith("{"))//Someone is trying to do while(TRUE) X();
                            {
                                csLine += " { ";
                                csLine  = GenerateTimeCheck(csLine, false);
                                AddBracketAfterNextCommand = true;
                            }
                            else
                            {
                                ProtectedBracketLoops.Add(bracketInsideMethod);//Make sure no loops are created as well
                            }
                        }
                    }
                    foreach (string call in CalledBeforeProtectedCalls)
                    {
                        if (csLine.StartsWith(call))
                        {
                            csLine = GenerateTimeCheck(csLine, true);//Make sure no other loops are created as well
                        }
                    }
                    string noSpacedLine = csLine.Replace(" ", "");
                    Match match;
                    foreach (string[] globFunc in EnumerableFunctionInfos.Values)
                    {
                        if (RegexContains(csLine, GenerateRegex(globFunc[1], int.Parse(globFunc[3])), out match))
                        {
                            csLine = GenerateNewFunction(csLine, globFunc, match);
                        }
                    }


                    AddToClass(csClass, csLine,
                               split, breaksplit, lineSplit, i, ref map);
                }
                else if (!InState)
                {
                    bool   wasSemicolan;
                    string line = GetUntil(split, ";", ")", i, out skipUntil, out wasSemicolan);
                    if (!wasSemicolan)
                    {
                        GenerateGlobalFunction(ref inMethod, ref line);
                    }
                    else
                    {
                        AddDefaultInitializers(ref line);
                    }

                    AddToClass(csClass, line,
                               split, breaksplit, lineSplit, i, ref map);
                }
                else
                {
                    AddToClass(csClass, "fake", split, breaksplit, lineSplit, i, ref map);
                    m_compiler.AddError(String.Format("({0},{1}): {3}: {2}\n",
                                                      map[csClass.Count - 1], 1, "Invalid expression term '" + word + "'", "Error"));
                    CompiledScript = "";
                    PositionMap    = null;
                    return;
                }
                i++;
            }

            PositionMap    = map;
            CompiledScript = CSCodeGenerator.CreateCompilerScript(m_compiler, new List <string>(), string.Join("\n", csClass.ToArray()));
        }