private void PreprocessDefine(PreprocessorRowTokenizer tokenizer) { var definePreprocessor = new DefinePreprocessor(tokenizer); definePreprocessor.Preprocess(); m_Defines[definePreprocessor.DefineName] = definePreprocessor.DefineValue ?? string.Empty; }
public bool Preprocess(PreprocessorRowTokenizer tokenizer) { if (tokenizer.Tokens.Count < 2) { throw new Z80AssemblerException($"Az {tokenizer.Tokens[0]} utasításnak meg kell adni a file nevét!"); } string fileName = tokenizer.Tokens[1].Replace("\"", "").Replace("'", ""); List <string> includedProgramLines = new List <string>(); foreach (string includeDirectory in m_IncludeDirectories) { var filePath = Path.Combine(includeDirectory, fileName); if (File.Exists(filePath)) { if (m_IncludedFiles.Any(kvp => kvp.Key.Equals(filePath))) { throw new Z80AssemblerException($"Rekurzív file hivatkozás az #INCLUDE utasításban! A file {filePath} már beágyazásra került a(z) {m_IncludedFiles[filePath]} fileban!"); } try { using (FileStream fs = new FileStream(filePath, FileMode.Open)) { using (StreamReader sr = new StreamReader(fs)) { while (!sr.EndOfStream) { includedProgramLines.Add(sr.ReadLine()); } } } if (includedProgramLines.Count == 0) { throw new Z80AssemblerException($"A hivatkozott file:{filePath} üres!"); } Z80Preprocessor preprocessor = new Z80Preprocessor(includedProgramLines, m_IncludeDirectories, filePath, m_Defines); if (!preprocessor.Preprocess()) { throw new Z80AssemblerException(preprocessor.StatusMessage); } PreprocessedProgramLines.AddRange(preprocessor.PreprocessedProgramLines); m_IncludedFiles.Add(filePath, m_FileName); return(true); } catch (Exception e) { StatusMessage = $"A '{fileName}' file feldolgozásakor a következő hiba lépett fel:{e.Message}"; return(false); } } } throw new Z80AssemblerException($"Az #INCLUDE utasításban megadott file:{fileName} nem található a megadott útvonalak egyikén sem!"); }
private void ProcessInclude(PreprocessorRowTokenizer tokenizer) { var includePreprocessor = new IncludePreprocessor(m_IncludeDirectories, m_IncludedFiles, m_FileName, m_Defines); if (!includePreprocessor.Preprocess(tokenizer)) { throw new Z80AssemblerException(includePreprocessor.StatusMessage); } m_PreprocessedProgramLines.AddRange(includePreprocessor.PreprocessedProgramLines); }
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 ProcessUndef(PreprocessorRowTokenizer tokenizer) { if (tokenizer.Tokens.Count < 2) { throw new Z80AssemblerException("Az #UNDEF utasítás nem állhat üresen! "); } if (m_Defines.ContainsKey(tokenizer.Tokens[1])) { m_Defines.Remove(tokenizer.Tokens[1]); } }
private void ProcessMacro(ref int rowIndex, ref int lineNumber, PreprocessorRowTokenizer tokenizer) { MacroPreprocessor m = new MacroPreprocessor(m_IncludeDirectories, m_FileName, m_Defines); if (!m.PreprocessMacro(ref rowIndex, ref lineNumber, m_ProgramLines, tokenizer)) { throw new Z80AssemblerException(m.StatusMessage); } if (!m_Macros.ContainsKey(m.Name)) { m_Macros.Add(m.Name, m); } else { throw new Z80AssemblerException($"A '{m.Name}' nevű makró már definiálva van!"); } }
public DefinePreprocessor(PreprocessorRowTokenizer tokenizer) { m_Tokenizer = tokenizer; }
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); } } }
private void InterpretPreprocessorDirective(ref int rowIndex, ref int lineNumber, PreprocessorRowTokenizer tokenizer) { switch (tokenizer.Tokens[0]) { case PreprocessorConstans.PreprocessorDirectives.Define: PreprocessDefine(tokenizer); break; case PreprocessorConstans.PreprocessorDirectives.Undef: ProcessUndef(tokenizer); break; case PreprocessorConstans.PreprocessorDirectives.Include: ProcessInclude(tokenizer); break; case PreprocessorConstans.PreprocessorDirectives.Macro: ProcessMacro(ref rowIndex, ref lineNumber, tokenizer); break; case PreprocessorConstans.PreprocessorDirectives.Else: throw new Z80AssemblerException("Az #ELSE utasítást csak az #IFDEF/#IFNDEF és #ENDIF utasítások között lehet használni!"); case PreprocessorConstans.PreprocessorDirectives.EndIf: throw new Z80AssemblerException("Az #ENDIF utasítást #IFDEF vagy #IFNDEF utasításoknak kell megelőznie!"); case PreprocessorConstans.PreprocessorDirectives.Endm: throw new Z80AssemblerException("Az #ENDM utasítást a #MACRO utasításnak kell megelőznie!"); } }
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); } }