public Method ConvertToIrisMethod()
        {
            IrisType returnType = _signature.ReturnType;

            Variable[] parameters = GetParameters();

            if (IsStatic)
            {
                return(CreateMethodHelper(returnType, parameters));
            }
            else
            {
                // Iris can call instance methods by passing "this" as parameter 0
                Variable[] staticParams = new Variable[parameters.Length + 1];
                IrisType   instanceType = DeclaringType.ConvertToIrisType();

                if (instanceType == IrisType.Integer || instanceType == IrisType.Boolean)
                {
                    instanceType = instanceType.MakeByRefType();
                }

                staticParams[0] = new Variable(instanceType, "this");
                Array.Copy(parameters, 0, staticParams, 1, parameters.Length);
                return(CreateMethodHelper(returnType, staticParams));
            }
        }
        protected void ParseVariableList(List <Tuple <Variable, FilePosition> > variables, bool isArgumentList)
        {
            bool first = true;

            do
            {
                bool isByRef = isArgumentList && Accept(Token.KwVar);

                FilePosition nameStart = _lexer.TokenStartPosition;
                if (!Accept(Token.Identifier))
                {
                    if (!isArgumentList && !first)
                    {
                        return; // Allow semicolon on the final var declaration
                    }
                    AddErrorAtTokenStart("Expecting variable name.");
                    SkipStatement();
                    return;
                }

                first = false;

                // Parse name list
                List <Tuple <string, FilePosition> > names = new List <Tuple <string, FilePosition> >();
                names.Add(new Tuple <string, FilePosition>(_lexeme, nameStart));
                while (Accept(Token.ChrComma))
                {
                    nameStart = _lexer.TokenStartPosition;
                    if (!Accept(Token.Identifier))
                    {
                        AddErrorAtTokenStart("Expecting variable name after ','.");
                    }
                    else
                    {
                        names.Add(new Tuple <string, FilePosition>(_lexeme, nameStart));
                    }
                }

                Expect(Token.ChrColon);

                // Now parse the type and create the variable(s)
                SubRange subRange = null;
                IrisType type     = ParseType(ref subRange, expectSubRange: !isArgumentList);
                if (isByRef)
                {
                    type = type.MakeByRefType();
                }

                foreach (Tuple <string, FilePosition> name in names)
                {
                    variables.Add(new Tuple <Variable, FilePosition>(new Variable(type, name.Item1, subRange), name.Item2));
                }
            }while (Accept(Token.ChrSemicolon));
        }
        /// <summary>
        /// Convert a type from the debugger's type system into Iris's type system
        /// </summary>
        /// <param name="lmrType">LMR Type</param>
        /// <returns>Iris type</returns>
        public static IrisType GetIrisTypeForLmrType(Type lmrType)
        {
            if (lmrType.IsPrimitive)
            {
                switch (lmrType.FullName)
                {
                case "System.Int32":
                    return(IrisType.Integer);

                case "System.Boolean":
                    return(IrisType.Boolean);
                }
            }
            else if (lmrType.IsArray)
            {
                if (lmrType.GetArrayRank() != 1)
                {
                    return(IrisType.Invalid);
                }

                IrisType elementType = GetIrisTypeForLmrType(lmrType.GetElementType());
                if (elementType == IrisType.Invalid)
                {
                    return(IrisType.Invalid);
                }

                return(elementType.MakeArrayType());
            }
            else if (lmrType.IsByRef)
            {
                IrisType elementType = GetIrisTypeForLmrType(lmrType.GetElementType());
                if (elementType == IrisType.Invalid)
                {
                    return(IrisType.Invalid);
                }

                return(elementType.MakeByRefType());
            }
            else if (lmrType.FullName.Equals("System.String"))
            {
                return(IrisType.String);
            }

            // Unknown
            return(IrisType.Invalid);
        }
        private IrisType ProcessArrayAccess(FilePosition fp, Symbol symbol, SymbolLoadMode mode)
        {
            IrisType symbolType = symbol.Type;
            IrisType resultType = IrisType.Invalid;

            if (symbolType != IrisType.Invalid)
            {
                if (!symbolType.IsArray)
                {
                    AddError(fp, string.Format("Symbol '{0}' is not an array, but is being used as an array.", _lexeme));
                }
                else
                {
                    EmitLoadSymbol(symbol, SymbolLoadMode.Dereference);
                    resultType = symbol.Type.GetElementType();
                }
            }

            FilePosition indexerPosition = _lexer.TokenStartPosition;
            IrisType     indexerType     = ParseExpression();

            if (indexerType != IrisType.Integer)
            {
                AddError(indexerPosition, "Expecting integer value as array index.");
            }

            Expect(Token.ChrCloseBracket);

            if (resultType != IrisType.Invalid)
            {
                if (mode == SymbolLoadMode.ElementAddress)
                {
                    MethodGenerator.LoadElementAddress(resultType);
                    resultType = resultType.MakeByRefType();
                }
                else if (mode == SymbolLoadMode.Element)
                {
                    MethodGenerator.LoadElement(resultType);
                }
            }

            return(resultType);
        }
        protected IrisType ParseBaseExpression(SymbolLoadMode mode)
        {
            FilePosition fp = _lastParsedPosition;

            if (Accept(Token.Identifier))
            {
                Symbol symbol = LookupSymbol(fp, _lexeme);

                if (Accept(Token.ChrOpenBracket))
                {
                    return(ProcessArrayAccess(fp, symbol, mode == SymbolLoadMode.Address ? SymbolLoadMode.ElementAddress : SymbolLoadMode.Element));
                }
                if (Accept(Token.ChrOpenParen))
                {
                    return(ProcessCall(fp, symbol, skipArgList: false));
                }

                IrisType type = symbol.Type;
                if (type.IsMethod)
                {
                    return(ProcessCall(fp, symbol, skipArgList: true));
                }
                if (type != IrisType.Invalid)
                {
                    EmitLoadSymbol(symbol, mode);
                }

                if (mode == SymbolLoadMode.Address && !type.IsByRef)
                {
                    return(type.MakeByRefType());
                }
                else if (mode == SymbolLoadMode.Dereference)
                {
                    return(DerefType(type));
                }
                else
                {
                    return(type);
                }
            }
            else if (Accept(Token.KwTrue))
            {
                MethodGenerator.PushIntConst(1);
                return(IrisType.Boolean);
            }
            else if (Accept(Token.KwFalse))
            {
                MethodGenerator.PushIntConst(0);
                return(IrisType.Boolean);
            }
            else if (Accept(Token.Number))
            {
                MethodGenerator.PushIntConst(_lastIntegerLexeme);
                return(IrisType.Integer);
            }
            else if (Accept(Token.String))
            {
                MethodGenerator.PushString(_lexeme);
                return(IrisType.String);
            }
            else if (Accept(Token.ChrOpenParen))
            {
                IrisType type = ParseExpression(mode);
                Expect(Token.ChrCloseParen);
                return(type);
            }

            AddError(fp, "Expecting expression.");
            return(IrisType.Invalid);
        }