Beispiel #1
0
        private void consumeVariable(string line, string filename, int ln, out string name, out Atom prop)
        {
            name = "";
            prop = null;

            bool declaration = false;
            string value = null;
            int size = -1;

            string decl = "";

            if (LeavePreprocessorDirectives)
                line = decl = this.lineBeforePreprocessing.Trim();
            else
                decl = line.Trim();

            if (line.Contains("="))
            {
                var chunks = line.Split(new char[] { '=' }, 2);
                decl = chunks[0].Trim();
                value = chunks[1].Trim();
            }
            else
            {
                decl = line.Trim();
                value = null;
            }

            if (decl.Contains("[") && !decl.Contains("list("))
            {
                string[] arrparts = decl.Split(new char[] { '[' }, 2);
                string line_split = arrparts[0];
                string arr_decl = arrparts[1];
                string str_size = "";

                var idx = arr_decl.IndexOf(']');
                if (idx >= 0)
                {
                    str_size = arr_decl.Substring(0, idx);
                }
                else
                {
                    log.WarnFormat("{0}:{1}: MALFORMED CODE: Unable to find ]", filename, ln);
                    log.Warn(line);
                }

                if (str_size != "" && !int.TryParse(str_size, out size))
                {
                    log.WarnFormat("Failed to parse {0} as int.", str_size);
                    return;
                }
                // print(repr({"size":size,"line":line_split}))
                decl = line_split;
            }
            // print(repr({"decl":decl,"value":value}))

            // (var)(/global|const|tmp)(/type/fragment)name
            if (decl.StartsWith("var/"))
            {
                declaration = true;
                decl = decl.Substring(4);
            }
            List<string> pathchunks = decl.Split('/').ToList();
            name = pathchunks.Last();
            string special = null;
            var typepath = "/";
            if (declaration)
            {
                switch (pathchunks[0])
                {
                    case "tmp":
                    case "global":
                    case "const":
                        special = pathchunks[0];
                        pathchunks = pathchunks.Skip(1).ToList();
                        break;
                }
                if (!pathchunks.Contains("list") && size != -1)
                {
                    pathchunks.Insert(0, "list");
                }
                typepath = "/" + ("/".join(pathchunks.Take(pathchunks.Count - 1)));
            }

            float parseval;
            if (typepath != "/")
            {
                if (value == "null")
                {
                    prop = new BYONDNull(filename, ln) { type = new BYONDType(typepath), declarative = declaration, special = special, size = size };
                }
                else
                {
                    prop = new Atom(typepath, filename, ln);//{declarative=declaration, special=special,size=size};
                }
            }
            else if (value == "null" || value == null)
            {
                prop = new BYONDNull(filename, ln) { type = new BYONDType(typepath), declarative = declaration, special = special, size = size };
            }
            else if (value != null && value[0] == '"')
            {
                prop = new BYONDString(value.Substring(1, value.Length - 1), filename, ln) { declarative = declaration, special = special, size = size };
            }
            else if (value != null && value[0] == '\'')
            {
                prop = new BYONDFileRef(value.Substring(1, value.Length - 1), filename, ln) { declarative = declaration, special = special, size = size };
            }
            else if (value != null && float.TryParse(value, out parseval))
            {
                prop = new BYONDNumber(parseval, filename, ln) { declarative = declaration, special = special, size = size };
            }
            else
            {
                prop = new BYONDUnhandledValue(value, filename, ln) { type = new BYONDType(typepath), declarative = declaration, special = special, size = size };
            }
        }
Beispiel #2
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
            }
        }