/// <summary>Parse the input X# source code file and generate the matching target assembly /// language.</summary> /// <param name="aSrcPathname">X# source code file.</param> /// <returns>The resulting target assembler content. The returned object contains /// a code and a data block.</returns> public Assembler Generate(string aSrcPathname) { try { mPatterns.EmitUserComments = EmitUserComments; mLineNo = 0; var xResult = new Assembler(); using (var xInput = new StreamReader(aSrcPathname)) { // Read one X# source code line at a time and process it. while (true) { mLineNo++; string xLine = xInput.ReadLine(); if (xLine == null) { break; } var xAsm = ProcessLine(xLine, mLineNo); xResult.Data.AddRange(xAsm.Data); xResult.Code.AddRange(xAsm.Code); } } AssertLastFunctionComplete(); return xResult; } catch (Exception E) { throw new Exception("Error while generating output for file " + Path.GetFileName(aSrcPathname), E); } }
/// <summary>Parse the input X# source code file and generate the matching target assembly /// language.</summary> /// <param name="aReader">X# source code reader.</param> /// <returns>The resulting target assembler content. The returned object contains /// a code and a data block.</returns> public Assembler Generate(StreamReader aReader) { if (aReader == null) { throw new ArgumentNullException(nameof(aReader)); } mPatterns.EmitUserComments = EmitUserComments; mLineNo = 0; var xResult = new Assembler(); // Read one X# source code line at a time and process it. while (true) { mLineNo++; string xLine = aReader.ReadLine(); if (xLine == null) { break; } var xAsm = ProcessLine(xLine, mLineNo); xResult.Data.AddRange(xAsm.Data); xResult.Code.AddRange(xAsm.Code); } AssertLastFunctionComplete(); return xResult; }
/// <summary>Process a single X# source code line and translate it into the target /// assembler syntax.</summary> /// <param name="aLine">The processed X# source code line.</param> /// <param name="lineNumber">Line number for debugging and diagnostic messages.</param> /// <returns>The resulting target assembler content. The returned object contains /// a code and a data block.</returns> protected Assembler ProcessLine(string aLine, int lineNumber) { Assembler xAsm; aLine = aLine.Trim(); if (String.IsNullOrEmpty(aLine) || aLine == "//") { xAsm = new Assembler(); xAsm += ""; return xAsm; } // Currently we use a new assembler for every line. // If we dont it could create a really large in memory object. xAsm = mPatterns.GetCode(aLine, lineNumber); if (xAsm == null) { var xMsg = new StringBuilder(); if (mPathname != "") { xMsg.Append("File " + mPathname + ", "); } xMsg.Append("Line " + mLineNo + ", "); xMsg.Append("Parsing error: " + aLine); throw new Exception(xMsg.ToString()); } return xAsm; }