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 }; } }
///////////////////////// // 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 } }