//************************************************************************ //*** FUNCTION SearchSymbol //*** ******************************************************************** //*** DESCRIPTION : Takes a string and searches for a symbol //*** that fits that key //*** INPUT ARGS : string str //*** OUTPUT ARGS : N/A //*** IN/OUT ARGS : N/A //*** RETURN : Symbol? //************************************************************************ public bool SearchSymbol(string symbolLabel, string currentLine, out Globals.Symbol?tempN) { bool rtnVal = true; tempN = null; symbolLabel = symbolLabel.Trim(); if (ValidateLabel(symbolLabel, currentLine, "Searching symbol")) { if (symbolLabel.Length > 6) { symbolLabel = symbolLabel.Substring(0, 6); } } else { return(false); } Globals.Symbol temp; if (SymbolTableBST.TryGetValue(symbolLabel, out temp)) { tempN = temp; } else { Chronicler.LogError("Symbol(" + symbolLabel + ") not found", "Searching for symbol"); rtnVal = false; } return(rtnVal); }
//****************************************************************************** //*** FUNCTION ValidateLabel //*** ************************************************************************** //*** DESCRIPTION : Takes a string and ensures the string is a valid //*** symbol label //*** INPUT ARGS : string label, string currentLine, string errorPrefix="" //*** OUTPUT ARGS : N/A //*** IN/OUT ARGS : N/A //*** RETURN : bool isValid //****************************************************************************** public static bool ValidateLabel(string label, string currentLine, string errorPrefix = "") { bool isValid = true; if (label.Length > 12) { Chronicler.LogError("Symbol Label(" + label + ") is too long, \n\tmust be less than 12 charachters in length, skipping: \"" + currentLine + "\"" + "\n", errorPrefix); isValid = false; } else if (label.Length == 0) { Chronicler.LogError("Symbol Label(" + label + ") is empty, skipping: \"" + currentLine + "\"" + "\n", errorPrefix); isValid = false; } else if (!char.IsLetter(label[0])) { Chronicler.LogError("Symbol Label(" + label + ") does not start with a letter(" + label[0] + "), \n\tskipping: \"" + currentLine + "\"" + "\n", errorPrefix); isValid = false; } else//only continue validation on short Label that fit in the 12 chars { for (int i = 0; i < label.Length && isValid == true; i++) { if (!char.IsLetterOrDigit(label[i])) { Chronicler.LogError("Invalid special charachters('" + label[i] + "') detected in Symbol Label(" + label + "), \n\tskipping: \"" + currentLine + "\"" + "\n", errorPrefix); isValid = false; } } } return(isValid); }
public static bool ParseNewStyleLiteral(string operand, out LiteralTable.LiteralValue literalValue, out string comment, string callingModule = "") { operand = operand.Trim(); callingModule = callingModule == "" ? "Parse New Style Literal" : callingModule; literalValue = new LiteralTable.LiteralValue(); comment = ""; if (operand[0] != '=') { Chronicler.LogError("New style literals must begin with '='", callingModule); return(false); } operand = operand.Substring(1, operand.Length - 1).Trim(); bool rtnVal = ParseOldStyleLiteral(operand, out literalValue, out comment, callingModule); literalValue.isOldStyleLiteral = false; return(rtnVal); }
//****************************************************************************** //*** FUNCTION TestAndSetRFlag //*** ************************************************************************** //*** DESCRIPTION : maps rflag string vals to boolean vals //*** INPUT ARGS : string rFlagIn, string currentLine, //*** string errorPrefix = "" //*** OUTPUT ARGS : bool rFlagOut //*** IN/OUT ARGS : N/A //*** RETURN : bool discardLine //****************************************************************************** bool TestAndSetRFlag(string rFlagIn, out bool rFlagOut, string currentLine, string errorPrefix = "") { bool discardLine = false; if (rFlagIn == "true" || rFlagIn == "1") { rFlagOut = true; } else if (rFlagIn == "false" || rFlagIn == "0") { rFlagOut = false; } else { rFlagOut = default; discardLine = true; Chronicler.LogError("Invalid RFlag value(" + rFlagIn + "), skipping: \"" + currentLine + "\"" + "\n", errorPrefix); } return(discardLine); }
//******************************************************************************************* //*** FUNCTION ParseNum //*** *************************************************************************************** //*** DESCRIPTION : parses an int str to a symbol //*** INPUT ARGS : string digits, string currentLine="" //*** OUTPUT ARGS : out Globals.Symbol? sym //*** IN/OUT ARGS : N/A //*** RETURN : bool rtnVal //******************************************************************************************* static public bool ParseNum(string digits, out Globals.Symbol?sym, string currentLine = "") { Globals.Symbol tmp = default; bool rtnVal = true; if (int.TryParse(digits, out tmp.value) == true) { tmp.label = digits; tmp.RFlag = false; tmp.MFlag = false; sym = tmp; } else { Chronicler.LogError("Unable to parse integer value(" + digits + "), skipping: \"" + currentLine + "\"", "Resolving Expresion"); sym = null; rtnVal = false; } return(rtnVal); }
public bool addSymbol(string label, bool rflag, int value, string currentLine) { label = label.Trim(); if (ValidateLabel(label, currentLine, "Pass One adding symbol")) { Globals.Symbol newSym = default; newSym.label = label; if (newSym.label.Length > 6) { newSym.label = newSym.label.Substring(0, 6); } newSym.RFlag = rflag; newSym.value = value; newSym.MFlag = false; if (SymbolTableBST.ContainsKey(newSym.label)) { Chronicler.LogError("Symbol with same Label('" + newSym.label + "') already exists! Setting MFlag and \n\tskipping: \"" + currentLine + "\"" + "\n", "Adding Symbol"); Globals.Symbol sym = SymbolTableBST.GetValueOrDefault(newSym.label); if (sym.MFlag == false) { sym.MFlag = true; SymbolTableBST.Remove(newSym.label); SymbolTableBST.Add(newSym.label, sym); } return(false); } else { Chronicler.Write("Adding symbol: ", Chronicler.OutputOptions.INFO); newSym.Print(Chronicler.OutputOptions.INFO); SymbolTableBST.Add(newSym.label, newSym); } } else { return(false); } return(true); }
public static void Execute(Globals.DataStructures dataStructures, List <PassOne.ExpresionLine> expresionLines, string filePath) { Chronicler.Write("\nPassTwo\n"); foreach (PassOne.ExpresionLine expresionLine in expresionLines) { //evaluate expresion if (expresionLine.DeferExpresionResolutiontoPass2 && (expresionLine.instructionFormat == 3 || expresionLine.instructionFormat == 4)) { if (ExpresionHandler.ResolveF3F4Expresion(dataStructures, expresionLine.operandFieldAndComment, expresionLine.operandFieldAndComment, out expresionLine.expresionData) != true) { expresionLine.validLine = false; } } //convert expresion format if (expresionLine.Opcode == "" && expresionLine.IsEQU != true && (expresionLine.instructionFormat == 3 || expresionLine.instructionFormat == 4))//don't redo work { switch (expresionLine.expresionData.ExpresionType) { case Globals.ExpresionData.Contents.SYMBOL: int?value = null; 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 (value.HasValue && expresionLine.instructionFormat == 4) { expresionLine.Opcode = value.Value.ToString("X5"); } else if (value.HasValue && expresionLine.instructionFormat == 3) { expresionLine.Opcode = value.Value.ToString("X3"); } break; case Globals.ExpresionData.Contents.ERROR: Chronicler.WriteLine("This is wrong for some reason, you should look at it:\n" + expresionLine.OriginalLine, Chronicler.OutputOptions.ERR); break; case Globals.ExpresionData.Contents.LITERAL: if (expresionLine.expresionData.literal.isOldStyleLiteral != true) { expresionLine.Opcode = expresionLine.locationCounter.ToString("X6"); } break; case Globals.ExpresionData.Contents.EMPTY: //consider break break; } } if (expresionLine.operationData.HasValue && expresionLine.operationData.Value.format == 2) { string[] tmp = expresionLine.operandFieldAndComment.Split(";", StringSplitOptions.RemoveEmptyEntries); if (tmp.Length > 0) { expresionLine.operandFieldAndComment = tmp[0]; } string[] subStrs = expresionLine.operandFieldAndComment.Split(",", StringSplitOptions.RemoveEmptyEntries); if (subStrs.Length == 1) { int val; if (dataStructures.opcodeTable.RegisterTable.TryGetValue(subStrs[0].Trim(), out val)) { expresionLine.Opcode = val.ToString(); } else { Chronicler.LogError("failed parsing F2: " + expresionLine.OriginalLine); } } else if (subStrs.Length == 2) { int val; if (dataStructures.opcodeTable.RegisterTable.TryGetValue(subStrs[0].Trim(), out val)) { expresionLine.Opcode = val.ToString() + "0"; } else { Chronicler.LogError("failed parsing F2: " + expresionLine.OriginalLine); } if (dataStructures.opcodeTable.RegisterTable.TryGetValue(subStrs[1].Trim(), out val)) { expresionLine.Opcode += val.ToString(); } else { Chronicler.LogError("failed parsing F2: " + expresionLine.OriginalLine); } } else { Chronicler.LogError("failed parsing F2, incorect term count: " + expresionLine.OriginalLine); } } if (expresionLine.operationData.HasValue) { expresionLine.Opcode = expresionLine.operationData.Value.code.ToString("X") + expresionLine.Opcode; } } DumpObjFile(filePath, expresionLines, dataStructures); }
//************************************************************************ //*** FUNCTION LoadSymbols //*** ******************************************************************** //*** DESCRIPTION : opens a file and populates SymbolTableBST //*** INPUT ARGS : string filePath //*** OUTPUT ARGS : N/A //*** IN/OUT ARGS : N/A //*** RETURN : N/A //************************************************************************ public void LoadSymbols(string filePath) { Globals.Symbol symbol = default; symbol.label = ""; symbol.IFlag = true; char[] tmpLabel = new char[7]; //discard line flag bool discardLine; //get the line and trim whitespace string currentLine; string[] rflagAndValueStrings; string rFlag; 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) { //discard line flag discardLine = false; //get the line and trim whitespace currentLine = streamReader.ReadLine().CompactAndTrimWhitespaces(); if (currentLine == "") { Chronicler.LogError("blank line, skipping: \"" + currentLine + "\"" + "\n", "Adding Symbol"); discardLine = true; } else if (currentLine.CountStringCharachters(':') != 1)//check incorrect colon seperator count { Chronicler.LogError("Extra colon seperators in current line, skipping: \"" + currentLine + "\"" + "\n", "Adding Symbol"); discardLine = true; } if (!discardLine) { string[] symbolSubstrings = currentLine.Split(':'); //validate Label string label = symbolSubstrings[0].Trim(); discardLine = !ValidateLabel(label, currentLine, "Adding Symbol"); if (!discardLine) { rflagAndValueStrings = symbolSubstrings[1].Trim().Split(' '); //validate RFlag rFlag = rflagAndValueStrings[0].Trim(); discardLine = TestAndSetRFlag(rFlag, out symbol.RFlag, currentLine, "Adding Symbol"); if (!discardLine) { string value = rflagAndValueStrings[1].Trim(); if (!int.TryParse(value, out symbol.value) || value[0] == '+') { discardLine = true; Chronicler.LogError("Invalid integer value(" + value + "), skipping: \"" + currentLine + "\"" + "\n", "Adding Symbol"); } if (!discardLine) { //parse data into Symbol struct int symbolLabelIndex = 0; for (symbolLabelIndex = 0; symbolLabelIndex < 6 && symbolLabelIndex < label.Length; symbolLabelIndex++) { tmpLabel[symbolLabelIndex] = label[symbolLabelIndex]; } tmpLabel[symbolLabelIndex] = '\0'; StringBuilder sb = new StringBuilder(""); foreach (char c in tmpLabel.TakeWhile(c => c != '\0')) { sb.Append(c); } symbol.label = sb.ToString().Trim(); symbol.MFlag = false; if (SymbolTableBST.ContainsKey(symbol.label)) { Chronicler.LogError("Symbol with same Label('" + symbol.label + "') already exists! Setting MFlag and \n\tskipping: \"" + currentLine + "\"" + "\n", "Adding Symbol"); Globals.Symbol sym = SymbolTableBST.GetValueOrDefault(symbol.label); if (sym.MFlag == false) { sym.MFlag = true; SymbolTableBST.Remove(symbol.label); SymbolTableBST.Add(symbol.label, sym); } } else { Chronicler.Write("Adding symbol: ", Chronicler.OutputOptions.INFO); symbol.Print(Chronicler.OutputOptions.INFO); SymbolTableBST.Add(symbol.label, symbol); } } } } } } } } catch (IOException e) { Chronicler.LogError("failed to open File: " + filePath); } } } catch (IOException e) { Chronicler.LogError("failed to open File: " + filePath); } }
public static bool ParseOldStyleLiteral(string operand, out LiteralTable.LiteralValue literalValue, out string comment, string callingModule = "") { Regex literalRegex = new Regex(@"(^[\t ]*(?<literalCharID>[Cc])[\t ]*(?<literalValueString>'.*')[\t ]*(?<comment>;.*){0,1}$)|(^[\t ]*(?<literalCharIDx>[Xx])[\t ]*(?<literalValueStringx>'[a-fA-F0-9]*')[\t ]*(?<commentx>;.*){0,1}$)"); Match match = literalRegex.Match(operand); literalValue = new LiteralTable.LiteralValue(); comment = ""; if (match.Success)//if we succeed, format it { literalValue.isOldStyleLiteral = true; if (match.Groups["literalCharID"].Value != "") { literalValue.label = match.Groups["literalCharID"].Value + match.Groups["literalValueString"].Value; comment = match.Groups["comment"].Value; StringBuilder sb = new StringBuilder(literalValue.label); sb[0] = 'C'; literalValue.label = sb.ToString(); char[] tmpArr = literalValue.label.Substring(2, literalValue.label.Length - 3).ToCharArray(); literalValue.hexValue = Globals.CharArrToHexStr(tmpArr); literalValue.dataType = LiteralTable.LiteralValue.DataType.CHAR; } else { literalValue.label = match.Groups["literalCharIDx"].Value + match.Groups["literalValueStringx"].Value; comment = match.Groups["commentx"].Value; literalValue.label = literalValue.label.ToUpper(); literalValue.hexValue = literalValue.label.Substring(2, literalValue.label.Length - 3); literalValue.hexValue = (literalValue.hexValue.Length % 2 == 1 ? "0" : "") + literalValue.hexValue; literalValue.dataType = LiteralTable.LiteralValue.DataType.HEX; } return(true); } //if we fail try to figure out how and provide detailed feedback StringBuilder operandMutaion = new StringBuilder(operand.Trim()); callingModule = callingModule == "" ? "Parse Old Style Literal" : callingModule; if (operandMutaion.Length == 0) { Chronicler.LogError("No literal value was given", callingModule); } operandMutaion[0] = char.ToUpper(operandMutaion[0]); bool isChar = false; if (operandMutaion[0] != 'C' && operandMutaion[0] == 'X') { Chronicler.LogError("The charachter '" + operandMutaion[0] + "' is not a valid literal identifier. Valid identifiers are 'XxCc'.", callingModule); return(false); } else if (operandMutaion[0] == 'C') { isChar = true; } //remove whitespace while (operandMutaion.Length > 2 && char.IsWhiteSpace(operandMutaion[1])) { operandMutaion = operandMutaion.Remove(1, 1); } if (operandMutaion[1] != '\'') { Chronicler.LogError("Was expecting ''', but found '" + operandMutaion[1] + "'", callingModule); return(false); } int lastApos = -1; for (int i = 2; i < operandMutaion.Length; i++) { if (operandMutaion[i] == '\'') { lastApos = i; } } if (lastApos == -1) { Chronicler.LogError("Was unable to find closing '''", callingModule); return(false); } else { string subStr = operandMutaion.ToString().Substring(2, lastApos - 2); if (!isChar) { char?errorChar; if (!validateHex(subStr, out errorChar) && errorChar != '\'') { Chronicler.LogError("Invalid Hex char detected in hex literal: " + errorChar.Value, callingModule); return(false); } else { lastApos = -1; for (int i = 2; i < operandMutaion.Length && lastApos == -1; i++) { if (operandMutaion[i] == '\'') { lastApos = i; } } } } int lastComma = operandMutaion.Length; for (int i = lastApos; i < operandMutaion.Length && lastComma == operandMutaion.Length; i++) { if (operandMutaion[i] == ';') { lastComma = i; } } subStr = operandMutaion.ToString().Substring(lastApos, lastComma - lastApos); Chronicler.LogError("Parsing literal failed; was their garbage after the literal before the comment? Found:(" + subStr + ")", callingModule); return(false); } }
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); }
////******************************************************************************************* ////*** FUNCTION ParseExpresionFile ////*** *************************************************************************************** ////*** DESCRIPTION : Parses the Expresion File ////*** INPUT ARGS : SymbolTable symbolTable, LiteralTable literalTable, string filePath ////*** OUTPUT ARGS : N/A ////*** IN/OUT ARGS : N/A ////*** RETURN : N/A ////******************************************************************************************* //public static void ParseExpresionFile(SymbolTable symbolTable, LiteralTable literalTable, string filePath) //{ // try // { // using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan)) // { // try // { // using (StreamReader streamReader = new StreamReader(fileStream)) // { // int LineNumber = 1; // Chronicler.WriteLine("EXPRESION\tVALUE\tRELOCATABLE\tN-Bit\tI-Bit\tX-Bit"); // while (!streamReader.EndOfStream) // { // //get the line and trim whitespace // string currentLine = streamReader.ReadLine().Trim(); // if (ResolveF3F4Expresion(symbolTable, literalTable, currentLine, currentLine, out Globals.Symbol? symbol)) // { // if (symbol != null) // { // StringBuilder sb = new StringBuilder(""); // for (int x = 0; x < (16 - currentLine.Length); x++) // { // sb.Append(" "); // } // Chronicler.Write(currentLine + sb.ToString()); // Chronicler.Write(symbol.Value.value.ToString()); // Chronicler.Write("\t" + ((symbol.Value.RFlag) ? "RELOCATABLE" : "ABSOLUTE")); // Chronicler.NewLine(); // } // } // else // { // Chronicler.LogError("Line: \"" + LineNumber + "\" Skipping: \"" + currentLine + "\"", "Expresion File Parsing"); // } // LineNumber++; // } // Chronicler.LogInfo("DONE loading symbols!"); // } // } // catch (IOException e) // { // Chronicler.WriteLine(e.Message); // Chronicler.LogError("failed to open File: " + filePath); // } // } // } // catch (IOException e) // { // Chronicler.WriteLine(e.Message); // Chronicler.LogError("failed to open File: " + filePath); // } //} //******************************************************************************************* //*** FUNCTION ResolveF3F4Expresion //*** *************************************************************************************** //*** DESCRIPTION : Resolves an expresion and adds a literal or gets a symbol //*** INPUT ARGS : SymbolTable symbolTable, LiteralTable literalTable, //*** string expresion, string currentLine //*** OUTPUT ARGS : out Globals.Symbol? symbol //*** IN/OUT ARGS : N/A //*** RETURN : bool rtnVal //******************************************************************************************* public static bool ResolveF3F4Expresion(Globals.DataStructures dataStructures, string expresionString, string currentLine, out Globals.ExpresionData expresionData, string callingModule = "ExpresionHandler") { expresionData = new Globals.ExpresionData(); bool rtnVal = true; Regex testXValue = new Regex(@"(^[^=][^,;]*(?<x>,x|X){0,1}.*$)|(^[\t ]*=.*$)"); bool hasXValue = testXValue.Match(expresionString).Groups["x"].Value != ""; expresionString = expresionString.Trim(); if (Parser.guessOperandType(expresionString) == Parser.OperandType.NEW_STYLE_LITERAL || Parser.guessOperandType(expresionString) == Parser.OperandType.OLD_STYLE_LITERAL) { Chronicler.LogInfo("Parsing as literal: " + expresionString); if (Parser.guessOperandType(expresionString) == Parser.OperandType.NEW_STYLE_LITERAL) { LiteralTable.LiteralValue tmp = new LiteralTable.LiteralValue(); string comment = ""; Parser.ParseNewStyleLiteral(expresionString, out tmp, out comment, callingModule); expresionData.literal = tmp; dataStructures.literalTable.add(tmp); } else if (Parser.guessOperandType(expresionString) == Parser.OperandType.OLD_STYLE_LITERAL) { LiteralTable.LiteralValue tmp = new LiteralTable.LiteralValue(); string comment = ""; Parser.ParseOldStyleLiteral(expresionString, out tmp, out comment, callingModule); expresionData.literal = tmp; } } else if (expresionString.Length > 0 && expresionString[0] == '@') { expresionString = expresionString.Substring(1, expresionString.Length - 1); hasXValue = testXValue.Match(expresionString).Groups["x"].Value != ""; if (hasXValue != true) { if (ParseTerms(dataStructures, expresionString, currentLine, out expresionData) != true) { rtnVal = false; } expresionData.N = true; expresionData.I = false; } else { rtnVal = false; Chronicler.LogError("Can not apply both indirect adressing \n\tand x register indexing, skipping: \"" + currentLine + "\"", "Resovling Expresion"); } } else if (expresionString.Length > 0 && expresionString[0] == '#') { expresionString = expresionString.Substring(1, expresionString.Length - 1); hasXValue = testXValue.Match(expresionString).Groups["x"].Value != ""; if (hasXValue != true) { if (ParseTerms(dataStructures, expresionString, currentLine, out expresionData) != true) { rtnVal = false; } expresionData.N = false; expresionData.I = false; } else { rtnVal = false; Chronicler.LogError("Can not apply both immediate adressing \n\tand x register indexing, skipping:\"" + currentLine + "\"", "Resovling Expresion"); } } else if (hasXValue == true) { expresionString = testXValue.Replace(expresionString, "$2$4$5"); if (ParseTerms(dataStructures, expresionString, currentLine, out expresionData) != true) { rtnVal = false; } expresionData.N = true; expresionData.I = true; expresionData.X = true; } else { rtnVal = ParseTerms(dataStructures, expresionString, currentLine, out expresionData); } return(rtnVal); }
//******************************************************************************************* //*** FUNCTION ParseTerms //*** *************************************************************************************** //*** DESCRIPTION : parses an arithmatic operation str to a symbol, or add a literal //*** INPUT ARGS : SymbolTable symbolTable, LiteralTable literalTable, //*** string expresion, string currentLine //*** OUTPUT ARGS : out Globals.Symbol? result //*** IN/OUT ARGS : N/A //*** RETURN : bool rtnVal //******************************************************************************************* static bool ParseTerms(Globals.DataStructures dataStructures, string expresionString, string currentLine, out Globals.ExpresionData expresionData) { bool rtnVal = true; expresionString = expresionString.Trim(); expresionData = new Globals.ExpresionData(); Regex testForCommentOnlyLine = new Regex(@"^[\t ]*(;.*)$"); Match commentOnlyLine = testForCommentOnlyLine.Match(expresionString); if (commentOnlyLine.Success) { expresionData.comment = commentOnlyLine.Groups["$1"].Value; return(true); } string line = expresionString.Trim(); if (rtnVal == true && (Regex.Match(line, @"^[\t ]{0,}(-{0,1}[\t ]{0,}[A-Za-z0-9]+).*$").Success != true)) { rtnVal = false; Chronicler.LogError("Could not parse first(" + line + ") term in: " + currentLine, "parsing terms"); } if (rtnVal == true && (Regex.Match(line, @"^[\t ]{0,}(-{0,1}[\t ]{0,}[A-Za-z0-9]+)[\t ]{0,}(([+-])[\t ]{0,}(-{0,1}[\t ]{0,}[A-Za-z0-9]+)){0,1}[\t ]{0,}(;.*){0,1}$").Success != true)) { rtnVal = false; Chronicler.LogError("Couldn't parse second term in: " + currentLine, "parsing terms"); } string first = ""; string arithmaticOperator = ""; string second = ""; if (rtnVal == true) { Match fullLine = (Regex.Match(line, @"^[\t ]{0,}(?<first>-{0,1}[\t ]{0,}[A-Za-z0-9]+)[\t ]{0,}(?<testTermCount>(?<operand>[+-])[\t ]{0,}(?<second>-{0,1}[\t ]{0,}[A-Za-z0-9]+)){0,1}[\t ]{0,}(;.*){0,1}$")); if (fullLine.Success != true) { rtnVal = false; Chronicler.WriteLine("Error parsing literal"); } first = fullLine.Groups["first"].Value.Trim(); arithmaticOperator = fullLine.Groups["operand"].Value.Trim(); second = fullLine.Groups["second"].Value.Trim(); Regex stripWhiteSpace = new Regex(@"\s+"); first = stripWhiteSpace.Replace(first, ""); arithmaticOperator = stripWhiteSpace.Replace(arithmaticOperator, ""); second = stripWhiteSpace.Replace(second, ""); if (second != "" && arithmaticOperator == "") { rtnVal = false; } } if (rtnVal == true) { rtnVal = ParseTerm(dataStructures.symbolTable, first, out expresionData.first, currentLine); if (second != "") { rtnVal = ParseTerm(dataStructures.symbolTable, second, out expresionData.second, currentLine); if (expresionData.first.HasValue && expresionData.second.HasValue) { if (arithmaticOperator == "+") { expresionData.rflag = Globals.Symbol.AddRFlags(expresionData.first.Value, expresionData.second.Value); expresionData.operatorValue = Globals.ExpresionData.Arithmetic.ADD; } else if (arithmaticOperator == "-") { expresionData.rflag = Globals.Symbol.SubtractRFlags(expresionData.first.Value, expresionData.second.Value); expresionData.operatorValue = Globals.ExpresionData.Arithmetic.SUBTRACT; } else { rtnVal = false; Chronicler.LogError("Invalid operator value for line: " + currentLine, "term arithmatic module"); } } else { Chronicler.LogError("Couldn't resolve symbols in artithmetic: " + currentLine, "term arithmatic module"); } rtnVal = rtnVal == true?ParseTerm(dataStructures.symbolTable, second, out expresionData.second, currentLine) : false; } if (expresionData.first.HasValue && !expresionData.second.HasValue && second == "") { expresionData.rflag = expresionData.first.Value.RFlag; } } return(rtnVal); }