/// <summary> /// get binary format of each instruction /// </summary> private string GetBinaryFormat(IFormatInstructions _operator) { int opcode = OperatorsInfo.GetOPCode(_operator.Operator); switch (OperatorsInfo.GetInstructionFormat(_operator.Operator)) { case EInstructionFormat.FORMAT_1: { int Rc = 0; int Ra = 0; int Rb = 0; InstructionFormat1 format = (InstructionFormat1)_operator; if (format.RegisterA != null) { Ra = (format.RegisterA?.ToString() == "") ? 0 : Convert.ToInt32(Regex.Replace(format.RegisterA.ToString(), @"[.\D+]", "")); } if (format.RegisterC != null) { Rb = (format.RegisterB?.ToString() == "") ? 0 : Convert.ToInt32(Regex.Replace(format.RegisterB.ToString(), @"[.\D+]", "")); } if (format.RegisterC != null) { Rc = (format.RegisterC.ToString() == "") ? 0 : Convert.ToInt32(Regex.Replace(format.RegisterC.ToString(), @"[.\D+]", "")); } return($"{Convert.ToString(opcode, 2).PadLeft(5, '0')}" + $"{Convert.ToString(Ra, 2).PadLeft(3, '0')}" + $"{Convert.ToString(Rb, 2).PadLeft(3, '0')}" + $"{Convert.ToString(Rc, 2).PadLeft(3, '0')}00"); } case EInstructionFormat.FORMAT_2: { InstructionFormat2 format = (InstructionFormat2)_operator; int Ra = (format.RegisterA.ToString() == "") ? 0 : Convert.ToInt32(Regex.Replace(format.RegisterA.ToString(), @"[.\D+]", "")); int constOrAddr; if (constants.ContainsKey(format.ConstOrAddress.ToString())) { constOrAddr = constants[format.ConstOrAddress.ToString()]; } else if (variables.ContainsKey(format.ConstOrAddress.ToString())) { constOrAddr = variables[format.ConstOrAddress.ToString()]; } else if (labels.ContainsKey(format.ConstOrAddress.ToString())) { constOrAddr = labels[format.ConstOrAddress.ToString()]; } else { //check if the constant or address is a direct input try { constOrAddr = UnitConverter.BinaryToByte( UnitConverter.HexToBinary( format.ConstOrAddress.ToString().Replace("#", "") ) ); } catch (OverflowException) { //send error message (undefined variable) AsmLogger.Error($"Overflow in instruction: {_operator}", currentLine.ToString(), $"Value '{format.ConstOrAddress}'"); return(null); } catch { //send error message (undefined variable) AsmLogger.Error($"Variable not defined: {_operator}", currentLine.ToString(), "Variable called but never defined"); return(null); } } return($"{UnitConverter.IntToBinary(opcode, defaultWidth: 5)}" + $"{UnitConverter.IntToBinary(Ra, defaultWidth: 3)}" + $"{UnitConverter.IntToBinary(constOrAddr, defaultWidth: 8)}"); } case EInstructionFormat.FORMAT_3: { InstructionFormat3 format = (InstructionFormat3)_operator; int constOrAddr = 0; if (constants.ContainsKey(format.ConstOrAddress.ToString())) { constOrAddr = constants[format.ConstOrAddress.ToString()]; } else if (variables.ContainsKey(format.ConstOrAddress.ToString())) { constOrAddr = variables[format.ConstOrAddress.ToString()]; } else if (labels.ContainsKey(format.ConstOrAddress.ToString())) { constOrAddr = labels[format.ConstOrAddress.ToString()]; } else { //check if the constant or address is a direct input try { constOrAddr = Convert.ToInt32(format.ConstOrAddress.ToString().Replace("#", ""), 16); } catch { //send error message (undefined variable) return(null); } } return($"{Convert.ToString(opcode, 2).PadLeft(5, '0')}" + $"{Convert.ToString(constOrAddr, 2).PadLeft(11, '0')}"); } default: { throw new Exception("Token is not an instruction"); } } }
/// <summary> /// Creates an instruction /// </summary> /// <param name="lexer">Lexer to be used</param> private void MakeInstruction(Lexer lexer) { // tmep list to store possible parameters Token[] tempList = new Token[3]; // holder of instruction IFormatInstructions instruction; // parameter count int parameters = 0; // current token Token currToken = lexer.CurrrentToken; switch (OperatorsInfo.GetInstructionFormat(currToken)) { case EInstructionFormat.FORMAT_1: // extract possible registers while (parameters < OperatorsInfo.GetNumberOfParams(currToken)) { lexer.MoveNext(); tempList[parameters] = lexer.CurrrentToken; parameters++; } instruction = new InstructionFormat1( currToken, tempList[0], tempList[1], tempList[2] ); AddInstruction(instruction); break; case EInstructionFormat.FORMAT_2: // extract possible registers while (parameters < OperatorsInfo.GetNumberOfParams(currToken)) { lexer.MoveNext(); tempList[parameters] = lexer.CurrrentToken; parameters++; } instruction = new InstructionFormat2( currToken, tempList[0], tempList[1] ); AddInstruction(instruction); break; case EInstructionFormat.FORMAT_3: // extract possible registers while (parameters < OperatorsInfo.GetNumberOfParams(currToken)) { lexer.MoveNext(); tempList[parameters] = lexer.CurrrentToken; parameters++; } instruction = new InstructionFormat3( currToken, tempList[0] ); AddInstruction(instruction); break; default: break; } }