fix #2080
This commit is contained in:
parent
6a15518c9d
commit
0d10a0c881
|
|
@ -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
81
TestSuite/params12.pas
Normal 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.
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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++)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue