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)
|
private void GenerateArrayInitCode(ILGenerator il, LocalBuilder lb, IArrayInitializer InitalValue, ITypeNode ArrayType)
|
||||||
{
|
{
|
||||||
IExpressionNode[] ElementValues = InitalValue.ElementValues;
|
IExpressionNode[] ElementValues = InitalValue.ElementValues;
|
||||||
if (ElementValues[0] is IArrayInitializer)
|
if (ElementValues.Length > 0 && ElementValues[0] is IArrayInitializer)
|
||||||
{
|
{
|
||||||
bool is_unsized_array;
|
bool is_unsized_array;
|
||||||
Type FieldType, ArrType;
|
Type FieldType, ArrType;
|
||||||
|
|
@ -4076,7 +4076,7 @@ namespace PascalABCCompiler.NETGenerator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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);
|
TypeInfo ti = helper.GetTypeReference(ElementValues[0].type);
|
||||||
LocalBuilder llb = il.DeclareLocal(ti.tp.MakePointerType());
|
LocalBuilder llb = il.DeclareLocal(ti.tp.MakePointerType());
|
||||||
|
|
@ -4127,14 +4127,19 @@ namespace PascalABCCompiler.NETGenerator
|
||||||
PushIntConst(il, i);
|
PushIntConst(il, i);
|
||||||
this.il = ilb;
|
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
|
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);
|
il.Emit(OpCodes.Ldelem_Ref);
|
||||||
|
|
||||||
this.il = il;
|
this.il = il;
|
||||||
ElementValues[i].visit(this);
|
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);
|
il.Emit(OpCodes.Call, ti.assign_meth);
|
||||||
this.il = ilb;
|
this.il = ilb;
|
||||||
|
|
@ -10853,7 +10858,7 @@ namespace PascalABCCompiler.NETGenerator
|
||||||
else
|
else
|
||||||
il.Emit(OpCodes.Ldsfld, helper.GetVariable((value.Event as ICommonNamespaceEventNode).Field).fb);
|
il.Emit(OpCodes.Ldsfld, helper.GetVariable((value.Event as ICommonNamespaceEventNode).Field).fb);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void visit(SemanticTree.ILambdaFunctionNode value)
|
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.Add(element);
|
||||||
_elements_as_arr = null;
|
_elements_as_arr = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RemoveElement(T element)
|
||||||
|
{
|
||||||
|
_elements.Remove(element);
|
||||||
|
_elements_as_arr = null;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Добавляет список элементов к списку.
|
/// Добавляет список элементов к списку.
|
||||||
/// </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)
|
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);
|
vdn = syntax_tree_visitor.context.add_var_definition(get_temp_arr_name(), loc);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (syntax_tree_visitor.context.converted_type != null)
|
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);
|
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
|
else
|
||||||
|
{
|
||||||
vdn = syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(), loc);
|
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)
|
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);
|
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
|
else
|
||||||
|
{
|
||||||
vdn = syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(), loc);
|
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);
|
syntax_tree_visitor.context.close_var_definition_list(pr.type,null);
|
||||||
|
|
||||||
expression_node fst=null;
|
expression_node fst=null;
|
||||||
|
|
@ -973,7 +986,6 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
|
|
||||||
expression_node bfc = create_simple_function_call(SystemLibrary.SystemLibrary.resize_func,
|
expression_node bfc = create_simple_function_call(SystemLibrary.SystemLibrary.resize_func,
|
||||||
loc, fst, icn);
|
loc, fst, icn);
|
||||||
tc.snl.AddElement(bfc);
|
|
||||||
/*if (factparams.Count == 0)
|
/*if (factparams.Count == 0)
|
||||||
{
|
{
|
||||||
possible_type_convertions ptci=new possible_type_convertions();
|
possible_type_convertions ptci=new possible_type_convertions();
|
||||||
|
|
@ -1615,10 +1627,14 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
{
|
{
|
||||||
//statement_list_stack.top().statements.AddRange(ptcal.snl);
|
//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);
|
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.remove_range(fn.parameters.Count - 1, exprs.Count - fn.parameters.Count);
|
||||||
//exprs.AddElement(ptcal.var_ref);
|
//exprs.AddElement(ptcal.var_ref);
|
||||||
//exprs[i] = 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;
|
break;
|
||||||
}
|
}
|
||||||
if ((ptcal[i]==null)||(ptcal[i].first==null)||exprs[i] is null_const_node)
|
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.remove_range(fn.parameters.Count - 1, exprs.Count - fn.parameters.Count);
|
||||||
//exprs.AddElement(ptcal.var_ref);
|
//exprs.AddElement(ptcal.var_ref);
|
||||||
//exprs[i] = 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;
|
common_function_node cfn = (common_function_node)fn;
|
||||||
for (int j = exprs.Count; j < cfn.parameters.Count; j++)
|
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)
|
&& 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);
|
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;
|
//compiled_function_node cfn = (compiled_function_node)fn;
|
||||||
for (int j = exprs.Count; j < fn.parameters.Count; j++)
|
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);
|
AddError(get_location(_simple_property), "PROPERTYACCESSOR_{0}_OR_{1}_EXPECTED", compiler_string_consts.PascalReadAccessorName, compiler_string_consts.PascalWriteAccessorName);
|
||||||
if (_simple_property.property_type == null)
|
if (_simple_property.property_type == null)
|
||||||
AddError(get_location(_simple_property.property_name), "TYPE_NAME_EXPECTED");
|
AddError(get_location(_simple_property.property_name), "TYPE_NAME_EXPECTED");
|
||||||
|
|
||||||
common_property_node pn = context.add_property(_simple_property.property_name.name,
|
common_property_node pn = context.add_property(_simple_property.property_name.name,
|
||||||
get_location(_simple_property.property_name));
|
get_location(_simple_property.property_name));
|
||||||
assign_doc_info(pn, _simple_property);
|
assign_doc_info(pn, _simple_property);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue