Exemplo n.º 1
0
        /////////////////////////
        // HAIRINESS BELOW
        public void ProcessFile(string filename)
        {
            this.cpath.Clear();
            this.popLevels.Clear();
            this.pindent = 0;
            this.ignoreLevel.Clear();
            this.contextDebugOn = DebugContext; //|| filename.EndsWith("Chemistry-Machinery.dm");
            this.ignoreDebugOn = DebugIgnore; //|| filename.EndsWith("Chemistry-Machinery.dm");
            this.ppcDebugOn = DebugPreprocessing;
            this.ignoreStartIndent = -1;
            this.loadingProc = null;
            this.comment = "";
            //this.fileLayout = []
            this.lineBeforePreprocessing = "";
            this.current_filename = filename;

            Match m;
            using (TextReader f = File.OpenText(filename))
            {
                int ln = 0;
                ignoreLevel.Clear();
                string cline = "";
                while (f.Peek() != -1)
                {
                    string line = f.ReadLine();

                    ln++;

                    bool skipNextChar = false;
                    string nl = "";

                    line = line.TrimEnd();

                    if (line.EndsWith("\\"))
                    {
                        cline += line.Substring(0, line.Length - 1);
                        continue;
                    }
                    else
                    {
                        line = cline + line;
                        if ( ignoreDebugOn &&cline != "")
                            log.DebugFormat("{0}:{1}: Combined line with prior line. {2}", filename, ln, line);
                        cline = "";
                    }

                    this.lineBeforePreprocessing = line;
                    var line_len = line.Length;
                    for (int i = 0; i < line_len; i++)
                    {
                        string c = line.Substring(i, 1);
                        string nc = "";
                        if (line_len > i + 1)
                            nc = line.Substring(i + 1, 1);
                        string tok = c + nc;

                        if (skipNextChar)
                        {
                            ignoreDebug(string.Format("Skipping {0}.", tok));
                            skipNextChar = false;
                            // this.comment += c
                            ignoreDebug(string.Format("this.comment = {0}.", this.comment));
                            continue;
                        }
                        if (tok == "//")
                        {
                            //if(this.ignoreDebugOn) debug(filename,ln,this.cpath,'{} ({})'.format(tok,len(ignoreLevel)))
                            if (ignoreLevel.Count == 0)
                            {
                                this.comment = line.Substring(i);
                                // if this.ignoreDebugOn: print('this.comment = {}.'.format(repr(this.comment)))
                                // print('Found '+this.comment)
                                this.finishComment(cleansed_line: nl);
                                break;
                            }
                        }
                        if (ignoreTokens.ContainsKey(tok))
                        {
                            string pc = "";
                            if (i > 0)
                                pc = line.Substring(i - 1, 1);
                            if (tok == "{\"" && pc == "\"")
                            {
                                this.comment += c;
                                continue;
                            }
                            // if this.ignoreDebugOn: print(repr(this.ignoreTokens[tok]))
                            string stop = ignoreTokens[tok];
                            // End comment
                            if (stop == null)
                            {
                                if (ignoreLevel.Count > 0)
                                {
                                    if (ignoreLevel.Peek() == tok)
                                    {
                                        skipNextChar = true;
                                        this.comment += tok;
                                        ignoreLevel.Pop();
                                        if (ignoreLevel.Count == 0)
                                            this.finishComment();
                                        continue;
                                    }
                                    else
                                    {
                                        this.comment += c;
                                        continue;
                                    }
                                }
                            }
                            else  // Start comment
                            {
                                skipNextChar = true;
                                ignoreLevel.Push(stop);
                                this.comment = tok;
                                continue;
                            }
                            if (this.ignoreDebugOn)
                                debug(filename, ln, this.cpath, string.Format("{0} ({1})", tok, ignoreLevel.Count));
                        }
                        if (ignoreLevel.Count == 0)
                            nl += c;
                        else
                            this.comment += c;
                    }
                    if (line != nl)
                    {
                        ignoreDebug("IN : " + line);
                        line = nl;
                        ignoreDebug("OUT: " + line);
                        ignoreDebug(string.Format("this.comment = {0}.", comment));
                    }
                    if (ignoreLevel.Count > 0)
                    {
                        this.comment += "\n";
                        continue;
                    }

                    line = REGEX_LINE_COMMENT.Replace(line, "");

                    if (line.Trim() == "")
                    {
                        //if (loadingProc != null)
                        //    loadingProc.AddBlankLine();
                        continue;
                    }

                    /////////////////////////////
                    // Preprocessing defines.
                    if (line.Trim().StartsWith("#"))
                    {
                        if (line.EndsWith("\\")) continue;
                        var tokenChunks = line.Split('#');
                        tokenChunks = tokenChunks[1].Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
                        var directive = tokenChunks[0];

                        //if (line.Contains("MAX_PILL_SPRITE"))
                        //    throw new Exception("MAX PILL SPRITE");
                        if (directive == "define")
                        {
                            // //define SOMETHING Value
                            var defineChunks = line.Split(new char[] { ' ', '\t' }, 3, StringSplitOptions.RemoveEmptyEntries).ToList();
                            if (defineChunks.Count == 2)
                                defineChunks.Add("1");
                            else if (defineChunks.Count == 3)
                                defineChunks[2] = this.PreprocessLine(defineChunks[2]);
                            // print(repr(defineChunks))
                            try
                            {
                                Defines[defineChunks[1]] = new BYONDNumber(float.Parse(defineChunks[2]), filename, ln);
                            }
                            catch
                            {
                                Defines[defineChunks[1]] = new BYONDString(defineChunks[2], filename, ln);
                            }
                            //this.fileLayout += [("DEFINE", defineChunks[1], defineChunks[2])]
                        }
                        else if (directive == "undef")
                        {
                            var undefChunks = line.Split(new char[] { ' ', '\t' }, 2);
                            if (Defines.ContainsKey(undefChunks[1]))
                                Defines.Remove(undefChunks[1]);
                            //this.fileLayout += [("UNDEF", undefChunks[1])]

                            // OpenBYOND tokens.
                        }
                        else if (directive.StartsWith("__OB_"))
                        {
                            int numtabs = 0;
                            m = REGEX_TABS.Match(line);
                            if (m.Success)
                                numtabs = m.Groups["tabs"].Length;
                            string atom = this.DetermineContext(filename, ln, line, numtabs);
                            // if atom is None: continue
                            // print("OBTOK {0}".format(repr(tokenChunks)))
                            this.handleOBToken(tokenChunks[0].Replace("__OB_", ""), atom, tokenChunks.Skip(1).ToArray());
                            // this.fileLayout += [("OBTOK", atom.path)]
                            continue;
                        }
                        else
                        {
                            var chunks = line.Split(' ');
                            //this.fileLayout += [("PP_TOKEN", line)]
                            log.WarnFormat("BUG: Unhandled preprocessor directive #{0} in {1}:{2}", directive, filename, ln);
                        }
                        continue;
                    }

                    // Preprocessing
                    line = this.PreprocessLine(line);

                    m = REGEX_TABS.Match(this.lineBeforePreprocessing);
                    if (m.Success)
                    {
                        var numtabs = m.Groups["tabs"].Length;
                        //if(lineBeforePreprocessing.StartsWith("\t"))
                        //    log.DebugFormat("TABS: {0} ? {1} - {2}: {3}", numtabs, this.ignoreStartIndent, this.loadingProc, line);
                        if (this.ignoreStartIndent > -1 && this.ignoreStartIndent < numtabs)
                        {
                            if (loadingProc != null)
                            {
                                // this.loadingProc.AddCode(numtabs - this.ignoreStartIndent, this.lineBeforePreprocessing.strip())
                                this.AddCodeToProc(this.ignoreStartIndent, this.lineBeforePreprocessing);
                            }
                            if (contextDebugOn) log.DebugFormat("TABS: {0} ? {1} - {2}: {3}", numtabs, this.ignoreStartIndent, this.loadingProc, line);
                            continue;
                        }
                        else
                        {
                            if (this.contextDebugOn && this.ignoreStartIndent > -1) log.DebugFormat("BREAK ({0} -> {1}): {2}", this.ignoreStartIndent, numtabs, line);
                            this.ignoreStartIndent = -1;
                            this.loadingProc = null;
                        }
                    }
                    else
                    {
                        if (this.contextDebugOn && this.ignoreStartIndent > -1) log.Debug("BREAK " + line);
                        this.ignoreStartIndent = -1;
                        this.loadingProc = null;
                    }
                    if (!line.Trim().StartsWith("var/"))
                    {
                        m = REGEX_ATOMDEF.Match(line);
                        if (m.Success)
                        {
                            var numtabs = m.Groups["tabs"].Length;
                            var atom_str = m.Groups["atom"].Value;
                            var atom_path = new List<string>(this.SplitPath(atom_str));
                            var atom = this.ProcessAtom(filename, ln, line, atom_str, atom_path, numtabs);
                            //if(atom==null) continue;
                            //this.fileLayout += [("ATOMDEF", atom.path)];
                            continue;
                        }
                        else
                        {
                            m = REGEX_ABSOLUTE_PROCDEF.Match(line);
                            if (m.Success)
                            {
                                var numtabs = m.Groups["tabs"].Length;
                                var atom = string.Format("{0}/{1}({2})", m.Groups["atom"].Value, m.Groups["proc"].Value, m.Groups["args"].Value);
                                var atom_path = new List<string>(this.SplitPath(atom));
                                //log.DebugFormat("PROCESSING ABS PROC AT INDENT > {0} {1} -> {2}", numtabs, atom, "/".join(atom_path));
                                var proc = this.ProcessAtom(filename, ln, line, atom, atom_path, numtabs, m.Groups["args"].Value.Split(','));
                                if (proc == null)
                                    continue;
                                this.ignoreStartIndent = numtabs;
                                this.loadingProc = (Proc)proc;
                                //this.fileLayout += [("PROCDEF", proc.path)]
                                continue;
                            }
                            else
                            {

                                m = REGEX_RELATIVE_PROCDEF.Match(line);
                                if (m.Success)
                                {
                                    var numtabs = m.Groups["tabs"].Length;
                                    var atom = string.Format("{0}({1})", m.Groups["proc"].Value, m.Groups["args"].Value);
                                    var atom_path = new List<string>(this.SplitPath(atom));
                                    // print("IGNORING RELATIVE PROC AT INDENT > " + str(numtabs) + " " + line)
                                    var proc = this.ProcessAtom(filename, ln, line, atom, atom_path, numtabs, m.Groups["args"].Value.Split(','));
                                    if (proc == null)
                                        continue;
                                    this.ignoreStartIndent = numtabs;
                                    this.loadingProc = (Proc)proc;
                                    //this.fileLayout += [("PROCDEF", proc.path)]
                                    continue;
                                }
                                else
                                {
                                    if (line.Contains("(") && line.Trim().StartsWith("/") && !line.Contains("list("))
                                    {
                                        log.WarnFormat("{0}:{1}: Possible skipped proc: {2}", filename, ln, line);
                                    }
                                }
                            }
                        }
                    }
                    var path = "/".join(this.cpath);
                    // if len(this.cpath) > 0 and "proc" in this.cpath:
                    //    continue
                    if (line.Contains("=") || line.Trim().StartsWith("var/"))
                    {
                        if (!Atoms.ContainsKey(path))
                            this.Atoms[path] = new Atom(path);
                        string name;
                        Atom prop;
                        this.consumeVariable(line, filename, ln, out name, out prop);
                        this.Atoms[path].Properties[name] = prop;
                        //this.fileLayout += [("VAR", path, name)];
                    }
                }
                //this.fileLayouts[filename] = this.fileLayout
            }
        }
Exemplo n.º 2
0
        private Atom ProcessAtom(string filename, int ln, string line, string atom, List<string> atom_path, int numtabs, string[] procArgs = null)
        {
            // Reserved words that show up on their own
            if (reservedWords.Contains(atom))
                return null;

            // Other things to ignore (false positives, comments)
            if (atom.StartsWith("var/") || atom.StartsWith("//"))
                return null;

            // Things part of a string or list.
            if (numtabs > 0 && atom.Trim().StartsWith("/"))
                return null;

            if (contextDebugOn)
                log.DebugFormat("{0} > {1}", numtabs, line.TrimEnd());

            // Global scope (no tabs)
            if (numtabs == 0)
            {
                this.cpath = atom_path;
                // Ensure cpath has a slash at the front (empty first entry)
                if (this.cpath.Count == 0)
                    this.cpath.Add("");
                else if (this.cpath[0] != "")
                    this.cpath.Insert(0, "");

                // Create new poplevel stack, add current path length to it.
                this.popLevels = new Stack<int>();
                this.popLevels.Push(this.cpath.Count);

                if (this.contextDebugOn)
                    debug(filename, ln, this.cpath, "0 - " + string.Join("/", atom_path));

            }
            else if (numtabs > pindent) // Going up a tab level.
            {
                // Add path to cpath.
                this.cpath.AddRange(atom_path);

                // Add new poplevel with current path length.
                this.popLevels.Push(atom_path.Count);

                if (this.contextDebugOn)
                    debug(filename, ln, this.cpath, ">");

            }
            else if (numtabs < pindent) // Going down.
            {
                if (this.contextDebugOn)
                    log.DebugFormat("({0} - {1})={2}: {3}", this.pindent, numtabs, this.pindent - numtabs, string.Join("/", this.cpath));

                // This is complex as f**k, so bear with me.
                // For every poplevel we've lost, we need to slice off some path chunks or we f**k up our context.
                //
                // /butt
                //   ugly
                //     dirty    // /butt/ugly/dirty, 2 poplevels both with content 1 (number of things we added to path)
                //   nice       // Here, we slice off 1 path segment, and add "nice", getting /butt/nice.
                for (int i = 0; i < (this.pindent - numtabs + 1); i++)
                {
                    // Pop a poplevel out, find out how many path chunks we need to remove.
                    var popsToDo = this.popLevels.Pop();

                    if (this.contextDebugOn)
                        log.DebugFormat(" pop {0} {1}", popsToDo, this.popLevels);

                    // Now pop off the path segments.
                    for (int j = 0; j < popsToDo; j++)
                    {
                        this.cpath.RemoveAt(this.cpath.Count - 1);

                        if (this.contextDebugOn)
                            log.DebugFormat("  pop {0}/{1}: {2}", i + 1, popsToDo, "/".join(this.cpath));
                    }
                }

                // Add new stuff.
                this.cpath.AddRange(atom_path);

                // Add new poplevel for the new stuff.
                this.popLevels.Push(atom_path.Count);

                if (this.contextDebugOn)
                    debug(filename, ln, this.cpath, "<");

            }
            else if (numtabs == this.pindent) // Same level.
            {
                // Same as above, but we're only going down one indent.
                var levelsToPop = this.popLevels.Pop();

                // Pop off path segments.
                for (int i = 0; i < levelsToPop; i++)
                    this.cpath.RemoveAt(this.cpath.Count - 1);

                // New stuff
                this.cpath.AddRange(atom_path);

                // New poplevel.
                this.popLevels.Push(atom_path.Count);

                if (this.contextDebugOn)
                    log.DebugFormat("popLevels: {0}", this.popLevels.Count);
                if (this.contextDebugOn)
                    debug(filename, ln, this.cpath, ">");
            }

            var origpath = string.Join("/", this.cpath);

            // definition?
            List<string> defs = new List<string>();

            // Trim off /proc or /var, if needed.
            List<string> prep_path = new List<string>(this.cpath);

            foreach (string special in new string[] { "proc" })
            {
                if (prep_path.Contains(special))
                {
                    defs.Add(special);
                    prep_path.Remove(special);
                }
            }

            var npath = "/".join(prep_path);

            if (!Atoms.ContainsKey(npath))
            {
                if (procArgs != null)
                {
                    //assert npath.endswith(')')

                    // if origpath != npath:
                    //    print(origpath,proc_def)

                    var proc = new Proc(npath, procArgs, filename, ln);
                    proc.origpath = origpath;
                    proc.definition = defs.Contains("proc");
                    this.Atoms[npath] = proc;
                }
                else
                {
                    this.Atoms[npath] = new Atom(npath, filename, ln);
                }
                // if this.debugOn: print('Added ' + npath)
            }
            this.pindent = numtabs;
            return this.Atoms[npath];
        }