public void Assemble(IEnumerable <string> code) { foreach (var lineOfCode in code) { if (string.IsNullOrWhiteSpace(lineOfCode)) { continue; } Statement statement = null; if (!lineOfCode.Trim().StartsWith(":")) //TODO:Refactor { statement = interpreter.Interpret(lineOfCode); } if (lineOfCode.Trim().StartsWith(":")) { string label = lineOfCode.Trim().TrimStart(new[] { ':' }).ToUpper(); if (labelAddressTable.ContainsKey(label)) { throw new ArgumentException("Dupe Label"); } labelAddressTable.Add(label, dump.Count); //Fix Labelling IEnumerable <int> value; if (labelIndexTable.TryGetValue(label, out value)) { int labelAddress = dump.Count; foreach (int ind in value) { dump[ind] = (ushort)labelAddress; } } } else if (statement != null && statement.Instruction == Ins.DAT) { AddData(lineOfCode); } else if (statement != null && (statement.OperandA is RegisterOperand && statement.OperandB is RegisterOperand)) { //Instruction is 1 word long if (statement.OperandA.ReferencedAddress() == -1 && statement.OperandB.ReferencedAddress() == -1) { ushort fullOpCode = PackOpCode(statement); dump.Add(fullOpCode); } else { Future(); } } else if (statement != null && (statement.OperandA is WordOperand && 32 <= statement.OperandA.ReferencedAddress() && statement.OperandA.ReferencedAddress() <= 63 && statement.OperandB is RegisterOperand)) { //Instruction is 1 word long // 0x20-0x3f | literal value 0xffff-0x1e (-1..30) (literal) (only for a) int refAddress = statement.OperandA.ReferencedAddress(); ushort fullOpCode = PackOpCode((ushort)statement.Instruction, (ushort)refAddress, statement.OperandB.ToOpcode()); dump.Add(fullOpCode); } else if (statement != null && (statement.OperandA is WordOperand && statement.OperandB is RegisterOperand)) { //Instruction is 2 words long int refAddress = statement.OperandA.ReferencedAddress(); ushort partialOpCode = PackOpCode(statement); dump.Add(partialOpCode); dump.Add((ushort)refAddress); } else if (statement != null && statement.OperandA is LabelOperand) { //Instruction is 2 words long var labelOperand = statement.OperandA as LabelOperand; int labelAddress; if (labelAddressTable.TryGetValue(labelOperand.LabelName, out labelAddress)) { labelOperand.Address = labelAddress; } else { labelOperand.Address = 0x0000; } ushort partialOpcode = PackOpCode((ushort)statement.Instruction, (ushort)WordOps.NXT_WORD, statement.OperandB.ToOpcode()); dump.Add(partialOpcode); IEnumerable <int> labelIndicesInMemory; if (labelIndexTable.TryGetValue(labelOperand.LabelName, out labelIndicesInMemory)) { var indices = labelIndicesInMemory; indices = indices.Concat(new[] { dump.Count }); labelIndexTable[labelOperand.LabelName] = indices.ToList(); } else { labelIndexTable.Add(labelOperand.LabelName, new List <int> { dump.Count }); } dump.Add((ushort)labelOperand.Address); } else { Future(); } } }
public void Test_for_lower_case() { string code = "set A,B"; var statement = li.Interpret(code); Assert.AreEqual(Ins.SET, statement.Instruction); }