Ejemplo n.º 1
0
        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());
            }
        }
Ejemplo n.º 2
0
      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();

         }

      }