public override void visit(SyntaxTree.class_members _class_members) { foreach (var def in _class_members.members.Where(d => d is const_definition || d is consts_definitions_list || d is variable_definitions || d is var_def_statement)) { var lambdaSearcher = new LambdaSearcher(def); if (lambdaSearcher.CheckIfContainsLambdas()) { AddError(new LambdasNotAllowedInFieldsInitialization(get_location(lambdaSearcher.FoundLambda))); } } weak_node_test_and_visit(_class_members.access_mod); foreach (SyntaxTree.declaration sd in _class_members.members) { hard_node_test_and_visit(sd); } }
public override void visit(SyntaxTree.interface_node _interface_node) { if (_interface_node.interface_definitions != null && _interface_node.interface_definitions.defs != null) { foreach (var def in _interface_node.interface_definitions.defs.Where(d => d is const_definition || d is consts_definitions_list || d is variable_definitions)) { var lambdaSearcher = new LambdaSearcher(def); if (lambdaSearcher.CheckIfContainsLambdas()) { AddError(new LambdasNotAllowedInInterfacePartOfModuleInInit(get_location(lambdaSearcher.FoundLambda))); } } } weak_node_test_and_visit(_interface_node.interface_definitions); }
public void visit_implementation(SyntaxTree.unit_module _unit_module) { if (_unit_module.initialization_part != null) { var lambdaSearcher = new LambdaSearcher(_unit_module.initialization_part); if (lambdaSearcher.CheckIfContainsLambdas()) { AddError(new LambdasNotAllowedInInitializationPartOfModule(get_location(lambdaSearcher.FoundLambda))); } } if (_unit_module.finalization_part != null) { var lambdaSearcher = new LambdaSearcher(_unit_module.finalization_part); if (lambdaSearcher.CheckIfContainsLambdas()) { AddError(new LambdasNotAllowedInFinalizationPartOfModule(get_location(lambdaSearcher.FoundLambda))); } } //using_list.AddRange(implementation_using_list); /*if (_unit_module.implementation_part != null) { weak_node_test_and_visit(_unit_module.implementation_part.using_namespaces); }*/ SymbolTable.Scope[] used_units = build_referenced_units(referenced_units,false); _compiled_unit.implementation_scope = convertion_data_and_alghoritms.symbol_table.CreateUnitImplementationScope(_compiled_unit.scope, used_units); location loc = null; if (_unit_module.unit_name != null) { loc = get_location(_unit_module.unit_name); } common_namespace_node cnsn = context.create_namespace(_unit_module.unit_name.idunit_name.name + compiler_string_consts.ImplementationSectionNamespaceName, _compiled_unit, _compiled_unit.implementation_scope, loc); //cnsn.scope=_compiled_unit.implementation_scope; if (_unit_module.implementation_part != null) { hard_node_test_and_visit(_unit_module.implementation_part); } //weak_node_test_and_visit(_unit_module.initialization_part); context.enter_code_block_without_bind(); statement_node init_statements = convert_weak(_unit_module.initialization_part); context.leave_code_block(); common_namespace_function_node initialization_function = null; if (init_statements != null) { context.check_labels(context.converted_namespace.labels); //(ssyy) Блокируем поставленные метки, чтобы не допустить переход из finalization-секции //context.block_defined_labels(context.converted_namespace.labels); initialization_function = new common_namespace_function_node(compiler_string_consts.initialization_function_name, null, init_statements.location, context.converted_namespace, convertion_data_and_alghoritms.symbol_table.CreateScope(context.converted_namespace.scope)); initialization_function.function_code = init_statements; cnsn.functions.AddElement(initialization_function); _compiled_unit.main_function = initialization_function; context.apply_special_local_vars(_compiled_unit.main_function); } context.enter_code_block_without_bind(); statement_node final_statements = convert_weak(_unit_module.finalization_part); context.leave_code_block(); common_namespace_function_node finalization_function = null; if (final_statements != null) { context.check_labels(context.converted_namespace.labels); finalization_function = new common_namespace_function_node(compiler_string_consts.finalization_function_name, null, final_statements.location, context.converted_namespace, convertion_data_and_alghoritms.symbol_table.CreateScope(context.converted_namespace.scope)); finalization_function.function_code = final_statements; cnsn.functions.AddElement(finalization_function); _compiled_unit.finalization_method = finalization_function; context.apply_special_local_vars(_compiled_unit.finalization_method); } context.check_all_name_unit_defined(_compiled_unit); }
public override void visit(SyntaxTree.block _block) { if (context.converting_block() != block_type.namespace_block && _block.defs != null && _block.defs.defs != null) { foreach (var def in _block.defs.defs.Where(d => d is const_definition || d is consts_definitions_list || d is variable_definitions)) { var lambdaSearcher = new LambdaSearcher(def); if (lambdaSearcher.CheckIfContainsLambdas()) { AddError(new LambdasNotAllowedInDeclarationsSection(get_location(lambdaSearcher.FoundLambda))); // SSM 6.06.15 - Хочется убрать это. В разделе описаний лямбды нужны - пусть и без замыканий. Если внутри подпрограммы - не нужны, но Вы же запретили везде! } } } weak_node_test_and_visit(_block.defs); //ssyy добавил генерацию вызова конструктора предка без параметров if (context.converting_block() == block_type.function_block) { common_method_node cmn = context.top_function as common_method_node; if (cmn != null && cmn.is_constructor && !(cmn.polymorphic_state == SemanticTree.polymorphic_state.ps_static)) { context.allow_inherited_ctor_call = true; if (_block.program_code != null && _block.program_code.subnodes != null) { //(ssyy) Для записей конструктор предка не вызываем. bool should_ctor_add = context.converted_type.is_class; if (should_ctor_add) { if (_block.program_code.subnodes.Count > 0) { SyntaxTree.procedure_call pc = _block.program_code.subnodes[0] as SyntaxTree.procedure_call; if (pc != null || _block.program_code.subnodes[0] is SyntaxTree.inherited_message) { //SyntaxTree.inherited_ident ii = pc.func_name as SyntaxTree.inherited_ident; //SyntaxTree.method_call mc = pc.func_name as SyntaxTree.method_call; //SyntaxTree.ident id = pc.func_name as SyntaxTree.ident; //if (/*ii != null*/id != null || mc != null /*&& mc.dereferencing_value is SyntaxTree.inherited_ident*/) { //(ssyy) Не уверен, что следующий оператор необходим. convertion_data_and_alghoritms.check_node_parser_error(_block.program_code); statement_node inh = convert_strong(_block.program_code.subnodes[0]); compiled_constructor_call c1 = inh as compiled_constructor_call; if (c1 != null && !c1._new_obj_awaited) { should_ctor_add = false; } else { common_constructor_call c2 = inh as common_constructor_call; if (c2 != null && !c2._new_obj_awaited) { should_ctor_add = false; } } } } } } if (should_ctor_add) { //Пытаемся добавить вызов .ctor() предка... //Для начала проверим, есть ли у предка таковой. bool not_found = true; SymbolInfo sym = context.converted_type.base_type.find_in_type(compiler_string_consts.default_constructor_name, context.CurrentScope); while (not_found && sym != null) { compiled_constructor_node ccn = sym.sym_info as compiled_constructor_node; if (ccn != null && ccn.parameters.Count == 0) { not_found = false; } else { common_method_node cnode = sym.sym_info as common_method_node; if (cnode != null && cnode.is_constructor && (cnode.parameters.Count == 0 || cnode.parameters[0].default_value != null)) { not_found = false; } } sym = sym.Next; } if (not_found) { //У предка нет конструктора по умолчанию AddError(get_location(_block.program_code), "INHERITED_CONSTRUCTOR_CALL_EXPECTED"); } else { //Генерируем вызов .ctor() предка SyntaxTree.inherited_ident ii = new SyntaxTree.inherited_ident(); ii.name = compiler_string_consts.default_constructor_name; _block.program_code.subnodes.Insert(0, new SyntaxTree.procedure_call(ii)); //context.allow_inherited_ctor_call = false; } } } } } //\ssyy //ssyy if (context.converting_block() == block_type.namespace_block) { context.check_predefinition_defined(); } if (lambdaProcessingState == LambdaProcessingState.None && _block.program_code != null) { var lambdaSearcher = new LambdaSearcher(_block.program_code); var lambdaIsFound = lambdaSearcher.CheckIfContainsLambdas(); if ((context.converting_block() == block_type.function_block || context.converting_block() == block_type.namespace_block) && lambdaIsFound) // TODO: Пока обрабатываются только блок функции и основной блок, необходимо обрабатывать случаи появлений лямбд в var_def_statement { if (context.converting_block() == block_type.function_block) { if (context.func_stack.top().functions_nodes_list.Count > 0) { AddError(new LambdasNotAllowedWhenNestedSubprogrammesAreUsed(get_location(lambdaSearcher.FoundLambda))); } } lambdaProcessingState = LambdaProcessingState.TypeInferencePhase; visit_program_code(_block.program_code); lambdaProcessingState = LambdaProcessingState.ClosuresProcessingPhase; CapturedVariablesSubstitutionsManager.Substitute(this, _block.defs, _block.program_code); lambdaProcessingState = LambdaProcessingState.FinishPhase; context.code = visit_program_code(_block.program_code); lambdaProcessingState = LambdaProcessingState.None; } else { context.code = visit_program_code(_block.program_code); } } else { context.code = visit_program_code(_block.program_code); } }
public override void visit(SyntaxTree.foreach_stmt _foreach_stmt) { var lambdaSearcher = new LambdaSearcher(_foreach_stmt.in_what); if (lambdaSearcher.CheckIfContainsLambdas()) { AddError(new LambdasNotAllowedInForeachInWhatSatetement(get_location(lambdaSearcher.FoundLambda))); } //throw new NotSupportedError(get_location(_foreach_stmt)); definition_node dn = null; var_definition_node vdn = null; statements_list sl2 = new statements_list(get_location(_foreach_stmt)); convertion_data_and_alghoritms.statement_list_stack_push(sl2); expression_node in_what = convert_strong(_foreach_stmt.in_what); expression_node tmp = in_what; if (in_what is typed_expression) in_what = convert_typed_expression_to_function_call(in_what as typed_expression); type_node elem_type = null; if (in_what.type == null) in_what = tmp; //if (in_what.type.find_in_type("GetEnumerator") == null) if (!FindIEnumerableElementType(_foreach_stmt, in_what.type, ref elem_type)) //if (!IsGetEnumerator(in_what.type, ref elem_type)) AddError(in_what.location, "CAN_NOT_EXECUTE_FOREACH_BY_EXPR_OF_TYPE_{0}", in_what.type.name); if (_foreach_stmt.type_name == null) { location loc1 = get_location(_foreach_stmt.identifier); dn = context.check_name_node_type(_foreach_stmt.identifier.name, loc1, general_node_type.variable_node); vdn = (var_definition_node)dn; if (!check_name_in_current_scope(_foreach_stmt.identifier.name)) AddError(loc1, "FOREACH_LOOP_CONTROL_MUST_BE_SIMPLE_LOCAL_VARIABLE"); } else { //AddError(new NotSupportedError(get_location(_foreach_stmt.type_name))); vdn = context.add_var_definition(_foreach_stmt.identifier.name, get_location(_foreach_stmt.identifier)); type_node tn; if (_foreach_stmt.type_name is SyntaxTree.no_type_foreach) { tn = elem_type; } else { tn = convert_strong(_foreach_stmt.type_name); //if (tn == SystemLibrary.SystemLibrary.void_type) // AddError(new VoidNotValid(get_location(_foreach_stmt.type_name))); check_for_type_allowed(tn, get_location(_foreach_stmt.type_name)); } context.close_var_definition_list(tn, null); } //elem_type = vdn.type; if (!(vdn.type is compiled_generic_instance_type_node)) convertion_data_and_alghoritms.check_convert_type_with_inheritance(vdn.type, elem_type, get_location(_foreach_stmt.identifier)); //if (!convertion_data_and_alghoritms.eq_type_nodes(elem_type, vdn.type)) //AddError(new TypesOfVarAndElementsInForeachMustBeEqual(vdn.type.name,elem_type.name,get_location(_foreach_stmt.identifier))); //AddError(new SimpleSemanticError("Тип элемента контейнера: " + elem_type.ToString() + " Тип переменной foreach: " + vdn.type.ToString(), get_location(_foreach_stmt.identifier))); //convertion_data_and_alghoritms.check_convert_type_with_inheritance(vdn.type, elem_type, get_location(_foreach_stmt.identifier)); //if (in_what.type.type_special_kind == SemanticTree.type_special_kind.set_type) /*{ if (!convertion_data_and_alghoritms.eq_type_nodes(elem_type, vdn.type)) { possible_type_convertions ptc = type_table.get_convertions(vdn.type,elem_type); if (ptc.first == null || ptc.first.is_explicit) if (vdn.node_location_kind == SemanticTree.node_location_kind.in_namespace_location) throw new CanNotConvertTypes(new namespace_variable_reference(vdn as namespace_variable, get_location(_foreach_stmt.identifier)), vdn.type, elem_type, get_location(_foreach_stmt.identifier)); else if (vdn.node_location_kind == SemanticTree.node_location_kind.in_function_location) throw new CanNotConvertTypes(new local_variable_reference(vdn as local_variable, 0, get_location(_foreach_stmt.identifier)), vdn.type, elem_type, get_location(_foreach_stmt.identifier)); else if (vdn.node_location_kind == SemanticTree.node_location_kind.in_block_location) throw new CanNotConvertTypes(new local_block_variable_reference(vdn as local_block_variable,get_location(_foreach_stmt.identifier)),vdn.type,elem_type, get_location(_foreach_stmt.identifier)); else throw new ForeachLoopControlMustBeSimpleLocalVariable(get_location(_foreach_stmt.identifier)); } }*/ statements_list sl = new statements_list(get_location(_foreach_stmt.stmt)); convertion_data_and_alghoritms.statement_list_stack_push(sl); CheckToEmbeddedStatementCannotBeADeclaration(_foreach_stmt.stmt); foreach_node fn = new foreach_node(vdn, in_what, null, get_location(_foreach_stmt)); context.cycle_stack.push(fn); context.loop_var_stack.Push(vdn); context.enter_code_block_with_bind(); statement_node body = convert_strong(_foreach_stmt.stmt); context.leave_code_block(); context.loop_var_stack.Pop(); sl = convertion_data_and_alghoritms.statement_list_stack.pop(); //if (!(st is statements_list)) if (sl.statements.Count > 0 || sl.local_variables.Count > 0) { sl.statements.AddElement(body); body = sl; } //CheckToEmbeddedStatementCannotBeADeclaration(_foreach_stmt.stmt); //statement_node body = convert_strong(_foreach_stmt.stmt); //foreach_node fn = new foreach_node(vdn, in_what, body, get_location(_foreach_stmt)); fn.what_do = body; //statements_list sl2 = new statements_list(get_location(_foreach_stmt)); convertion_data_and_alghoritms.statement_list_stack.pop(); sl2.statements.AddElement(fn); context.cycle_stack.pop(); //if (_foreach_stmt.type_name != null) //sl2.local_variables.Add(vdn as local_block_variable); return_value(sl2); }
public override void visit(SyntaxTree.foreach_stmt _foreach_stmt) { var lambdaSearcher = new LambdaSearcher(_foreach_stmt.in_what); if (lambdaSearcher.CheckIfContainsLambdas()) { AddError(new LambdasNotAllowedInForeachInWhatSatetement(get_location(lambdaSearcher.FoundLambda))); } expression_node in_what = convert_strong(_foreach_stmt.in_what); // SSM 29.07.16 - если in_what - одномерный массив, то заменить код foreach на for var is1dimdynarr = false; var comptn = in_what.type as compiled_type_node; if (comptn != null && comptn.type_special_kind == SemanticTree.type_special_kind.array_kind && comptn.rank == 1) { is1dimdynarr = true; } if (!is1dimdynarr) { var comtn = in_what.type as common_type_node; if (comtn != null && comtn.internal_type_special_kind == SemanticTree.type_special_kind.array_kind && comtn.rank == 1) { is1dimdynarr = true; } } /* SSM 23.08.16 Закомментировал оптимизацию. Не работает с лямбдами. Лямбды обходят старое дерево. А заменить foreach на for на этом этапе пока не получается - не развита инфраструктура * * if (is1dimdynarr) // Замена foreach на for для массива { // сгенерировать код для for и вызвать соответствующий visit var arrid = GenIdentName(); var vdarr = new var_statement(arrid, new semantic_addr_value(in_what)); // semantic_addr_value - перевод в синтаксис для мгновенного вычисления семантического выражения, которое уже вычислено в in_what var i = GenIdentName(); var x = _foreach_stmt.identifier; // Возможны 3 случая: // 1. _foreach_stmt.type_name = null - значит, переменная определена в другом месте // 2. _foreach_stmt.type_name = no_type_foreach - значит, это for var x in a // 3. _foreach_stmt.type_name = T - значит, это for var x: T in a statement vd; if (_foreach_stmt.type_name == null) // 1. vd = new assign(x, arrid.indexer(i)); else if (_foreach_stmt.type_name is no_type_foreach) // 2. vd = new var_statement(x, arrid.indexer(i)); else // 3. vd = new var_statement(x,_foreach_stmt.type_name, arrid.indexer(i)); // Превратить старое тело в statement_list и добавить к нему в начало x := a[i] или var x := a[i] var newbody = _foreach_stmt.stmt.ToStatementList(); newbody.AddFirst(vd); var high = arrid.dot_node("Length").Minus(1); var fornode = new SyntaxTree.for_node(i, 0, high, newbody, for_cycle_type.to, null, null, true); //var stl = new SyntaxTree.statement_list(vdarr, fornode); //Replace(_foreach_stmt, stl); visit(vdarr); visit(fornode); return; }*/ /// SSM 29.07.16 //throw new NotSupportedError(get_location(_foreach_stmt)); definition_node dn = null; var_definition_node vdn = null; statements_list sl2 = new statements_list(get_location(_foreach_stmt)); convertion_data_and_alghoritms.statement_list_stack_push(sl2); expression_node tmp = in_what; if (in_what is typed_expression) in_what = convert_typed_expression_to_function_call(in_what as typed_expression); type_node elem_type = null; if (in_what.type == null) in_what = tmp; //if (in_what.type.find_in_type("GetEnumerator") == null) //(in_what.type as common_type_node).internal_type_special_kind == SemanticTree.type_special_kind.array_kind //in_what.type as compiled_type_node if (!FindIEnumerableElementType(/*_foreach_stmt, */in_what.type, ref elem_type)) //if (!IsGetEnumerator(in_what.type, ref elem_type)) AddError(in_what.location, "CAN_NOT_EXECUTE_FOREACH_BY_EXPR_OF_TYPE_{0}", in_what.type.name); if (_foreach_stmt.type_name == null) { location loc1 = get_location(_foreach_stmt.identifier); dn = context.check_name_node_type(_foreach_stmt.identifier.name, loc1, general_node_type.variable_node); vdn = (var_definition_node)dn; if (!check_name_in_current_scope(_foreach_stmt.identifier.name)) AddError(loc1, "FOREACH_LOOP_CONTROL_MUST_BE_SIMPLE_LOCAL_VARIABLE"); } else { //AddError(new NotSupportedError(get_location(_foreach_stmt.type_name))); vdn = context.add_var_definition(_foreach_stmt.identifier.name, get_location(_foreach_stmt.identifier)); type_node tn; if (_foreach_stmt.type_name is SyntaxTree.no_type_foreach) { tn = elem_type; } else { tn = convert_strong(_foreach_stmt.type_name); //if (tn == SystemLibrary.SystemLibrary.void_type) // AddError(new VoidNotValid(get_location(_foreach_stmt.type_name))); check_for_type_allowed(tn, get_location(_foreach_stmt.type_name)); } context.close_var_definition_list(tn, null); } //elem_type = vdn.type; if (!(vdn.type is compiled_generic_instance_type_node)) convertion_data_and_alghoritms.check_convert_type_with_inheritance(vdn.type, elem_type, get_location(_foreach_stmt.identifier)); //if (!convertion_data_and_alghoritms.eq_type_nodes(elem_type, vdn.type)) //AddError(new TypesOfVarAndElementsInForeachMustBeEqual(vdn.type.name,elem_type.name,get_location(_foreach_stmt.identifier))); //AddError(new SimpleSemanticError("Тип элемента контейнера: " + elem_type.ToString() + " Тип переменной foreach: " + vdn.type.ToString(), get_location(_foreach_stmt.identifier))); //convertion_data_and_alghoritms.check_convert_type_with_inheritance(vdn.type, elem_type, get_location(_foreach_stmt.identifier)); //if (in_what.type.type_special_kind == SemanticTree.type_special_kind.set_type) /*{ if (!convertion_data_and_alghoritms.eq_type_nodes(elem_type, vdn.type)) { possible_type_convertions ptc = type_table.get_convertions(vdn.type,elem_type); if (ptc.first == null || ptc.first.is_explicit) if (vdn.node_location_kind == SemanticTree.node_location_kind.in_namespace_location) throw new CanNotConvertTypes(new namespace_variable_reference(vdn as namespace_variable, get_location(_foreach_stmt.identifier)), vdn.type, elem_type, get_location(_foreach_stmt.identifier)); else if (vdn.node_location_kind == SemanticTree.node_location_kind.in_function_location) throw new CanNotConvertTypes(new local_variable_reference(vdn as local_variable, 0, get_location(_foreach_stmt.identifier)), vdn.type, elem_type, get_location(_foreach_stmt.identifier)); else if (vdn.node_location_kind == SemanticTree.node_location_kind.in_block_location) throw new CanNotConvertTypes(new local_block_variable_reference(vdn as local_block_variable,get_location(_foreach_stmt.identifier)),vdn.type,elem_type, get_location(_foreach_stmt.identifier)); else throw new ForeachLoopControlMustBeSimpleLocalVariable(get_location(_foreach_stmt.identifier)); } }*/ statements_list sl = new statements_list(get_location(_foreach_stmt.stmt)); convertion_data_and_alghoritms.statement_list_stack_push(sl); CheckToEmbeddedStatementCannotBeADeclaration(_foreach_stmt.stmt); foreach_node fn = new foreach_node(vdn, in_what, null, get_location(_foreach_stmt)); context.cycle_stack.push(fn); context.loop_var_stack.Push(vdn); context.enter_code_block_with_bind(); statement_node body = convert_strong(_foreach_stmt.stmt); context.leave_code_block(); context.loop_var_stack.Pop(); sl = convertion_data_and_alghoritms.statement_list_stack.pop(); //if (!(st is statements_list)) if (sl.statements.Count > 0 || sl.local_variables.Count > 0) { sl.statements.AddElement(body); body = sl; } //CheckToEmbeddedStatementCannotBeADeclaration(_foreach_stmt.stmt); //statement_node body = convert_strong(_foreach_stmt.stmt); //foreach_node fn = new foreach_node(vdn, in_what, body, get_location(_foreach_stmt)); fn.what_do = body; //statements_list sl2 = new statements_list(get_location(_foreach_stmt)); convertion_data_and_alghoritms.statement_list_stack.pop(); sl2.statements.AddElement(fn); context.cycle_stack.pop(); //if (_foreach_stmt.type_name != null) //sl2.local_variables.Add(vdn as local_block_variable); return_value(sl2); }