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

            Token tok = reader.Peek();
            if (tok.IsRelationalOperator())
            {
                reader.Read();
                Expression term = null;
                if (!this.ParseSimpleExpression(reader, out term))
                {
                    return false;
                }

                result = new RelationalExpression(start, firstTerm, ((KeywordToken)tok).Value, term);
            }
            else
            {
                result = firstTerm;
            }

            return true;
        }
예제 #2
0
        private bool TryEmitRelationExpresion(
            RelationalExpression relExpr, 
            CompilerContext context, 
            Scope scope, 
            MethodImpl method, 
            out TypeDefinition valueType)
        {
            context.TryFindTypeByName("boolean", out valueType);
            TypeDefinition rightSideType = null;
            if (!this.TryEmitExpression(relExpr.Right, context, scope, method, out rightSideType))
            {
                return false;
            }

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

            if (rightSideType.IsFloatingPoint)
            {
                if (leftSideType.IsFloatingPoint)
                {
                    switch (rightSideType.Size)
                    {
                        case 4:
                            method.Statements.Add(new AsmStatement { Instruction = "fld dword ptr [esp]" });
                            break;
                        case 8:
                            method.Statements.Add(new AsmStatement { Instruction = "fld qword ptr [esp]" });
                            break;
                        default:
                            method.Statements.Add(new AsmStatement { Instruction = "fld tword ptr [esp]" });
                            break;
                    }

                    method.Statements.Add(new AsmStatement { Instruction = string.Format("add esp,{0}", rightSideType.Size) });
                    method.Statements.Add(new AsmStatement { Instruction = "fcompp" });
                    method.Statements.Add(new AsmStatement { Instruction = "fnstsw	ax" });
                    method.Statements.Add(new AsmStatement { Instruction = "sahf" });
                    switch (relExpr.Operator)
                    {
                        case Keyword.Equals:
                            {
                                method.Statements.Add(new AsmStatement { Instruction = "sete al" });
                            } break;
                        case Keyword.LessThan:
                            {
                                method.Statements.Add(new AsmStatement { Instruction = "seta al" });
                            } break;
                        case Keyword.LessThanOrEquals:
                            {
                                method.Statements.Add(new AsmStatement { Instruction = "setae al" });
                            } break;
                        case Keyword.GreaterThan:
                            {
                                method.Statements.Add(new AsmStatement { Instruction = "setb al" });
                            } break;
                        case Keyword.GreaterThanOrEquals:
                            {
                                method.Statements.Add(new AsmStatement { Instruction = "setbe al" });
                            } break;
                        case Keyword.NotEqual:
                            {
                                method.Statements.Add(new AsmStatement { Instruction = "setne al" });
                            } break;
                    }
                }
                else
                {
                    string message = string.Format(
                        System.Globalization.CultureInfo.InvariantCulture,
                        Properties.Resources.CodeGenerator_NoAutomaticConversion,
                        leftSideType.FullName,
                        rightSideType.FullName);
                    this.log.Write(new Message(
                        relExpr.Start.Path,
                        relExpr.Start.Line,
                        relExpr.Start.Column,
                        Severity.Error,
                        message));
                    return false;
                }
            }
            else if(leftSideType.IsFloatingPoint)
            {
                string message = string.Format(
                    System.Globalization.CultureInfo.InvariantCulture,
                    Properties.Resources.CodeGenerator_NoAutomaticConversion,
                    leftSideType.FullName,
                    rightSideType.FullName);
                this.log.Write(new Message(
                    relExpr.Start.Path,
                    relExpr.Start.Line,
                    relExpr.Start.Column,
                    Severity.Error,
                    message));
                return false;
            }
            else
            {
                if(leftSideType.Size <= 4 && rightSideType.Size <= 4)
                {
                    method.Statements.Add(new AsmStatement { Instruction = "pop ecx"});
                    method.Statements.Add(new AsmStatement { Instruction = "cmp eax,ecx"});
                    switch (relExpr.Operator)
                    {
                        case Keyword.Equals:
                            {
                                method.Statements.Add(new AsmStatement { Instruction = "sete al" });
                            } break;
                        case Keyword.LessThan:
                            {
                                method.Statements.Add(new AsmStatement { Instruction = "setl al" });
                            } break;
                        case Keyword.LessThanOrEquals:
                            {
                                method.Statements.Add(new AsmStatement { Instruction = "setle al" });
                            } break;
                        case Keyword.GreaterThan:
                            {
                                method.Statements.Add(new AsmStatement { Instruction = "setg al" });
                            } break;
                        case Keyword.GreaterThanOrEquals:
                            {
                                method.Statements.Add(new AsmStatement { Instruction = "setge al" });
                            } break;
                        case Keyword.NotEqual:
                            {
                                method.Statements.Add(new AsmStatement { Instruction = "setne al" });
                            } break;
                    }
                }
            }

            return true;
        }