public bool Preprocess() { int lineNumber = 0; int rowIndex = -1; while (++rowIndex < m_ProgramLines.Count) { try { lineNumber++; string line = m_ProgramLines[rowIndex].TrimStart(' ', '\t'); if (line.StartsWith("#")) { PreprocessorRowTokenizer tokenizer = new PreprocessorRowTokenizer(line.ToUpper()); tokenizer.TokenizeRow(); if (tokenizer.Tokens.Count == 0) { throw new Z80AssemblerException("Üres preprocesszor utasítás!"); } switch (tokenizer.Tokens[0]) { case PreprocessorConstans.PreprocessorDirectives.IfnDef: case PreprocessorConstans.PreprocessorDirectives.IfDef: { if (tokenizer.Tokens.Count < 2) { throw new Z80AssemblerException($"Az {tokenizer.Tokens[0]} utasításnak szüksége van operandusra!"); } ProcessConditionalGroup(ref rowIndex, ref lineNumber, tokenizer); } break; default: InterpretPreprocessorDirective(ref rowIndex, ref lineNumber, tokenizer); break; } } else { PreprocessAssemblyRow(line, lineNumber); } } catch (Z80AssemblerException exception) { m_StatusMessage.AppendLine($"{exception.Message} Sor:{lineNumber} File:{m_FileName}"); WrongLineNumber = lineNumber; return(false); } } return(true); }
private void ProcessConditionalGroup(ref int rowIndex, ref int lineNumber, PreprocessorRowTokenizer tokenizer) { bool skipNextRow = tokenizer.Tokens[0] == PreprocessorConstans.PreprocessorDirectives.IfDef ? m_Defines.All(kvp => kvp.Key != tokenizer.Tokens[1]) : m_Defines.Any(kvp => kvp.Key == tokenizer.Tokens[1]); bool stop = false; bool conditionContainsElse = false; while (!stop) { if (++rowIndex == m_ProgramLines.Count) { throw new Z80AssemblerException($"Az {tokenizer} utasítás nincs lezárva #ENDIF utasítással!"); } lineNumber++; string line = m_ProgramLines[rowIndex].TrimStart(' ', '\t'); if (line.StartsWith("#")) { tokenizer = new PreprocessorRowTokenizer(line.ToUpper()); tokenizer.TokenizeRow(); if (tokenizer.Tokens.Count == 0) { throw new Z80AssemblerException("Hibás preprocesszor utasítás!"); } switch (tokenizer.Tokens[0]) { case PreprocessorConstans.PreprocessorDirectives.Else: { if (conditionContainsElse) { throw new Z80AssemblerException("Egy feltételes szekció csak egy #ELSE utasítást tartalmazhat!"); } skipNextRow = !skipNextRow; conditionContainsElse = true; } continue; case PreprocessorConstans.PreprocessorDirectives.EndIf: stop = true; continue; case PreprocessorConstans.PreprocessorDirectives.IfDef: case PreprocessorConstans.PreprocessorDirectives.IfnDef: ProcessConditionalGroup(ref rowIndex, ref lineNumber, tokenizer); continue; default: { if (!skipNextRow) { InterpretPreprocessorDirective(ref rowIndex, ref lineNumber, tokenizer); } else { m_SkippedLineNumbers.Add(lineNumber); } } continue; } } if (!skipNextRow) { PreprocessAssemblyRow(line, lineNumber); } else { m_SkippedLineNumbers.Add(lineNumber); } } }
public bool PreprocessMacro(ref int rowIndex, ref int lineNumber, IReadOnlyList <string> programLines, PreprocessorRowTokenizer tokenizer) { try { if (tokenizer.Tokens.Count < 2) { throw new Z80AssemblerException("A macro nevét meg kell adni!"); } PreprocessMacroAndParameterNames(tokenizer.Tokens[1]); bool stopProcessing = false; while (!stopProcessing) { lineNumber++; if (++rowIndex == programLines.Count) { throw new Z80AssemblerException($"Az {tokenizer} utasítás nincs lezárva #ENDM utasítással!"); } string line = programLines[rowIndex].ToUpper().TrimStart(' ', '\t'); if (line.StartsWith("#")) { tokenizer = new PreprocessorRowTokenizer(line); tokenizer.TokenizeRow(); if (tokenizer.Tokens.Count == 0) { throw new Z80AssemblerException("Hibás preprocesszor utasítás!"); } switch (tokenizer.Tokens[0]) { case PreprocessorConstans.PreprocessorDirectives.Include: case PreprocessorConstans.PreprocessorDirectives.Macro: { throw new Z80AssemblerException("Makró definíció nem tartalmazhat #MACRO és #INCLUDE utasításokat!"); } case PreprocessorConstans.PreprocessorDirectives.Endm: { stopProcessing = true; } continue; default: { m_MacroLines.Add(line); } continue; } } m_MacroLines.Add(line); } if (m_MacroLines.Count == 0) { throw new Z80AssemblerException("Üres makró definíció!"); } return(true); } catch (Z80AssemblerException e) { StatusMessage = e.Message; return(false); } }