예제 #1
0
        private bool BuildProcessorInstruction(AssemblyRow row)
        {
            try
            {
                if (row.State == AssemblyRowState.Assembled)
                {
                    return(true);
                }

                var operandresolver  = new OperandResolver(row, AssembledProgram.SymbolTable);
                var resolvedOperands = operandresolver.Resolve();

                IZ80InstructionBuilder builder =
                    m_InstructionBuilderFactory.GetInstructionBuilder(row.Instruction.Mnemonic, resolvedOperands,
                                                                      AssembledProgram.SymbolTable[AssemblerConstans.LocationCounterSymbol].Value);

                if (builder != null)
                {
                    builder.Build();
                    if (builder.InstructionBytes != null)
                    {
                        row.InstructionBytes.Clear();
                        row.InstructionBytes.AddRange(builder.InstructionBytes);
                        row.State       = resolvedOperands.Any(o => o.State == OperandState.FutureSymbol) ? AssemblyRowState.ContainsFutureSymbol : AssemblyRowState.Assembled;
                        row.ClockCycles = builder.ClockCycles;
                    }
                }
            }
            catch (Z80AssemblerException exception)
            {
                m_StatusMessage.AppendLine($"{exception.Message} Sor:{row.RowNumber}");
                WrongLineNumber = row.RowNumber;
                return(false);
            }
            return(true);
        }
예제 #2
0
        public void InterpretRow()
        {
            InterpretedAssemblyRow = new AssemblyRow();
            InterpretStateMachine sMachine = InterpretStateMachine.Init;

            foreach (string token in m_TokenizedRows)
            {
                switch (sMachine)
                {
                case InterpretStateMachine.Init:
                    if (token.StartsWith(";"))
                    {
                        InterpretedAssemblyRow.Comment = token;
                    }
                    else if (IsSymbol(token))
                    {
                        if (!char.IsLetter(token[0]))
                        {
                            throw new Z80AssemblerException($"A cimke csak betűvel kezdődhet:'{token}'");
                        }

                        InterpretedAssemblyRow.Label = token.ToUpper();
                        sMachine = InterpretStateMachine.Label;
                    }
                    else if (IsProcessorInstruction(token))
                    {
                        InterpretedAssemblyRow.Instruction.Mnemonic = token.ToUpper();
                        InterpretedAssemblyRow.Instruction.Type     = InstructionType.ProcessorInstruction;
                        sMachine = InterpretStateMachine.Instruction;
                    }
                    else if (IsPseudoInstruction(token))
                    {
                        InterpretedAssemblyRow.Instruction.Mnemonic = token.ToUpper();
                        InterpretedAssemblyRow.Instruction.Type     = InstructionType.AssemblerInstruction;
                        sMachine = InterpretStateMachine.Instruction;
                    }
                    else
                    {
                        throw new Z80AssemblerException($"Helytelen szó a sorban:'{token}'");
                    }
                    continue;

                case InterpretStateMachine.Label:
                    if (IsProcessorInstruction(token))
                    {
                        InterpretedAssemblyRow.Instruction.Mnemonic = token.ToUpper();
                        InterpretedAssemblyRow.Instruction.Type     = InstructionType.ProcessorInstruction;
                        sMachine = InterpretStateMachine.Instruction;
                    }
                    else if (IsPseudoInstruction(token))
                    {
                        InterpretedAssemblyRow.Instruction.Mnemonic = token.ToUpper();
                        InterpretedAssemblyRow.Instruction.Type     = InstructionType.AssemblerInstruction;
                        sMachine = InterpretStateMachine.Instruction;
                    }
                    else
                    {
                        throw new Z80AssemblerException($"Helytelen utasítás:'{token.ToUpper()}'! Az utasítás csak processzor, vagy assembler utasítás lehet!");
                    }
                    continue;

                case InterpretStateMachine.Instruction:
                {
                    if (token.StartsWith(";"))
                    {
                        InterpretedAssemblyRow.Comment = token;
                    }
                    else
                    {
                        var operandStrings = SplitOperands(token, ',');
                        foreach (string operandString in operandStrings)
                        {
                            if (!string.IsNullOrEmpty(operandString))
                            {
                                if (operandString.StartsWith("'") && !operandString.EndsWith("'") ||
                                    operandString.StartsWith("\"") && !operandString.EndsWith("\""))
                                {
                                    throw new Z80AssemblerException(
                                              $"Szintaxis hiba: a karakterlánc nincs lezárva:{operandString}!");
                                }

                                InterpretedAssemblyRow.Operands.Add(new Operand(IsLiteral(operandString) ? operandString : operandString.ToUpper()));
                            }
                        }
                        sMachine = InterpretStateMachine.Operands;
                    }
                    continue;
                }

                case InterpretStateMachine.Operands:
                    if (token.StartsWith(";"))
                    {
                        InterpretedAssemblyRow.Comment = token;
                    }
                    else
                    {
                        throw new Z80AssemblerException($"Helytelen szó a sorban:'{token}'");
                    }
                    continue;
                }
            }
        }
예제 #3
0
 public OperandResolver(AssemblyRow row, IReadOnlyDictionary <string, Symbol> symbolTable)
 {
     m_AssemblyRow = row;
     m_SymbolTable = symbolTable;
 }
예제 #4
0
        private bool ResolveAssemblerInstruction(AssemblyRow row)
        {
            try
            {
                if (row.Instruction.Mnemonic == AssemblerConstans.AssemblerInstructions.Org)
                {
                    var parser = new OrgInstructionParser(row, AssembledProgram.SymbolTable);
                    var result = parser.Parse();
                    if (result.ResultCode == ParseResultCode.Error)
                    {
                        throw new Z80AssemblerException(result.Message);
                    }

                    if (result.ResultCode == ParseResultCode.Ok)
                    {
                        ushort orgOperandValue = result.ResultValue;
                        if (row.State != AssemblyRowState.Interpreted)
                        {
                            if (m_CurrentProgramSection == null)
                            {
                                m_CurrentProgramSection = new ProgramSection {
                                    ProgramStartAddress = orgOperandValue
                                };
                            }
                            else
                            {
                                m_CurrentProgramSection.SectionLength =
                                    (ushort)(AssembledProgram.SymbolTable[AssemblerConstans.LocationCounterSymbol].Value -
                                             m_CurrentProgramSection.ProgramStartAddress);
                                AssembledProgram.ProgramSections.Add(m_CurrentProgramSection);
                                m_CurrentProgramSection = new ProgramSection {
                                    ProgramStartAddress = orgOperandValue
                                };
                            }
                        }

                        AssembledProgram.SymbolTable[AssemblerConstans.LocationCounterSymbol].Value = orgOperandValue;
                        if (!string.IsNullOrEmpty(row.Label))
                        {
                            AssembledProgram.SymbolTable[row.Label] = new Symbol {
                                Name = row.Label, Value = orgOperandValue, LineNumber = row.RowNumber
                            };
                        }

                        row.State = AssemblyRowState.Interpreted;
                    }

                    return(true);
                }

                if (row.Instruction.Mnemonic == AssemblerConstans.AssemblerInstructions.End)
                {
                    if (row.State != AssemblyRowState.Interpreted)
                    {
                        if (m_CurrentProgramSection == null)
                        {
                            throw new Z80AssemblerException(" Hiányzó 'ORG' utasítás!");
                        }

                        m_CurrentProgramSection.SectionLength =
                            (ushort)(AssembledProgram.SymbolTable[AssemblerConstans.LocationCounterSymbol].Value - m_CurrentProgramSection.ProgramStartAddress);
                        AssembledProgram.ProgramSections.Add(m_CurrentProgramSection);
                        m_CurrentProgramSection = null;
                    }
                    row.State = AssemblyRowState.Interpreted;
                    return(true);
                }

                if (row.State == AssemblyRowState.Interpreted || row.State == AssemblyRowState.Assembled)
                {
                    return(true);
                }

                if (row.Instruction.Mnemonic == AssemblerConstans.AssemblerInstructions.Equ ||
                    row.Instruction.Mnemonic == AssemblerConstans.AssemblerInstructions.EqualSymbol)
                {
                    var parser = new EquInstructionParser(row, AssembledProgram.SymbolTable);

                    var parseResult = parser.Parse();
                    if (parseResult.ResultCode == ParseResultCode.Error)
                    {
                        throw new Z80AssemblerException(parseResult.Message);
                    }

                    if (parseResult.ResultCode == ParseResultCode.Ok)
                    {
                        var symbol = AssembledProgram.SymbolTable.First(s => s.Key == row.Label.ToUpper());
                        symbol.Value.Value = parseResult.ResultValue;
                        row.State          = AssemblyRowState.Interpreted;
                    }
                    else
                    {
                        row.State = AssemblyRowState.ContainsFutureSymbol;
                    }

                    return(true);
                }

                row.InstructionBytes.Clear();
                var resolver = AssemblerInstructionResolver.Create(row.Instruction.Mnemonic,
                                                                   AssembledProgram.SymbolTable,
                                                                   IncludeDirectories);
                var resolverResult = resolver.Resolve(row);

                if (resolverResult.ResultCode == ParseResultCode.Error)
                {
                    throw new Z80AssemblerException(resolverResult.Message);
                }

                row.InstructionBytes.AddRange(resolver.InstructionBytes);
                row.State = resolverResult.ResultCode == ParseResultCode.Ok
                    ? AssemblyRowState.Assembled
                    : AssemblyRowState.ContainsFutureSymbol;
            }
            catch (Z80AssemblerException exception)
            {
                m_StatusMessage.AppendLine($"{exception.Message} Sor:{row.RowNumber}");
                WrongLineNumber = row.RowNumber;
                return(false);
            }
            return(true);
        }