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; }
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>(); }
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) { }
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>(); }
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); } } } }
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 }); } } } }
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; }