Пример #1
0
        private IfsType InferFunctionDefnType(ITree node, fsScope scope)
        {
            fsScope innerScope = new fsScope(scope);

            List<IfsType> functionTypes = new List<IfsType>();

            string funcName = GetChildByType(node, fsharp_ssParser.NAME).GetChild(0).Text;

            ITree args = GetChildByType(node, fsharp_ssParser.ARGS);
            List<string> argsNames = new List<string>();

            for (int i = 0; i < args.ChildCount; i++)
            {
                ITree arg = args.GetChild(i);

                IfsType argType;
                if (arg.ChildCount > 0)
                {
                    ITree annotatedArgTypeNode = arg.GetChild(0);
                    argType = new fsType(annotatedArgTypeNode.Text, null);
                }
                else
                {
                    argType = new fsTypeVar();
                }

                argsNames.Add(arg.Text);
                innerScope.AddVar(arg.Text, argType);
                innerScope.SetVarInfo(arg.Text, ScopePositionType.functionArg);
            }

            fsDerFuncInfo funcInfo = new fsDerFuncInfo(funcName, argsNames, 0, 0,
                enteredFunctionsNames[enteredFunctionsNames.Count - 1]);
            if (funcName != "main")
            {
                enteredFunctionsNames.Add(funcName);
            }
            functionsInfos.Add(funcName, funcInfo);
            node.AddChild(new fsTreeNode(funcInfo));
            if (GetChildByType(node, fsharp_ssParser.REC) != null)
            {
                innerScope.AddFunction(funcName, fsType.GetIdentityType(innerScope, argsNames));
                innerScope.SetVarInfo(funcName, ScopePositionType.functionClass);
            }

            IfsType bodyType = Analyse(GetChildByType(node, fsharp_ssParser.BODY), innerScope);

            ITree annotatedReturningTypeNode = GetChildByType(node, fsharp_ssParser.TYPE);
            if (annotatedReturningTypeNode != null && annotatedReturningTypeNode.ChildCount > 0)
            {
                IfsType annotatedReturningType = new fsType(annotatedReturningTypeNode.GetChild(0).Text, null);
                UnifyWrapper(ref bodyType, ref annotatedReturningType, innerScope);
            }

            for (int i = 0; i < argsNames.Count; i++)
            {
                functionTypes.Add(innerScope.GetVarType(argsNames[i]));
            }
            functionTypes.Add(bodyType);
            fsType functionType = fsType.GetFunctionType(functionTypes);

            enteredFunctionsNames.RemoveAt(enteredFunctionsNames.Count - 1);
            return functionType;
        }
Пример #2
0
        private IfsType InferBodyType(ITree node, fsScope scope)
        {
            IfsType exprType = null;

            for (int i = 0; i < node.GetChild(0).ChildCount; i++)
            {
                ITree childNode = node.GetChild(0).Text == "elif" ? node.GetChild(0) : node.GetChild(0).GetChild(i);
                ITree funcNameNode = null;
                bool isLambda = false;

                if (childNode.Type == fsharp_ssParser.FUNCTION_DEFN)
                {
                    funcNameNode = GetChildByType(childNode, fsharp_ssParser.NAME);
                    if (funcNameNode == null)
                    {
                        isLambda = true;
                        funcNameNode = new fsTreeNode("NAME", fsharp_ssParser.NAME);
                        funcNameNode.AddChild(new fsTreeNode(GetUniqueFunctionName()));
                        childNode.AddChild(funcNameNode);
                    }
                }

                exprType = Analyse(childNode, scope);

                if (childNode.Type == fsharp_ssParser.FUNCTION_DEFN)
                {
                    scope.AddFunction(funcNameNode.GetChild(0).Text, exprType);
                    scope.SetVarInfo(funcNameNode.GetChild(0).Text, ScopePositionType.functionClass);

                    if (isLambda)
                    {
                        fsTreeNode lambdaCall = new fsTreeNode("FUNCTION_CALL", fsharp_ssParser.FUNCTION_CALL);
                        fsTreeNode lambdaCallArgs = new fsTreeNode("ARGS", fsharp_ssParser.ARGS);
                        lambdaCall.AddChild(funcNameNode);
                        lambdaCall.AddChild(lambdaCallArgs);
                        node.GetChild(0).AddChild(lambdaCall);
                    }
                }
                else if (childNode.Type == fsharp_ssParser.VALUE_DEFN)
                {
                    string varName = GetChildByType(childNode, fsharp_ssParser.NAME).GetChild(0).Text;
                    scope.AddVar(varName, exprType);
                    scope.SetVarInfo(varName, ScopePositionType.local);
                }
            }

            if (exprType == null)
            {
                throw new Exception("Cannot recognize body type");
            }

            return exprType;
        }