public static Operand Parse(string text) { //v=LABEL | ($ff | 255 | %10101010) | ($ffff | 64000 | %1010101010101010 //v //[v] //[[v]] //[v,X] //[[v,X]] //[[v],X] AddressingModes addressingMode = AddressingModes.Implied; string parsed = text; if (parsed != null) { bool isAddress = false; bool isIndirect = false; bool isIndexed = false; bool isPreIndexed = false; bool isPostIndexed = false; if (parsed[0] == '[') { if (parsed[parsed.Length - 1] != ']') { throw new InvalidOperationException("can't parse {" + text + "}"); } isAddress = true; parsed = parsed.Substring(1, parsed.Length - 2); if (parsed[0] == '[') { isIndirect = true; if (parsed.Substring(parsed.Length - 3, 3) == ",X]") { isPreIndexed = true; parsed = parsed.Substring(1, parsed.Length - 4); } else if (parsed.Substring(parsed.Length - 3, 3) == "],X") { isPostIndexed = true; parsed = parsed.Substring(1, parsed.Length - 4); } else if (parsed[parsed.Length - 1] == ']') { parsed = parsed.Substring(1, parsed.Length - 2); } else { throw new InvalidOperationException("can't parse {" + text + "}"); } } if (parsed.Substring(parsed.Length - 2, 2) == ",X") { isIndexed = true; parsed = parsed.Substring(0, parsed.Length - 2); } } if (parsed.Length == 0) { throw new InvalidOperationException("can't parse {" + text + "}"); } //parse label or literal UInt ui = null; string name = null; if (char.IsLetter(parsed[0]) || parsed[0] == '_') { if (!parsed.All(c => char.IsLetterOrDigit(c) || c == '_')) { throw new InvalidOperationException("can't parse {" + text + "}"); } name = parsed; } else { ui = UInt.Parse(parsed); if (isAddress && ui is U8) { ui = new U16(((U8)ui).Read()); } } if (isAddress) { //address literal or pointer (label) if (isIndirect) { if (isPreIndexed) { addressingMode = AddressingModes.IndirectPreIndexed; } else if (isPostIndexed) { addressingMode = AddressingModes.IndirectPostIndexed; } else { addressingMode = AddressingModes.Indirect; } } else { if (isIndexed) { addressingMode = AddressingModes.Indexed; } else { addressingMode = AddressingModes.Absolute; } } Value value = null; if (ui != null) { value = new Literal(ui); } else { value = new Pointer(name); } return(new Operand(value, addressingMode)); } else { //immediate literal or constant (label) if (ui != null) { if (ui is U8) { addressingMode = AddressingModes.Immediate; } else if (ui is U16) { addressingMode = AddressingModes.BigImmediate; } else { throw new NotSupportedException("only U8 and U16 supported"); } return(new Operand(new Literal(ui), addressingMode)); } else { //how to tell if a constant label is 8 or 16? //TODO: look up .EQU in symbol table return(new Operand(new Constant(name, null), addressingMode)); } } } else { //implied return(new Operand()); } }
public static Operand Parse(string text) { //v=LABEL | ($ff | 255 | %10101010) | ($ffff | 64000 | %1010101010101010 //v //[v] //[[v]] //[v,X] //[[v,X]] //[[v],X] AddressingModes addressingMode = AddressingModes.Implied; string parsed = text; if (parsed != null) { bool isAddress = false; bool isIndirect = false; bool isIndexed = false; bool isPreIndexed = false; bool isPostIndexed = false; if (parsed[0] == '[') { if (parsed[parsed.Length - 1] != ']') throw new InvalidOperationException("can't parse {" + text + "}"); isAddress = true; parsed = parsed.Substring(1, parsed.Length - 2); if (parsed[0] == '[') { isIndirect = true; if (parsed.Substring(parsed.Length - 3, 3) == ",X]") { isPreIndexed = true; parsed = parsed.Substring(1, parsed.Length - 4); } else if (parsed.Substring(parsed.Length - 3, 3) == "],X") { isPostIndexed = true; parsed = parsed.Substring(1, parsed.Length - 4); } else if (parsed[parsed.Length - 1] == ']') { parsed = parsed.Substring(1, parsed.Length - 2); } else { throw new InvalidOperationException("can't parse {" + text + "}"); } } if (parsed.Substring(parsed.Length - 2, 2) == ",X") { isIndexed = true; parsed = parsed.Substring(0, parsed.Length - 2); } } if (parsed.Length == 0) throw new InvalidOperationException("can't parse {" + text + "}"); //parse label or literal UInt ui = null; string name = null; if (char.IsLetter(parsed[0])||parsed[0]=='_') { if (!parsed.All(c => char.IsLetterOrDigit(c) || c=='_')) throw new InvalidOperationException("can't parse {" + text + "}"); name = parsed; } else { ui = UInt.Parse(parsed); if (isAddress && ui is U8) { ui = new U16(((U8)ui).Read()); } } if (isAddress) { //address literal or pointer (label) if (isIndirect) { if (isPreIndexed) addressingMode = AddressingModes.IndirectPreIndexed; else if (isPostIndexed) addressingMode = AddressingModes.IndirectPostIndexed; else addressingMode = AddressingModes.Indirect; } else { if (isIndexed) { addressingMode = AddressingModes.Indexed; } else { addressingMode = AddressingModes.Absolute; } } Value value = null; if (ui!=null) { value = new Literal(ui); } else { value=new Pointer(name); } return new Operand(value, addressingMode); } else { //immediate literal or constant (label) if (ui!=null) { if (ui is U8) { addressingMode = AddressingModes.Immediate; } else if (ui is U16) { addressingMode = AddressingModes.BigImmediate; } else { throw new NotSupportedException("only U8 and U16 supported"); } return new Operand(new Literal(ui), addressingMode); } else { //how to tell if a constant label is 8 or 16? //TODO: look up .EQU in symbol table return new Operand(new Constant(name,null), addressingMode); } } } else { //implied return new Operand(); } }