diff --git a/NETGenerator/NETGenerator.cs b/NETGenerator/NETGenerator.cs index 618f1c7a0..89db124e0 100644 --- a/NETGenerator/NETGenerator.cs +++ b/NETGenerator/NETGenerator.cs @@ -4029,7 +4029,7 @@ namespace PascalABCCompiler.NETGenerator private void GenerateArrayInitCode(ILGenerator il, LocalBuilder lb, IArrayInitializer InitalValue, ITypeNode ArrayType) { IExpressionNode[] ElementValues = InitalValue.ElementValues; - if (ElementValues[0] is IArrayInitializer) + if (ElementValues.Length > 0 && ElementValues[0] is IArrayInitializer) { bool is_unsized_array; Type FieldType, ArrType; @@ -4076,7 +4076,7 @@ namespace PascalABCCompiler.NETGenerator } } else - if (ElementValues[0] is IRecordConstantNode || ElementValues[0] is IRecordInitializer) + if (ElementValues.Length > 0 && (ElementValues[0] is IRecordConstantNode || ElementValues[0] is IRecordInitializer)) { TypeInfo ti = helper.GetTypeReference(ElementValues[0].type); LocalBuilder llb = il.DeclareLocal(ti.tp.MakePointerType()); @@ -4127,14 +4127,19 @@ namespace PascalABCCompiler.NETGenerator PushIntConst(il, i); this.il = ilb; } - if (ti != null && ti.tp.IsValueType && !TypeFactory.IsStandType(ti.tp) && !ti.tp.IsEnum) - il.Emit(OpCodes.Ldelema, ti.tp); + + if (ti != null && ti.tp.IsValueType && !TypeFactory.IsStandType(ti.tp) && lb.LocalType.GetElementType().IsValueType && (helper.IsConstructedGenericType(ti.tp) || ti.tp.IsGenericType || !ti.tp.IsEnum)) + { + if (!(ti.tp is EnumBuilder)) + il.Emit(OpCodes.Ldelema, ti.tp); + } else - if (ti != null && ti.assign_meth != null) + if (ti != null && ti.assign_meth != null && lb.LocalType.GetElementType() != TypeFactory.ObjectType) il.Emit(OpCodes.Ldelem_Ref); + this.il = il; ElementValues[i].visit(this); - if (ti != null && ti.assign_meth != null) + if (ti != null && ti.assign_meth != null && lb.LocalType.GetElementType() != TypeFactory.ObjectType) { il.Emit(OpCodes.Call, ti.assign_meth); this.il = ilb; @@ -10853,7 +10858,7 @@ namespace PascalABCCompiler.NETGenerator else il.Emit(OpCodes.Ldsfld, helper.GetVariable((value.Event as ICommonNamespaceEventNode).Field).fb); } - + public override void visit(SemanticTree.ILambdaFunctionNode value) { } diff --git a/TestSuite/params12.pas b/TestSuite/params12.pas new file mode 100644 index 000000000..e2d2e56ea --- /dev/null +++ b/TestSuite/params12.pas @@ -0,0 +1,81 @@ +procedure p2(params a: array of T); +begin + assert(a.Length = 3); + assert(a[0].ToString() = '1'); + assert(a[1].ToString() = '2'); + assert(a[2].ToString() = '3'); +end; + +procedure p(params a: array of T); +begin + p2(a[0], a[1], a[2]); +end; + +type TRec = record + x: integer; +end; + +type digits = (one, two, three); + +procedure p3(params a: array of TRec); +begin + assert(a[0].x = 1); + assert(a[1].x = 2); +end; + +procedure p4(params a: array of digits); +begin + assert(a[0] = one); + assert(a[1] = two); +end; + +procedure p5(params a: array of object); +begin + assert(a[0] = nil); + assert(a[1] = nil); +end; + +procedure p6(params a: array of integer?); +begin + assert(a[0] = nil); + assert(a[1] = nil); +end; + +procedure p7(params a: array of integer?); +begin + assert(a[0] = 1); + assert(a[1] = 2); +end; + +procedure p8(params a: array of integer); +procedure Nested(params a: array of integer); +begin + assert(a[0] = 1); + assert(a[1] = 2); +end; +begin + Nested(a[0], a[1]); +end; + +type CharSet = set of char; + +procedure p9(params a: array of CharSet); +begin + assert('d' in a[0]); + assert('k' in a[1]); +end; + +begin + p(1,2,3); + var r1: TRec; + var r2: TRec; + r1.x := 1; + r2.x := 2; + p3(r1, r2); + p4(one, two); + p5(nil, nil); + p6(nil, nil); + p7(1, 2); + p8(1, 2); + p9(['d','e'], ['k']); +end. \ No newline at end of file diff --git a/TreeConverter/Collections/extandable_collection.cs b/TreeConverter/Collections/extandable_collection.cs index 8d8d9786e..bb2bf1710 100644 --- a/TreeConverter/Collections/extandable_collection.cs +++ b/TreeConverter/Collections/extandable_collection.cs @@ -74,7 +74,13 @@ namespace PascalABCCompiler.Collections _elements.Add(element); _elements_as_arr = null; } - + + public void RemoveElement(T element) + { + _elements.Remove(element); + _elements_as_arr = null; + } + /// /// Добавляет список элементов к списку. /// diff --git a/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs b/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs index 2b716d7ae..cfb6b55e8 100644 --- a/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs +++ b/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs @@ -912,16 +912,29 @@ namespace PascalABCCompiler.TreeConverter if (cfn.is_generic_function || !syntax_tree_visitor.context.has_nested_functions && syntax_tree_visitor.context.converted_func_stack.size == 1) { vdn = syntax_tree_visitor.context.add_var_definition(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); + syntax_tree_visitor.context.converted_type.fields.RemoveElement(vdn as class_field); + } else + { vdn = syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(), loc); + syntax_tree_visitor.context.converted_namespace.variables.RemoveElement(vdn as namespace_variable); + } } 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); + syntax_tree_visitor.context.converted_type.fields.RemoveElement(vdn as class_field); + } else + { vdn = syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(), loc); + syntax_tree_visitor.context.converted_namespace.variables.RemoveElement(vdn as namespace_variable); + } syntax_tree_visitor.context.close_var_definition_list(pr.type,null); expression_node fst=null; @@ -973,7 +986,6 @@ namespace PascalABCCompiler.TreeConverter 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(); @@ -1615,10 +1627,14 @@ namespace PascalABCCompiler.TreeConverter { //statement_list_stack.top().statements.AddRange(ptcal.snl); statements_expression_node sre = new statements_expression_node(ptcal.snl, ptcal.var_ref, ptcal.var_ref.location); + List args = new List(); + for (int j = fn.parameters.Count - 1; j < exprs.Count; j++) + args.Add(convert_type(exprs[j], fn.parameters[fn.parameters.Count - 1].type.element_type)); exprs.remove_range(fn.parameters.Count - 1, exprs.Count - fn.parameters.Count); //exprs.AddElement(ptcal.var_ref); //exprs[i] = ptcal.var_ref; - exprs[i] = sre; + exprs[i] = new array_initializer(args, ptcal.var_ref.location); + exprs[i].type = fn.parameters[fn.parameters.Count - 1].type; break; } if ((ptcal[i]==null)||(ptcal[i].first==null)||exprs[i] is null_const_node) @@ -1643,7 +1659,9 @@ namespace PascalABCCompiler.TreeConverter //exprs.remove_range(fn.parameters.Count - 1, exprs.Count - fn.parameters.Count); //exprs.AddElement(ptcal.var_ref); //exprs[i] = ptcal.var_ref; - exprs.AddElement(sre); + var arri = new array_initializer(new List(), ptcal.var_ref.location); + arri.type = fn.parameters[fn.parameters.Count - 1].type; + exprs.AddElement(arri); } common_function_node cfn = (common_function_node)fn; for (int j = exprs.Count; j < cfn.parameters.Count; j++) @@ -1660,7 +1678,10 @@ namespace PascalABCCompiler.TreeConverter && fn.parameters != null && fn.parameters.Count - 1 == exprs.Count && fn.parameters[fn.parameters.Count - 1].is_params) { statements_expression_node sre = new statements_expression_node(ptcal.snl, ptcal.var_ref, ptcal.var_ref.location); - exprs.AddElement(sre); + //exprs.AddElement(sre); + var arri = new array_initializer(new List(), ptcal.var_ref.location); + arri.type = fn.parameters[fn.parameters.Count - 1].type; + exprs.AddElement(arri); } //compiled_function_node cfn = (compiled_function_node)fn; for (int j = exprs.Count; j < fn.parameters.Count; j++) diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 06452e4a3..534109e2a 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -4165,6 +4165,7 @@ namespace PascalABCCompiler.TreeConverter AddError(get_location(_simple_property), "PROPERTYACCESSOR_{0}_OR_{1}_EXPECTED", compiler_string_consts.PascalReadAccessorName, compiler_string_consts.PascalWriteAccessorName); if (_simple_property.property_type == null) AddError(get_location(_simple_property.property_name), "TYPE_NAME_EXPECTED"); + common_property_node pn = context.add_property(_simple_property.property_name.name, get_location(_simple_property.property_name)); assign_doc_info(pn, _simple_property);