bug fix #2375
This commit is contained in:
parent
e63874ad29
commit
7360970117
27
TestSuite/records17.pas
Normal file
27
TestSuite/records17.pas
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
type
|
||||
r1 = record
|
||||
i := 1;
|
||||
static function f(a: r1): boolean;
|
||||
begin
|
||||
Result := a = a;
|
||||
end;
|
||||
static function f2(a: r1): boolean;
|
||||
begin
|
||||
Result := a <> a;
|
||||
end;
|
||||
|
||||
{static function operator=(a, b: r1): boolean;
|
||||
begin
|
||||
Result := a.i = b.i;
|
||||
end;
|
||||
|
||||
static function operator<>(a, b: r1): boolean;
|
||||
begin
|
||||
Result := a.i <> b.i;
|
||||
end;}
|
||||
end;
|
||||
|
||||
begin
|
||||
assert(r1.f(new r1));
|
||||
assert(not r1.f2(new r1));
|
||||
end.
|
||||
34
TestSuite/records18.pas
Normal file
34
TestSuite/records18.pas
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
var flag: boolean;
|
||||
|
||||
type
|
||||
r1 = record
|
||||
i := 1;
|
||||
static function f(a: r1): boolean;
|
||||
begin
|
||||
Result := a = a;
|
||||
end;
|
||||
static function f2(a: r1): boolean;
|
||||
begin
|
||||
Result := a <> a;
|
||||
end;
|
||||
|
||||
static function operator=(a, b: r1): boolean;
|
||||
begin
|
||||
flag := true;
|
||||
Result := a.i = b.i;
|
||||
end;
|
||||
|
||||
static function operator<>(a, b: r1): boolean;
|
||||
begin
|
||||
flag := true;
|
||||
Result := a.i <> b.i;
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
assert(r1.f(new r1));
|
||||
assert(flag);
|
||||
flag := false;
|
||||
assert(not r1.f2(new r1));
|
||||
assert(flag);
|
||||
end.
|
||||
|
|
@ -1017,22 +1017,42 @@ namespace PascalABCCompiler.TreeConverter
|
|||
|
||||
private readonly System.Collections.Generic.Stack<common_type_node> type_stack = new System.Collections.Generic.Stack<common_type_node>();
|
||||
|
||||
private void add_notequal_operator_if_need()
|
||||
internal void add_notequal_operator_if_need(bool not_add_body= false)
|
||||
{
|
||||
List<SymbolInfo> si_list = _ctn.find_in_type(compiler_string_consts.noteq_name);
|
||||
common_method_node cmn = null;
|
||||
common_parameter prm1 = null;
|
||||
common_parameter prm2 = null;
|
||||
foreach (SymbolInfo si2 in si_list)
|
||||
if (si2.sym_info is common_method_node)
|
||||
return;
|
||||
{
|
||||
cmn = si2.sym_info as common_method_node;
|
||||
if (cmn.function_code != null)
|
||||
return;
|
||||
}
|
||||
SymbolInfo si = si_list[0];
|
||||
SymbolTable.ClassMethodScope scope = convertion_data_and_alghoritms.symbol_table.CreateClassMethodScope(_ctn.scope, _cmn.scope, null, si.ToString());
|
||||
common_method_node cmn = new common_method_node(compiler_string_consts.GetNETOperName(compiler_string_consts.noteq_name),SystemLibrary.SystemLibrary.bool_type,null,_ctn,
|
||||
SemanticTree.polymorphic_state.ps_static,SemanticTree.field_access_level.fal_public,scope);
|
||||
cmn.IsOperator = true;
|
||||
common_parameter prm1 = new common_parameter("a",_ctn,SemanticTree.parameter_type.value,cmn,concrete_parameter_type.cpt_none,null,null);
|
||||
common_parameter prm2 = new common_parameter("b",_ctn,SemanticTree.parameter_type.value,cmn,concrete_parameter_type.cpt_none,null,null);
|
||||
cmn.parameters.AddElement(prm1);
|
||||
cmn.parameters.AddElement(prm2);
|
||||
statements_list body = new statements_list(null);
|
||||
if (cmn == null)
|
||||
{
|
||||
cmn = new common_method_node(compiler_string_consts.GetNETOperName(compiler_string_consts.noteq_name), SystemLibrary.SystemLibrary.bool_type, null, _ctn,
|
||||
SemanticTree.polymorphic_state.ps_static, SemanticTree.field_access_level.fal_public, scope);
|
||||
cmn.IsOperator = true;
|
||||
prm1 = new common_parameter("a", _ctn, SemanticTree.parameter_type.value, cmn, concrete_parameter_type.cpt_none, null, null);
|
||||
prm2 = new common_parameter("b", _ctn, SemanticTree.parameter_type.value, cmn, concrete_parameter_type.cpt_none, null, null);
|
||||
cmn.parameters.AddElement(prm1);
|
||||
cmn.parameters.AddElement(prm2);
|
||||
cmn.is_overload = true;
|
||||
_ctn.methods.AddElement(cmn);
|
||||
_ctn.Scope.AddSymbol(compiler_string_consts.noteq_name, new SymbolInfo(cmn));
|
||||
}
|
||||
else
|
||||
{
|
||||
prm1 = cmn.parameters[0] as common_parameter;
|
||||
prm2 = cmn.parameters[1] as common_parameter;
|
||||
}
|
||||
if (not_add_body)
|
||||
return;
|
||||
statements_list body = new statements_list(null);
|
||||
foreach (class_field cf in _ctn.fields)
|
||||
{
|
||||
if (cf.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
|
||||
|
|
@ -1048,26 +1068,45 @@ namespace PascalABCCompiler.TreeConverter
|
|||
}
|
||||
body.statements.AddElement(new return_node(new bool_const_node(false,null),null));
|
||||
cmn.function_code = body;
|
||||
cmn.is_overload = true;
|
||||
_ctn.methods.AddElement(cmn);
|
||||
_ctn.Scope.AddSymbol(compiler_string_consts.noteq_name,new SymbolInfo(cmn));
|
||||
|
||||
}
|
||||
|
||||
private void add_equal_operator_if_need()
|
||||
internal void add_equal_operator_if_need(bool not_add_body=false)
|
||||
{
|
||||
List<SymbolInfo> si_list = _ctn.find_in_type(compiler_string_consts.eq_name);
|
||||
common_method_node cmn = null;
|
||||
common_parameter prm1 = null;
|
||||
common_parameter prm2 = null;
|
||||
foreach (SymbolInfo si2 in si_list)
|
||||
if (si2.sym_info is common_method_node)
|
||||
return;
|
||||
{
|
||||
cmn = si2.sym_info as common_method_node;
|
||||
if (cmn.function_code != null)
|
||||
return;
|
||||
}
|
||||
|
||||
SymbolInfo si = si_list[0];
|
||||
SymbolTable.ClassMethodScope scope = convertion_data_and_alghoritms.symbol_table.CreateClassMethodScope( _ctn.scope, _cmn.scope, null, si.ToString());
|
||||
common_method_node cmn = new common_method_node(compiler_string_consts.GetNETOperName(compiler_string_consts.eq_name),SystemLibrary.SystemLibrary.bool_type,null,_ctn,
|
||||
SemanticTree.polymorphic_state.ps_static,SemanticTree.field_access_level.fal_public,scope);
|
||||
cmn.IsOperator = true;
|
||||
common_parameter prm1 = new common_parameter("a",_ctn,SemanticTree.parameter_type.value,cmn,concrete_parameter_type.cpt_none,null,null);
|
||||
common_parameter prm2 = new common_parameter("b",_ctn,SemanticTree.parameter_type.value,cmn,concrete_parameter_type.cpt_none,null,null);
|
||||
cmn.parameters.AddElement(prm1);
|
||||
cmn.parameters.AddElement(prm2);
|
||||
if (cmn == null)
|
||||
{
|
||||
cmn = new common_method_node(compiler_string_consts.GetNETOperName(compiler_string_consts.eq_name), SystemLibrary.SystemLibrary.bool_type, null, _ctn,
|
||||
SemanticTree.polymorphic_state.ps_static, SemanticTree.field_access_level.fal_public, scope);
|
||||
cmn.IsOperator = true;
|
||||
prm1 = new common_parameter("a", _ctn, SemanticTree.parameter_type.value, cmn, concrete_parameter_type.cpt_none, null, null);
|
||||
prm2 = new common_parameter("b", _ctn, SemanticTree.parameter_type.value, cmn, concrete_parameter_type.cpt_none, null, null);
|
||||
cmn.parameters.AddElement(prm1);
|
||||
cmn.parameters.AddElement(prm2);
|
||||
cmn.is_overload = true;
|
||||
_ctn.methods.AddElement(cmn);
|
||||
_ctn.Scope.AddSymbol(compiler_string_consts.eq_name, new SymbolInfo(cmn));
|
||||
}
|
||||
else
|
||||
{
|
||||
prm1 = cmn.parameters[0] as common_parameter;
|
||||
prm2 = cmn.parameters[1] as common_parameter;
|
||||
}
|
||||
if (not_add_body)
|
||||
return;
|
||||
statements_list body = new statements_list(null);
|
||||
foreach (class_field cf in _ctn.fields)
|
||||
{
|
||||
|
|
@ -1084,9 +1123,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
}
|
||||
body.statements.AddElement(new return_node(new bool_const_node(true,null),null));
|
||||
cmn.function_code = body;
|
||||
cmn.is_overload = true;
|
||||
_ctn.methods.AddElement(cmn);
|
||||
_ctn.Scope.AddSymbol(compiler_string_consts.eq_name,new SymbolInfo(cmn));
|
||||
|
||||
}
|
||||
|
||||
public void leave_record()
|
||||
|
|
@ -1094,8 +1131,8 @@ namespace PascalABCCompiler.TreeConverter
|
|||
check_implement_interfaces();
|
||||
if (!_ctn.IsEnum)
|
||||
{
|
||||
add_equal_operator_if_need();
|
||||
add_notequal_operator_if_need();
|
||||
//add_equal_operator_if_need();
|
||||
//add_notequal_operator_if_need();
|
||||
}
|
||||
if (type_stack.Count != 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3918,6 +3918,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
record_type_name = null;
|
||||
record_is_generic = false;
|
||||
context.converted_type.internal_is_value = true;
|
||||
|
||||
if (_class_definition.body == null &&
|
||||
(_class_definition.class_parents == null || _class_definition.class_parents.types.Count == 0))
|
||||
{
|
||||
|
|
@ -3930,6 +3931,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
}
|
||||
else
|
||||
{
|
||||
|
||||
context.converted_type.ForwardDeclarationOnly = false;
|
||||
weak_node_test_and_visit(_class_definition.body);
|
||||
|
||||
|
|
@ -4051,7 +4053,13 @@ namespace PascalABCCompiler.TreeConverter
|
|||
|
||||
private void visit_class_member_realizations(SyntaxTree.class_body_list _class_body)
|
||||
{
|
||||
foreach (SyntaxTree.class_members clmem in _class_body.class_def_blocks)
|
||||
if (context.converted_type.internal_is_value)
|
||||
{
|
||||
context.add_equal_operator_if_need();
|
||||
context.add_notequal_operator_if_need();
|
||||
}
|
||||
|
||||
foreach (SyntaxTree.class_members clmem in _class_body.class_def_blocks)
|
||||
{
|
||||
foreach (SyntaxTree.declaration sd in clmem.members)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue