Пример #1
0
        private bool ParseTermExpression(TokenReader reader, out Expression result)
        {
            result = null;
            Token start = reader.Peek();
            Expression outer = null;
            if (!this.ParseFactorExpression(reader, out outer))
            {
                return false;
            }

            Token tok = reader.Peek();
            while (tok.Is(Keyword.Star) || tok.Is(Keyword.Slash) || tok.Is(Keyword.Div) || tok.Is(Keyword.And) || tok.Is(Keyword.Mod))
            {
                reader.Read();
                Expression factor = null;
                if (!this.ParseFactorExpression(reader, out factor))
                {
                    return false;
                }

                outer = new TermExpression(start, outer, ((KeywordToken)tok).Value, factor);
                tok = reader.Peek();
            }

            result = outer;
            return true;
        }
Пример #2
0
        private bool TryEmitTermExpression(
            TermExpression expression,
            CompilerContext context,
            Scope scope,
            MethodImpl method,
            out TypeDefinition valueType)
        {
            TypeDefinition rightSideType = null;
            if (!this.TryEmitExpression(expression.Right, context, scope, method, out rightSideType))
            {
                valueType = null;
                return false;
            }

            this.PushResult(method, rightSideType);
            TypeDefinition leftSideType = null;
            if (!this.TryEmitExpression(expression.Left, context, scope, method, out leftSideType))
            {
                valueType = null;
                return false;
            }

            if (leftSideType.IsFloatingPoint)
            {
                if (rightSideType.IsFloatingPoint)
                {
                    if (rightSideType.Size == 8)
                    {
                        method.Statements.Add(new AsmStatement { Instruction = "fld qword ptr [esp]" });
                    }
                    else
                    {
                        method.Statements.Add(new AsmStatement { Instruction = "fld dword ptr [esp]" });
                    }

                    method.Statements.Add(new AsmStatement { Instruction = "add esp," + rightSideType.Size });
                }
                else if (rightSideType.Size <= 4)
                {
                    method.Statements.Add(new AsmStatement { Instruction = "fild [esp]" });
                    method.Statements.Add(new AsmStatement { Instruction = "add esp," + rightSideType.Size });
                }

                switch (expression.Operator)
                {
                    case Keyword.Star:
                        {
                            method.Statements.Add(new AsmStatement { Instruction = "fmulp" });
                        } break;
                    case Keyword.Slash:
                        {
                            method.Statements.Add(new AsmStatement { Instruction = "fdivp" });
                        } break;
                }
            }
            else if (leftSideType.Size <= 4)
            {
                if (rightSideType.Size <= 4 && !rightSideType.IsFloatingPoint)
                {
                    method.Statements.Add(new AsmStatement { Instruction = "pop ecx" });
                    switch (expression.Operator)
                    {
                        case Keyword.Star:
                            {
                                method.Statements.Add(new AsmStatement { Instruction = "imul eax,ecx" });
                            } break;
                        case Keyword.Mod:
                            {
                                method.Statements.Add(new AsmStatement { Instruction = "xor edx,edx" });
                                method.Statements.Add(new AsmStatement { Instruction = "idiv ecx" });
                                method.Statements.Add(new AsmStatement { Instruction = "mov eax,edx" });
                            } break;
                        case Keyword.And:
                            {
                                method.Statements.Add(new AsmStatement { Instruction = "and eax,ecx" });
                            } break;
                        case Keyword.Div:
                            {
                                method.Statements.Add(new AsmStatement { Instruction = "xor edx,edx" });
                                method.Statements.Add(new AsmStatement { Instruction = "idiv ecx" });
                            } break;
                    }
                }
            }

            valueType = leftSideType;
            return true;
        }