Ejemplo n.º 1
0
 /// <summary>
 /// Method that compares this addressing mode with another.
 /// </summary>
 /// <param name="am">
 /// Another addressing mode to be compared with.
 /// </param>
 /// Bool value that tells whether two addressing modes are equal or not.
 /// <returns></returns>
 public bool Equals(AddressingMode am)
 {
     return(this.name.Equals(am.name));
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Assembles the given code.
 /// </summary>
 /// <param name="outputPath">
 /// Path to output file.
 /// </param>
 /// <returns>
 /// Binary code of assembled program.
 /// </returns>
 public byte[] Assemble(string outputPath = "out.o")
 {
     try
     {
         if (!code.EndsWith("\n"))
         {
             code += "\r\n";
         }
         var provider = CSharpCodeProvider.CreateProvider("c#");
         var options  = new CompilerParameters();
         var assemblyContainingNotDynamicClass = Path.GetFileName(Assembly.GetExecutingAssembly().Location);
         options.ReferencedAssemblies.Add(assemblyContainingNotDynamicClass);
         string parserCode    = File.ReadAllText("Grammar/cs/" + ((SystemComponent)cpu).Name + "Parser.cs");
         string constantsCode = File.ReadAllText("Grammar/cs/" + ((SystemComponent)cpu).Name + "Constants.cs");
         string tokenizerCode = File.ReadAllText("Grammar/cs/" + ((SystemComponent)cpu).Name + "Tokenizer.cs");
         string analyzerCode  = File.ReadAllText("Grammar/cs/" + ((SystemComponent)cpu).Name + "Analyzer.cs");
         var    results       = provider.CompileAssemblyFromSource(options, new[] { parserCode, constantsCode, tokenizerCode, analyzerCode });
         if (results.Errors.Count > 0)
         {
             foreach (var error in results.Errors)
             {
                 File.AppendAllText("error.txt", error + "\n");
             }
             return(null);
         }
         else
         {
             Parser parser   = null;
             var    t        = results.CompiledAssembly.GetType("MultiArc_Compiler." + cpu.Name + "Parser", true);
             object instance = Activator.CreateInstance(t, new[] { new StringReader(code) });
             parser = (Parser)instance;
             try
             {
                 Node n = parser.Parse();
                 instructions.Clear();
                 labels.Clear();
                 symbolTable.Clear();
                 getInstructionsFromTree(n);
                 getOriginFromTree(n);
                 binaryCode = new byte[instructions.Count * cpu.Constants.MAX_BYTES]; // THIS MUST BE TESTED.
                 count      = 0;
                 separators.Clear();
                 separators = new LinkedList <int>();
                 // First passing:
                 for (int i = 0; i < instructions.Count; i++)
                 {
                     Instruction inst = cpu.Constants.GetInstruction(instructions.ElementAt(i).GetName());
                     if (labels.ContainsKey(instructions.ElementAt(i)))
                     {
                         Symbol symbol = new Symbol(labels[instructions.ElementAt(i)], 0, count, true);
                         if (symbolTable.Contains(symbol))
                         {
                             throw new Exception("Label already defined");
                         }
                         else
                         {
                             symbolTable.AddLast(symbol);
                         }
                     }
                     for (int j = inst.Mask.Length - 1; j >= 0; j--)
                     {
                         binaryCode[count + j] = inst.Mask[j];
                     }
                     LinkedList <AddressingMode> addrModes        = new LinkedList <AddressingMode>();
                     LinkedList <int>            argumentsIndexes = new LinkedList <int>();
                     for (int j = 0; j < instructions.ElementAt(i).GetChildCount(); j++)
                     {
                         AddressingMode am = null;
                         am = cpu.Constants.GetAddressingMode(instructions.ElementAt(i).GetChildAt(j).Name);
                         if (!object.ReferenceEquals(am, null))
                         {
                             addrModes.AddLast(am);
                             argumentsIndexes.AddLast(j);
                         }
                     }
                     for (int j = 0; j < inst.Arguments.Count; j++)
                     {
                         int argcodeValue = inst.Arguments.ElementAt(j).CodeValues[addrModes.ElementAt(j).Name];
                         int argcodeStart = inst.Arguments.ElementAt(j).CodeStarts[addrModes.ElementAt(j).Name];
                         int argcodeEnd   = inst.Arguments.ElementAt(j).CodeEnds[addrModes.ElementAt(j).Name];
                         int argcodeSize  = 1;
                         for (int k = argcodeStart; k >= argcodeEnd; k--)
                         {
                             if (k % 8 == 0 && k != argcodeEnd)
                             {
                                 argcodeSize++;
                             }
                         }
                         int argcodeCount = argcodeStart - argcodeEnd;
                         int byteCount    = argcodeSize - 1;
                         for (int k = argcodeStart; k >= argcodeEnd; k--)
                         {
                             int semiValue = (argcodeValue & (1 << argcodeCount)) << argcodeEnd % 8;
                             binaryCode[count + inst.Size - 1 - argcodeEnd / 8 - byteCount] |= (byte)((semiValue & (1 << (argcodeEnd % 8 + argcodeCount))) >> byteCount * 8); // This might be a problem.
                             if ((argcodeEnd + argcodeCount) % 8 == 0)
                             {
                                 byteCount--;
                             }
                             argcodeCount--;
                         }
                         AddressingMode am              = addrModes.ElementAt(j);
                         int            argumentIndex   = argumentsIndexes.ElementAt(j);
                         int            operandValue    = 0;
                         bool           shouldBeWritten = false;
                         if (am.OperandInValues)
                         {
                             shouldBeWritten = true;
                             string expr = "";
                             if (instructions.ElementAt(i).GetChildAt(argumentIndex).GetChildAt(0) is Production)
                             {
                                 expr = ((Production)instructions.ElementAt(i).GetChildAt(argumentIndex).GetChildAt(0)).Name;
                             }
                             else
                             {
                                 for (int l = 0; l < instructions.ElementAt(i).GetChildAt(argumentIndex).GetChildCount(); l++)
                                 {
                                     expr += ((Token)instructions.ElementAt(i).GetChildAt(argumentIndex).GetChildAt(l)).Image;
                                 }
                             }
                             if (am.Values.ContainsKey(expr.ToLower()))
                             {
                                 operandValue = am.Values[expr.ToLower()];
                             }
                         }
                         else if (am.OperandReadFromExpression)
                         {
                             Node node       = (instructions.ElementAt(i).GetChildAt(argumentIndex));
                             int  childCount = node.GetChildCount();
                             Node child      = node;
                             int  sign       = 1;
                             while (!(child.GetChildAt(0) is Token))
                             {
                                 child = child.GetChildAt(0);
                             }
                             for (int l = 0; l < node.GetChildCount() && !child.Name.Equals("DEC_NUMBER") && !child.Name.Equals("HEX_NUMBER") && !child.Name.Equals("OCT_NUMBER") && !child.Name.Equals("BIN_NUMBER") && !child.Name.Equals("IDENTIFIER"); l++)
                             {
                                 child = node.GetChildAt(l);
                                 if (l != 0 && node.GetChildAt(l - 1).Name.Equals("SIGN"))
                                 {
                                     if (((Token)node.GetChildAt(l - 1)).Image.Equals("+"))
                                     {
                                         sign = 1;
                                     }
                                     else
                                     {
                                         sign = -1;
                                     }
                                 }
                             }
                             if (child.Name.Equals("DEC_NUMBER"))
                             {
                                 operandValue    = Convert.ToInt32(((Token)child).Image.ToLower()) * sign;
                                 shouldBeWritten = true;
                             }
                             else if (child.Name.Equals("HEX_NUMBER"))
                             {
                                 operandValue    = Convert.ToInt32(((Token)child).Image.ToLower().Substring(0, ((Token)child).Image.Length - 1), 16) * sign;
                                 shouldBeWritten = true;
                             }
                             else if (child.Name.Equals("OCT_NUMBER"))
                             {
                                 operandValue    = Convert.ToInt32(((Token)child).Image.ToLower().Substring(0, ((Token)child).Image.Length - 1), 8) * sign;
                                 shouldBeWritten = true;
                             }
                             else if (child.Name.Equals("BIN_NUMBER"))
                             {
                                 operandValue    = Convert.ToInt32(((Token)child).Image.ToLower().Substring(0, ((Token)child).Image.Length - 1), 2) * sign;
                                 shouldBeWritten = true;
                             }
                             else if (child.Name.Equals("IDENTIFIER"))
                             {
                                 string label = ((Token)child).Image;
                                 operandValue = 0;
                                 foreach (Symbol s in symbolTable)
                                 {
                                     if (s.Label.ToLower().Equals(label))
                                     {
                                         operandValue = s.Offset;
                                         break;
                                     }
                                 }
                             }
                             if (am.OperandType.ToLower().Equals("relative"))
                             {
                                 operandValue = operandValue - inst.Size - count;
                             }
                         }
                         else if (am.OperandValueDefinedByUser)
                         {
                             Node node        = (instructions.ElementAt(i).GetChildAt(argumentIndex));
                             int  childCount  = node.GetChildCount();
                             Node child       = node;
                             bool labelNotYet = false;
                             int  sign        = 1;
                             while (!(child.GetChildAt(0) is Token))
                             {
                                 child = child.GetChildAt(0);
                             }
                             for (int l = 0; l < node.GetChildCount() && !child.Name.Equals("DEC_NUMBER") && !child.Name.Equals("HEX_NUMBER") && !child.Name.Equals("OCT_NUMBER") && !child.Name.Equals("BIN_NUMBER") && !child.Name.Equals("IDENTIFIER"); l++)
                             {
                                 child = node.GetChildAt(l);
                                 if (l != 0 && node.GetChildAt(l - 1).Name.Equals("SIGN"))
                                 {
                                     if (((Token)node.GetChildAt(l - 1)).Image.Equals("+"))
                                     {
                                         sign = 1;
                                     }
                                     else
                                     {
                                         sign = -1;
                                     }
                                 }
                             }
                             if (child.Name.Equals("DEC_NUMBER"))
                             {
                                 operandValue = Convert.ToInt32(((Token)child).Image.ToLower()) * sign;
                             }
                             else if (child.Name.Equals("HEX_NUMBER"))
                             {
                                 operandValue = Convert.ToInt32(((Token)child).Image.ToLower().Substring(0, ((Token)child).Image.Length - 1), 16) * sign;
                             }
                             else if (child.Name.Equals("OCT_NUMBER"))
                             {
                                 operandValue = Convert.ToInt32(((Token)child).Image.ToLower().Substring(0, ((Token)child).Image.Length - 1), 8) * sign;
                             }
                             else if (child.Name.Equals("BIN_NUMBER"))
                             {
                                 operandValue = Convert.ToInt32(((Token)child).Image.ToLower().Substring(0, ((Token)child).Image.Length - 1), 2) * sign;
                             }
                             else if (child.Name.Equals("IDENTIFIER"))
                             {
                                 string label = ((Token)child).Image;
                                 operandValue = 0;
                                 bool found = false;
                                 foreach (Symbol s in symbolTable)
                                 {
                                     if (s.Label.ToLower().Equals(label))
                                     {
                                         operandValue = s.Offset;
                                         found        = true;
                                         break;
                                     }
                                 }
                                 if (found == false)
                                 {
                                     labelNotYet = true;
                                 }
                             }
                             int    relativeOperandValue = operandValue - inst.Size - count;
                             string image = getExpression(instructions.ElementAt(i), "");
                             if (labelNotYet == false)
                             {
                                 operandValue    = am.GetOperandValue(image, count + inst.Size, relativeOperandValue, operandValue);
                                 shouldBeWritten = true;
                             }
                         }
                         if (shouldBeWritten == true)
                         {
                             int operandStart = inst.Arguments.ElementAt(j).OperandStarts[am.Name];
                             int operandEnd   = inst.Arguments.ElementAt(j).OperandEnds[am.Name];
                             int operandSize  = 1;
                             for (int k = operandStart; k >= operandEnd; k--)
                             {
                                 if (k % 8 == 0 && k != operandEnd)
                                 {
                                     operandSize++;
                                 }
                             }
                             int operandCount = operandStart - operandEnd;
                             byteCount = operandSize - 1;
                             for (int k = operandStart; k >= operandEnd; k--)
                             {
                                 int semiValue = (operandValue & (1 << operandCount)) << operandEnd % 8;
                                 binaryCode[count + inst.Size - 1 - operandEnd / 8 - byteCount] |= (byte)((semiValue & (1 << (operandEnd % 8 + operandCount))) >> byteCount * 8); // This might be a problem.
                                 if ((operandEnd + operandCount) % 8 == 0)
                                 {
                                     byteCount--;
                                 }
                                 operandCount--;
                             }
                         }
                     }
                     separators.AddLast(count);
                     count += inst.Size;
                 }
                 separators.AddLast(count);
                 count = 0;
                 // Second passing:
                 for (int i = 0; i < instructions.Count; i++)
                 {
                     Instruction inst = cpu.Constants.GetInstruction(instructions.ElementAt(i).GetName());
                     LinkedList <AddressingMode> addrModes        = new LinkedList <AddressingMode>();
                     LinkedList <int>            argumentsIndexes = new LinkedList <int>();
                     for (int j = 0; j < instructions.ElementAt(i).GetChildCount(); j++)
                     {
                         AddressingMode am = null;
                         am = cpu.Constants.GetAddressingMode(instructions.ElementAt(i).GetChildAt(j).Name);
                         if (!object.ReferenceEquals(am, null))
                         {
                             addrModes.AddLast(am);
                             argumentsIndexes.AddLast(j);
                         }
                     }
                     for (int j = 0; j < inst.Arguments.Count; j++)
                     {
                         AddressingMode am                 = addrModes.ElementAt(j);
                         int            argumentIndex      = argumentsIndexes.ElementAt(j);
                         int            operandValue       = 0;
                         bool           shouldBeOverwriten = false;
                         if (am.OperandReadFromExpression)
                         {
                             Node node       = (instructions.ElementAt(i).GetChildAt(argumentIndex));
                             int  childCount = node.GetChildCount();
                             Node child      = node;
                             while (!(child.GetChildAt(0) is Token))
                             {
                                 child = child.GetChildAt(0);
                             }
                             for (int l = 0; l < node.GetChildCount() && !child.Name.Equals("DEC_NUMBER") && !child.Name.Equals("HEX_NUMBER") && !child.Name.Equals("OCT_NUMBER") && !child.Name.Equals("BIN_NUMBER") && !child.Name.Equals("IDENTIFIER"); l++)
                             {
                                 child = node.GetChildAt(l);
                             }
                             if (child.Name.Equals("IDENTIFIER"))
                             {
                                 string label = ((Token)child).Image;
                                 operandValue       = 0;
                                 shouldBeOverwriten = true;
                                 bool found = false;
                                 foreach (Symbol s in symbolTable)
                                 {
                                     if (s.Label.ToLower().Equals(label))
                                     {
                                         operandValue = s.Offset;
                                         found        = true;
                                         break;
                                     }
                                 }
                                 if (found == false)
                                 {
                                     operandValue = Program.Mem.FirstFreeInRAM(am.Result.Size / 8);
                                     if (operandValue == -1)
                                     {
                                         throw new Exception("Memory full");
                                     }
                                     Symbol newSymbol = new Symbol(label, 0, operandValue, true);
                                     symbolTable.AddLast(newSymbol);
                                     Program.Mem.Allocate(operandValue, am.Result.Size / 8);
                                 }
                             }
                             if (am.OperandType.ToLower().Equals("relative"))
                             {
                                 operandValue = operandValue - inst.Size - count;
                             }
                         }
                         else if (am.OperandValueDefinedByUser)
                         {
                             Node node       = (instructions.ElementAt(i).GetChildAt(argumentIndex));
                             int  childCount = node.GetChildCount();
                             Node child      = node;
                             while (!(child.GetChildAt(0) is Token))
                             {
                                 child = child.GetChildAt(0);
                             }
                             for (int l = 0; l < node.GetChildCount() && !child.Name.Equals("DEC_NUMBER") && !child.Name.Equals("HEX_NUMBER") && !child.Name.Equals("OCT_NUMBER") && !child.Name.Equals("BIN_NUMBER") && !child.Name.Equals("IDENTIFIER"); l++)
                             {
                                 child = node.GetChildAt(l);
                             }
                             if (child.Name.Equals("IDENTIFIER"))
                             {
                                 string label = ((Token)child).Image;
                                 bool   found = false;
                                 shouldBeOverwriten = true;
                                 foreach (Symbol s in symbolTable)
                                 {
                                     if (s.Label.ToLower().Equals(label))
                                     {
                                         operandValue = s.Offset;
                                         found        = true;
                                         break;
                                     }
                                 }
                                 if (found == false)
                                 {
                                     operandValue = Program.Mem.FirstFree(Program.Mem.AuSize);
                                     Program.Mem.Allocate(operandValue, Program.Mem.AuSize); // This must be improved.
                                 }
                             }
                             int    relativeOperandValue = operandValue - inst.Size - count;
                             string image = getExpression(instructions.ElementAt(i), "");
                             operandValue = am.GetOperandValue(image, count + inst.Size, relativeOperandValue, operandValue);
                         }
                         if (shouldBeOverwriten == true)
                         {
                             int operandStart = inst.Arguments.ElementAt(j).OperandStarts[am.Name];
                             int operandEnd   = inst.Arguments.ElementAt(j).OperandEnds[am.Name];
                             int operandSize  = 1;
                             for (int k = operandStart; k >= operandEnd; k--)
                             {
                                 if (k % 8 == 0 && k != operandEnd)
                                 {
                                     operandSize++;
                                 }
                             }
                             int operandCount = operandStart - operandEnd;
                             int byteCount    = operandSize - 1;
                             for (int k = operandStart; k >= operandEnd; k--)
                             {
                                 int semiValue = (operandValue & (1 << operandCount)) << operandEnd % 8;
                                 binaryCode[count + inst.Size - 1 - operandEnd / 8 - byteCount] |= (byte)((semiValue & (1 << (operandEnd % 8 + operandCount))) >> byteCount * 8); // This might be a problem.
                                 if ((operandEnd + operandCount) % 8 == 0)
                                 {
                                     byteCount--;
                                 }
                                 operandCount--;
                             }
                         }
                     }
                     count += inst.Size;
                 }
                 output.Text += DateTime.Now.ToString() + " Compile successfull.\n";
                 output.ScrollToCaret();
                 byte[] ret = new byte[count];
                 for (int i = 0; i < count; i++)
                 {
                     ret[i] = binaryCode[i];
                 }
                 for (int i = 0; i < count; i += Program.Mem.AuSize)
                 {
                     byte[] toWrite = new byte[Program.Mem.AuSize];
                     for (int j = 0; j < Program.Mem.AuSize && i + j < count; j++)
                     {
                         toWrite[j] = ret[j + i];
                     }
                     Program.Mem[(uint)(i + origin)] = toWrite;
                 }
                 return(ret);
             }
             catch (ParserLogException ex)
             {
                 string o = "Error(s) in code existed. Compile unsuccessfull.\r\nList of errors:\r\n";
                 for (int j = 0; j < ex.Count; j++)
                 {
                     ParseException pe = ex[j];
                     o += (j + 1) + ": Syntax error " + '\'' + pe.ErrorMessage + '\'' + " in line " + pe.Line + " and column " + pe.Column + "\n";
                 }
                 output.Text += DateTime.Now.ToString() + " " + o;
                 output.ScrollToCaret();
                 return(null);
             }
         }
     }
     catch (Exception ex)
     {
         File.AppendAllText("error.txt", ex.ToString());
         return(null);
     }
 }