예제 #1
0
파일: Parser.cs 프로젝트: strunberg/TEA
        private bool ParseSimpleExpression(TokenReader reader, out Expression result)
        {
            Token start = reader.Peek();
            result = null;
            Expression outer = null;
            if (!this.ParseTermExpression(reader, out outer))
            {
                return false;
            }

            Token tok = reader.Peek();
            while (tok.Is(Keyword.Plus) || tok.Is(Keyword.Minus) || tok.Is(Keyword.Or))
            {
                reader.Read();
                Expression term = null;
                if (!this.ParseTermExpression(reader, out term))
                {
                    return false;
                }

                outer = new SimpleExpression(start, outer, ((KeywordToken)tok).Value, term);

                tok = reader.Peek();
            }

            result = outer;
            return true;
        }
예제 #2
0
        private bool TryEmitSimpleExpression(
            SimpleExpression 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.Plus:
                        {
                            method.Statements.Add(new AsmStatement { Instruction = "faddp" });
                        } break;
                    case Keyword.Minus:
                        {
                            method.Statements.Add(new AsmStatement { Instruction = "fsubp" });
                        } 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.Plus:
                            {
                                method.Statements.Add(new AsmStatement { Instruction = "add eax,ecx" });
                            } break;
                        case Keyword.Minus:
                            {
                                method.Statements.Add(new AsmStatement { Instruction = "sub eax,ecx" });
                            } break;
                        case Keyword.Or:
                            {
                                method.Statements.Add(new AsmStatement { Instruction = "or eax,ecx" });
                            } break;
                    }
                }
            }

            valueType = leftSideType;
            return true;
        }