private void VisitCommonMethodCall(common_method_call en) { VisitExpression(en.obj); for (int i = 0; i < en.parameters.Count; i++) { VisitExpression(en.parameters[i]); } }
private void VisitCommonMethodCall(common_method_call en) { VisitExpression(en.obj); for (int i = 0; i < en.parameters.Count; i++) VisitExpression(en.parameters[i]); }
private void VisitCommonMethodCall(common_method_call expr) { VisitExpression(expr.obj); WriteMethodReference(expr.function_node); //ssyy if (expr.last_result_function_call) { bw.Write((byte)1); } else { bw.Write((byte)0); } //\ssyy bw.Write(expr.virtual_call); bw.Write(expr.parameters.Count); foreach (expression_node e in expr.parameters) VisitExpression(e); }
private base_function_call create_not_static_method_call(function_node fn, expression_node en, location loc, bool procedure_allowed) { try_convert_typed_expression_to_function_call(ref en); if ((!procedure_allowed) && (fn.return_value_type == null)) { AddError(loc, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", fn); } if (fn.semantic_node_type == semantic_node_type.common_method_node) { common_method_node cmn = (common_method_node)fn; if (cmn.is_constructor) { AddError(loc, "CAN_NOT_CALL_CONSTRUCTOR_AS_PROCEDURE"); } if (cmn.original_function != null && cmn.original_function is compiled_function_node && (cmn.original_function as compiled_function_node).ConnectedToType != null) { common_static_method_call csmc = new common_static_method_call(cmn, loc); return csmc; } if (cmn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) { AddError(new CanNotCallStaticMethodWithExpression(en, fn)); } common_method_call cmc = new common_method_call(cmn, en, loc); cmc.virtual_call = !inherited_ident_processing; return cmc; } if (fn.semantic_node_type == semantic_node_type.compiled_function_node) { compiled_function_node cfn = (compiled_function_node)fn; if (cfn.ConnectedToType != null) { compiled_static_method_call csmc = new compiled_static_method_call(cfn, loc); return csmc; } else { if (cfn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) { if (!cfn.is_extension_method) AddError(new CanNotCallStaticMethodWithExpression(en, fn)); else return new compiled_static_method_call(cfn, loc); } compiled_function_call cfc = new compiled_function_call(cfn, en, loc); cfc.virtual_call = !inherited_ident_processing; return cfc; } } if (fn.semantic_node_type == semantic_node_type.compiled_constructor_node) { AddError(loc, "CAN_NOT_CALL_CONSTRUCTOR_AS_PROCEDURE"); } if (fn.semantic_node_type == semantic_node_type.common_namespace_function_node && (fn as common_namespace_function_node).ConnectedToType != null) { common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node,loc); //cnfc.parameters.AddElement(en); return cnfc; } if (fn.semantic_node_type == semantic_node_type.indefinite_definition_node) { indefinite_function_call ifc = new indefinite_function_call(fn, loc); return ifc; } throw new CompilerInternalError("Invalid method kind"); }
private function_node GenerateSetMethod(common_property_node cpn, common_method_node accessor, location loc) { common_method_node cmn = new common_method_node( "set_" + cpn.name, loc, cpn.common_comprehensive_type, cpn.polymorphic_state, cpn.field_access_level, null); cpn.common_comprehensive_type.methods.AddElement(cmn); //cmn.return_value_type = cpn.property_type; cmn.is_overload = true; foreach (common_parameter cp in accessor.parameters) { common_parameter new_cp = new common_parameter(cp.name, cp.type, cp.parameter_type, cp.common_function, cp.concrete_parameter_type, cp.default_value, loc); cmn.parameters.AddElement(new_cp); } expression_node meth_call; if (cpn.polymorphic_state == SemanticTree.polymorphic_state.ps_common) { meth_call = new common_method_call(accessor, new this_node(cpn.common_comprehensive_type, loc), loc); foreach (common_parameter cp in cmn.parameters) { (meth_call as common_method_call).parameters.AddElement(new common_parameter_reference(cp, 0, loc)); } } else { meth_call = new common_static_method_call(accessor, loc); foreach (common_parameter cp in cmn.parameters) { (meth_call as common_static_method_call).parameters.AddElement(new common_parameter_reference(cp, 0, loc)); } } cmn.function_code = meth_call; cpn.common_comprehensive_type.scope.AddSymbol("set_" + cpn.name, new SymbolInfo(cmn)); return cmn; }
//\ssyy //ssyy public void generate_inherited_from_base_and_interface_function(common_type_node ctype, function_node func) { common_method_node gen_func = context.create_function(func.name, null) as common_method_node; gen_func.polymorphic_state = SemanticTree.polymorphic_state.ps_common; gen_func.newslot_awaited = true; gen_func.is_final = true; gen_func.is_overload = true; gen_func.field_access_level = SemanticTree.field_access_level.fal_public; gen_func.return_value_type = func.return_value_type; //gen_func.return_variable = func.retu foreach (parameter par in func.parameters) { concrete_parameter_type cpt = (par.parameter_type == SemanticTree.parameter_type.value) ? concrete_parameter_type.cpt_const : concrete_parameter_type.cpt_var; common_parameter c_p = new common_parameter(par.name, par.parameter_type, gen_func, cpt, null); c_p.type = par.type; c_p.set_param_is_params(par.is_params); c_p.inital_value = par.inital_value; gen_func.parameters.AddElement(c_p); } local_variable lv = new local_variable(compiler_string_consts.self_word, gen_func.cont_type, gen_func, null); gen_func.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(lv)); gen_func.self_variable = lv; base_function_call bfc; this_node tn = null; common_method_node commn = func as common_method_node; if (commn != null) { tn = new this_node(commn.comperehensive_type as type_node, null); bfc = new common_method_call(commn, tn, null); } else { compiled_function_node compn = func as compiled_function_node; tn = new this_node(compn.comperehensive_type as type_node, null); bfc = new compiled_function_call(compn, tn, null); } foreach (parameter p in gen_func.parameters) { bfc.parameters.AddElement( create_variable_reference(p, null)); } //Это запретит чистку стека bfc.last_result_function_call = true; statements_list snlist = new statements_list(null); snlist.statements.AddElement(bfc); snlist.statements.AddElement(new empty_statement(null)); gen_func.function_code = snlist; context.pop_top_function(); //context.leave_block(); }
public override void visit(SyntaxTree.assign _assign) { internal_is_assign = true; addressed_expression to = convert_address_strong(_assign.to); internal_is_assign = false; if (to == null) AddError(get_location(_assign.to), "CAN_NOT_ASSIGN_TO_LEFT_PART"); #region Вывод параметров лямбда-выражения var fld1 = _assign.from as SyntaxTree.function_lambda_definition; if (fld1 != null) { MaybeConvertFunctionLambdaDefinitionToProcedureLambdaDefinition(fld1); LambdaHelper.InferTypesFromVarStmt(to.type, _assign.from as SyntaxTree.function_lambda_definition, this); //lroman// } #endregion //(ssyy) Вставляю проверки прямо сюда, т.к. запарился вылавливать другие случаи. bool flag=false; general_node_type node_type = general_node_type.constant_definition; if (convertion_data_and_alghoritms.check_for_constant_or_readonly(to, out flag, out node_type)) { if (flag) AddError(to.location, "CAN_NOT_ASSIGN_TO_CONSTANT_OBJECT"); else AddError(new CanNotAssignToReadOnlyElement(to.location,node_type)); } //expression_node from = convert_strong(_assign.from); /// SSM исправление Саушкина 10.03.16 expression_node from; var fromAsLambda = _assign.from as function_lambda_definition; if (fromAsLambda != null) { var lambdaVisitMode = fromAsLambda.lambda_visit_mode; fromAsLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; from = convert_strong(_assign.from); fromAsLambda.lambda_visit_mode = lambdaVisitMode; } else { from = convert_strong(_assign.from); } /// end //SSM 4.04.16 if (to.type is undefined_type) to.type = from.type; if (stflambda.Count>0) // мы находимся внутри лямбды - возможно, вложенной { var fld = stflambda.Peek(); if (_assign.to is ident && (_assign.to as ident).name.ToLower()=="result" && fld.RealSemTypeOfResExpr == null) // если это - первое присваивание Result { fld.RealSemTypeOfResExpr = from.type; fld.RealSemTypeOfResult = to.type; } } location loc = get_location(_assign); bool oper_ass_in_prop = false; //проверка на обращение к полю записи возвращенной из функции с целью присваивания //нужно чтобы пользователь не мог менять временный обьект if (to.semantic_node_type == semantic_node_type.static_property_reference || to.semantic_node_type == semantic_node_type.non_static_property_reference) { property_node pn = null; base_function_call prop_expr = null; if (to.semantic_node_type == semantic_node_type.static_property_reference) pn = (to as static_property_reference).property; else pn = (to as non_static_property_reference).property; PascalABCCompiler.SyntaxTree.Operators ot = PascalABCCompiler.SyntaxTree.Operators.Undefined; switch (_assign.operator_type) { case PascalABCCompiler.SyntaxTree.Operators.AssignmentAddition: ot = PascalABCCompiler.SyntaxTree.Operators.Plus; oper_ass_in_prop = true; break; case PascalABCCompiler.SyntaxTree.Operators.AssignmentBitwiseAND: ot = PascalABCCompiler.SyntaxTree.Operators.BitwiseAND; oper_ass_in_prop = true; break; case PascalABCCompiler.SyntaxTree.Operators.AssignmentBitwiseLeftShift: ot = PascalABCCompiler.SyntaxTree.Operators.BitwiseLeftShift; oper_ass_in_prop = true; break; case PascalABCCompiler.SyntaxTree.Operators.AssignmentBitwiseOR: ot = PascalABCCompiler.SyntaxTree.Operators.BitwiseOR; oper_ass_in_prop = true; break; case PascalABCCompiler.SyntaxTree.Operators.AssignmentBitwiseRightShift: ot = PascalABCCompiler.SyntaxTree.Operators.BitwiseRightShift; oper_ass_in_prop = true; break; case PascalABCCompiler.SyntaxTree.Operators.AssignmentBitwiseXOR: ot = PascalABCCompiler.SyntaxTree.Operators.BitwiseXOR; oper_ass_in_prop = true; break; case PascalABCCompiler.SyntaxTree.Operators.AssignmentDivision: ot = PascalABCCompiler.SyntaxTree.Operators.Division; oper_ass_in_prop = true; break; case PascalABCCompiler.SyntaxTree.Operators.AssignmentModulus: ot = PascalABCCompiler.SyntaxTree.Operators.ModulusRemainder; oper_ass_in_prop = true; break; case PascalABCCompiler.SyntaxTree.Operators.AssignmentMultiplication: ot = PascalABCCompiler.SyntaxTree.Operators.Multiplication; oper_ass_in_prop = true; break; case PascalABCCompiler.SyntaxTree.Operators.AssignmentSubtraction: ot = PascalABCCompiler.SyntaxTree.Operators.Minus; oper_ass_in_prop = true; break; } if (oper_ass_in_prop) { if (pn.get_function == null) AddError(new ThisPropertyCanNotBeReaded(pn,loc)); if (to.semantic_node_type == semantic_node_type.non_static_property_reference) { prop_expr = create_not_static_method_call(pn.get_function,(to as non_static_property_reference).expression,loc,false); prop_expr.parameters.AddRange((to as non_static_property_reference).fact_parametres); } else { prop_expr = create_static_method_call(pn.get_function,loc,pn.comprehensive_type,false); prop_expr.parameters.AddRange((to as static_property_reference).fact_parametres); } from = find_operator(ot,prop_expr,from,loc); } } else if (to is class_field_reference) { if ((to as class_field_reference).obj.type.type_special_kind == SemanticTree.type_special_kind.record && (to as class_field_reference).obj is base_function_call) { //исключим ситуацию обращения к массиву if (!(((to as class_field_reference).obj is common_method_call) && ((to as class_field_reference).obj as common_method_call).obj.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper)) AddError(loc, "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO"); } //else check_field_reference_for_assign(to as class_field_reference,loc); } else if (context.is_in_cycle() && !SemanticRules.AllowChangeLoopVariable && to.semantic_node_type == semantic_node_type.namespace_variable_reference) { if (context.is_loop_variable((to as namespace_variable_reference).var)) AddError(to.location, "CANNOT_ASSIGN_TO_LOOP_VARIABLE"); } else if (context.is_in_cycle() && !SemanticRules.AllowChangeLoopVariable && to.semantic_node_type == semantic_node_type.local_variable_reference) { if (context.is_loop_variable((to as local_variable_reference).var)) AddError(to.location, "CANNOT_ASSIGN_TO_LOOP_VARIABLE"); } else if (context.is_in_cycle() && !SemanticRules.AllowChangeLoopVariable && to.semantic_node_type == semantic_node_type.local_block_variable_reference) { if (context.is_loop_variable((to as local_block_variable_reference).var)) AddError(to.location, "CANNOT_ASSIGN_TO_LOOP_VARIABLE"); } else if (to is simple_array_indexing) if ((to as simple_array_indexing).simple_arr_expr is class_field_reference && ((to as simple_array_indexing).simple_arr_expr as class_field_reference).obj != null && ((to as simple_array_indexing).simple_arr_expr as class_field_reference).obj is constant_node) AddError(loc, "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO"); if ((to.semantic_node_type == semantic_node_type.static_event_reference) || (to.semantic_node_type == semantic_node_type.nonstatic_event_reference)) { statement_node event_assign = null; if (_assign.operator_type == PascalABCCompiler.SyntaxTree.Operators.Assignment) { //throw new CanNotAssignToEvent(); } static_event_reference ser = (static_event_reference)to; expression_node right_del = convertion_data_and_alghoritms.convert_type(from, ser.en.delegate_type); switch (_assign.operator_type) { case PascalABCCompiler.SyntaxTree.Operators.AssignmentAddition: { if (to.semantic_node_type == semantic_node_type.static_event_reference) { event_assign = convertion_data_and_alghoritms.create_simple_function_call( ser.en.add_method, loc, right_del); } else { if (ser.en.semantic_node_type == semantic_node_type.compiled_event) { nonstatic_event_reference nser = (nonstatic_event_reference)ser; compiled_function_node cfn = (compiled_function_node)ser.en.add_method; compiled_function_call tmp_event_assign = new compiled_function_call(cfn, nser.obj, loc); tmp_event_assign.parameters.AddElement(right_del); event_assign = tmp_event_assign; } else if (ser.en.semantic_node_type == semantic_node_type.common_event) { nonstatic_event_reference nser = (nonstatic_event_reference)ser; common_method_node cfn = (common_method_node)ser.en.add_method; common_method_call tmp_event_assign = new common_method_call(cfn, nser.obj, loc); tmp_event_assign.parameters.AddElement(right_del); event_assign = tmp_event_assign; } } break; } case PascalABCCompiler.SyntaxTree.Operators.AssignmentSubtraction: { if (to.semantic_node_type == semantic_node_type.static_event_reference) { event_assign = convertion_data_and_alghoritms.create_simple_function_call( ser.en.remove_method, loc, right_del); } else { if (ser.en.semantic_node_type == semantic_node_type.compiled_event) { nonstatic_event_reference nser = (nonstatic_event_reference)ser; compiled_function_node cfn = (compiled_function_node)ser.en.remove_method; compiled_function_call tmp_event_assign = new compiled_function_call(cfn, nser.obj, loc); tmp_event_assign.parameters.AddElement(right_del); event_assign = tmp_event_assign; } else if (ser.en.semantic_node_type == semantic_node_type.common_event) { nonstatic_event_reference nser = (nonstatic_event_reference)ser; common_method_node cfn = (common_method_node)ser.en.remove_method; common_method_call tmp_event_assign = new common_method_call(cfn, nser.obj, loc); tmp_event_assign.parameters.AddElement(right_del); event_assign = tmp_event_assign; } } break; } default: { AddError(loc, "ASSIGN_TO_EVENT"); //throw new CanNotApplyThisOperationToEvent break; } } return_value(event_assign); return; } if (_assign.operator_type == PascalABCCompiler.SyntaxTree.Operators.Assignment || oper_ass_in_prop) { if (to.semantic_node_type == semantic_node_type.static_property_reference) { static_property_reference spr = (static_property_reference)to; if (spr.property.set_function == null) { AddError(new ThisPropertyCanNotBeWrited(spr.property, loc)); } check_property_params(spr, loc); function_node set_func = spr.property.set_function; from = convertion_data_and_alghoritms.convert_type(from, spr.property.property_type); spr.fact_parametres.AddElement(from); base_function_call bfc = create_static_method_call(set_func, loc, spr.property.comprehensive_type, true); bfc.parameters.AddRange(spr.fact_parametres); return_value((statement_node)bfc); return; } else if (to.semantic_node_type == semantic_node_type.non_static_property_reference) { non_static_property_reference nspr = (non_static_property_reference)to; check_property_params(nspr, loc); from = convertion_data_and_alghoritms.convert_type(from, nspr.property.property_type); nspr.fact_parametres.AddElement(from); //Обработка s[i]:='c' if (SystemUnitAssigned) if (nspr.property.comprehensive_type == SystemLibrary.SystemLibrary.string_type) { if (nspr.property == SystemLibrary.SystemLibrary.string_type.default_property_node) { if (SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure != null) { expressions_list exl = new expressions_list(); exl.AddElement(nspr.expression); exl.AddElement(nspr.fact_parametres[0]); exl.AddElement(from); function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure.SymbolInfo, loc); expression_node ret = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, exl.ToArray()); return_value((statement_node)ret); return; } } } if (nspr.property.set_function == null) { AddError(new ThisPropertyCanNotBeWrited(nspr.property, loc)); } function_node set_func = nspr.property.set_function; base_function_call bfc = create_not_static_method_call(set_func, nspr.expression, loc, true); bfc.parameters.AddRange(nspr.fact_parametres); return_value((statement_node)bfc); return; } else if (to is simple_array_indexing && (to as simple_array_indexing).simple_arr_expr.type.type_special_kind == SemanticTree.type_special_kind.short_string) { expression_node expr = (to as simple_array_indexing).simple_arr_expr; expression_node ind_expr = (to as simple_array_indexing).ind_expr; from = convertion_data_and_alghoritms.convert_type(from,SystemLibrary.SystemLibrary.char_type); ind_expr = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.SetCharInShortStringProcedure.sym_info as function_node,loc,expr,ind_expr,new int_const_node((expr.type as short_string_type_node).Length,null),from); return_value(find_operator(compiler_string_consts.assign_name, expr, ind_expr, get_location(_assign))); return; } else if (to.type.type_special_kind == SemanticTree.type_special_kind.short_string) { if (from.type is null_type_node) AddError(get_location(_assign), "NIL_WITH_VALUE_TYPES_NOT_ALLOWED"); expression_node clip_expr = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node, loc, convertion_data_and_alghoritms.convert_type(from, SystemLibrary.SystemLibrary.string_type), new int_const_node((to.type as short_string_type_node).Length, null)); statement_node en = find_operator(compiler_string_consts.assign_name, to, clip_expr, get_location(_assign)); return_value(en); return; } else { assign_is_converting = true; statement_node en = find_operator(compiler_string_consts.assign_name, to, from, get_location(_assign)); assign_is_converting = false; return_value(en); return; } } else { assign_is_converting = true; statement_node en = find_operator(_assign.operator_type, to, from, get_location(_assign)); assign_is_converting = false; return_value(en); return; } //throw new CompilerInternalError("Undefined assign to type"); }
private base_function_call_list convert_functions_to_calls(expression_node obj, function_node_list fnl, location loc, bool is_static) { base_function_call_list ret = new base_function_call_list(); foreach (function_node fnode in fnl) { base_function_call bfc = null; switch (fnode.semantic_node_type) { case semantic_node_type.common_namespace_function_node: { common_namespace_function_node cmfn = fnode as common_namespace_function_node; common_namespace_function_call cnfc = new common_namespace_function_call(cmfn, loc); if (cmfn.ConnectedToType != null) cnfc.parameters.AddElement(obj); if (cmfn.is_generic_function && !cmfn.is_generic_function_instance && cmfn.ConnectedToType != null && cmfn.parameters.Count == 1) { expressions_list parameters = new expressions_list(); parameters.AddElement(obj); function_node inst = null; try { inst = generic_convertions.DeduceFunction(cmfn, parameters, true, loc); } catch { continue; } cnfc = new common_namespace_function_call((common_namespace_function_node)inst, loc); if (cmfn.ConnectedToType != null) cnfc.parameters.AddElement(obj); } /*if (cmfn.parameters.Count >= 1 && cmfn.parameters[cmfn.parameters.Count - 1].is_params) { convertion_data_and_alghoritms.select_function(cnfc.parameters, new SymbolInfo(cmfn), loc); }*/ bfc = cnfc; break; } case semantic_node_type.basic_function_node: { //Может здесь стоит и выругаться, но я не буду пока этого делать. break; } case semantic_node_type.common_in_function_function_node: { common_in_function_function_node ciffn = fnode as common_in_function_function_node; int depth = convertion_data_and_alghoritms.symbol_table.GetRelativeScopeDepth(ciffn.scope, context.top_function.scope); common_in_function_function_call ciffc = new common_in_function_function_call(ciffn, depth, loc); bfc = ciffc; break; } case semantic_node_type.common_method_node: { common_method_node cmn = fnode as common_method_node; //Если cmn конструктор - то плохо, но его не должно сюда попасть. if (cmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) { if (!is_static) { if (obj == null) obj = GetCurrentObjectReference(cmn.cont_type.Scope, cmn, loc);//new this_node(context.converted_type, loc); common_method_call cmc = new common_method_call(cmn, obj, loc); cmc.virtual_call = !inherited_ident_processing; bfc = cmc; } //ssyy!!! Мне сложно понять предназначение данного кода, но, по-видимому, //следует его переписать так. else if (cmn.is_constructor) { if (cmn.parameters.Count == 0) { if (cmn.cont_type.IsAbstract) AddError(loc, "ABSTRACT_CONSTRUCTOR_{0}_CALL", cmn.cont_type.name); ret.clear(); ret.AddElement(new common_constructor_call(cmn, loc)); return ret; } } } else { if (is_static) { common_static_method_call csmc = new common_static_method_call(cmn, loc); bfc = csmc; } } break; } case semantic_node_type.compiled_function_node: { compiled_function_node cfn = fnode as compiled_function_node; if (cfn.cont_type.Scope == null && cfn is compiled_function_node) (cfn.cont_type as compiled_type_node).init_scope(); if (cfn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) { //ispravleno ibond //if (is_static) { if (cfn.is_generic_function && !cfn.is_generic_function_instance && cfn.ConnectedToType != null && cfn.parameters.Count == 1) { expressions_list parameters = new expressions_list(); parameters.AddElement(obj); function_node inst = null; try { inst = generic_convertions.DeduceFunction(cfn, parameters, true, loc); } catch { continue; } if (inst is common_namespace_function_node) bfc = new common_namespace_function_call((common_namespace_function_node)inst, loc); else if (inst is compiled_function_node) bfc = new compiled_static_method_call((compiled_function_node)inst, loc); else bfc = new compiled_static_method_call(cfn, loc); } else { compiled_static_method_call csmc = new compiled_static_method_call(cfn, loc); bfc = csmc; } if (cfn.ConnectedToType != null) bfc.parameters.AddElement(obj); } } else { if (!is_static) { if (obj == null) obj = GetCurrentObjectReference(cfn.cont_type.Scope, cfn, loc);//new this_node(context.converted_type, loc); compiled_function_call cfc = new compiled_function_call(cfn, obj, loc); cfc.virtual_call = !inherited_ident_processing; bfc = cfc; } } break; } case semantic_node_type.compiled_constructor_node: { //Этот код мы вроде не должны вызывать, но если он все-же вызовется. compiled_constructor_node ccn = fnode as compiled_constructor_node; compiled_constructor_call ccc = new compiled_constructor_call(ccn, loc); bfc = ccc; break; } default: { throw new CompilerInternalError("Undefined method type."); } } if (bfc != null) { ret.AddElement(bfc); } } return ret; }
/// <summary> /// Обрабатывает случай, когда левая часть присваивания имеет тип event. /// </summary> /// <returns>True - обработка прошла, иначе False.</returns> private bool ProcessAssignmentToEventIfPossible(assign _assign, addressed_expression to, expression_node from, location loc) { if ((to.semantic_node_type == semantic_node_type.static_event_reference) || (to.semantic_node_type == semantic_node_type.nonstatic_event_reference)) { statement_node event_assign = null; static_event_reference ser = (static_event_reference)to; expression_node right_del = convertion_data_and_alghoritms.convert_type(from, ser.en.delegate_type); switch (_assign.operator_type) { case Operators.AssignmentAddition: { if (to.semantic_node_type == semantic_node_type.static_event_reference) { event_assign = convertion_data_and_alghoritms.create_simple_function_call( ser.en.add_method, loc, right_del); } else { if (ser.en.semantic_node_type == semantic_node_type.compiled_event) { nonstatic_event_reference nser = (nonstatic_event_reference)ser; compiled_function_node cfn = (compiled_function_node)ser.en.add_method; compiled_function_call tmp_event_assign = new compiled_function_call(cfn, nser.obj, loc); tmp_event_assign.parameters.AddElement(right_del); event_assign = tmp_event_assign; } else if (ser.en.semantic_node_type == semantic_node_type.common_event) { nonstatic_event_reference nser = (nonstatic_event_reference)ser; common_method_node cfn = (common_method_node)ser.en.add_method; common_method_call tmp_event_assign = new common_method_call(cfn, nser.obj, loc); tmp_event_assign.parameters.AddElement(right_del); event_assign = tmp_event_assign; } } break; } case Operators.AssignmentSubtraction: { if (to.semantic_node_type == semantic_node_type.static_event_reference) { event_assign = convertion_data_and_alghoritms.create_simple_function_call( ser.en.remove_method, loc, right_del); } else { if (ser.en.semantic_node_type == semantic_node_type.compiled_event) { nonstatic_event_reference nser = (nonstatic_event_reference)ser; compiled_function_node cfn = (compiled_function_node)ser.en.remove_method; compiled_function_call tmp_event_assign = new compiled_function_call(cfn, nser.obj, loc); tmp_event_assign.parameters.AddElement(right_del); event_assign = tmp_event_assign; } else if (ser.en.semantic_node_type == semantic_node_type.common_event) { nonstatic_event_reference nser = (nonstatic_event_reference)ser; common_method_node cfn = (common_method_node)ser.en.remove_method; common_method_call tmp_event_assign = new common_method_call(cfn, nser.obj, loc); tmp_event_assign.parameters.AddElement(right_del); event_assign = tmp_event_assign; } } break; } default: { AddError(loc, "ASSIGN_TO_EVENT"); //throw new CanNotApplyThisOperationToEvent break; } } return_value(event_assign); return(true); } return(false); }
public void make_constructor() { #if (DEBUG) if (converting_block()!=block_type.function_block) { throw new CompilerInternalError("Create constructor call without function"); } if (_func_stack.top().node_location_kind!=SemanticTree.node_location_kind.in_class_location) { throw new CompilerInternalError("Create constructor applied to non class method"); } #endif common_function_node top_func=_func_stack.top(); top_func.return_value_type=_ctn; common_method_node top_method=(common_method_node)top_func; common_method_node cmn=new common_method_node(top_func.name,_ctn,top_method.loc,_ctn, SemanticTree.polymorphic_state.ps_static,_fal,top_func.scope); cmn.is_constructor=true; cmn.is_overload=top_function.is_overload; //parameter_list pl = new parameter_list(); foreach (common_parameter pr in top_method.parameters) { common_parameter new_par = new common_parameter(pr.name, pr.type, pr.parameter_type, cmn, pr.concrete_parameter_type, pr.default_value, pr.loc); cmn.parameters.AddElement(new_par); } //cmn.parameters.AddRange(top_method.parameters); statements_list stl=new statements_list(top_func.loc); cmn.function_code=stl; this_node thn=new this_node(_ctn,top_func.loc); common_method_call csmc=new common_method_call(top_method,thn,top_func.loc); foreach(common_parameter cp in cmn.parameters) { common_parameter_reference cpr=new common_parameter_reference(cp,0,top_func.loc); csmc.parametres.AddElement(cpr); } stl.statements.AddElement(csmc); _ctn.methods.AddElement(cmn); top_method.pascal_associated_constructor=cmn; }
/// <summary> /// Этот метод вызывается если мы встречаем простой вызов функии, например f(1). /// Он определяет является ли эта функция методом класса, вложенной функцией и т.д. и создает соответствующее обращение. /// Например, для метода класса он добавляет this, а для вложенной функции вычисляет статическую глубину. /// </summary> /// <param name="exprs">Список параметров.</param> /// <param name="si">Список методов.</param> /// <param name="loc">Расположение вызова.</param> /// <param name="converted_type">Тип в котором мы находимся. null, если мы вне типа.</param> /// <param name="top_function">Функция в которой мы находимся.</param> /// <param name="allow_procedure">Может ли это быть вызов процедуры. false если вызов стоит в выражении или правой части опреатора присваивания.</param> /// <returns>Возвращает узел вызова метода.</returns> public expression_node create_full_function_call(expressions_list exprs,SymbolInfo si,location loc, common_type_node converted_type,common_function_node top_function,bool allow_procedure) { function_node fn=select_function(exprs,si,loc); /* if (fn.compile_time_executor != null) { expression_node ex = fn.compile_time_executor(loc, exprs.ToArray()); if (ex != null) { return ex; } } */ //allow_procedure = true; if ((!allow_procedure)&&(fn.return_value_type==null)) { throw new SimpleSemanticError(loc, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", fn.name); } expression_node expr_node=null; switch (fn.semantic_node_type) { case semantic_node_type.basic_function_node: case semantic_node_type.common_namespace_function_node: { expr_node=create_simple_function_call(fn,loc,exprs.ToArray()); break; } case semantic_node_type.common_method_node: case semantic_node_type.compiled_function_node: { SemanticTree.IClassMemberNode icmn=(SemanticTree.IClassMemberNode)fn; if (icmn.polymorphic_state==SemanticTree.polymorphic_state.ps_static) { expr_node=create_simple_function_call(fn,loc,exprs.ToArray()); break; } //expression_node tn = new this_node(converted_type,loc); base_function_call cmc=null; switch (fn.semantic_node_type) { case semantic_node_type.common_method_node: { //ssyy добавил if (((common_method_node)fn).is_constructor) { common_constructor_call ccc = new common_constructor_call((common_method_node)fn, loc); //(ssyy) По-видимому, здесь всегда можно присваивать false, так как при создании нового объекта мы сюда не заходим... ccc._new_obj_awaited = false; if (!syntax_tree_visitor.context.allow_inherited_ctor_call) { throw new SimpleSemanticError(loc, "INHERITED_CONSTRUCTOR_CALL_MUST_BE_FIRST"); } cmc = ccc; } else //\ssyy { cmc = new common_method_call((common_method_node)fn, syntax_tree_visitor.GetCurrentObjectReference(((common_method_node)fn).cont_type.Scope, fn, loc), loc); (cmc as common_method_call).virtual_call = !syntax_tree_visitor.inherited_ident_processing; } break; } case semantic_node_type.compiled_function_node: { cmc = new compiled_function_call((compiled_function_node)fn, syntax_tree_visitor.GetCurrentObjectReference(((compiled_function_node)fn).cont_type.Scope, fn, loc), loc); (cmc as compiled_function_call).virtual_call = !syntax_tree_visitor.inherited_ident_processing; break; } } cmc.parameters.AddRange(exprs); expr_node=cmc; break; } case semantic_node_type.common_in_function_function_node: { common_in_function_function_node cffn=(common_in_function_function_node)fn; common_in_function_function_call cffc=new common_in_function_function_call(cffn, symtab.GetRelativeScopeDepth(cffn.function.scope,top_function.scope),loc); cffc.parameters.AddRange(exprs); expr_node=cffc; break; } //ssyy добавил case semantic_node_type.compiled_constructor_node: { compiled_constructor_node ccn = fn as compiled_constructor_node; if (ccn == null) { throw new CompilerInternalError("compiled_constructor_node expected"); } compiled_constructor_call ccc = new compiled_constructor_call(ccn, loc); ccc.parameters.AddRange(exprs); ccc._new_obj_awaited = false; if (!syntax_tree_visitor.context.allow_inherited_ctor_call) { throw new SimpleSemanticError(loc, "INHERITED_CONSTRUCTOR_CALL_MUST_BE_FIRST"); } expr_node = ccc; break; } case semantic_node_type.indefinite_definition_node: { indefinite_function_call ifc = new indefinite_function_call(fn, loc); ifc.parameters.AddRange(exprs); expr_node = ifc; break; } //\ssyy default: { throw new NotSupportedError(loc); } } return expr_node; }
private common_method_call create_common_method_call(common_method_node cmn,location loc,expression_node obj, params expression_node[] exprs) { #if (DEBUG) if (cmn.polymorphic_state==SemanticTree.polymorphic_state.ps_static) { throw new CompilerInternalError("Static method can not be called with type"); } #endif common_method_call cmc=new common_method_call(cmn,obj,loc); cmc.virtual_call = !syntax_tree_visitor.inherited_ident_processing; cmc.parameters.AddRange(exprs); return cmc; }
private expression_node CreateMethodCall() { expression_node obj = CreateExpression(); common_method_node meth = GetMethodByOffset(); common_method_call cmc = new common_method_call(meth, obj, null); //ssyy cmc.last_result_function_call = br.ReadByte() == 1; //\ssyy cmc.virtual_call = br.ReadBoolean(); int num = br.ReadInt32(); for (int i = 0; i < num; i++) cmc.parameters.AddElement(CreateExpression()); return cmc; }
public expression_node convert_delegates_to_delegates(location call_location, expression_node[] parameters) { if (parameters.Length != 1) { throw new PascalABCCompiler.TreeConverter.CompilerInternalError("Invalid delegates convertion"); } delegate_internal_interface dii_to= (delegate_internal_interface)_to.get_internal_interface(internal_interface_kind.delegate_interface); delegate_internal_interface dii = (delegate_internal_interface)parameters[0].type.get_internal_interface(internal_interface_kind.delegate_interface); expression_node pr = parameters[0]; base_function_call ifnotnull = null; if (_to.semantic_node_type == semantic_node_type.compiled_type_node) { ifnotnull = new compiled_constructor_call((compiled_constructor_node)dii_to.constructor, call_location); } else { ifnotnull = new common_constructor_call((common_method_node)dii_to.constructor, call_location); } //ccc = new common_constructor_call(dii_to.constructor, call_location); expression_node par = null; if (parameters[0].type.semantic_node_type == semantic_node_type.compiled_type_node) { par = new compiled_function_call((compiled_function_node)dii.invoke_method, parameters[0], call_location); } else { par = new common_method_call((common_method_node)dii.invoke_method, parameters[0], call_location); } ifnotnull.parameters.AddElement(par); null_const_node ncn = new null_const_node(_to, call_location); null_const_node ncn2 = new null_const_node(_to, call_location); PascalABCCompiler.TreeConverter.SymbolInfo si = pr.type.find_in_type(PascalABCCompiler.TreeConverter.compiler_string_consts.eq_name); basic_function_node fn = si.sym_info as basic_function_node; expression_node condition = null; if (fn != null) { basic_function_call condition_bfc = new basic_function_call(fn, call_location); condition_bfc.parameters.AddElement(pr); condition_bfc.parameters.AddElement(ncn); condition = condition_bfc; } else if (si.sym_info is compiled_function_node) { compiled_static_method_call condition_cfc = new compiled_static_method_call(si.sym_info as compiled_function_node, call_location); condition_cfc.parameters.AddElement(pr); condition_cfc.parameters.AddElement(ncn); condition = condition_cfc; } question_colon_expression qce = new question_colon_expression(condition, ncn2, ifnotnull, call_location); return qce; }
public static expression_node convert_delegate_to_return_value_type(location call_location, params expression_node[] parameters) { expression_node par=parameters[0]; internal_interface ii = par.type.get_internal_interface(internal_interface_kind.delegate_interface); delegate_internal_interface dii = (delegate_internal_interface)ii; common_method_node cmn = dii.invoke_method as common_method_node; if (cmn != null) { expression_node exp = new common_method_call(cmn, par, call_location); return exp; } compiled_function_node cfn = dii.invoke_method as compiled_function_node; if (cfn != null) { expression_node exp = new compiled_function_call(cfn, par, call_location); return exp; } return null; }
private void add_overloads_for_default_parameter() { List<parameter> default_params = new List<parameter>(); foreach (parameter p in top_function.parameters) { if (p.default_value != null) { default_params.Add(p); } } int num_of_defaults = default_params.Count-1; if (default_params.Count > 0 && converted_func_stack.size == 1) while (num_of_defaults >= 0) { if (converted_type == null) { common_namespace_function_node cnfn = new common_namespace_function_node(top_function.name, top_function.return_value_type, null, converted_namespace, null); foreach (parameter p in top_function.parameters) { if (p.default_value == null) cnfn.parameters.AddElement(p); } for (int i = 0; i < num_of_defaults; i++) cnfn.parameters.AddElement(default_params[i]); statements_list sl = new statements_list(null); common_namespace_function_call cnfc = new common_namespace_function_call(top_function as common_namespace_function_node, null); foreach (common_parameter p in cnfn.parameters) { cnfc.parameters.AddElement(new common_parameter_reference(p, 0, null)); } for (int i = num_of_defaults; i < default_params.Count; i++) cnfc.parameters.AddElement(default_params[i].default_value); if (cnfn.return_value_type != null) sl.statements.AddElement(new return_node(cnfc, null)); else sl.statements.AddElement(cnfc); cnfn.function_code = sl; converted_namespace.functions.AddElement(cnfn); } else { common_method_node cmn = top_function as common_method_node; common_method_node cnfn = new common_method_node(top_function.name, top_function.return_value_type, null, converted_type, top_function.polymorphic_state, top_function.field_access_level, null); foreach (parameter p in top_function.parameters) { if (p.default_value == null) cnfn.parameters.AddElement(p); } for (int i = 0; i < num_of_defaults; i++) cnfn.parameters.AddElement(default_params[i]); statements_list sl = new statements_list(null); common_method_call cnfc = new common_method_call(cmn, (cnfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) ? new this_node(converted_type, null) : null, null); foreach (common_parameter p in cnfn.parameters) { cnfc.parameters.AddElement(new common_parameter_reference(p, 0, null)); } for (int i = num_of_defaults; i < default_params.Count; i++) cnfc.parameters.AddElement(default_params[i].default_value); if (cnfn.return_value_type != null) sl.statements.AddElement(new return_node(cnfc, null)); else sl.statements.AddElement(cnfc); cnfn.function_code = sl; cnfn.is_constructor = cmn.is_constructor; converted_type.methods.AddElement(cnfn); } num_of_defaults--; } }