/// <summary> /// Populates an existing symbol table with symbols parsed from the desired segment. /// </summary> /// <param name="reader">A StreamReader instance that will read the input assembly file.</param> /// <param name="desiredSegment">The program segment to parse symbols from.</param> /// <param name="symTable">The SymbolTable instance to populate.</param> public void GenerateSymbolTableForSegment(StreamReader reader, SegmentType desiredSegment, SymbolTable symTable) { SegmentType currSegmentType = SegmentType.Invalid; int currAlignment = CommonConstants.DEFAULT_ALIGNMENT; // a list of all exceptions we encounter during parsing. // users can view them all at once instead of working through them piecemeal. var exceptionList = new List <AssemblyException>(); int lineNum = 0; while (!reader.EndOfStream) { try { ++lineNum; // trim the whitespace from any read-in line. string line = reader.ReadLine().Trim(); // get a substring up until the commented line, ignoring those in user quotes. line = ParserCommon.GetSanitizedString(line); // ignore blank lines. trim should remove all whitespace try { if (!string.IsNullOrWhiteSpace(line)) { LineParseResults directiveResults = ParserCommon.HandleAssemblerDirective(line, lineNum, currSegmentType, currAlignment); currAlignment = directiveResults.NewAlignment; currSegmentType = directiveResults.NewSegment; // further processing is needed, and the current segment type is the desired segment type. if (!directiveResults.IsLineAssemblerDirective && currSegmentType == desiredSegment) { if (!TryHandlingLinkageDeclaration(line, lineNum, currSegmentType, symTable)) { ISymbolTableBuilder segParser = m_SymbolBuilderFac.GetParserForSegment(lineNum, currSegmentType); var asmLine = new LineData(line, lineNum); segParser.ParseSymbolsInLine(asmLine, symTable, currAlignment); } } } } catch (AssemblyException) { throw; } catch (Exception ex) { throw new AssemblyException(lineNum, ex.Message); } } catch (AssemblyException ex) { exceptionList.Add(ex); } } // if any exceptions were encountered, throw an aggregate exception with // all of the encountered exceptions. if (exceptionList.Any()) { throw new AggregateAssemblyError(exceptionList); } // reset the StreamReader to the beginning position. reader.Seek(0, SeekOrigin.Begin); }
/// <summary> /// Generates code for the given assembly file. /// </summary> /// <param name="reader">A StreamReader instance that will read the input assembly file.</param> /// <param name="objFile">The basic object file that will be written to.</param> public void GenerateCode(string fileName, StreamReader reader, BasicObjectFile objFile) { SegmentType currSegmentType = SegmentType.Invalid; int currAlignment = CommonConstants.DEFAULT_ALIGNMENT; // a list of all exceptions we encounter during parsing. // users can view them all at once instead of working through them piecemeal. var exceptionList = new List <AssemblyException>(); int lineNum = 0; while (!reader.EndOfStream) { try { ++lineNum; // trim the whitespace from any read-in line. string line = reader.ReadLine().Trim(); // get a substring up until the commented line, ignoring those in user quotes. line = ParserCommon.GetSanitizedString(line); // ignore blank lines. trim should remove all whitespace if (line.Any()) { LineParseResults directiveResults = ParserCommon.HandleAssemblerDirective(line, lineNum, currSegmentType, currAlignment); // if we have a new data alignment, we need to record this in case the disassembler // parses this file. otherwise, it will interpret padding bytes as actual data elements. if (currAlignment != directiveResults.NewAlignment) { objFile.AddAlignmentChangeDeclaration(directiveResults.NewAlignment); } currAlignment = directiveResults.NewAlignment; currSegmentType = directiveResults.NewSegment; // if our segment type is valid, then we're processing actual data versus an assembler directive. if (!directiveResults.IsLineAssemblerDirective && currSegmentType != SegmentType.Invalid) { if (!TryHandlingLinkageDeclaration(line, lineNum, objFile)) { ISegmentCodeGenerator codeGen = m_CodeGenFac.GetCodeGeneratorForSegment(currSegmentType); var asmLine = new LineData(line, lineNum); try { codeGen.GenerateCodeForSegment(fileName, asmLine, objFile, currAlignment); } catch (AssemblyException) { throw; } catch (Exception ex) { throw new AssemblyException(lineNum, ex.Message); } } } } } catch (AssemblyException ex) { exceptionList.Add(ex); } } // if any exceptions were encountered, throw an aggregate exception with // all of the encountered exceptions. if (exceptionList.Any()) { throw new AggregateAssemblyError(exceptionList); } // reset the StreamReader to the beginning position. reader.Seek(0, SeekOrigin.Begin); }