This commit is contained in:
Ivan Bondarev 2020-12-30 14:54:53 +01:00
parent e63874ad29
commit 7360970117
4 changed files with 134 additions and 28 deletions

27
TestSuite/records17.pas Normal file
View 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
View 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.

View file

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

View file

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