Exemplo n.º 1
0
        private IfsType Analyse(ITree node, fsScope scope)
        {
            IfsType nodeType = null;

            if (inferenceFunctions.ContainsKey(node.Type))
            {
                nodeType = inferenceFunctions[node.Type](node, scope);
                ITree childTypeNode = GetChildByType(node, fsharp_ssParser.TYPE);

                if (childTypeNode != null)
                {
                    node.DeleteChild(GetChildIndexByType(node, fsharp_ssParser.TYPE));
                }

                fsTreeNode typeNameNode = new fsTreeNode(nodeType);
                fsScope.ScopeVarOrFuncTypeChanged += typeNameNode.ScopeVarOrFuncTypeChangedHandler;
                node.AddChild(typeNameNode);
            }
            else
            {
                throw new Exception($"Can`t infer type for node: {node.Text}");
            }

            return nodeType;
        }
Exemplo n.º 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;
        }
Exemplo n.º 3
0
        private IfsType InferIDType(ITree node, fsScope scope)
        {
            IfsType type = scope.GetFunctionType(node.Text) ?? scope.GetVarType(node.Text);
            if (type == null)
            {
                throw new Exception($"Undeclared variable: {node.Text}");
            }

            if (type is fsTypeVar)
            {
                (type as fsTypeVar).IsFromScope = true;
                (type as fsTypeVar).ScopeVarName = node.Text;
            }

            if (GetChildByType(node, VAR_INFO) == null)
            {
                fsTreeNode typeNode = new fsTreeNode(scope.GetVarInfo(node.Text, false));
                node.AddChild(typeNode);
            }

            return type;
        }
Exemplo n.º 4
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;
        }