protected IrisType ParseFactor(SymbolLoadMode mode)
        {
            Operator     opr  = AcceptOperator(OperatorMaps.Instance.Factor);
            FilePosition fp   = _lexer.TokenStartPosition;
            IrisType     type = ParseBaseExpression(mode);

            if (opr != Operator.None)
            {
                type = DerefType(type);
                if (type == IrisType.String)
                {
                    AddError(fp, "Unary operators cannot be applied to string values.");
                }
                else if (opr == Operator.Not)
                {
                    VerifyExpressionType(fp, type, IrisType.Boolean);
                }
                else if (opr == Operator.Negate && type == IrisType.Boolean)
                {
                    AddError(fp, "Unary negate operator cannot be applied to boolean values.");
                }

                MethodGenerator.Operator(opr);
            }

            return(type);
        }
        protected IrisType ParseTerm(SymbolLoadMode mode)
        {
            IrisType     lhs = ParseFactor(mode);
            FilePosition fp  = _lexer.TokenStartPosition;
            Operator     opr = AcceptOperator(OperatorMaps.Instance.Term);

            if (opr != Operator.None)
            {
                IrisType rhs = ParseTerm(mode);
                return(ProcessArithemticOperator(fp, lhs, rhs, opr));
            }

            return(lhs);
        }
        protected IrisType ParseExpression(SymbolLoadMode mode = SymbolLoadMode.Dereference)
        {
            IrisType     lhs = ParseCompareExpression(mode);
            FilePosition fp  = _lexer.TokenStartPosition;
            Operator     opr = AcceptOperator(OperatorMaps.Instance.Logic);

            if (opr != Operator.None)
            {
                VerifyExpressionType(fp, lhs, IrisType.Boolean);
                IrisType rhs = ParseExpression(mode);
                VerifyExpressionType(fp, rhs, IrisType.Boolean);
                MethodGenerator.Operator(opr);
            }

            return(lhs);
        }
        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 void EmitLoadSymbol(Symbol symbol, SymbolLoadMode mode)
        {
            bool isByRef = symbol.Type.IsByRef;

            if (symbol.StorageClass == StorageClass.Argument)
            {
                if (mode == SymbolLoadMode.Address && !isByRef)
                {
                    MethodGenerator.PushArgumentAddress(symbol.Location);
                }
                else
                {
                    MethodGenerator.PushArgument(symbol.Location);
                }
            }
            else if (symbol.StorageClass == StorageClass.Local)
            {
                if (mode == SymbolLoadMode.Address && !isByRef)
                {
                    MethodGenerator.PushLocalAddress(symbol.Location);
                }
                else
                {
                    MethodGenerator.PushLocal(symbol.Location);
                }
            }
            else
            {
                if (mode == SymbolLoadMode.Address && !isByRef)
                {
                    MethodGenerator.PushGlobalAddress(symbol);
                }
                else
                {
                    MethodGenerator.PushGlobal(symbol);
                }
            }

            if (mode == SymbolLoadMode.Dereference && isByRef)
            {
                MethodGenerator.Load(symbol.Type.GetElementType());
            }
        }
        protected IrisType ParseCompareExpression(SymbolLoadMode mode)
        {
            IrisType     lhs = ParseArithmeticExpression(mode);
            FilePosition fp  = _lexer.TokenStartPosition;
            Operator     opr = AcceptOperator(OperatorMaps.Instance.Compare);

            if (opr != Operator.None)
            {
                IrisType rhs = ParseCompareExpression(mode);
                if (lhs == IrisType.String && rhs == IrisType.String)
                {
                    Symbol strcmp = LookupSymbol(fp, "strcmp");
                    MethodGenerator.Call(strcmp);
                    MethodGenerator.PushIntConst(0);
                }

                MethodGenerator.Operator(opr);
                return(ApplyTypeRules(fp, lhs, rhs, boolResult: true));
            }

            return(lhs);
        }
Ejemplo n.º 7
0
        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;
        }
Ejemplo n.º 8
0
        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;
        }
Ejemplo n.º 9
0
        protected IrisType ParseFactor(SymbolLoadMode mode)
        {
            Operator opr = AcceptOperator(OperatorMaps.Instance.Factor);
            FilePosition fp = _lexer.TokenStartPosition;
            IrisType type = ParseBaseExpression(mode);
            if (opr != Operator.None)
            {
                type = DerefType(type);
                if (type == IrisType.String)
                    AddError(fp, "Unary operators cannot be applied to string values.");
                else if (opr == Operator.Not)
                    VerifyExpressionType(fp, type, IrisType.Boolean);
                else if (opr == Operator.Negate && type == IrisType.Boolean)
                    AddError(fp, "Unary negate operator cannot be applied to boolean values.");

                MethodGenerator.Operator(opr);
            }

            return type;
        }
Ejemplo n.º 10
0
        protected IrisType ParseTerm(SymbolLoadMode mode)
        {
            IrisType lhs = ParseFactor(mode);
            FilePosition fp = _lexer.TokenStartPosition;
            Operator opr = AcceptOperator(OperatorMaps.Instance.Term);
            if (opr != Operator.None)
            {
                IrisType rhs = ParseTerm(mode);
                return ProcessArithemticOperator(fp, lhs, rhs, opr);
            }

            return lhs;
        }
Ejemplo n.º 11
0
        protected IrisType ParseCompareExpression(SymbolLoadMode mode)
        {
            IrisType lhs = ParseArithmeticExpression(mode);
            FilePosition fp = _lexer.TokenStartPosition;
            Operator opr = AcceptOperator(OperatorMaps.Instance.Compare);
            if (opr != Operator.None)
            {
                IrisType rhs = ParseCompareExpression(mode);
                if (lhs == IrisType.String && rhs == IrisType.String)
                {
                    Symbol strcmp = LookupSymbol(fp, "strcmp");
                    MethodGenerator.Call(strcmp);
                    MethodGenerator.PushIntConst(0);
                }

                MethodGenerator.Operator(opr);
                return ApplyTypeRules(fp, lhs, rhs, boolResult: true);
            }

            return lhs;
        }
Ejemplo n.º 12
0
        protected IrisType ParseExpression(SymbolLoadMode mode = SymbolLoadMode.Dereference)
        {
            IrisType lhs = ParseCompareExpression(mode);
            FilePosition fp = _lexer.TokenStartPosition;
            Operator opr = AcceptOperator(OperatorMaps.Instance.Logic);
            if (opr != Operator.None)
            {
                VerifyExpressionType(fp, lhs, IrisType.Boolean);
                IrisType rhs = ParseExpression(mode);
                VerifyExpressionType(fp, rhs, IrisType.Boolean);
                MethodGenerator.Operator(opr);
            }

            return lhs;
        }
Ejemplo n.º 13
0
        protected void EmitLoadSymbol(Symbol symbol, SymbolLoadMode mode)
        {
            bool isByRef = symbol.Type.IsByRef;
            if (symbol.StorageClass == StorageClass.Argument)
            {
                if (mode == SymbolLoadMode.Address && !isByRef)
                    MethodGenerator.PushArgumentAddress(symbol.Location);
                else
                    MethodGenerator.PushArgument(symbol.Location);
            }
            else if (symbol.StorageClass == StorageClass.Local)
            {
                if (mode == SymbolLoadMode.Address && !isByRef)
                    MethodGenerator.PushLocalAddress(symbol.Location);
                else
                    MethodGenerator.PushLocal(symbol.Location);
            }
            else
            {
                if (mode == SymbolLoadMode.Address && !isByRef)
                    MethodGenerator.PushGlobalAddress(symbol);
                else
                    MethodGenerator.PushGlobal(symbol);
            }

            if (mode == SymbolLoadMode.Dereference && isByRef)
                MethodGenerator.Load(symbol.Type.GetElementType());
        }
        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);
        }