public exception_filter(type_node filter_type, local_block_variable_reference exception_var, statement_node exception_handler, location loc) : base(loc) { _filter_type = filter_type; _exception_var = exception_var; _exception_handler = exception_handler; }
private void VisitLocalBlockVariableReference(local_block_variable_reference en) { IncreaseNumUseVar(en); }
private void IncreaseNumUseVar(local_block_variable_reference lvr) { VarInfo vi = helper.GetVariable(lvr.var); if (vi == null) return; vi.num_use++; vi.act_num_use++; vi.cur_use++; //if (vi.cur_ass == 0 && !lvr.var.name.Contains("$")) helper.AddTempWarning(lvr.var,new UseWithoutAssign(lvr.var.name, lvr.location)); }
private void IncreaseNumAssVar(local_block_variable_reference lvr) { VarInfo vi = helper.GetVariable(lvr.var); vi.num_use++; vi.cur_ass++; vi.num_ass++; vi.last_ass_loc = lvr.location; if (vi.last_ass_loc == null) vi.num_ass--; if (vi.cur_use > 0) vi.cur_use--; }
private void VisitLocalBlockVariableReference(local_block_variable_reference expr) { bw.Write(GetMemberOffset(expr.var)); //bw.Write(expr.static_depth); }
public override void visit(SyntaxTree.try_stmt _try_stmt) { context.enter_code_block_without_bind(); context.enter_exception_handlers(); statement_node try_statements = convert_strong(_try_stmt.stmt_list); context.leave_code_block(); location loc = get_location(_try_stmt); exception_filters_list efl = new exception_filters_list(); SyntaxTree.try_handler_except try_hand_except = _try_stmt.handler as SyntaxTree.try_handler_except; if (try_hand_except != null) { if (try_hand_except.except_block.handlers != null) { int hand_count = try_hand_except.except_block.handlers.handlers.Count; for (int i = 0; i < hand_count; i++) { SyntaxTree.exception_handler eh = try_hand_except.except_block.handlers.handlers[i]; type_node filter_type = convert_strong(eh.type_name); if (!SemanticRules.GenerateNativeCode && !(filter_type.is_generic_parameter || filter_type == SystemLibrary.SystemLibrary.exception_base_type || type_table.is_derived(SystemLibrary.SystemLibrary.exception_base_type, filter_type))) { AddError(get_location(eh.type_name), "EXCEPTION_TYPE_MUST_BE_SYSTEM_EXCEPTION_OR_DERIVED_FROM_EXCEPTION"); } current_catch_excep = new int_const_node(2,null);//create_constructor_call(filter_type, new expressions_list(), null); local_block_variable_reference lvr = null; context.enter_code_block_without_bind(); if (eh.variable != null) { context.check_name_redefinition = false; local_block_variable lbv = context.add_var_definition(eh.variable.name, get_location(eh.variable), filter_type, SemanticTree.polymorphic_state.ps_common) as local_block_variable; context.check_name_redefinition = true; lvr = new local_block_variable_reference(lbv, lbv.loc); } statement_node stm = convert_strong(eh.statements); context.leave_code_block(); /*if (eh.variable != null) { context.leave_scope(); }*/ exception_filter ef = new exception_filter(filter_type, lvr, stm, get_location(eh)); efl.AddElement(ef); current_catch_excep = null; } } else { context.enter_code_block_without_bind(); exception_filter ef = new exception_filter(null, null, convert_strong(try_hand_except.except_block.stmt_list), get_location(try_hand_except.except_block.stmt_list)); context.leave_code_block(); efl.AddElement(ef); } if (try_hand_except.except_block.else_stmt_list != null) { context.enter_code_block_without_bind(); statement_node else_stm = convert_strong(try_hand_except.except_block.else_stmt_list); context.leave_code_block(); type_node ftype = SystemLibrary.SystemLibrary.object_type; exception_filter else_ef = new exception_filter(ftype, null, else_stm, else_stm.location); efl.AddElement(else_ef); } } else { type_node filter_type = compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.ExceptionName)); expression_node current_catch_excep = create_constructor_call(filter_type, new expressions_list(), null); local_block_variable_reference lvr = null; local_block_variable tmp_var = context.add_var_definition(context.BuildName("$try_temp" + UniqueNumStr()), null, SystemLibrary.SystemLibrary.bool_type, null) as local_block_variable; statements_list stm = new statements_list(null); SyntaxTree.try_handler_finally try_hndlr_finally = _try_stmt.handler as SyntaxTree.try_handler_finally; context.enter_code_block_without_bind(); statement_node finally_stmt = convert_strong(try_hndlr_finally.stmt_list); context.leave_code_block(); stm.statements.AddElement(finally_stmt); basic_function_call bfc = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,null); bfc.parameters.AddElement(new local_block_variable_reference(tmp_var,null)); stm.statements.AddElement(new if_node(bfc,new rethrow_statement_node(null),null,null)); exception_filter ef = new exception_filter(filter_type, lvr, stm, null); efl.AddElement(ef); bfc = new basic_function_call(SystemLibrary.SystemLibrary.bool_assign as basic_function_node,null); bfc.parameters.AddElement(new local_block_variable_reference(tmp_var,null)); bfc.parameters.AddElement(new bool_const_node(true,null)); (try_statements as statements_list).statements.AddElement(bfc); (try_statements as statements_list).statements.AddElement(new throw_statement_node(current_catch_excep,null)); return_value(new try_block(try_statements, null, efl, loc)); context.leave_exception_handlers(); return; } statement_node finally_st = null; SyntaxTree.try_handler_finally try_handler_finally = _try_stmt.handler as SyntaxTree.try_handler_finally; if (try_handler_finally != null) { context.enter_code_block_without_bind(); finally_st = convert_strong(try_handler_finally.stmt_list); context.leave_code_block(); } try_block tb = new try_block(try_statements, finally_st, efl, loc); context.leave_exception_handlers(); return_value(tb); }
/// <summary> /// Возвращает список преобразований типов для вызова метода. /// </summary> /// <param name="factparams">Список фактических параметров.</param> /// <param name="formalparams">Список формальных параметров.</param> /// <param name="is_alone_method_defined">Для единственного метода у которого типы параметров совпадают, но в качестве var параметра мы передаем константное значение мы можем сгенерировать более подробное сообщение об ошибке.</param> /// <returns>Список преобразований типов.</returns> internal possible_type_convertions_list get_conversions(expressions_list factparams, parameter_list formalparams,bool is_alone_method_defined, location locg) { //TODO:Явно указывать capacity при создании. possible_type_convertions_list tc = new possible_type_convertions_list(); possible_type_convertions ptc; if (factparams.Count>formalparams.Count) { if ( (formalparams.Count==0) || (!(formalparams[formalparams.Count-1].is_params)) ) { return null; } } type_node for_par_type = null; array_internal_interface aii=null; if (formalparams.Count > 0) { parameter pr=formalparams[formalparams.Count - 1]; if (pr.is_params && //это для возможности вызова сразу с массивом[], типа просто не обращаем внимаение на params !(factparams.Count == formalparams.Count && factparams[factparams.Count - 1].type == formalparams[formalparams.Count - 1].type)) { //TODO: Добавить проверку на правильность. aii = (array_internal_interface) pr.type.get_internal_interface(internal_interface_kind.unsized_array_interface); for_par_type = aii.element_type; tc.snl = new statement_node_list(); location loc=null; if (factparams.Count > 0) loc = factparams[factparams.Count-1].location; //var_definition_node vdn=syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(),loc); var_definition_node vdn = null; if (syntax_tree_visitor.context.converted_func_stack.size > 0) { common_function_node cfn = syntax_tree_visitor.context.converted_func_stack.first(); if (cfn.is_generic_function) { vdn = syntax_tree_visitor.context.add_var_definition(get_temp_arr_name(), loc); } else vdn = syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(), loc); } else if (syntax_tree_visitor.context.converted_type != null) vdn = syntax_tree_visitor.context.add_field(get_temp_arr_name(), loc, pr.type, polymorphic_state.ps_static); else vdn = syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(), loc); syntax_tree_visitor.context.close_var_definition_list(pr.type,null); expression_node fst=null; /*switch (syntax_tree_visitor.context.converting_block()) { case block_type.function_block: { fst=new local_variable_reference((local_variable)vdn,0,loc); break; } case block_type.namespace_block: { fst=new namespace_variable_reference((namespace_variable)vdn,loc); break; } }*/ switch (vdn.semantic_node_type) { case semantic_node_type.local_variable: { fst = new local_variable_reference((local_variable)vdn, 0, loc); break; } case semantic_node_type.namespace_variable: { fst = new namespace_variable_reference((namespace_variable)vdn, loc); break; } case semantic_node_type.local_block_variable: { fst = new local_block_variable_reference((local_block_variable)vdn, loc); break; } case semantic_node_type.class_field: { class_field cf = vdn as class_field; cf.polymorphic_state = polymorphic_state.ps_static; fst = new static_class_field_reference(cf, loc); break; } default: throw new CompilerInternalError("Invalid node type"); } tc.var_ref = fst; int del=factparams.Count-formalparams.Count+1; int_const_node icn=new int_const_node(del,loc); expression_node bfc = create_simple_function_call(SystemLibrary.SystemLibrary.resize_func, loc, fst, icn); tc.snl.AddElement(bfc); /*if (factparams.Count == 0) { possible_type_convertions ptci=new possible_type_convertions(); ptci.first=null; ptci.second=null; ptci.from=null; ptci.to = for_par_type; tc.AddElement(ptci); }*/ } } for(int i=0;i<factparams.Count;i++) { type_node formal_param_type = null; if ((for_par_type!=null)&&(i >= formalparams.Count-1)) { formal_param_type = for_par_type; } else { formal_param_type = formalparams[i].type; } if (possible_equal_types(factparams[i].type, formal_param_type)) { if ((i<formalparams.Count)&&(formalparams[i].parameter_type==SemanticTree.parameter_type.var)) { bool is_pascal_array_ref = false; bool is_ok = false; if (factparams[i].is_addressed==false) { if (factparams[i].semantic_node_type == semantic_node_type.common_method_call) { common_method_call cmc = (common_method_call)factparams[i]; internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface); if (ii != null) { if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) { bounded_array_interface bai = (bounded_array_interface)ii; class_field cf = bai.int_array; expression_node left = new class_field_reference(cf, cmc.obj, cmc.location); expression_node right = cmc.parameters[0]; //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); right = convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); right = create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value),cmc.location)); factparams[i] = new simple_array_indexing(left, right, cmc.type, cmc.location); is_pascal_array_ref = true; } } } if (!is_pascal_array_ref) { //Если мы попали сюда, то мы пытаемся передать по ссылке значение, //которое не мохет быть передано по ссылке. Например, передать //по ссылки из одной функции в другую константный параметр. if (is_alone_method_defined) { if (syntax_tree_visitor.assign_is_converting) { AddError(factparams[i].location, "CAN_NOT_ASSIGN_TO_LEFT_PART"); } else { if (formalparams[i] is common_parameter && (formalparams[i] as common_parameter).concrete_parameter_type == concrete_parameter_type.cpt_const /*&& factparams[i] is common_parameter_reference*/) { is_ok = true; } else if (formalparams[i] is common_parameter && (formalparams[i] as common_parameter).concrete_parameter_type == concrete_parameter_type.cpt_const) ; //throw new ThisExpressionCanNotBePassedAsConstParameter(factparams[i].location); else if (is_string_getter(factparams[i])) { if (factparams[i] is compiled_function_call) factparams[i] = make_unmanaged_string_getter(factparams[i] as compiled_function_call); else factparams[i] = make_unmanaged_shortstring_getter(factparams[i] as base_function_call); is_ok = true; } else AddError(new ThisExpressionCanNotBePassedAsVarParameter(factparams[i])); } } else if (is_string_getter(factparams[i])) { if (factparams[i] is compiled_function_call) factparams[i] = make_unmanaged_string_getter(factparams[i] as compiled_function_call); else factparams[i] = make_unmanaged_shortstring_getter(factparams[i] as base_function_call); is_ok = true; } if (!is_ok) return null; } } } //Разобраться: может лучше добавлять null к списку. possible_type_convertions ptci=new possible_type_convertions(); ptci.first=null; ptci.second=null; ptci.from=factparams[i].type; ptci.to = formal_param_type; tc.AddElement(ptci); if ((for_par_type != null) && (i >= formalparams.Count - 1)) { expression_node to = new simple_array_indexing(tc.var_ref,//factparams[formalparams.Count - 1], new int_const_node(i - formalparams.Count + 1, factparams[i].location), aii.element_type, factparams[i].location); expression_node from = factparams[i]; statement_node stat = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, to, from, factparams[i].location); tc.snl.AddElement(stat); } continue; } if ((i<formalparams.Count)&&(formalparams[i].parameter_type==SemanticTree.parameter_type.var)) { return null; } else { ptc = type_table.get_convertions(factparams[i].type, formal_param_type); if (ptc.first==null) { if (type_table.is_derived(formal_param_type, factparams[i].type)) { possible_type_convertions ptci=new possible_type_convertions(); ptci.first=null; ptci.second=null; ptci.from=factparams[i].type; ptci.to = formal_param_type; tc.AddElement(ptci); if ((for_par_type != null) && (i >= formalparams.Count - 1)) { expression_node to = new simple_array_indexing(tc.var_ref,//factparams[formalparams.Count - 1], new int_const_node(i - formalparams.Count + 1, factparams[i].location), aii.element_type, factparams[i].location); expression_node from = factparams[i]; statement_node stat = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, to, from, factparams[i].location); tc.snl.AddElement(stat); } } else { if (is_alone_method_defined) { AddError(new CanNotConvertTypes(factparams[i], factparams[i].type, formal_param_type, locg)); } return null; } } else { tc.AddElement(ptc); if ((for_par_type != null) && (i >= formalparams.Count - 1)) { expression_node to = new simple_array_indexing(tc.var_ref,//factparams[formalparams.Count - 1], new int_const_node(i - formalparams.Count + 1, factparams[i].location), aii.element_type, factparams[i].location); expression_node from = create_simple_function_call(ptc.first.convertion_method, factparams[i].location, factparams[i]); statement_node stat = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, to, from, factparams[i].location); tc.snl.AddElement(stat); } } } } if (tc.snl != null) foreach (statement_node sn in tc.snl) sn.location = null; return tc; }
private expression_node CreateLocalBlockVariableReference() { local_block_variable lv = GetLocalBlockVariableByOffset(br.ReadInt32()); local_block_variable_reference lvr = new local_block_variable_reference(lv, null); return lvr; }
public exception_filter(type_node filter_type, local_block_variable_reference exception_var, statement_node exception_handler, location loc) : base(loc) { _filter_type = filter_type; _exception_var = exception_var; _exception_handler = exception_handler; }
internal expression_node GetInitalValueForVariable(var_definition_node vdn, expression_node userInitalValue) { if (userInitalValue != null) { if (CurrentStatementList != null) { //Инициализировать надо в текущем стейтменте location lid = ((local_block_variable)vdn).loc; local_block_variable_reference lbvr = new local_block_variable_reference((local_block_variable)vdn, lid); if (vdn.type.type_special_kind == SemanticTree.type_special_kind.set_type) { userInitalValue = syntax_tree_visitor.get_init_call_for_set_as_constr(vdn,userInitalValue); //userInitalValue.type = SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node; } else if (userInitalValue is array_initializer) { array_initializer arr = userInitalValue as array_initializer; if (vdn.type.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) { for (int i=0; i<arr.element_values.Count; i++) { //arr.element_values[i] = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, varref2, arr.element_values[i], null); arr.element_values[i] = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node,null,convertion_data_and_alghoritms.convert_type(arr.element_values[i],SystemLibrary.SystemLibrary.string_type),new int_const_node((vdn.type.element_type as short_string_type_node).Length,null)); } } } CurrentStatementList.statements.AddElement(syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, lbvr, userInitalValue, lid)); if (vdn.type.type_special_kind == SemanticTree.type_special_kind.set_type) { lbvr.type = SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node; } return null; } if (userInitalValue is constant_node) { if (vdn.type.type_special_kind == SemanticTree.type_special_kind.short_string) { expression_node varref2 = convertion_data_and_alghoritms.CreateVariableReference(vdn, null); userInitalValue = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, varref2, userInitalValue, null); } return userInitalValue; } if (userInitalValue is array_initializer) { array_initializer arr = userInitalValue as array_initializer; if (vdn.type.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) { expression_node varref2 = convertion_data_and_alghoritms.CreateVariableReference(vdn, null); for (int i=0; i<arr.element_values.Count; i++) { //arr.element_values[i] = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, varref2, arr.element_values[i], null); arr.element_values[i] = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node,null,convertion_data_and_alghoritms.convert_type(arr.element_values[i],SystemLibrary.SystemLibrary.string_type),new int_const_node((vdn.type.element_type as short_string_type_node).Length,null)); } } return userInitalValue; } expression_node varref = convertion_data_and_alghoritms.CreateVariableReference(vdn, userInitalValue.location); if (vdn.type.type_special_kind == SemanticTree.type_special_kind.set_type) { userInitalValue = syntax_tree_visitor.get_init_call_for_set_as_constr(vdn,userInitalValue); //userInitalValue.type = SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node; } else if (vdn.type.type_special_kind == SemanticTree.type_special_kind.short_string) { expression_node cmc = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node,null,convertion_data_and_alghoritms.convert_type(userInitalValue,SystemLibrary.SystemLibrary.string_type),new int_const_node((vdn.type as short_string_type_node).Length,null)); userInitalValue = cmc; } userInitalValue = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, varref, userInitalValue, userInitalValue.location); if (vdn.type.type_special_kind == SemanticTree.type_special_kind.set_type) { varref.type = SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node; } return userInitalValue; } type_node tp = vdn.type; if (syntax_tree_visitor.SystemUnitAssigned && SystemLibrary.SystemLibInitializer.TextFileType.Found && tp.name == compiler_string_consts.text_file_name_type_name) if (tp == SystemLibrary.SystemLibInitializer.TextFileType.TypeNode) SystemLibrary.SystemLibInitializer.TextFileType.TypeNode.type_special_kind = PascalABCCompiler.SemanticTree.type_special_kind.text_file; //(ssyy) Вставил switch и обработку BinaryFile switch (tp.type_special_kind) { case SemanticTree.type_special_kind.typed_file: userInitalValue = syntax_tree_visitor.get_init_call_for_typed_file(vdn, tp.element_type); break; case SemanticTree.type_special_kind.set_type: userInitalValue = syntax_tree_visitor.get_init_call_for_set(vdn); break; case SemanticTree.type_special_kind.binary_file: userInitalValue = syntax_tree_visitor.get_init_call_for_binary_file(vdn); break; case SemanticTree.type_special_kind.text_file: userInitalValue = syntax_tree_visitor.get_init_call_for_text_file(vdn); break; default: if (tp is short_string_type_node) userInitalValue = SystemLibrary.SystemLibrary.empty_string;//syntax_tree_visitor.get_init_call_for_short_string(vdn); else if (tp == SystemLibrary.SystemLibrary.string_type && SemanticRules.InitStringAsEmptyString) userInitalValue = SystemLibrary.SystemLibrary.empty_string; break; } return userInitalValue; }