public String Do(String line, long l, String name, System.IO.StreamReader f, ParseFile parent) { String outString = ""; if (line.Length > 7 && line.Substring(0, 7) == "include") { ParseFile parseFile = new ParseFile(); String s = line.Substring(8).Trim(); if (System.IO.File.Exists(s)) { parseFile.Do(s, s); } else { if (Program.defined["naive_targets_path"] != null && System.IO.File.Exists(Program.defined["naive_targets_path"] + s)) { parseFile.Do(Program.defined["naive_targets_path"] + s, s); } else { if (Program.defined["naive_libs_path"] != null && System.IO.File.Exists(Program.defined["naive_libs_path"] + s)) { parseFile.Do(Program.defined["naive_libs_path"] + s, s); } else { Program.Error(name, l, "Cant find file:" + s); } } } return(outString); } else if (line.Length > 6 && line.Substring(0, 6) == "define") { if (line.Substring(7).IndexOf('(') < 0) // const define { String[] s = line.Substring(7).Trim().Replace('\t', ' ').Replace(" ", " ").Split(' '); if (s.Length == 2) { Program.defined.Add(s[0], s[1]); Console.WriteLine("Defined: " + s[0] + " as " + s[1]); } else if (s.Length == 1) { Program.defined.Add(s[0], ""); Console.WriteLine("Defined: " + s[0] + " as ''"); } return(outString); } else // macro define { String s = line.Substring(7).Trim().Replace('\t', ' ').Replace(" ", " "); Match res = Regex.Match(s, @"(\w[\w\d]+)\((.+)\)\b*(.+)", RegexOptions.IgnoreCase); if (res.Success) { String key = res.Groups[1].ToString(); String par = res.Groups[2].ToString(); String fun = res.Groups[3].ToString(); Program.fundefined.Add(key, fun + "," + par); Console.WriteLine("Defined: " + key + " with params " + par + " as " + fun); } return(outString); } } else if (line.Length > 5 && line.Substring(0, 5) == "undef") { String[] s = line.Substring(7).Trim().Replace('\t', ' ').Replace(" ", " ").Split(' '); if (Program.IfDefined(s[0])) { Program.defined.Remove(s[0]); } if (Program.IfFunDefined(s[0])) { Program.fundefined.Remove(s[0]); } return(outString); } else if (line.Length > 5 && line.Substring(0, 5) == "ifdef") { String[] s = line.Substring(7).Trim().Replace('\t', ' ').Replace(" ", " ").Split(' '); if (!Program.defined.ContainsKey(s[0])) { int q = 1; while (q > 0) { line = f.ReadLine(); parent.fileLine++; Program.totalLines++; if (line == null) { break; } if (line.IndexOf("ifdef") >= -1) { q++; } else if (line.IndexOf("ifndef") >= -1) { q++; } else if (line.IndexOf("endif") >= -1) { q--; } } } return(outString); } else if (line.Length > 6 && line.Substring(0, 6) == "ifndef") { String[] s = line.Substring(7).Trim().Replace('\t', ' ').Replace(" ", " ").Split(' '); if (Program.defined.ContainsKey(s[0])) { int q = 1; while (q > 0) { line = f.ReadLine(); parent.fileLine++; Program.totalLines++; if (line == null) { break; } if (line.IndexOf("ifdef") >= -1) { q++; } else if (line.IndexOf("ifndef") >= -1) { q++; } else if (line.IndexOf("endif") >= -1) { q--; } } } return(outString); } else if (line.Length > 5 && line.Substring(0, 5) == "endif") { return(outString); } else { outString = line; foreach (var item in Program.fundefined) { Match res = Regex.Match(outString, item.Key + @"\((.+)\)", RegexOptions.IgnoreCase); if (res.Success) { String[] par = res.Groups[1].ToString().Split(','); String[] fun = item.Value.Split(','); if (par.Length == fun.Length - 1) { String s1 = fun[0]; for (int i = 0; i < par.Length; i++) { s1 = s1.Replace(fun[i + 1], par[i]); } outString = outString.Replace(res.Groups[0].ToString(), s1); outString = outString.Replace("@0", "local0label" + Program.macrocounter); Program.macrocounter++; outString = outString.Replace("@1", "local1label" + Program.macrocounter); Program.macrocounter++; outString = outString.Replace("@2", "local2label" + Program.macrocounter); Program.macrocounter++; outString = outString.Replace("@3", "local3label" + Program.macrocounter); Program.macrocounter++; outString = outString.Replace("@4", "local4label" + Program.macrocounter); Program.macrocounter++; outString = outString.Replace("@5", "local5label" + Program.macrocounter); Program.macrocounter++; outString = outString.Replace("@6", "local6label" + Program.macrocounter); Program.macrocounter++; outString = outString.Replace("@7", "local7label" + Program.macrocounter); Program.macrocounter++; outString = outString.Replace("@8", "local8label" + Program.macrocounter); Program.macrocounter++; outString = outString.Replace("@9", "local9label" + Program.macrocounter); Program.macrocounter++; outString = outString.Replace("@a", "localalabel" + Program.macrocounter); Program.macrocounter++; outString = outString.Replace("@b", "localblabel" + Program.macrocounter); Program.macrocounter++; outString = outString.Replace("@c", "localclabel" + Program.macrocounter); Program.macrocounter++; outString = outString.Replace("@d", "localdlabel" + Program.macrocounter); Program.macrocounter++; outString = outString.Replace("@e", "localelabel" + Program.macrocounter); Program.macrocounter++; outString = outString.Replace("@f", "localflabel" + Program.macrocounter); Program.macrocounter++; } else { Program.Error(name, l, "Macro mismatch parameters count"); } } } foreach (var item in Program.defined) { outString = outString.Replace(item.Key, item.Value); } return(outString.Replace(" ", "").Replace("\t", "")); } }
static void Main(String[] args) { // ReadArgs Console.WriteLine("Naive assembler, Copyright 2017 Yury Botov"); if (args.Length < 1) { Console.WriteLine("Using: {pathto\\}naive filename.target._"); Console.WriteLine("for example: naive test.stm8s._"); Console.WriteLine("Configuration must be in naive.cfg at current directory"); return; } String fullpath = args[0]; String path = ""; String file = ""; String fileName = ""; String file1Ext = ""; String file2Ext = ""; if (fullpath.IndexOf('\'') >= 0) { Int32 pos = fullpath.LastIndexOf('\''); path = fullpath.Substring(0, pos); file = fullpath.Substring(pos + 1); } else { file = fullpath; } String[] a = file.Split('.'); fileName = a[0]; file1Ext = a[1]; file2Ext = a[2]; if (file2Ext != "_") { Console.WriteLine("Wrong extension, must be *.target._"); return; } if (file1Ext != "stm8s" && file1Ext != "stm8l") { Console.WriteLine("Wrong target, now support only stm8s and stm8l"); return; } target = file1Ext; // Load settings file if (System.IO.File.Exists("naive.cfg")) { System.IO.StreamReader configFile = new System.IO.StreamReader("naive.cfg"); String cfgline = ""; cfgline = configFile.ReadLine(); while (configFile.Peek() >= 0) { if (cfgline.Length == 0) { cfgline = configFile.ReadLine(); continue; } String[] cfgpair = cfgline.Split('|'); defined.Add(cfgpair[0], cfgpair[1]); cfgline = configFile.ReadLine(); } configFile.Close(); } else { Console.WriteLine("naive.cfg in current directory is absent. Please create it with right paths."); return; } // Open output file if (defined["user_output_path"] != null) { Console.WriteLine("Open output file: " + defined["user_output_path"] + fileName + ".asm"); output = new System.IO.StreamWriter(defined["user_output_path"] + fileName + ".asm"); if (output == null) { Console.WriteLine("Can not open output file, may be bad path in naive.cfg?"); return; } } else { Console.WriteLine("Do not defined 'user_output_path' Look at you naive.cfg in current directory"); return; } if (target == "stm8s" || target == "stm8l") { output.Write(AsmStm8.header); } // ParseFile ParseFile parseFile = new ParseFile(); if (defined["user_code_path"] != null) { parseFile.Do(defined["user_code_path"] + file, file); } else { Console.WriteLine("Do not defined 'user_code_path' Look at you naive.cfg in current directory"); return; } if (target == "stm8s" || target == "stm8l") { output.Write(AsmStm8.footer); } output.Close(); Console.WriteLine("Total " + totalFiles + " files with " + totalLines + " lines parsed"); if (target == "stm8s" || target == "stm8l") { // start native stm8 assembler if it present if (System.IO.File.Exists(defined["stm8s_sdk_path"] + "asm.exe") && System.IO.File.Exists(defined["stm8s_sdk_path"] + "lyn.exe") && System.IO.File.Exists(defined["stm8s_sdk_path"] + "obsend.exe") && System.IO.File.Exists(defined["stm8s_sdk_path"] + "abslist.exe")) { String command = "\"" + defined["stm8s_sdk_path"] + "asm.exe\" -sym -li=" + defined["user_output_path"] + fileName + ".lsr " + defined["user_output_path"] + fileName + "\n\"" + defined["stm8s_sdk_path"] + "lyn.exe\" " + defined["user_output_path"] + fileName + ".obj, " + defined["user_output_path"] + fileName + ",;\n\"" + defined["stm8s_sdk_path"] + "obsend.exe\" " + defined["user_output_path"] + fileName + ",f," + defined["user_output_path"] + fileName + ".s19,s\n\"" + defined["stm8s_sdk_path"] + "abslist.exe\" " + defined["user_output_path"] + fileName + ".lsr -o " + defined["user_output_path"] + fileName + ".lst -fmt srec -exe " + defined["user_output_path"] + fileName + ".s19 -map " + defined["user_output_path"] + fileName + ".map\nexit\n"; var process = new Process { StartInfo = new ProcessStartInfo { FileName = "cmd.exe", RedirectStandardInput = true, UseShellExecute = false } }; process.Start(); using (StreamWriter pWriter = process.StandardInput) { if (pWriter.BaseStream.CanWrite) { foreach (var line in command.Split('\n')) { pWriter.WriteLine(line); } } } } else { Console.WriteLine("Check stm8s sdk path in naive.cfg now it wrong"); return; } } return; }