Esempio n. 1
0
 /// <summary>
 /// Creates an instance of the second-pass assembler,
 /// which generates the code in the .text segment.
 /// </summary>
 /// <param name="symbolTable">The symbol table generated by the first-pass parser.</param>
 /// <param name="procFactory">The instruction processor factory to retrieve code generator implementations from.</param>
 public TextCodeGenerator(ILogger logger, SymbolTable symbolTable, InstructionProcessorFactory procFactory)
 {
     m_Logger          = logger;
     m_ParserFac       = procFactory;
     m_SymTbl          = symbolTable;
     m_CurrTextAddress = CommonConstants.BASE_TEXT_ADDRESS;
 }
 /// <summary>
 /// Creates a mapping to segment types to their declarations.
 /// Add future supported segment types here.
 /// </summary>
 /// <param name="procFactory">The instruction processor factory to retrieve instruction size estimator implementations from.</param>
 public SegmentSymbolParserFactory(InstructionProcessorFactory procFac)
 {
     m_ParserTable = new Dictionary <SegmentType, ISymbolTableBuilder>()
     {
         { SegmentType.Data, new DataSymbolBuilder() },
         { SegmentType.Text, new TextSymbolBuilder(procFac) }
     };
 }
Esempio n. 3
0
 /// <summary>
 /// Creates an instance of the CodeGeneratorFactory.
 /// </summary>
 /// <param name="logger">The logging implementation to use for logging warnings/information.</param>
 /// <param name="symTable">The populated symbol table.</param>
 /// <param name="procFactory">The instruction processor factory to retrieve code generator implementations from.</param>
 public CodeGeneratorFactory(ILogger logger, SymbolTable symTable, InstructionProcessorFactory procFactory)
 {
     m_CodeGeneratorTable = new Dictionary <SegmentType, ISegmentCodeGenerator>()
     {
         { SegmentType.Data, new DataCodeGenerator(symTable) },
         { SegmentType.Text, new TextCodeGenerator(logger, symTable, procFactory) }
     };
 }
Esempio n. 4
0
        private static (int acc, bool terminated) Execute(ImmutableArray <Instruction> instructions)
        {
            var lineExecutions = new bool[instructions.Length];

            var acc         = 0;
            var currentLine = 0;

            bool Terminated() => currentLine == instructions.Length;

            while (!Terminated() && !lineExecutions[currentLine])
            {
                var(operation, argument) = instructions[currentLine];

                var instructionProcessor = InstructionProcessorFactory.Get(operation);

                var(accAfter, lineAfter) = instructionProcessor.Evaluate(argument, acc, currentLine);

                lineExecutions[currentLine] = true;
                (acc, currentLine)          = (accAfter, lineAfter);
            }

            return(acc, Terminated());
        }
 /// <summary>
 /// Creates an instance of the first pass assembler, which determines
 /// the locations of labels and generates a symbol table.
 /// </summary>
 /// <param name="logger">The logging implementation to use.</param>
 /// <param name="procFactory">The instruction processor factory to retrieve instruction size estimator implementations from.</param>
 public SymbolTableBuilder(ILogger logger, InstructionProcessorFactory procFac)
 {
     m_Logger            = logger;
     m_SymbolBuilderFac  = new SegmentSymbolParserFactory(procFac);
     m_CurrExternAddress = CommonConstants.BASE_EXTERN_ADDRESS;
 }
 /// <summary>
 /// Creates a new instance of a CodeGenerator.
 /// </summary>
 /// <param name="logger">The logging implementation to use for logging warnings/information.</param>
 /// <param name="symTable">The symbol table to use to resolve references with.</param>
 /// <param name="procFactory">The instruction processor factory to retrieve code generator implementations from.</param>
 public CodeGenerator(ILogger logger, SymbolTable symTable, InstructionProcessorFactory procFac)
 {
     m_CodeGenFac = new CodeGeneratorFactory(logger, symTable, procFac);
 }
Esempio n. 7
0
 /// <summary>
 /// Creates a new instance of a text segment parser
 /// TODO: determine if signedness/unsignedness has any tangible effect
 /// on code generation.
 /// </summary>
 /// <param name="procFactory">The instruction processor factory to retrieve instruction size estimator implementations from.</param>
 public TextSymbolBuilder(InstructionProcessorFactory procFac)
 {
     m_CurrTextAddress  = CommonConstants.BASE_TEXT_ADDRESS;
     m_SizeEstimatorFac = procFac;
 }
        /// <summary>
        /// Task for assembling one individual file.
        /// </summary>
        /// <param name="inputFile">The input file to assemble.</param>
        /// <param name="logger">The logging implementation to log errors/info to.</param>
        /// <param name="options">The options to use while assembling.</param>
        /// <returns>True if the assembler could successfully generate code for the file; otherwise returns false.</returns>
        public AssemblerResult AssembleFile(string inputFile, string outputFile, ILogger logger, AssemblerOptions options)
        {
            var result = new AssemblerResult();

            logger.Log(LogLevel.Info, "Invoking assembler for file " + inputFile);
            try
            {
                bool furtherProcessingNeeded = true;
                if (File.Exists(inputFile) &&
                    File.Exists(outputFile))
                {
                    DateTime inputFileWriteTime  = File.GetLastWriteTimeUtc(inputFile);
                    DateTime outputFileWriteTime = File.GetLastWriteTimeUtc(outputFile);
                    if (outputFileWriteTime > inputFileWriteTime)
                    {
                        logger.Log(LogLevel.Info, "Nothing to do for file " + inputFile);
                        furtherProcessingNeeded = false;
                    }
                }

                if (furtherProcessingNeeded)
                {
                    using (var reader = new StreamReader(File.OpenRead(inputFile)))
                    {
                        var symTable = new SymbolTable();

                        // build the symbol table
                        var instructionProcFac = new InstructionProcessorFactory(symTable);
                        var symTableBuilder    = new SymbolTableBuilder(logger, instructionProcFac);
                        symTableBuilder.GenerateSymbolTableForSegment(reader, SegmentType.Data, symTable);
                        symTableBuilder.GenerateSymbolTableForSegment(reader, SegmentType.Text, symTable);

                        // use the symbol table to generate code with references resolved.
                        var objFile = new BasicObjectFile(inputFile, symTable);

                        var codeGenerator = new CodeGenerator(logger, symTable, instructionProcFac);
                        codeGenerator.GenerateCode(inputFile, reader, objFile);

                        if (!objFile.TextElements.Any())
                        {
                            logger.Log(LogLevel.Warning, "No .text segment to assemble. Stop.");
                            result.OperationSuccessful = false;
                        }
                        else
                        {
                            // write the object file out.
                            var writerFac            = new ObjectFileWriterFactory();
                            IObjectFileWriter writer = writerFac.GetWriterForOutputFile(outputFile);
                            writer.WriteObjectFile(outputFile, objFile);
                        }
                    }
                }
            }
            catch (AggregateAssemblyError ex)
            {
                foreach (AssemblyException asEx in ex.AssemblyErrors)
                {
                    logger.Log(LogLevel.Critical, "In file \"" + inputFile + "\" (line " + asEx.LineNumber + "):\n\t");
                    logger.Log(LogLevel.Critical, asEx.Message);
                    result.AddUserAssemblyError(asEx);
                }
            }
            catch (Exception ex)
            {
                logger.Log(LogLevel.Critical, ex.StackTrace);
                logger.Log(LogLevel.Critical, ex.Message);
                if (ex.InnerException != null)
                {
                    logger.Log(LogLevel.Critical, ex.InnerException.StackTrace);
                    logger.Log(LogLevel.Critical, ex.InnerException.Message);
                }
                result.AddInternalAssemblerError(ex);
            }

            return(result);
        }