public CapturedVariablesTreeNodeLambdaScope(CapturedVariablesTreeNode parentNode, function_lambda_definition lambdaDef, int scopeNum, syntax_tree_node correspondingSyntaxTreeNode)
     : base(parentNode, scopeNum, correspondingSyntaxTreeNode)
 {
     LambdaDefinition       = lambdaDef;
     CapturedVarsSymbolInfo = new List <SymbolInfo>();
     ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod = null;
 }
示例#2
0
 public CapturedVariablesSubstitutionClassGenerator(CapturedVariablesTreeNode capturedVariablesRootTreeNode)
 {
     _capturedVariablesRootTreeNode = capturedVariablesRootTreeNode;
     _capturedVarsClassDefs         = new Dictionary <int, ScopeClassDefinition>();
     _substitutions             = new Dictionary <SubstitutionKey, dot_node>();
     _lambdasToBeAddedAsMethods = new List <CapturedVariablesTreeNodeLambdaScope>();
 }
        private void CreateNodesForUpperScopesIfExist()
        {
            if (_visitor.context._ctn != null)
            {
                _rootNode        = new CapturedVariablesTreeNodeClassScope(null, _visitor.context._ctn.Scope.ScopeNum, null, _visitor.context._ctn.name);
                _currentTreeNode = _rootNode;

                _scopesCapturedVarsNodesDictionary.Add(_visitor.context._ctn.Scope.ScopeNum, _currentTreeNode);

                _classScope = (CapturedVariablesTreeNodeClassScope)_rootNode;
            }

            if (_visitor.context.func_stack.top() != null)
            {
                var newTreeNode = new CapturedVariablesTreeNodeProcedureScope(_currentTreeNode, _visitor.context.func_stack.top(), _visitor.context.func_stack.top().scope.ScopeNum, null);

                if (_rootNode == null)
                {
                    _rootNode = newTreeNode;
                }
                if (_currentTreeNode != null)
                {
                    _currentTreeNode.ChildNodes.Add(newTreeNode);
                }
                _currentTreeNode = newTreeNode;

                _scopesCapturedVarsNodesDictionary.Add(_visitor.context.func_stack.top().scope.ScopeNum, _currentTreeNode);

                _procedureScope = (CapturedVariablesTreeNodeProcedureScope)_currentTreeNode;
            }
        }
        public override void visit(statement_list stmtList)
        {
            var stl = new statements_list(_visitor.get_location(stmtList),
                                          _visitor.get_location_with_check(stmtList.left_logical_bracket),
                                          _visitor.get_location_with_check(stmtList.right_logical_bracket));

            _visitor.convertion_data_and_alghoritms.statement_list_stack_push(stl);

            var newTreeNode = new CapturedVariablesTreeNodeBlockScope(_currentTreeNode, stl.Scope.ScopeNum, stmtList);

            if (_rootNode == null)
            {
                _rootNode = newTreeNode;
            }
            if (_currentTreeNode != null)
            {
                _currentTreeNode.ChildNodes.Add(newTreeNode);
            }
            _currentTreeNode = newTreeNode;

            _scopesCapturedVarsNodesDictionary.Add(stl.Scope.ScopeNum, _currentTreeNode);

            if (stmtList.subnodes != null)
            {
                foreach (var stmt in stmtList.subnodes)
                {
                    ProcessNode(stmt);
                }
            }

            _visitor.convertion_data_and_alghoritms.statement_list_stack.pop();

            _currentTreeNode = _currentTreeNode.ParentNode;
        }
 protected CapturedVariablesTreeNode(CapturedVariablesTreeNode parentNode, int scopeNum, syntax_tree_node correspondingSyntaxTreeNode)
 {
     ParentNode = parentNode;
     ChildNodes = new List <CapturedVariablesTreeNode>();
     VariablesDefinedInScope = new List <CapturedSymbolInfo>();
     ScopeIndex = scopeNum;
     CorrespondingSyntaxTreeNode = correspondingSyntaxTreeNode;
     LambdasDefinedInScope       = new List <CapturedVariablesTreeNodeLambdaScope>();
 }
示例#6
0
 public ScopeClassDefinition(syntax_tree_node syntaxTreeNode,
                             type_declaration classDeclaration,
                             CapturedVariablesTreeNode correspondingTreeNode,
                             string generatedSubstitutingFieldName = null)
 {
     CorrespondingSyntaxTreeNode     = syntaxTreeNode;
     ClassDeclaration                = classDeclaration;
     _generatedSubstitutingFieldName = generatedSubstitutingFieldName;
     CorrespondingTreeNode           = correspondingTreeNode;
     NestedLambdas = new List <CapturedVariablesTreeNodeLambdaScope>();
 }
        public override void visit(function_lambda_definition lambdaDefinition)
        {
            if (lambdaDefinition.formal_parameters != null && lambdaDefinition.formal_parameters.params_list != null && lambdaDefinition.formal_parameters.params_list.Count != 0)
            {
                var varDefsList = new List <statement>();
                for (var i = 0; i < lambdaDefinition.formal_parameters.params_list.Count; i++)
                {
                    var varType = lambdaDefinition.formal_parameters.params_list[i].vars_type is lambda_inferred_type?
                                  LambdaHelper.ConvertSemanticTypeToSyntaxType((type_node)((lambda_inferred_type)lambdaDefinition.formal_parameters.params_list[i].vars_type).real_type) :
                                      lambdaDefinition.formal_parameters.params_list[i].vars_type;

                    for (var j = 0; j < lambdaDefinition.formal_parameters.params_list[i].idents.idents.Count; j++)
                    {
                        var varName = "<>" + lambdaDefinition.formal_parameters.params_list[i].idents.idents[j].name;
                        var vds     = new var_def_statement(new ident(lambdaDefinition.formal_parameters.params_list[i].idents.idents[j].name), varType);
                        vds.inital_value = new ident(varName);
                        lambdaDefinition.formal_parameters.params_list[i].idents.idents[j].name = varName;
                        varDefsList.Add(new var_statement(vds));
                    }
                }

                ((statement_list)lambdaDefinition.proc_body).subnodes.InsertRange(0, varDefsList);
            }

            var procDecl = LambdaHelper.ConvertLambdaNodeToProcDefNode(lambdaDefinition);

            _visitor.body_exists = true;
            _visitor.hard_node_test_and_visit(procDecl.proc_header);

            var newTreeNode = new CapturedVariablesTreeNodeLambdaScope(_currentTreeNode,
                                                                       lambdaDefinition,
                                                                       _visitor.context.func_stack.top().scope.ScopeNum, lambdaDefinition);

            _currentTreeNode.LambdasDefinedInScope.Add(newTreeNode);
            _currentLambdaScopeNodeStack.Push(newTreeNode);

            if (_currentTreeNode != null)
            {
                _currentTreeNode.ChildNodes.Add(newTreeNode);
            }
            _currentTreeNode = newTreeNode;
            _scopesCapturedVarsNodesDictionary.Add(_currentTreeNode.ScopeIndex, _currentTreeNode);

            VisitProcParameters(procDecl.proc_header.parameters);
            ProcessNode(procDecl.proc_body);

            _visitor.context.leave_block();
            _visitor.context.remove_lambda_function(procDecl.proc_header.name.meth_name.name, false);

            _currentTreeNode = _currentTreeNode.ParentNode;
            _currentLambdaScopeNodeStack.Pop();

            LambdaHelper.RemoveLambdaInfoFromCompilationContext(_visitor.context, lambdaDefinition);
        }
        public CapturedVariablesTreeNodeForScope(CapturedVariablesTreeNode parentNode, int scopeNum, syntax_tree_node correspondingSyntaxTreeNode)
            : base(parentNode, scopeNum, correspondingSyntaxTreeNode)
        {
            var blockScope = parentNode;

            while (!(blockScope is CapturedVariablesTreeNodeBlockScope))
            {
                blockScope = blockScope.ParentNode;
            }

            EnclosedUpperBlockScope = (CapturedVariablesTreeNodeBlockScope)blockScope;
        }
 public CapturedVariablesTreeNodeForEachScope(CapturedVariablesTreeNode parentNode, int scopeNum, syntax_tree_node correspondingSyntaxTreeNode)
     : base(parentNode, scopeNum, correspondingSyntaxTreeNode)
 {
 }
示例#10
0
        private void VisitCapturedVar(CapturedVariablesTreeNode scope, CapturedVariablesTreeNode.CapturedSymbolInfo symbolInfo)
        {
            var varName           = ((IVAriableDefinitionNode)symbolInfo.SymbolInfo.sym_info).name.ToLower();
            var ff                = symbolInfo.SymbolInfo.sym_info.GetType();
            var isSelfWordInClass = scope is CapturedVariablesTreeNodeClassScope && varName == compiler_string_consts.self_word;

            foreach (var referencingLambda in symbolInfo.ReferencingLambdas.OrderByDescending(rl => rl.ScopeIndex))
            {
                if (scope != referencingLambda.ParentNode)
                {
                    var upperScopesStack        = new Stack <CapturedVariablesTreeNode>();
                    var crawlUpScope            = referencingLambda.ParentNode;
                    var anotherLambdaIsOnTheWay = crawlUpScope is CapturedVariablesTreeNodeLambdaScope;

                    while (crawlUpScope != null && crawlUpScope != scope && !anotherLambdaIsOnTheWay)
                    {
                        upperScopesStack.Push(crawlUpScope);
                        crawlUpScope            = crawlUpScope.ParentNode;
                        anotherLambdaIsOnTheWay = crawlUpScope is CapturedVariablesTreeNodeLambdaScope;
                    }

                    if (anotherLambdaIsOnTheWay || crawlUpScope == null)
                    {
                        continue;
                    }

                    var upperScopeWhereVarsAreCaptured      = scope;
                    var upperScopeWhereVarsAreCapturedClass =
                        _capturedVarsClassDefs[upperScopeWhereVarsAreCaptured.ScopeIndex].ClassDeclaration;
                    var ClassName  = upperScopeWhereVarsAreCapturedClass.type_name;
                    var ClassField = symbolInfo.SymbolInfo.sym_info as class_field;

                    var substKey = new SubstitutionKey(varName, symbolInfo.SyntaxTreeNodeWithVarDeclaration,
                                                       scope.CorrespondingSyntaxTreeNode);
                    if (!_substitutions.ContainsKey(substKey))
                    {
                        // SSM 22.10.17 Тут ошибка в случае захвата классовых полей - первый параметр должен быть не self, а имя класса
                        if (ClassField != null && ClassField.IsStatic)
                        {
                            _substitutions.Add(substKey, new dot_node(ClassName, new ident(varName)));// sc не заполнен, что плохо!
                        }
                        else
                        {
                            _substitutions.Add(substKey,
                                               new dot_node(
                                                   new ident(
                                                       _capturedVarsClassDefs[upperScopeWhereVarsAreCaptured.ScopeIndex]
                                                       .GeneratedSubstitutingFieldName), new ident(varName)));
                        }
                    }

                    while (upperScopesStack.Count != 0)
                    {
                        var foundScopeWhereVarsWereCaptured = false;
                        while (upperScopesStack.Count != 0 && !foundScopeWhereVarsWereCaptured)
                        {
                            if (
                                upperScopesStack.Peek()
                                .VariablesDefinedInScope.Exists(var => var.ReferencingLambdas.Count > 0))
                            {
                                foundScopeWhereVarsWereCaptured = true;
                            }
                            else
                            {
                                var curScope = upperScopesStack.Pop();

                                if (upperScopeWhereVarsAreCaptured == scope &&
                                    upperScopeWhereVarsAreCaptured is CapturedVariablesTreeNodeClassScope)
                                {
                                    continue;
                                }

                                substKey = new SubstitutionKey(varName, symbolInfo.SyntaxTreeNodeWithVarDeclaration,
                                                               curScope.CorrespondingSyntaxTreeNode);

                                dot_node dotnode;

                                if (upperScopeWhereVarsAreCaptured != scope)
                                {
                                    dotnode =
                                        new dot_node(
                                            new ident(
                                                _capturedVarsClassDefs[upperScopeWhereVarsAreCaptured.ScopeIndex]
                                                .GeneratedSubstitutingFieldName),
                                            new ident(
                                                _capturedVarsClassDefs[upperScopeWhereVarsAreCaptured.ScopeIndex]
                                                .GeneratedUpperClassFieldName));

                                    var nodeForDotNodeCalc = upperScopeWhereVarsAreCaptured.ParentNode;
                                    while (nodeForDotNodeCalc != scope)
                                    {
                                        if (_capturedVarsClassDefs.ContainsKey(nodeForDotNodeCalc.ScopeIndex) &&
                                            _capturedVarsClassDefs[nodeForDotNodeCalc.ScopeIndex]
                                            .AssignNodeForUpperClassFieldInitialization != null)
                                        {
                                            dotnode = new dot_node(dotnode,
                                                                   new ident(
                                                                       _capturedVarsClassDefs[
                                                                           nodeForDotNodeCalc.ScopeIndex]
                                                                       .GeneratedUpperClassFieldName));
                                        }

                                        nodeForDotNodeCalc = nodeForDotNodeCalc.ParentNode;
                                    }
                                    if (!isSelfWordInClass)
                                    {
                                        dotnode = new dot_node(dotnode, new ident(varName));
                                    }
                                }
                                else
                                {
                                    dotnode = new dot_node(new ident(
                                                               _capturedVarsClassDefs[
                                                                   upperScopeWhereVarsAreCaptured.ScopeIndex]
                                                               .GeneratedSubstitutingFieldName),
                                                           new ident(varName));
                                }

                                if (!_substitutions.ContainsKey(substKey))
                                {
                                    _substitutions.Add(substKey, dotnode);
                                }
                            }
                        }

                        if (foundScopeWhereVarsWereCaptured)
                        {
                            var nextNodeWhereVarsAreCaptured = upperScopesStack.Pop();
                            if (!_capturedVarsClassDefs.ContainsKey(nextNodeWhereVarsAreCaptured.ScopeIndex))
                            {
                                var classDef        = SyntaxTreeBuilder.BuildClassDefinition();
                                var typeDeclaration = new type_declaration(GeneratedClassName, classDef);
                                _capturedVarsClassDefs.Add(nextNodeWhereVarsAreCaptured.ScopeIndex,
                                                           new ScopeClassDefinition(
                                                               nextNodeWhereVarsAreCaptured.CorrespondingSyntaxTreeNode,
                                                               typeDeclaration,
                                                               nextNodeWhereVarsAreCaptured));
                            }

                            var nextNodeWhereVarsAreCapturedClass =
                                (class_definition)
                                _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex].ClassDeclaration
                                .type_def;

                            if (
                                _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex]
                                .AssignNodeForUpperClassFieldInitialization == null)
                            {
                                var fieldType =
                                    SyntaxTreeBuilder.BuildSimpleType(upperScopeWhereVarsAreCapturedClass.type_name.name);
                                var field =
                                    SyntaxTreeBuilder.BuildClassFieldsSection(
                                        new List <ident>
                                {
                                    new ident(
                                        _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex]
                                        .GeneratedUpperClassFieldName)
                                },
                                        new List <type_definition> {
                                    fieldType
                                });

                                nextNodeWhereVarsAreCapturedClass.body.Add(field);

                                _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex]
                                .AssignNodeForUpperClassFieldInitialization =
                                    new assign(
                                        new dot_node(
                                            new ident(
                                                _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex]
                                                .GeneratedSubstitutingFieldName),
                                            new ident(
                                                _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex]
                                                .GeneratedUpperClassFieldName)),
                                        new ident(
                                            _capturedVarsClassDefs[upperScopeWhereVarsAreCaptured.ScopeIndex]
                                            .GeneratedSubstitutingFieldName));
                            }

                            substKey = new SubstitutionKey(varName, symbolInfo.SyntaxTreeNodeWithVarDeclaration,
                                                           nextNodeWhereVarsAreCaptured.CorrespondingSyntaxTreeNode);

                            var dot =
                                new dot_node(
                                    new ident(
                                        _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex]
                                        .GeneratedSubstitutingFieldName),
                                    new ident(
                                        _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex]
                                        .GeneratedUpperClassFieldName));

                            var nodeForDotNodeCalculation = nextNodeWhereVarsAreCaptured.ParentNode;
                            while (nodeForDotNodeCalculation != scope)
                            {
                                if (_capturedVarsClassDefs.ContainsKey(nodeForDotNodeCalculation.ScopeIndex) &&
                                    _capturedVarsClassDefs[nodeForDotNodeCalculation.ScopeIndex]
                                    .AssignNodeForUpperClassFieldInitialization != null)
                                {
                                    dot = new dot_node(dot,
                                                       new ident(
                                                           _capturedVarsClassDefs[nodeForDotNodeCalculation.ScopeIndex]
                                                           .GeneratedUpperClassFieldName));
                                }

                                nodeForDotNodeCalculation = nodeForDotNodeCalculation.ParentNode;
                            }

                            if (!isSelfWordInClass)
                            {
                                dot = new dot_node(dot, new ident(varName));
                            }

                            if (!_substitutions.ContainsKey(substKey))
                            {
                                if (ClassField != null && ClassField.IsStatic)
                                {
                                    _substitutions.Add(substKey, new dot_node(ClassName, new ident(varName)));// sc не заполнен, что плохо!
                                }
                                else
                                {
                                    _substitutions.Add(substKey, dot);
                                }
                            }

                            upperScopeWhereVarsAreCaptured      = nextNodeWhereVarsAreCaptured;
                            upperScopeWhereVarsAreCapturedClass =
                                _capturedVarsClassDefs[upperScopeWhereVarsAreCaptured.ScopeIndex].ClassDeclaration;
                        }
                    }

                    if (!(upperScopeWhereVarsAreCaptured == scope &&
                          upperScopeWhereVarsAreCaptured is CapturedVariablesTreeNodeClassScope))
                    {
                        if (upperScopeWhereVarsAreCaptured != scope)
                        {
                            var dotnode1 = new dot_node(
                                new ident(compiler_string_consts.self_word),
                                new ident(
                                    _capturedVarsClassDefs[upperScopeWhereVarsAreCaptured.ScopeIndex]
                                    .GeneratedUpperClassFieldName));

                            if (upperScopeWhereVarsAreCaptured != scope)
                            {
                                var nodeForDotNodeCalc = upperScopeWhereVarsAreCaptured.ParentNode;
                                while (nodeForDotNodeCalc != scope)
                                {
                                    if (_capturedVarsClassDefs.ContainsKey(nodeForDotNodeCalc.ScopeIndex) &&
                                        _capturedVarsClassDefs[nodeForDotNodeCalc.ScopeIndex]
                                        .AssignNodeForUpperClassFieldInitialization != null)
                                    {
                                        dotnode1 = new dot_node(dotnode1,
                                                                new ident(
                                                                    _capturedVarsClassDefs[nodeForDotNodeCalc.ScopeIndex]
                                                                    .GeneratedUpperClassFieldName));
                                    }

                                    nodeForDotNodeCalc = nodeForDotNodeCalc.ParentNode;
                                }
                            }

                            if (!isSelfWordInClass)
                            {
                                var classScope = scope as CapturedVariablesTreeNodeClassScope;
                                if (classScope != null)
                                {
                                    Tuple <string, class_field, semantic_node> publicProperty;
                                    if (classScope.NonPublicMembersNamesMapping.TryGetValue(varName, out publicProperty))
                                    {
                                        dotnode1 = new dot_node(dotnode1, new ident(publicProperty.Item1));
                                    }
                                    else
                                    {
                                        dotnode1 = new dot_node(dotnode1, new ident(varName));
                                    }
                                }
                                else
                                {
                                    dotnode1 = new dot_node(dotnode1, new ident(varName));
                                }
                            }
                            _lambdaIdReferences.Add(new LambdaReferencesSubstitutionInfo
                            {
                                LambdaScope = referencingLambda,
                                VarName     = varName,
                                SyntaxTreeNodeWithVarDeclaration = symbolInfo.SyntaxTreeNodeWithVarDeclaration,
                                DotNode = dotnode1
                            });
                        }
                        else
                        {
                            var dotnode1 = new dot_node(
                                new ident(compiler_string_consts.self_word),
                                new ident(varName));

                            _lambdaIdReferences.Add(new LambdaReferencesSubstitutionInfo
                            {
                                LambdaScope = referencingLambda,
                                VarName     = varName,
                                SyntaxTreeNodeWithVarDeclaration = symbolInfo.SyntaxTreeNodeWithVarDeclaration,
                                DotNode = dotnode1
                            });
                        }
                    }
                    if (!referencingLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.HasValue ||
                        upperScopeWhereVarsAreCaptured.ScopeIndex >
                        referencingLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod)
                    {
                        referencingLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod =
                            upperScopeWhereVarsAreCaptured.ScopeIndex;
                    }
                }
                else
                {
                    if (!_capturedVarsClassDefs.ContainsKey(scope.ScopeIndex))
                    {
                        var classDef        = SyntaxTreeBuilder.BuildClassDefinition();
                        var typeDeclaration = new type_declaration(GeneratedClassName, classDef);
                        _capturedVarsClassDefs.Add(scope.ScopeIndex,
                                                   new ScopeClassDefinition(
                                                       scope.CorrespondingSyntaxTreeNode,
                                                       typeDeclaration,
                                                       scope));
                    }

                    var substKey = new SubstitutionKey(varName, symbolInfo.SyntaxTreeNodeWithVarDeclaration,
                                                       scope.CorrespondingSyntaxTreeNode);
                    if (!_substitutions.ContainsKey(substKey))
                    {
                        if (!isSelfWordInClass)
                        {
                            string propertyName = null;

                            var classScope = scope as CapturedVariablesTreeNodeClassScope;
                            if (classScope != null)
                            {
                                Tuple <string, class_field, semantic_node> publicProperty;
                                if (classScope.NonPublicMembersNamesMapping.TryGetValue(varName, out publicProperty))
                                {
                                    propertyName = publicProperty.Item1;
                                }
                            }

                            _substitutions.Add(substKey,
                                               new dot_node(
                                                   new ident(
                                                       _capturedVarsClassDefs[scope.ScopeIndex]
                                                       .GeneratedSubstitutingFieldName), new ident(propertyName ?? varName)));
                        }
                    }

                    var dotnode1 = new dot_node(
                        new ident(compiler_string_consts.self_word),
                        new ident(varName));

                    _lambdaIdReferences.Add(new LambdaReferencesSubstitutionInfo
                    {
                        LambdaScope = referencingLambda,
                        VarName     = varName,
                        SyntaxTreeNodeWithVarDeclaration = symbolInfo.SyntaxTreeNodeWithVarDeclaration,
                        DotNode = dotnode1
                    });

                    if (!referencingLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.HasValue ||
                        scope.ScopeIndex > referencingLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod)
                    {
                        referencingLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod = scope.ScopeIndex;
                    }
                }

                if (!_lambdasToBeAddedAsMethods.Contains(referencingLambda))
                {
                    _lambdasToBeAddedAsMethods.Add(referencingLambda);
                }
            }
        }
        public override void visit(for_node _for_node)
        {
            var loc1           = _visitor.get_location(_for_node.loop_variable);
            var loopIdentName  = _for_node.loop_variable.name.ToLower();
            var nodesToProcess = new List <syntax_tree_node>();

            var_definition_node vdn;
            var initv = _visitor.convert_strong(_for_node.initial_value);
            var tmp   = initv;

            if (initv is typed_expression)
            {
                initv = _visitor.convert_typed_expression_to_function_call(initv as typed_expression);
            }

            if (initv.type == null)
            {
                initv = tmp;
            }

            var headStmts = new statements_list(loc1);

            _visitor.convertion_data_and_alghoritms.statement_list_stack_push(headStmts);

            var newTreeNode = new CapturedVariablesTreeNodeForScope(_currentTreeNode, headStmts.Scope.ScopeNum, _for_node);

            if (_currentTreeNode != null)
            {
                _currentTreeNode.ChildNodes.Add(newTreeNode);
            }
            _currentTreeNode = newTreeNode;

            _scopesCapturedVarsNodesDictionary.Add(headStmts.Scope.ScopeNum, _currentTreeNode);


            if (_for_node.type_name == null && !_for_node.create_loop_variable)
            {
                var dn = _visitor.context.check_name_node_type(loopIdentName, loc1, general_node_type.variable_node);
                vdn = (var_definition_node)dn;
                nodesToProcess.Add(_for_node.loop_variable);
            }
            else
            {
                var tn = _for_node.type_name != null?_visitor.convert_strong(_for_node.type_name) : initv.type;

                vdn = _visitor.context.add_var_definition(loopIdentName,
                                                          _visitor.get_location(_for_node.loop_variable), tn,
                                                          polymorphic_state.ps_common);

                _currentTreeNode.VariablesDefinedInScope.Add(new CapturedVariablesTreeNode.CapturedSymbolInfo(_for_node, _visitor.context.find_first(loopIdentName)));
            }


            newTreeNode.SymbolInfoLoopVar = _visitor.context.find_first(loopIdentName);

            var fn = new PascalSharp.Internal.TreeConverter.TreeRealization.for_node(null, null, null, null, null, _visitor.get_location(_for_node));

            if (vdn.type == SystemLibrary.bool_type)
            {
                fn.bool_cycle = true;
            }
            _visitor.context.cycle_stack.push(fn);
            _visitor.context.loop_var_stack.Push(vdn);

            nodesToProcess.Add(_for_node.initial_value);
            nodesToProcess.Add(_for_node.finish_value);
            nodesToProcess.Add(_for_node.increment_value);

            foreach (var n in nodesToProcess)
            {
                ProcessNode(n);
            }

            if (!(_for_node.statements is statement_list))
            {
                var stmtList = new statement_list(_for_node.statements, _for_node.statements.source_context);
                _for_node.statements = stmtList;
            }
            ProcessNode(_for_node.statements);

            _visitor.context.cycle_stack.pop();
            _visitor.context.loop_var_stack.Pop();
            _visitor.convertion_data_and_alghoritms.statement_list_stack.pop();

            _currentTreeNode = _currentTreeNode.ParentNode;
        }
        public override void visit(foreach_stmt _foreach_stmt)
        {
            var loopIdentName = _foreach_stmt.identifier.name.ToLower();

            definition_node     dn  = null;
            var_definition_node vdn = null;

            var sl2 = new statements_list(_visitor.get_location(_foreach_stmt));

            _visitor.convertion_data_and_alghoritms.statement_list_stack_push(sl2);

            var newTreeNode = new CapturedVariablesTreeNodeForEachScope(_currentTreeNode, sl2.Scope.ScopeNum, _foreach_stmt);

            if (_currentTreeNode != null)
            {
                _currentTreeNode.ChildNodes.Add(newTreeNode);
            }
            _currentTreeNode = newTreeNode;

            _scopesCapturedVarsNodesDictionary.Add(sl2.Scope.ScopeNum, _currentTreeNode);

            var inWhat = _visitor.convert_strong(_foreach_stmt.in_what);
            var tmp    = inWhat;

            if (inWhat is typed_expression)
            {
                inWhat = _visitor.convert_typed_expression_to_function_call(inWhat as typed_expression);
            }

            type_node elemType = null;

            if (inWhat.type == null)
            {
                inWhat = tmp;
            }
            bool bb; // здесь bb не нужно. Оно нужно в foreach

            _visitor.FindIEnumerableElementType(/*_foreach_stmt, */ inWhat.type, ref elemType, out bb);

            if (_foreach_stmt.type_name == null)
            {
                var loc1 = _visitor.get_location(_foreach_stmt.identifier);
                dn  = _visitor.context.check_name_node_type(loopIdentName, loc1, general_node_type.variable_node);
                vdn = (var_definition_node)dn;
            }
            else
            {
                vdn = _visitor.context.add_var_definition(loopIdentName, _visitor.get_location(_foreach_stmt.identifier));

                type_node tn;
                if (_foreach_stmt.type_name is no_type_foreach)
                {
                    tn = elemType;
                }
                else
                {
                    tn = _visitor.convert_strong(_foreach_stmt.type_name);
                    _visitor.check_for_type_allowed(tn, _visitor.get_location(_foreach_stmt.type_name));
                }


                _visitor.context.close_var_definition_list(tn, null);

                _currentTreeNode.VariablesDefinedInScope.Add(new CapturedVariablesTreeNode.CapturedSymbolInfo(_foreach_stmt, _visitor.context.find_first(loopIdentName)));
            }

            newTreeNode.SymbolInfoLoopVar = _visitor.context.find_first(loopIdentName);

            if (!(vdn.type is compiled_generic_instance_type_node))
            {
                _visitor.convertion_data_and_alghoritms.check_convert_type_with_inheritance(vdn.type, elemType, _visitor.get_location(_foreach_stmt.identifier));
            }

            var fn = new foreach_node(vdn, inWhat, null, _visitor.get_location(_foreach_stmt));

            _visitor.context.cycle_stack.push(fn);
            _visitor.context.loop_var_stack.Push(vdn);

            ProcessNode(_foreach_stmt.in_what);

            if (!(_foreach_stmt.stmt is statement_list))
            {
                var stmtList = new statement_list(_foreach_stmt.stmt, _foreach_stmt.stmt.source_context);
                _foreach_stmt.stmt = stmtList;
            }

            ProcessNode(_foreach_stmt.stmt);

            _visitor.context.loop_var_stack.Pop();
            _visitor.convertion_data_and_alghoritms.statement_list_stack.pop();
            _visitor.context.cycle_stack.pop();

            _currentTreeNode = _currentTreeNode.ParentNode;
        }
        /*public List<function_lambda_definition> LambdasDefinedInScope
         * {
         *  get;
         *  private set;
         * }*/

        public CapturedVariablesTreeNodeBlockScope(CapturedVariablesTreeNode parentNode, int scopeNum, syntax_tree_node correspondingSyntaxTreeNode)
            : base(parentNode, scopeNum, correspondingSyntaxTreeNode)
        {
            //LambdasDefinedInScope = new List<function_lambda_definition>();
        }
示例#14
0
        private void AddReferencesToIdentInLambda(type_declaration upperScopeWhereVarsAreCapturedClass, CapturedVariablesTreeNode scope, string varName, syntax_tree_node syntaxTreeNodeWithVarDeclaration, dot_node substDotNode, bool nestedLambda)
        {
            for (var i = 0; i < scope.ChildNodes.Count; i++)
            {
                if (!(scope.ChildNodes[i] is CapturedVariablesTreeNodeLambdaScope))
                {
                    var substKey = new SubstitutionKey(varName, syntaxTreeNodeWithVarDeclaration,
                                                       scope.ChildNodes[i].CorrespondingSyntaxTreeNode);

                    if (_capturedVarsClassDefs.ContainsKey(scope.ChildNodes[i].ScopeIndex))
                    {
                        var cl = _capturedVarsClassDefs[scope.ChildNodes[i].ScopeIndex];
                        if (cl.AssignNodeForUpperClassFieldInitialization == null)
                        {
                            var fieldType =
                                SyntaxTreeBuilder.BuildSimpleType(upperScopeWhereVarsAreCapturedClass.type_name.name);
                            var field =
                                SyntaxTreeBuilder.BuildClassFieldsSection(
                                    new List <ident>
                            {
                                new ident(cl.GeneratedUpperClassFieldName)
                            },
                                    new List <type_definition> {
                                fieldType
                            });

                            var clClass = (class_definition)cl.ClassDeclaration.type_def;
                            clClass.body.Add(field);

                            cl.AssignNodeForUpperClassFieldInitialization =
                                new assign(
                                    new dot_node(new ident(cl.GeneratedSubstitutingFieldName), new ident(cl.GeneratedUpperClassFieldName)),
                                    new ident(compiler_string_consts.self_word));
                        }
                    }

                    if (!_substitutions.ContainsKey(substKey))
                    {
                        _substitutions.Add(substKey, substDotNode);
                    }

                    AddReferencesToIdentInLambda(upperScopeWhereVarsAreCapturedClass, scope.ChildNodes[i], varName, syntaxTreeNodeWithVarDeclaration, substDotNode, nestedLambda);
                }
                else
                {
                    var scopeAsLambda = scope.ChildNodes[i] as CapturedVariablesTreeNodeLambdaScope;
                    if (scopeAsLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.HasValue)
                    {
                        dot_node substDotNode1;
                        if (!nestedLambda)
                        {
                            var parts = new Stack <ident>();
                            var dn    = substDotNode;
                            parts.Push((ident)dn.right);

                            while (!(dn.left is ident && dn.right is ident))
                            {
                                dn = (dot_node)dn.left;
                                parts.Push((ident)dn.right);
                            }

                            substDotNode1 = new dot_node(new ident(_capturedVarsClassDefs[scopeAsLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.Value].GeneratedUpperClassFieldName), parts.Pop());
                            while (parts.Count > 0)
                            {
                                substDotNode1 = new dot_node(substDotNode1, parts.Pop());
                            }
                        }
                        else
                        {
                            var parts = new Stack <ident>();
                            var dn    = substDotNode;
                            parts.Push((ident)dn.right);

                            while (!(dn.left is ident && dn.right is ident))
                            {
                                dn = (dot_node)dn.left;
                                parts.Push((ident)dn.right);
                            }

                            parts.Push((ident)dn.left);

                            substDotNode1 = new dot_node(new ident(_capturedVarsClassDefs[scopeAsLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.Value].GeneratedUpperClassFieldName), parts.Pop());

                            while (parts.Count > 0)
                            {
                                substDotNode1 = new dot_node(substDotNode1, parts.Pop());
                            }
                        }

                        var substKey = new SubstitutionKey(varName, syntaxTreeNodeWithVarDeclaration,
                                                           scope.ChildNodes[0].CorrespondingSyntaxTreeNode);
                        if (!_substitutions.ContainsKey(substKey))
                        {
                            _substitutions.Add(substKey, substDotNode1);
                        }

                        AddReferencesToIdentInLambda(_capturedVarsClassDefs[scopeAsLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.Value].ClassDeclaration, scopeAsLambda.ChildNodes[0], varName, syntaxTreeNodeWithVarDeclaration, substDotNode1, true);
                    }
                    else
                    {
                        AddReferencesToIdentInLambda(upperScopeWhereVarsAreCapturedClass, scope.ChildNodes[0], varName, syntaxTreeNodeWithVarDeclaration, substDotNode, nestedLambda);
                    }
                }
            }
        }
示例#15
0
        private void VisitTreeAndBuildClassDefinitions(CapturedVariablesTreeNode currentNode)
        {
            var variablesFromThisScopeWhichWereCaptured = currentNode
                                                          .VariablesDefinedInScope
                                                          .Where(var => var.ReferencingLambdas.Count > 0)
                                                          .ToList();

            if (variablesFromThisScopeWhichWereCaptured.Count > 0)
            {
                if (currentNode is CapturedVariablesTreeNodeClassScope)
                {
                    if (!_capturedVarsClassDefs.ContainsKey(currentNode.ScopeIndex))
                    {
                        var classDef        = SyntaxTreeBuilder.BuildClassDefinition();
                        var typeDeclaration = new type_declaration(((CapturedVariablesTreeNodeClassScope)currentNode).ClassName, classDef);
                        _capturedVarsClassDefs.Add(currentNode.ScopeIndex,
                                                   new ScopeClassDefinition(currentNode.CorrespondingSyntaxTreeNode,
                                                                            typeDeclaration,
                                                                            currentNode,
                                                                            compiler_string_consts.self_word));
                    }
                }
                else
                {
                    if (!_capturedVarsClassDefs.ContainsKey(currentNode.ScopeIndex))
                    {
                        var classDef        = SyntaxTreeBuilder.BuildClassDefinition();
                        var typeDeclaration = new type_declaration(GeneratedClassName, classDef);
                        _capturedVarsClassDefs.Add(currentNode.ScopeIndex,
                                                   new ScopeClassDefinition(currentNode.CorrespondingSyntaxTreeNode,
                                                                            typeDeclaration,
                                                                            currentNode));
                    }


                    var vars = variablesFromThisScopeWhichWereCaptured
                               .Select(field => field.SymbolInfo.sym_info as IVAriableDefinitionNode)
                               .ToList();

                    var fieldNames = vars
                                     .Select(var => new ident(var.name))
                                     .ToList();

                    var fieldTypes = vars
                                     .Select(var => SyntaxTreeBuilder.BuildSemanticType(var.type))
                                     .ToList();

                    var classFields = SyntaxTreeBuilder.BuildClassFieldsSection(fieldNames, fieldTypes);

                    ((class_definition)_capturedVarsClassDefs[currentNode.ScopeIndex].ClassDeclaration.type_def).body
                    .Add(
                        classFields);

                    if (currentNode is CapturedVariablesTreeNodeProcedureScope)
                    {
                        var constructorSection = SyntaxTreeBuilder.BuildSimpleConstructorSection(fieldNames,
                                                                                                 fieldNames.Select(
                                                                                                     id =>
                                                                                                     new ident("_" +
                                                                                                               id.name))
                                                                                                 .ToList(),
                                                                                                 fieldTypes);
                        ((class_definition)_capturedVarsClassDefs[currentNode.ScopeIndex].ClassDeclaration.type_def)
                        .body.Add(constructorSection);
                    }
                }

                foreach (var capturedVar in variablesFromThisScopeWhichWereCaptured)
                {
                    VisitCapturedVar(currentNode, capturedVar);
                }
            }

            foreach (CapturedVariablesTreeNode childNode in currentNode.ChildNodes)
            {
                VisitTreeAndBuildClassDefinitions(childNode);
            }

            if (variablesFromThisScopeWhichWereCaptured.Count > 0)
            {
                var vars = variablesFromThisScopeWhichWereCaptured
                           .Select(x =>
                                   new
                {
                    IVarDefinitionNode = x.SymbolInfo.sym_info as IVAriableDefinitionNode,
                    VarDeclNode        = x.SyntaxTreeNodeWithVarDeclaration
                })
                           .Where(x => x.IVarDefinitionNode != null)
                           .ToList();

                foreach (var var in vars)
                {
                    foreach (CapturedVariablesTreeNode childNode in currentNode.ChildNodes)
                    {
                        _rewriteReferencesForNodesThatAreChildNodesToThoseThatContainCapturedVariableInfo.Add(
                            new RewriteReferencesForNodesThatAreChildNodesToThoseThatContainCapturedVariableInfo
                        {
                            TreeNode        = childNode,
                            Varname         = var.IVarDefinitionNode.name,
                            NodeWithVarDecl = var.VarDeclNode
                        });
                    }
                }
            }
        }
示例#16
0
        private void RewriteReferencesForNodesThatAreChildNodesToThoseThatContainCapturedVariable(CapturedVariablesTreeNode node, string varName, syntax_tree_node nodeWithVarDecl)
        {
            if (node is CapturedVariablesTreeNodeLambdaScope)
            {
                RewriteReferencesForNodesThatAreChildNodesToThoseThatContainCapturedVariable(node.ChildNodes[0], varName, nodeWithVarDecl);
                return;
            }

            if (!(node is CapturedVariablesTreeNodeBlockScope ||
                  node is CapturedVariablesTreeNodeForScope ||
                  node is CapturedVariablesTreeNodeForEachScope))
            {
                return;
            }

            var substKey = new SubstitutionKey(varName, nodeWithVarDecl, node.CorrespondingSyntaxTreeNode);

            if (!_substitutions.ContainsKey(substKey))
            {
                var             parentNode       = node.ParentNode;
                var             isReferenceFound = false;
                SubstitutionKey parentSubstKey   = null;

                while (parentNode != null && !isReferenceFound)
                {
                    parentSubstKey = new SubstitutionKey(varName, nodeWithVarDecl, parentNode.CorrespondingSyntaxTreeNode);
                    if (_substitutions.ContainsKey(parentSubstKey))
                    {
                        isReferenceFound = true;
                    }
                    else
                    {
                        parentNode = parentNode.ParentNode;
                    }
                }

                if (isReferenceFound)
                {
                    _substitutions.Add(substKey, _substitutions[parentSubstKey]);
                }
            }
            foreach (CapturedVariablesTreeNode childNode in node.ChildNodes)
            {
                RewriteReferencesForNodesThatAreChildNodesToThoseThatContainCapturedVariable(childNode, varName, nodeWithVarDecl);
            }
        }
 public CapturedVariablesTreeNodeClassScope(CapturedVariablesTreeNode parentNode, int scopeNum, syntax_tree_node correspondingSyntaxTreeNode, string className)
     : base(parentNode, scopeNum, correspondingSyntaxTreeNode)
 {
     NonPublicMembersNamesMapping = new Dictionary <string, Tuple <string, class_field, semantic_node> >();
     ClassName = className;
 }
 public CapturedVariablesTreeNodeProcedureScope(CapturedVariablesTreeNode parentNode, common_function_node function, int scopeNum, syntax_tree_node correspondingSyntaxTreeNode)
     : base(parentNode, scopeNum, correspondingSyntaxTreeNode)
 {
     FunctionNode = function;
 }