private void VisitCommonConstructorCall(common_constructor_call en) { for (int i = 0; i < en.parameters.Count; i++) { VisitExpression(en.parameters[i]); } }
private void VisitCommonConstructorCall(common_constructor_call en) { for (int i = 0; i < en.parameters.Count; i++) VisitExpression(en.parameters[i]); }
private void VisitCommonConstructorCall(common_constructor_call expr) { WriteMethodReference(expr.function_node); //ssyy добавил if (expr._new_obj_awaited) { bw.Write((byte)1); } else { bw.Write((byte)0); } //\ssyy bw.Write(expr.parameters.Count); foreach (expression_node e in expr.parameters) VisitExpression(e); }
private base_function_call create_static_method_call(function_node fn, location loc, type_node tn, bool procedure_allowed) { if ((!procedure_allowed) && (fn.return_value_type == null)) { AddError(loc, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", fn.name); } if (fn.semantic_node_type == semantic_node_type.common_method_node) { common_method_node cmn = (common_method_node)fn; if (cmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) { //ssyy изменил if (!cmn.is_constructor) { AddError(new CanNotCallNonStaticMethodWithClass(tn, loc, fn)); } if (cmn.cont_type.IsAbstract) ErrorsList.Add(new SimpleSemanticError(loc, "ABSTRACT_CONSTRUCTOR_{0}_CALL", cmn.name)); common_constructor_call csmc2 = new common_constructor_call(cmn, loc); return csmc2; //if (cmn.pascal_associated_constructor==null) //{ // throw new CanNotCallNonStaticMethodWithClass(tn,loc,fn); //} //common_constructor_call csmc2=new common_constructor_call(cmn.pascal_associated_constructor,loc); //return csmc2; //\ssyy } common_static_method_call csmc = new common_static_method_call(cmn, loc); return csmc; } if (fn.semantic_node_type == semantic_node_type.compiled_function_node) { compiled_function_node cfn = (compiled_function_node)fn; if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) { AddError(new CanNotCallNonStaticMethodWithClass(tn, loc, fn)); } compiled_static_method_call csmc2 = new compiled_static_method_call(cfn, loc); return csmc2; } if (fn.semantic_node_type == semantic_node_type.compiled_constructor_node) { compiled_constructor_node ccn = (compiled_constructor_node)fn; compiled_constructor_call ccc = new compiled_constructor_call(ccn, loc); return ccc; } if (fn.semantic_node_type == semantic_node_type.basic_function_node) { return new basic_function_call(fn as basic_function_node, loc); } if (fn.semantic_node_type == semantic_node_type.common_namespace_function_node && (fn as common_namespace_function_node).ConnectedToType != null) { return new common_namespace_function_call(fn as common_namespace_function_node,loc); } if (fn.semantic_node_type == semantic_node_type.indefinite_definition_node) { return new indefinite_function_call(fn, loc); } throw new CompilerInternalError("Invalid method kind"); }
private void ConvertPointersForWrite(expressions_list exprs) { for (int i = 0; i < exprs.Count; ++i) { if (exprs[i].type.IsPointer) { if (SystemLibrary.SystemLibInitializer.PointerOutputConstructor == null) { SymbolInfo si = (SystemLibrary.SystemLibInitializer.PointerOutputType.sym_info as common_type_node).find_in_type(compiler_string_consts.default_constructor_name); common_method_node cnode = null; do { cnode = si.sym_info as common_method_node; if (cnode.parameters.Count != 1) { cnode = null; si = si.Next; } } while (cnode == null); SystemLibrary.SystemLibInitializer.PointerOutputConstructor = cnode; } common_constructor_call cnc = new common_constructor_call(SystemLibrary.SystemLibInitializer.PointerOutputConstructor as common_method_node, exprs[i].location); //common_namespace_function_call cnfc = new common_namespace_function_call( // SystemLibrary.SystemLibInitializer.PointerToStringFunction.sym_info as common_namespace_function_node, // exprs[i].location); cnc.parameters.AddElement(exprs[i]); exprs[i] = cnc; } } }
//ssyy public void generate_inherit_constructors() { common_type_node _ctn = context.converted_type; if (_ctn == null) { throw new CompilerInternalError("Can generate inherited constructors only in class."); } if (_ctn.has_user_defined_constructor) { //Пользователь определил хотя бы один конструктор, никакие конструкторы не наследуем. return; } //Получили список процедур предка, имеющих имя Create SymbolInfo si = _ctn.base_type.find_in_type(compiler_string_consts.default_constructor_name, _ctn.base_type.Scope); delete_inherited_constructors(ref si, _ctn.base_type); while (si != null) { function_node fn = si.sym_info as function_node; compiled_constructor_node pconstr = fn as compiled_constructor_node; common_method_node mconstr = fn as common_method_node; //Если это конструктор... if (pconstr != null || mconstr != null && mconstr.is_constructor) { //Генерируем унаследованный конструктор location loc = null; SemanticTree.polymorphic_state ps; if (mconstr != null) { loc = mconstr.loc; ps = mconstr.polymorphic_state; } else //значит (pconstr != null) { ps = pconstr.polymorphic_state; } if (pconstr != null) context.set_field_access_level(pconstr.field_access_level); else context.set_field_access_level(mconstr.field_access_level); common_method_node gen_constr = context.create_function(compiler_string_consts.default_constructor_name, loc) as common_method_node; gen_constr.polymorphic_state = ps; gen_constr.is_overload = true; gen_constr.is_constructor = true; gen_constr.field_access_level = fn.field_access_level; gen_constr.return_value_type = _ctn; foreach (parameter par in fn.parameters) { //(ssyy) Интересно, зачем это. concrete_parameter_type cpt = (par.parameter_type == SemanticTree.parameter_type.var) ? concrete_parameter_type.cpt_var : concrete_parameter_type.cpt_none; common_parameter c_p = new common_parameter(par.name, par.parameter_type, gen_constr, cpt, null); c_p.type = par.type; c_p.set_param_is_params(par.is_params); c_p.inital_value = par.inital_value; gen_constr.parameters.AddElement(c_p); c_p.default_value = par.default_value; } base_function_call bfc; if (mconstr != null) { common_constructor_call c1 = new common_constructor_call(mconstr, null); c1._new_obj_awaited = false; bfc = c1; } else { compiled_constructor_call c2 = new compiled_constructor_call(pconstr, null); c2._new_obj_awaited = false; bfc = c2; } foreach (parameter p in gen_constr.parameters) { bfc.parameters.AddElement( create_variable_reference(p, null)); } statements_list snlist = new statements_list(null); snlist.statements.AddElement(bfc); snlist.statements.AddElement(new empty_statement(null)); gen_constr.function_code = snlist; context.leave_block(); if (fn.parameters.Count == 0 || fn.parameters[0].default_value != null) { _ctn.has_default_constructor = true; } } si = si.Next; } }
internal expression_node CreateDelegateCall(base_function_call fn_call) { common_type_node del = CreateDelegate(fn_call.simple_function_node); common_constructor_call deleg_costructor_call = new common_constructor_call(del.methods[0], fn_call.location); deleg_costructor_call.parameters.AddElement((base_function_call)fn_call); return deleg_costructor_call; }
public override function_node get_implicit_conversion_to(type_node ctn) { foreach (base_function_call fn in _proper_methods) { if (fn.simple_function_node.parameters.Count == 0 || (fn.simple_function_node is common_namespace_function_node && (fn.simple_function_node as common_namespace_function_node).ConnectedToType != null || fn.simple_function_node is compiled_function_node && (fn.simple_function_node as compiled_function_node).ConnectedToType != null) && fn.simple_function_node.parameters.Count == 1 && !fn.simple_function_node.parameters[0].is_params) { if (fn.simple_function_node.return_value_type == ctn) { convert_function_to_function_call cftfc = new convert_function_to_function_call(fn); return (new convert_types_function_node(cftfc.compile_time_executor, true)); } if (fn.simple_function_node.return_value_type == null) { continue; } //TODO: Очень внимательно рассмотреть. Если преобразование типов должно идти через compile_time_executor. possible_type_convertions ptc=type_table.get_convertions(fn.simple_function_node.return_value_type, ctn); if ((ptc.first == null) || (ptc.first.convertion_method == null)) { continue; } expression_node ennew=type_table.type_table_function_call_maker(ptc.first.convertion_method, null, fn); convert_function_to_function_call cftfc2 = new convert_function_to_function_call(ennew); return (new convert_types_function_node(cftfc2.compile_time_executor, false)); } else if (fn.simple_function_node.parameters.Count == 1 && fn.simple_function_node.parameters[0].is_params || (fn.simple_function_node is common_namespace_function_node && (fn.simple_function_node as common_namespace_function_node).ConnectedToType != null || fn.simple_function_node is compiled_function_node && (fn.simple_function_node as compiled_function_node).ConnectedToType != null) && fn.simple_function_node.parameters.Count == 2 && fn.simple_function_node.parameters[1].is_params) { base_function_call copy_fn = get_function_call_copy(fn); int param_num = (fn.simple_function_node is common_namespace_function_node && (fn.simple_function_node as common_namespace_function_node).ConnectedToType != null || fn.simple_function_node is compiled_function_node && (fn.simple_function_node as compiled_function_node).ConnectedToType != null) ? 1 : 0; if (fn.simple_function_node.return_value_type == ctn) { common_namespace_function_call cnfc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.NewArrayProcedureDecl,null); cnfc.parameters.AddElement(new typeof_operator(fn.simple_function_node.parameters[param_num].type, null)); cnfc.parameters.AddElement(new int_const_node(0,null)); if (copy_fn.parameters.Count < fn.simple_function_node.parameters.Count) copy_fn.parameters.AddElement(cnfc); convert_function_to_function_call cftfc = new convert_function_to_function_call(copy_fn); return (new convert_types_function_node(cftfc.compile_time_executor, true)); } if (fn.simple_function_node.return_value_type == null) { continue; } //TODO: Очень внимательно рассмотреть. Если преобразование типов должно идти через compile_time_executor. possible_type_convertions ptc=type_table.get_convertions(fn.simple_function_node.return_value_type, ctn); if ((ptc.first == null) || (ptc.first.convertion_method == null)) { continue; } common_namespace_function_call cnfc2 = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.NewArrayProcedureDecl,null); cnfc2.parameters.AddElement(new typeof_operator(fn.simple_function_node.parameters[param_num].type, null)); cnfc2.parameters.AddElement(new int_const_node(0,null)); if (copy_fn.parameters.Count < fn.simple_function_node.parameters.Count) copy_fn.parameters.AddElement(cnfc2); expression_node ennew=type_table.type_table_function_call_maker(ptc.first.convertion_method, null, copy_fn); convert_function_to_function_call cftfc2 = new convert_function_to_function_call(ennew); return (new convert_types_function_node(cftfc2.compile_time_executor, false)); } else if (fn.simple_function_node.parameters.Count == 1 && fn.simple_function_node.parameters[0].default_value != null || (fn.simple_function_node is common_namespace_function_node && (fn.simple_function_node as common_namespace_function_node).ConnectedToType != null || fn.simple_function_node is compiled_function_node && (fn.simple_function_node as compiled_function_node).ConnectedToType != null) && fn.simple_function_node.parameters.Count == 2 && fn.simple_function_node.parameters[1].default_value != null) { int param_num = (fn.simple_function_node is common_namespace_function_node && (fn.simple_function_node as common_namespace_function_node).ConnectedToType != null || fn.simple_function_node is compiled_function_node && (fn.simple_function_node as compiled_function_node).ConnectedToType != null) ? 1 : 0; base_function_call copy_fn = null; if (fn.simple_function_node.return_value_type == ctn) { copy_fn = get_function_call_copy(fn); copy_fn.parameters.AddElement(fn.simple_function_node.parameters[param_num].default_value); convert_function_to_function_call cftfc = new convert_function_to_function_call(copy_fn); return (new convert_types_function_node(cftfc.compile_time_executor, true)); } if (fn.simple_function_node.return_value_type == null) { continue; } //TODO: Очень внимательно рассмотреть. Если преобразование типов должно идти через compile_time_executor. possible_type_convertions ptc = type_table.get_convertions(fn.simple_function_node.return_value_type, ctn); if ((ptc.first == null) || (ptc.first.convertion_method == null)) { continue; } copy_fn = get_function_call_copy(fn); copy_fn.parameters.AddElement(fn.simple_function_node.parameters[param_num].default_value); expression_node ennew = type_table.type_table_function_call_maker(ptc.first.convertion_method, null, copy_fn); convert_function_to_function_call cftfc2 = new convert_function_to_function_call(ennew); return (new convert_types_function_node(cftfc2.compile_time_executor, false)); } else if (fn.simple_function_node.parameters.Count == fn.simple_function_node.num_of_default_parameters) { base_function_call copy_fn = get_function_call_copy(fn); if (fn.simple_function_node.return_value_type == ctn) { foreach (parameter p in fn.simple_function_node.parameters) copy_fn.parameters.AddElement(p.default_value); convert_function_to_function_call cftfc = new convert_function_to_function_call(copy_fn); return (new convert_types_function_node(cftfc.compile_time_executor, true)); } if (fn.simple_function_node.return_value_type == null) { continue; } //TODO: Очень внимательно рассмотреть. Если преобразование типов должно идти через compile_time_executor. possible_type_convertions ptc = type_table.get_convertions(fn.simple_function_node.return_value_type, ctn); if ((ptc.first == null) || (ptc.first.convertion_method == null)) { continue; } foreach (parameter p in fn.simple_function_node.parameters) copy_fn.parameters.AddElement(p.default_value); expression_node ennew = type_table.type_table_function_call_maker(ptc.first.convertion_method, null, copy_fn); convert_function_to_function_call cftfc2 = new convert_function_to_function_call(ennew); return (new convert_types_function_node(cftfc2.compile_time_executor, false)); } } internal_interface ii = ctn.get_internal_interface(internal_interface_kind.delegate_interface); if (ii == null) { if (ctn is compiled_type_node && (ctn as compiled_type_node).IsDelegate) { common_type_node del = type_constructor.instance.create_delegate(compilation_context.instance.get_delegate_type_name(), this.proper_methods[0].simple_function_node.return_value_type, this.proper_methods[0].simple_function_node.parameters, compilation_context.instance.converted_namespace, null); compilation_context.instance.converted_namespace.types.AddElement(del); ii = del.get_internal_interface(internal_interface_kind.delegate_interface); } else return null; } delegate_internal_interface dii = (delegate_internal_interface)ii; base_function_call _finded_call = null; foreach(base_function_call bfn in _proper_methods) { if (bfn.simple_function_node.parameters.Count != dii.parameters.Count) { continue; } if (bfn.simple_function_node.return_value_type != dii.return_value_type) { if (!type_table.is_derived(dii.return_value_type, bfn.simple_function_node.return_value_type)) // SSM 21/05/15 if (!(bfn.ret_type is lambda_any_type_node)) //lroman// continue; } bool find_eq = true; int i=0; while ((find_eq == true) && (i<bfn.simple_function_node.parameters.Count)) { /*var a1 = bfn.simple_function_node.parameters[i].type != dii.parameters[i].type; var a2 = bfn.simple_function_node.parameters[i].parameter_type != dii.parameters[i].parameter_type; var a3 = bfn.simple_function_node.parameters[i].is_params != dii.parameters[i].is_params;*/ //lroman// Добавил все, что связано с lambda_any_type_node. Считаем, что этот тип равен всем типам. Это используется при выводе параметров лямбды if ((bfn.simple_function_node.parameters[i].type != dii.parameters[i].type && !(bfn.simple_function_node.parameters[i].type is lambda_any_type_node)) || (bfn.simple_function_node.parameters[i].parameter_type != dii.parameters[i].parameter_type && !(bfn.simple_function_node.parameters[i].parameter_type is lambda_any_type_node)) || bfn.simple_function_node.parameters[i].is_params != dii.parameters[i].is_params) { find_eq = false; } i++; } if (find_eq) { _finded_call = bfn; break; } } //Вообщето если мы можем найти более одного вызова функции в цикле выше, то это внутренняя ошибка компилятора, но мы не будем ругаться. if (_finded_call == null) { return null; } if ((_finded_call is common_constructor_call) || (_finded_call is compiled_constructor_call)) { return null; } common_method_node cmn = dii.constructor as common_method_node; if (cmn != null) { common_constructor_call ccc = new common_constructor_call(cmn, null); ccc.parameters.AddElement(_finded_call); convert_function_to_function_call cftfc = new convert_function_to_function_call(ccc); return (new convert_types_function_node(cftfc.compile_time_executor, false)); } compiled_constructor_node ccn = dii.constructor as compiled_constructor_node; if (ccn != null) { compiled_constructor_call ccc = new compiled_constructor_call(ccn, null); ccc.parameters.AddElement(_finded_call); convert_function_to_function_call cftfc = new convert_function_to_function_call(ccc); return (new convert_types_function_node(cftfc.compile_time_executor, false)); } //Тут вообщето тоже внутренняя ошибка компилятора. (Не откомпилированный и не обычный конструктор). return null; }
/// <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 expression_node CreateCommonConstructorCall() { common_method_node meth = GetMethodByOffset(); //ssyy moved up common_constructor_call cmc = new common_constructor_call(meth, null); //\ssyy //ssyy добавил cmc._new_obj_awaited = (br.ReadByte() == 1); //\ssyy 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; }