This commit is contained in:
Бондарев Иван 2019-08-25 12:17:47 +02:00
parent 6a15518c9d
commit 0d10a0c881
5 changed files with 126 additions and 12 deletions

View file

@ -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)
{
}

81
TestSuite/params12.pas Normal file
View file

@ -0,0 +1,81 @@
procedure p2<T>(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<T>(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.

View file

@ -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;
}
/// <summary>
/// Добавляет список элементов к списку.
/// </summary>

View file

@ -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<expression_node> args = new List<expression_node>();
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<expression_node>(), 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<expression_node>(), 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++)

View file

@ -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);