Exemple #1
0
        public TypeBinderResult Bind(IVariableTypeProvider VariableTypeProvider, PrimitiveType ReturnType, TextRange RangeInLine)
        {
            var Result = st.Translate(RangeInLine);

            var TypeDict = new Dictionary <Expr, PrimitiveType>();

            BindExpr(VariableTypeProvider, TypeDict, Result.Semantics);
            var rt = TypeDict[Result.Semantics];

            if (rt == PrimitiveType.Int && ReturnType == PrimitiveType.Real)
            {
                var feCReal = new FunctionExpr {
                    Name = "creal", Parameters = new List <Expr> {
                        Result.Semantics
                    }
                };
                var CReal = Expr.CreateFunction(feCReal);
                var Range = Positions[Result.Semantics];
                Positions.Add(feCReal, Range);
                Positions.Add(CReal, Range);
                TypeDict.Add(CReal, PrimitiveType.Real);
                Result.Semantics = CReal;
            }
            else if (rt != ReturnType)
            {
                throw new InvalidSyntaxException("TypeMismatch : '{0}' expected.".Formats(GetTypeString(ReturnType)), new FileTextRange {
                    Text = Text, Range = Positions[Result.Semantics]
                });
            }

            var tbr = new TypeBinderResult
            {
                Semantics = Result.Semantics,
                TypeDict  = TypeDict
            };

            return(tbr);
        }
Exemple #2
0
 /// <summary>函数表达式</summary>
 public static Expr CreateFunction(FunctionExpr Value)
 {
     return(new Expr {
         _Tag = ExprTag.Function, Function = Value
     });
 }
Exemple #3
0
        private PrimitiveType BindFunctionExpr(IVariableTypeProvider VariableTypeProvider, Dictionary <Expr, PrimitiveType> TypeDict, FunctionExpr fe)
        {
            foreach (var p in fe.Parameters)
            {
                BindExpr(VariableTypeProvider, TypeDict, p);
            }
            var ParameterTypes = fe.Parameters.Select(p => TypeDict[p]).ToList();
            List <FunctionParameterAndReturnTypes> Functions;

            try
            {
                Functions = VariableTypeProvider.GetOverloads(fe.Name);
            }
            catch (Exception ex)
            {
                throw new InvalidSyntaxException("'{0}' : FunctionNotExist".Formats(fe.Name), new FileTextRange {
                    Text = Text, Range = Positions[fe]
                }, ex);
            }
            var Sorted = Functions.Where(fs => IsOverloadSatisfied(ParameterTypes, fs.ParameterTypes)).GroupBy(fs => GetOverloadTypeConversionPoint(ParameterTypes, fs.ParameterTypes)).OrderBy(g => g.Key).ToList();

            if (Sorted.Count == 0)
            {
                throw new InvalidSyntaxException("'{0}' : FunctionNotExist".Formats(fe.Name), new FileTextRange {
                    Text = Text, Range = Positions[fe]
                });
            }
            var MostMatchedGroup = Sorted.First().ToList();

            if (MostMatchedGroup.Count > 1)
            {
                throw new InvalidSyntaxException("'{0}' : MultipleFunctionOverloadExist".Formats(fe.Name), new FileTextRange {
                    Text = Text, Range = Positions[fe]
                });
            }
            var MostMatchedSignature = MostMatchedGroup.Single();

            for (int k = 0; k < ParameterTypes.Count; k += 1)
            {
                var pt   = ParameterTypes[k];
                var fspt = MostMatchedSignature.ParameterTypes[k];
                if (pt == PrimitiveType.Int && fspt == PrimitiveType.Real)
                {
                    var feCReal = new FunctionExpr {
                        Name = "creal", Parameters = new List <Expr> {
                            fe.Parameters[k]
                        }
                    };
                    var CReal = Expr.CreateFunction(feCReal);
                    var Range = Positions[fe.Parameters[k]];
                    Positions.Add(feCReal, Range);
                    Positions.Add(CReal, Range);
                    TypeDict.Add(CReal, PrimitiveType.Real);
                    fe.Parameters[k] = CReal;
                }
            }
            return(MostMatchedSignature.ReturnType);
        }
Exemple #4
0
        private void BindExpr(IVariableTypeProvider VariableTypeProvider, Dictionary <Expr, PrimitiveType> TypeDict, Expr e)
        {
            if (e.OnLiteral)
            {
                var l = e.Literal;
                if (l.OnBooleanValue)
                {
                    TypeDict.Add(e, PrimitiveType.Boolean);
                }
                else if (l.OnIntValue)
                {
                    TypeDict.Add(e, PrimitiveType.Int);
                }
                else if (l.OnRealValue)
                {
                    TypeDict.Add(e, PrimitiveType.Real);
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
            else if (e.OnVariable)
            {
                List <FunctionParameterAndReturnTypes> t;
                try
                {
                    t = VariableTypeProvider.GetOverloads(e.Variable.Name).Where(fs => fs.ParameterTypes == null).ToList();
                }
                catch (Exception ex)
                {
                    throw new InvalidSyntaxException(String.Format("'{0}' : VariableNotExist", e.Variable.Name), new FileTextRange {
                        Text = Text, Range = Positions[e]
                    }, ex);
                }
                if (t.Count == 0)
                {
                    throw new InvalidSyntaxException("'{0}' : VariableNotExist".Formats(e.Variable.Name), new FileTextRange {
                        Text = Text, Range = Positions[e]
                    });
                }
                if (t.Count > 1)
                {
                    throw new InvalidSyntaxException("'{0}' : VariableFunctionOverloadExist".Formats(e.Variable.Name), new FileTextRange {
                        Text = Text, Range = Positions[e]
                    });
                }
                TypeDict.Add(e, t.Single().ReturnType);
            }
            else if (e.OnFunction)
            {
                var t = BindFunctionExpr(VariableTypeProvider, TypeDict, e.Function);
                TypeDict.Add(e, t);
            }
            else if (e.OnIf)
            {
                var Condition = e.If.Condition;
                var TruePart  = e.If.TruePart;
                var FalsePart = e.If.FalsePart;

                BindExpr(VariableTypeProvider, TypeDict, Condition);
                var ConditionType = TypeDict[Condition];
                if (ConditionType != PrimitiveType.Boolean)
                {
                    throw new InvalidSyntaxException("TypeMismatch : 'Boolean' expected.", new FileTextRange {
                        Text = Text, Range = Positions[Condition]
                    });
                }
                BindExpr(VariableTypeProvider, TypeDict, TruePart);
                var TruePartType = TypeDict[TruePart];
                BindExpr(VariableTypeProvider, TypeDict, FalsePart);
                var           FalsePartType = TypeDict[FalsePart];
                PrimitiveType ReturnType;
                if (TruePartType == PrimitiveType.Int && FalsePartType == PrimitiveType.Real)
                {
                    var fe = new FunctionExpr {
                        Name = "creal", Parameters = new List <Expr> {
                            TruePart
                        }
                    };
                    var CReal = Expr.CreateFunction(fe);
                    var Range = Positions[TruePart];
                    Positions.Add(fe, Range);
                    Positions.Add(CReal, Range);
                    TypeDict.Add(CReal, PrimitiveType.Real);
                    e.If.TruePart = CReal;
                    ReturnType    = PrimitiveType.Real;
                }
                else if (TruePartType == PrimitiveType.Real && FalsePartType == PrimitiveType.Int)
                {
                    var fe = new FunctionExpr {
                        Name = "creal", Parameters = new List <Expr> {
                            FalsePart
                        }
                    };
                    var CReal = Expr.CreateFunction(fe);
                    var Range = Positions[FalsePart];
                    Positions.Add(fe, Range);
                    Positions.Add(CReal, Range);
                    TypeDict.Add(CReal, PrimitiveType.Real);
                    e.If.FalsePart = CReal;
                    ReturnType     = PrimitiveType.Real;
                }
                else if (TruePartType != FalsePartType)
                {
                    throw new InvalidSyntaxException("TypeMismatch: true_part is '{0}' and false_part is '{1}'.".Formats(GetTypeString(TruePartType), GetTypeString(FalsePartType)), new FileTextRange {
                        Text = Text, Range = Positions[e]
                    });
                }
                else
                {
                    ReturnType = TruePartType;
                }
                TypeDict.Add(e, ReturnType);
            }
            else if (e.OnAndAlso)
            {
                var Left  = e.AndAlso.Left;
                var Right = e.AndAlso.Right;
                BindExpr(VariableTypeProvider, TypeDict, Left);
                var LeftType = TypeDict[Left];
                if (LeftType != PrimitiveType.Boolean)
                {
                    throw new InvalidSyntaxException("TypeMismatch : 'Boolean' expected.", new FileTextRange {
                        Text = Text, Range = Positions[Left]
                    });
                }
                BindExpr(VariableTypeProvider, TypeDict, Right);
                var RightType = TypeDict[Right];
                if (RightType != PrimitiveType.Boolean)
                {
                    throw new InvalidSyntaxException("TypeMismatch : 'Boolean' expected.", new FileTextRange {
                        Text = Text, Range = Positions[Right]
                    });
                }
                TypeDict.Add(e, PrimitiveType.Boolean);
            }
            else if (e.OnOrElse)
            {
                var Left  = e.OrElse.Left;
                var Right = e.OrElse.Right;
                BindExpr(VariableTypeProvider, TypeDict, Left);
                var LeftType = TypeDict[Left];
                if (LeftType != PrimitiveType.Boolean)
                {
                    throw new InvalidSyntaxException("TypeMismatch : 'Boolean' expected.", new FileTextRange {
                        Text = Text, Range = Positions[Left]
                    });
                }
                BindExpr(VariableTypeProvider, TypeDict, Right);
                var RightType = TypeDict[Right];
                if (RightType != PrimitiveType.Boolean)
                {
                    throw new InvalidSyntaxException("TypeMismatch : 'Boolean' expected.", new FileTextRange {
                        Text = Text, Range = Positions[Right]
                    });
                }
                TypeDict.Add(e, PrimitiveType.Boolean);
            }
            else
            {
                throw new InvalidOperationException();
            }
        }
        private Expr TranslateExpr(SyntaxExpr e)
        {
            Expr m;

            if (e.OnLiteral)
            {
                m = Expr.CreateLiteral(TranslateLiteral(e.Literal.Literal));
            }
            else if (e.OnFunction)
            {
                var Parameters = new LinkedList <Expr>();
                var p          = e.Function.ParameterList;
                if (p.OnNull)
                {
                }
                else if (p.OnNonnull)
                {
                    var n = p.Nonnull.NonnullParameterList;
                    while (true)
                    {
                        if (n.OnSingle)
                        {
                            Parameters.AddFirst(TranslateExpr(n.Single.Expr));
                            break;
                        }
                        else if (n.OnMultiple)
                        {
                            Parameters.AddFirst(TranslateExpr(n.Multiple.Expr));
                            n = n.Multiple.NonnullParameterList;
                        }
                        else
                        {
                            throw new InvalidOperationException();
                        }
                    }
                }
                else
                {
                    throw new InvalidOperationException();
                }
                var Name = e.Function.Identifier.Name;
                if (Name == "if" && Parameters.Count == 3)
                {
                    var ie = new IfExpr {
                        Condition = Parameters.First.Value, TruePart = Parameters.First.Next.Value, FalsePart = Parameters.First.Next.Next.Value
                    };
                    Positions.Add(ie, Positions[e]);
                    m = Expr.CreateIf(ie);
                }
                else
                {
                    var fe = new FunctionExpr {
                        Name = Name, Parameters = Parameters.ToList()
                    };
                    Positions.Add(fe, Positions[e]);
                    m = Expr.CreateFunction(fe);
                }
            }
            else if (e.OnVariable)
            {
                var ve = new VariableExpr {
                    Name = e.Variable.Identifier.Name
                };
                Positions.Add(ve, Positions[e]);
                m = Expr.CreateVariable(ve);
            }
            else if (e.OnParen)
            {
                return(TranslateExpr(e.Paren.Expr));
            }
            else if (e.OnUnaryOperator)
            {
                var fe = new FunctionExpr {
                    Name = e.UnaryOperator.UnaryOperator.Name, Parameters = new List <Expr> {
                        TranslateExpr(e.UnaryOperator.Expr)
                    }
                };
                Positions.Add(fe, Positions[e]);
                m = Expr.CreateFunction(fe);
            }
            else if (e.OnBinaryOperator)
            {
                var Name = e.BinaryOperator.BinaryOperator.Name;
                if (Name == "&&")
                {
                    var aae = new AndAlsoExpr {
                        Left = TranslateExpr(e.BinaryOperator.Left), Right = TranslateExpr(e.BinaryOperator.Right)
                    };
                    Positions.Add(aae, Positions[e]);
                    m = Expr.CreateAndAlso(aae);
                }
                else if (Name == "||")
                {
                    var oee = new OrElseExpr {
                        Left = TranslateExpr(e.BinaryOperator.Left), Right = TranslateExpr(e.BinaryOperator.Right)
                    };
                    Positions.Add(oee, Positions[e]);
                    m = Expr.CreateOrElse(oee);
                }
                else
                {
                    var fe = new FunctionExpr {
                        Name = Name, Parameters = new List <Expr> {
                            TranslateExpr(e.BinaryOperator.Left), TranslateExpr(e.BinaryOperator.Right)
                        }
                    };
                    Positions.Add(fe, Positions[e]);
                    m = Expr.CreateFunction(fe);
                }
            }
            else
            {
                throw new InvalidOperationException();
            }
            Positions.Add(m, Positions[e]);
            return(m);
        }