예제 #1
0
        private IfsType InferValueDefnType(ITree node, fsScope scope)
        {
            derFunction = null;
            IfsType bodyType = Analyse(GetChildByType(node, fsharp_ssParser.BODY), scope);

            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, scope);
            }

            if (bodyType.Name == "function")
            {
                node.AddChild(new fsTreeNode(derFunction));
                varDerFuncTable.Add(GetChildByType(node, fsharp_ssParser.NAME).GetChild(0).Text, derFunction);
            }

            return bodyType;
        }
예제 #2
0
        private IfsType InferFuncCallType(ITree node, fsScope scope)
        {
            List<IfsType> factualArgsTypes = new List<IfsType>();

            string callFunctionName = GetChildByType(node, fsharp_ssParser.NAME).GetChild(0).Text;
            ITree args = GetChildByType(node, fsharp_ssParser.ARGS);

            for (int i = 0; i < args.ChildCount; i++)
            {
                ITree currentArg = args.GetChild(i);
                IfsType argType = Analyse(currentArg, scope);

                //if (argType is fsTypeVar)
                //{
                //    if (!(currentArg is fsTreeNode))
                //    {
                //        currentArg = new fsTreeNode(argType);
                //    }
                //    fsScope.ScopeVarOrFuncTypeChanged += (args.GetChild(i) as fsTreeNode).ScopeVarOrFuncTypeChangedHandler;
                //}

                factualArgsTypes.Add(argType);
            }

            if (scope.GetVarInfo(callFunctionName, false).PositionInScopeType == ScopePositionType.functionArg)
            {
                fsTreeNode typeFANode = new fsTreeNode(scope.GetVarInfo(callFunctionName, false));
                node.AddChild(typeFANode);
                List<string> argsNames = new List<string>();
                for (int i = 0; i < args.ChildCount; i++)
                {
                    argsNames.Add(args.GetChild(i).Text);
                }
                fsDerFuncInfo faDerFuncInfo = new fsDerFuncInfo(callFunctionName, argsNames,
                    0, argsNames.Count, null);
                node.AddChild(new fsTreeNode(faDerFuncInfo));
                return scope.GetVarType(callFunctionName);
            }

            if (callFunctionName.Length >= "printf".Length &&
                callFunctionName.Substring(0, "printf".Length) == "printf")
            {
                callFunctionName += $"_{uniqueFuctionId++}";
                functionsInfos.Add(callFunctionName, functionsInfos["printf"]);
                scope.AddFunction(callFunctionName, fsType.GetFunctionType(factualArgsTypes));
                scope.SetVarInfo(callFunctionName, ScopePositionType.functionClass);
            }

            IfsType formalFunctionType = scope.GetFunctionType(callFunctionName);
            if (formalFunctionType == null)
            {
                formalFunctionType = scope.GetVarType(callFunctionName);
            }

            if (formalFunctionType == null)
            {
                throw new Exception($"Undeclared function: {callFunctionName}");
            }

            IfsType returningType = (formalFunctionType as fsType).Types[(formalFunctionType as fsType).Types.Count - 1];
            factualArgsTypes.Add(returningType);
            IfsType factualFunctionType = fsType.GetFunctionType(factualArgsTypes);

            UnifyWrapper(ref factualFunctionType, ref formalFunctionType, scope);
            returningType = (formalFunctionType as fsType).Types[(formalFunctionType as fsType).Types.Count - 1];

            fsDerFuncInfo oldFuncInfo;
            if (functionsInfos.ContainsKey(callFunctionName))
            {
                oldFuncInfo = functionsInfos[callFunctionName];
            }
            else
            {
                oldFuncInfo = varDerFuncTable[callFunctionName];
            }

            derFunction = new fsDerFuncInfo(oldFuncInfo.Name,
                                            new List<string>(oldFuncInfo.ArgsNames),
                                            oldFuncInfo.BeforePassedArgsNum,
                                            oldFuncInfo.AfterPassedArgsNum,
                                            oldFuncInfo.ContextFuncName);

            if (callFunctionName.Length < "printf".Length ||
                callFunctionName.Substring(0, "printf".Length) != "printf")
            {
                derFunction.BeforePassedArgsNum = derFunction.AfterPassedArgsNum;
                derFunction.AfterPassedArgsNum += args.ChildCount;
            }

            node.AddChild(new fsTreeNode(derFunction));

            fsTreeNode typeNode = new fsTreeNode(scope.GetVarInfo(callFunctionName, false));
            node.AddChild(typeNode);

            return returningType;
        }
예제 #3
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;
        }
예제 #4
0
 public fsTreeNode(fsDerFuncInfo dfi)
     : base(new CommonToken(66, ""))
 {
     this.Text = "DER_FUNC_INFO";
     DerFuncInfo = dfi;
 }