//******************************************************************************************* //*** FUNCTION ParseTerm //*** *************************************************************************************** //*** DESCRIPTION : parses an term str(int or symbol) to a symbol struct //*** INPUT ARGS : SymbolTable symbolTable, string term, string currentLine="" //*** OUTPUT ARGS : out Globals.Symbol? sym //*** IN/OUT ARGS : N/A //*** RETURN : bool rtnVal //******************************************************************************************* static bool ParseTerm(SymbolTable symbolTable, string term, out Globals.Symbol?sym, string currentLine) { bool rtnVal = true; if (char.IsDigit(term[0]) || (term[0] == '-' && char.IsDigit(term[1]))) { sym = null; if (ParseNum(term, out Globals.Symbol? tmp, currentLine) == true) { sym = tmp; } else { Chronicler.LogDetailedInfo("Parse term(digit) in Expresion Handler failed"); rtnVal = false; } } else { int Mval = 1; if (term[0] == '-') { term.Substring(1, term.Length - 1); Mval = -1; } Chronicler.LogDetailedInfo("Parse term(sym) start"); if ((symbolTable.SearchSymbol(term.Trim(), currentLine, out sym)) != true) { Chronicler.LogDetailedInfo("Parse term(sym) in Expresion Handler failed"); rtnVal = false; } if (sym.HasValue) { Globals.Symbol tmp = sym.Value; tmp.value *= Mval; sym = tmp; } Chronicler.LogDetailedInfo("Parse term(sym) end"); } return(rtnVal); }
public static void Execute(Globals.DataStructures dataStructures, out List <ExpresionLine> expresionLines, string filePath) { int locationCounter = 0; int lineNumber = 0; expresionLines = new List <ExpresionLine>(); Regex regex = new Regex(@"^([\t ]*(?<label>[^\s]+:)[\t ]*){0,1}[\t ]*(?<flag>\+{0,1}[\t ]*)(?<operation>[^\s]+)(?<operandFieldAndComment>[\t ].*){0,1}[\t ]*($|(\r?\n))"); int programLength = 0; bool skipOperandParsing = false; try { using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan)) { try { using (StreamReader streamReader = new StreamReader(fileStream)) { while (!streamReader.EndOfStream) { lineNumber++; string currentLine = streamReader.ReadLine().Trim(); Match match = regex.Match(currentLine); skipOperandParsing = false; if (match.Success) { ExpresionLine expresionLine = new ExpresionLine(); expresionLine.OriginalLine = currentLine; expresionLine.lineNumber = lineNumber; expresionLine.locationCounter = locationCounter; expresionLine.label = match.Groups["label"].Value.Trim(); expresionLine.operation = match.Groups["operation"].Value.Trim(); expresionLine.operandFieldAndComment = match.Groups["operandFieldAndComment"].Value.Trim(); expresionLine.lineNumber = lineNumber; expresionLine.format4indicator = match.Groups["flag"].Value.Trim(); expresionLine.DeferExpresionResolutiontoPass2 = false; if (expresionLine.label != "") { if (expresionLine.label[expresionLine.label.Length - 1] == ':') { expresionLine.label = expresionLine.label.Substring(0, expresionLine.label.Length - 1).Trim(); } else { expresionLine.validLine = false; Chronicler.LogError("Labels must end in a ':'"); } if (expresionLine.validLine) { SymbolTable.ValidateLabel(expresionLine.label, currentLine, "pass one"); } } Regex commentChecker = new Regex(@"[\t ]*(?<com>;.*)"); Match comment = commentChecker.Match(currentLine); if (comment.Success) { expresionLine.OriginalLine = currentLine; expresionLine.locationCounter = 0; expresionLine.label = ""; expresionLine.operation = ""; expresionLine.operandFieldAndComment = ""; expresionLine.lineNumber = lineNumber; expresionLine.format4indicator = ""; expresionLine.CommentLine = true; expresionLine.DeferExpresionResolutiontoPass2 = false; skipOperandParsing = true; expresionLines.Add(expresionLine); } else { if (dataStructures.opcodeTable.assemblerDirectives.Contains(expresionLine.operation)) { switch (expresionLine.operation) { case "EQU": skipOperandParsing = true; expresionLine.IsEQU = true; if (expresionLine.operandFieldAndComment[0] == '*' && expresionLine.validLine) { dataStructures.symbolTable.addSymbol(expresionLine.label, true, locationCounter, currentLine); } else if (expresionLine.validLine) { if (ExpresionHandler.ResolveF3F4Expresion(dataStructures, expresionLine.operandFieldAndComment, currentLine, out expresionLine.expresionData) != true) { expresionLine.validLine = false; } else { if (expresionLine.expresionData.first.HasValue) { int value = expresionLine.expresionData.first.Value.value; if (expresionLine.expresionData.second.HasValue) { if (expresionLine.expresionData.operatorValue != null && expresionLine.expresionData.operatorValue == Globals.ExpresionData.Arithmetic.SUBTRACT) { value = (expresionLine.expresionData.first.Value.value) - expresionLine.expresionData.second.Value.value; } if (expresionLine.expresionData.operatorValue != null && expresionLine.expresionData.operatorValue == Globals.ExpresionData.Arithmetic.ADD) { value = (expresionLine.expresionData.first.Value.value) + expresionLine.expresionData.second.Value.value; } if (expresionLine.expresionData.rflag.HasValue != true) { expresionLine.validLine = false; } if (expresionLine.validLine) { expresionLine.locationCounter = value; dataStructures.symbolTable.addSymbol(expresionLine.label, expresionLine.expresionData.rflag.Value, value, currentLine); } else { Chronicler.LogError("Couldn't add \"" + currentLine + "\" to symbol table.", "pass one"); } } else { expresionLine.expresionData.rflag = expresionLine.expresionData.first.Value.RFlag; if (expresionLine.validLine) { expresionLine.locationCounter = value; dataStructures.symbolTable.addSymbol(expresionLine.label, expresionLine.expresionData.rflag.Value, value, currentLine); } else { Chronicler.LogError("Couldn't add \"" + currentLine + "\" to symbol table.", "pass one"); } } } else { Chronicler.LogError("EQU can not be a literal value", "pass one"); expresionLine.validLine = false; } } } break; case "BYTE": if (ExpresionHandler.ResolveF3F4Expresion(dataStructures, expresionLine.operandFieldAndComment, currentLine, out expresionLine.expresionData) != true) { expresionLine.validLine = false; } else { skipOperandParsing = false; if (expresionLine.expresionData.first.HasValue) { Chronicler.LogError("BYTE doesn't accept integer values", "pass one"); expresionLine.validLine = false; } else if (expresionLine.expresionData.literal != null) { if (expresionLine.expresionData.literal.isOldStyleLiteral) { if (expresionLine.label != "") { dataStructures.symbolTable.addSymbol(expresionLine.label, true, locationCounter, currentLine); } locationCounter += expresionLine.expresionData.literal.Length; expresionLine.Opcode = expresionLine.expresionData.literal.hexValue; } else { expresionLine.validLine = false; Chronicler.LogError("New style literals are not allowed in assembler directives"); } } } break; case "WORD": expresionLine.DeferExpresionResolutiontoPass2 = true; if (ExpresionHandler.ResolveF3F4Expresion(dataStructures, expresionLine.operandFieldAndComment, currentLine, out expresionLine.expresionData) != true) { expresionLine.validLine = false; } else { if (expresionLine.expresionData.first.HasValue) { int value = expresionLine.expresionData.first.Value.value; if (expresionLine.expresionData.second.HasValue) { if (expresionLine.expresionData.operatorValue != null && expresionLine.expresionData.operatorValue == Globals.ExpresionData.Arithmetic.SUBTRACT) { value = (expresionLine.expresionData.first.Value.value) - expresionLine.expresionData.second.Value.value; } if (expresionLine.expresionData.operatorValue != null && expresionLine.expresionData.operatorValue == Globals.ExpresionData.Arithmetic.ADD) { value = (expresionLine.expresionData.first.Value.value) + expresionLine.expresionData.second.Value.value; } } if (expresionLine.expresionData.rflag.HasValue != true) { expresionLine.validLine = false; } if (expresionLine.validLine && expresionLine.label != "") { dataStructures.symbolTable.addSymbol(expresionLine.label, true, locationCounter, currentLine); } if (expresionLine.validLine) { expresionLine.Opcode = value.ToString("X"); locationCounter += 3; } else { Chronicler.LogError("Couldn't parse \"" + currentLine + "\"", "pass one"); } } else if (expresionLine.expresionData.literal != null) { Chronicler.LogError("BYTE doesn't accept Charachter/Hex values", "pass one"); expresionLine.validLine = false; } } break; case "START": skipOperandParsing = true; Regex testBlankLine = new Regex(@"[\t ]*;.*"); if (expresionLine.operandFieldAndComment == "") { locationCounter = 0; } else if (testBlankLine.IsMatch(expresionLine.operandFieldAndComment)) { locationCounter = 0; } else { if (ExpresionHandler.ResolveF3F4Expresion(dataStructures, expresionLine.operandFieldAndComment, currentLine, out expresionLine.expresionData) != true) { expresionLine.validLine = false; } else { Regex stripComment = new Regex(@"[\t ]*(?<min>-{0,1})[\t ]*(?<val>[0-9]+)[\t ]*(;.*){0,1}"); Match match1 = stripComment.Match(expresionLine.operandFieldAndComment); if (match1.Success) { Globals.Symbol?tmp; ExpresionHandler.ParseNum(match1.Groups["min"].Value + match1.Groups["val"].Value, out tmp, "(" + match1.Groups["min"].Value + match1.Groups["val"].Value + ")" + currentLine); expresionLine.expresionData.comment = match1.Groups["$3"].Value; if (tmp.HasValue && locationCounter == 0) { locationCounter = tmp.Value.value; ExpresionLine.startLoc = locationCounter; } else { Chronicler.LogError("couldn't parse starting adress number, or start was not at beggining of the program", "Pass One"); } } else { expresionLine.validLine = false; Chronicler.LogError("couldn't parse starting adress", "Pass One"); } } } if (expresionLine.label != "") { dataStructures.symbolTable.addSymbol(expresionLine.label, true, locationCounter, currentLine); } break; case "END": skipOperandParsing = true; testBlankLine = new Regex(@"[\t ]*;.*"); if (expresionLine.operandFieldAndComment == "") { locationCounter = 0; } else if (testBlankLine.IsMatch(expresionLine.operandFieldAndComment)) { locationCounter = 0; } else { ExpresionHandler.ResolveF3F4Expresion(dataStructures, expresionLine.operandFieldAndComment, currentLine, out expresionLine.expresionData); if (expresionLine.expresionData.first.HasValue) { int value = expresionLine.expresionData.first.Value.value; if (expresionLine.expresionData.second.HasValue) { if (expresionLine.expresionData.operatorValue != null && expresionLine.expresionData.operatorValue == Globals.ExpresionData.Arithmetic.SUBTRACT) { value = (expresionLine.expresionData.first.Value.value) - expresionLine.expresionData.second.Value.value; } if (expresionLine.expresionData.operatorValue != null && expresionLine.expresionData.operatorValue == Globals.ExpresionData.Arithmetic.ADD) { value = (expresionLine.expresionData.first.Value.value) + expresionLine.expresionData.second.Value.value; } } if (expresionLine.expresionData.second.HasValue && expresionLine.expresionData.rflag.HasValue != true) { expresionLine.validLine = false; } if (expresionLine.validLine) { Globals.Symbol?symbol; if (dataStructures.symbolTable.SearchSymbol(expresionLine.expresionData.first.Value.label, currentLine, out symbol)) { programLength = locationCounter - symbol.Value.value; } } else { Chronicler.LogError("Couldn't add \"" + currentLine + "\" to symbol table.", "pass one"); } } else { Chronicler.LogError("END can not be a literal value", "pass one"); expresionLine.validLine = false; } } if (expresionLine.label != "") { dataStructures.symbolTable.addSymbol(expresionLine.label, true, locationCounter, currentLine); } break; case "RESB": skipOperandParsing = true; if (ExpresionHandler.ResolveF3F4Expresion(dataStructures, expresionLine.operandFieldAndComment, currentLine, out expresionLine.expresionData) != true) { expresionLine.validLine = false; } else { if (expresionLine.expresionData.first.HasValue) { int value = expresionLine.expresionData.first.Value.value; if (expresionLine.expresionData.second.HasValue) { if (expresionLine.expresionData.operatorValue != null && expresionLine.expresionData.operatorValue == Globals.ExpresionData.Arithmetic.SUBTRACT) { value = (expresionLine.expresionData.first.Value.value) - expresionLine.expresionData.second.Value.value; } if (expresionLine.expresionData.operatorValue != null && expresionLine.expresionData.operatorValue == Globals.ExpresionData.Arithmetic.ADD) { value = (expresionLine.expresionData.first.Value.value) + expresionLine.expresionData.second.Value.value; } } if (expresionLine.validLine && expresionLine.label != "") { dataStructures.symbolTable.addSymbol(expresionLine.label, true, locationCounter, currentLine); } else { Chronicler.LogError("Couldn't add \"" + currentLine + "\" to symbol table.", "pass one"); } if (expresionLine.validLine) { locationCounter += value; } } else if (expresionLine.expresionData.literal != null) { Chronicler.LogError("BYTE doesn't accept Charachter/Hex values", "pass one"); expresionLine.validLine = false; } } break; case "RESW": skipOperandParsing = true; if (ExpresionHandler.ResolveF3F4Expresion(dataStructures, expresionLine.operandFieldAndComment, currentLine, out expresionLine.expresionData) != true) { expresionLine.validLine = false; } else { if (expresionLine.expresionData.first.HasValue) { int value = expresionLine.expresionData.first.Value.value; if (expresionLine.expresionData.second.HasValue) { if (expresionLine.expresionData.operatorValue != null && expresionLine.expresionData.operatorValue == Globals.ExpresionData.Arithmetic.SUBTRACT) { value = (expresionLine.expresionData.first.Value.value) - expresionLine.expresionData.second.Value.value; } if (expresionLine.expresionData.operatorValue != null && expresionLine.expresionData.operatorValue == Globals.ExpresionData.Arithmetic.ADD) { value = (expresionLine.expresionData.first.Value.value) + expresionLine.expresionData.second.Value.value; } } if (expresionLine.validLine && expresionLine.label != "") { dataStructures.symbolTable.addSymbol(expresionLine.label, true, locationCounter, currentLine); } else { Chronicler.LogError("Couldn't add \"" + currentLine + "\" to symbol table.", "pass one"); } if (expresionLine.validLine) { locationCounter += value * 3; } } else if (expresionLine.expresionData.literal != null) { Chronicler.LogError("BYTE doesn't accept Charachter/Hex values", "pass one"); expresionLine.validLine = false; } } break; case "EXTREF": string[] arr = expresionLine.operandFieldAndComment.Split(',', StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < arr.Length; i++) { arr[i] = arr[i].Trim(); dataStructures.symbolTable.addSymbol(arr[i], false, 0, currentLine); } break; default: Chronicler.LogDetailedInfo("Doing: " + expresionLine.operation); break; } } else { opcodeTable.operationData operDat; if (dataStructures.opcodeTable.operationTableDictionary.TryGetValue(expresionLine.operation, out operDat)) { if (expresionLine.label != "") { dataStructures.symbolTable.addSymbol(expresionLine.label, true, locationCounter, currentLine); } switch (operDat.format) { case 1: locationCounter += 1; break; case 2: locationCounter += 2; break; case 3: if (expresionLine.format4indicator == "") { locationCounter += 3; } else { locationCounter += 4; } break; case 4: locationCounter += 4; break; default: break; } if (Parser.guessOperandType(expresionLine.operandFieldAndComment) == Parser.OperandType.DISPLACEMENT_OR_ADDRESS) { expresionLine.DeferExpresionResolutiontoPass2 = true; } else { expresionLine.DeferExpresionResolutiontoPass2 = false; } expresionLine.operationData = operDat; } else { expresionLine.operationData = null; } Chronicler.Write("Parsing operation: " + expresionLine.operation + "\n", Chronicler.OutputOptions.INFO); } } if (expresionLine.validLine && skipOperandParsing != true && expresionLine.operandFieldAndComment != "" && !expresionLine.DeferExpresionResolutiontoPass2) { if (ExpresionHandler.ResolveF3F4Expresion(dataStructures, expresionLine.operandFieldAndComment, currentLine, out expresionLine.expresionData) != true) { expresionLine.validLine = false; } } expresionLines.Add(expresionLine); } else { Chronicler.LogError("Couldn't parse fields on line: " + lineNumber); } } } } catch (IOException e) { Chronicler.LogError("failed to open File: " + filePath); } } } catch (IOException e) { Chronicler.LogError("failed to open File: " + filePath); } dataStructures.literalTable.setStartAddress(locationCounter); DumpIntermidiateFile(filePath, expresionLines, dataStructures); }