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); }
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; } } }
public OperandResolver(AssemblyRow row, IReadOnlyDictionary <string, Symbol> symbolTable) { m_AssemblyRow = row; m_SymbolTable = symbolTable; }
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); }