From e3ee0fed4cc09407624174c49fc70511fe6cfb7e Mon Sep 17 00:00:00 2001 From: Ivan Bondarev Date: Tue, 13 Aug 2024 13:49:30 +0200 Subject: [PATCH] #3097 --- NETGenerator/NETGenerator.cs | 4 +++ SemanticTree/SemanticTree.cs | 2 +- TestSuite/enum9.pas | 19 +++++++++++++ TreeConverter/SystemLib/static_executors.cs | 10 +++++-- .../TreeConversion/compilation_context.cs | 7 +++-- .../TreeConversion/syntax_tree_visitor.cs | 28 ++++++++++++++----- 6 files changed, 58 insertions(+), 12 deletions(-) create mode 100644 TestSuite/enum9.pas diff --git a/NETGenerator/NETGenerator.cs b/NETGenerator/NETGenerator.cs index 58187702b..a0300d86a 100644 --- a/NETGenerator/NETGenerator.cs +++ b/NETGenerator/NETGenerator.cs @@ -9850,6 +9850,10 @@ namespace PascalABCCompiler.NETGenerator case basic_function_type.ior: il.Emit(OpCodes.Or); break; case basic_function_type.ixor: il.Emit(OpCodes.Xor); break; + case basic_function_type.enumsand: il.Emit(OpCodes.And); break; + case basic_function_type.enumsor: il.Emit(OpCodes.Or); break; + case basic_function_type.enumsxor: il.Emit(OpCodes.Xor); break; + case basic_function_type.land: il.Emit(OpCodes.And); break; case basic_function_type.lor: il.Emit(OpCodes.Or); break; case basic_function_type.lxor: il.Emit(OpCodes.Xor); break; diff --git a/SemanticTree/SemanticTree.cs b/SemanticTree/SemanticTree.cs index 94ccc68ff..769d3e436 100644 --- a/SemanticTree/SemanticTree.cs +++ b/SemanticTree/SemanticTree.cs @@ -64,7 +64,7 @@ namespace PascalABCCompiler.SemanticTree //write,writei,writed,writec,writeb,read,readi,readd,readc,readb,expd,absd,absi //temporary functions (Нужны только на начальном этапе отладки. Потом обязательно удалить.) objtoobj, boolinc, booldec, boolsinc, boolsdec, booltoi, enumgr, enumgreq, enumsm, enumsmeq, booltob, booltosb, booltos, booltous, booltoui, booltol, booltoul, - ltop, ptol + ltop, ptol, enumsand, enumsor, enumsxor }; public enum runtime_statement_type { invoke_delegate, ctor_delegate, begin_invoke_delegate, end_invoke_delegate }; diff --git a/TestSuite/enum9.pas b/TestSuite/enum9.pas new file mode 100644 index 000000000..9d2124e48 --- /dev/null +++ b/TestSuite/enum9.pas @@ -0,0 +1,19 @@ +type + Days = ( + None = 0, // 0 + Monday = 1, // 1 + Tuesday = 2, // 2 + Wednesday = 4, // 4 + Thursday = 8, // 8 + Friday = 16, // 16 + Saturday = 32, // 32 + Sunday = 64, // 64 + Weekend = Saturday or Sunday + ); + +begin + var d : Days := Saturday; + var meetingDays := Days.Monday or Days.Friday; + assert((d and Days.Weekend) = Saturday); + assert((meetingDays and Days.Friday) = Days.Friday); +end. \ No newline at end of file diff --git a/TreeConverter/SystemLib/static_executors.cs b/TreeConverter/SystemLib/static_executors.cs index f237b679e..2d61a219e 100644 --- a/TreeConverter/SystemLib/static_executors.cs +++ b/TreeConverter/SystemLib/static_executors.cs @@ -2683,12 +2683,18 @@ namespace PascalABCCompiler.SystemLibrary int_const_node left = parameters[0] as int_const_node; if (left == null) { - return null; + if (parameters[0] is enum_const_node ecn) + left = new int_const_node(ecn.constant_value, ecn.location); + else + return null; } int_const_node right = parameters[1] as int_const_node; if (right == null) { - return null; + if (parameters[1] is enum_const_node ecn) + right = new int_const_node(ecn.constant_value, ecn.location); + else + return null; } return (make_int_const(((left.constant_value) | (right.constant_value)), call_location)); } diff --git a/TreeConverter/TreeConversion/compilation_context.cs b/TreeConverter/TreeConversion/compilation_context.cs index 95fde5f7e..d7d581c87 100644 --- a/TreeConverter/TreeConversion/compilation_context.cs +++ b/TreeConverter/TreeConversion/compilation_context.cs @@ -2052,8 +2052,11 @@ namespace PascalABCCompiler.TreeConverter SystemLibrary.SystemLibrary.make_binary_operator(StringConstants.greq_name,tctn,SemanticTree.basic_function_type.enumgreq,SystemLibrary.SystemLibrary.bool_type); SystemLibrary.SystemLibrary.make_binary_operator(StringConstants.sm_name,tctn,SemanticTree.basic_function_type.enumsm,SystemLibrary.SystemLibrary.bool_type); SystemLibrary.SystemLibrary.make_binary_operator(StringConstants.smeq_name,tctn,SemanticTree.basic_function_type.enumsmeq,SystemLibrary.SystemLibrary.bool_type); - - SystemLibrary.SystemLibrary.make_generated_type_conversion(tctn,SystemLibrary.SystemLibrary.byte_type,type_compare.greater_type,PascalABCCompiler.SemanticTree.basic_function_type.itob,false); + SystemLibrary.SystemLibrary.make_binary_operator(StringConstants.or_name, tctn, SemanticTree.basic_function_type.enumsor, tctn); + SystemLibrary.SystemLibrary.make_binary_operator(StringConstants.and_name, tctn, SemanticTree.basic_function_type.enumsand, tctn); + SystemLibrary.SystemLibrary.make_binary_operator(StringConstants.xor_name, tctn, SemanticTree.basic_function_type.enumsxor, tctn); + + SystemLibrary.SystemLibrary.make_generated_type_conversion(tctn,SystemLibrary.SystemLibrary.byte_type,type_compare.greater_type,PascalABCCompiler.SemanticTree.basic_function_type.itob,false); SystemLibrary.SystemLibrary.make_generated_type_conversion(tctn,SystemLibrary.SystemLibrary.sbyte_type,type_compare.greater_type,PascalABCCompiler.SemanticTree.basic_function_type.itosb,false); SystemLibrary.SystemLibrary.make_generated_type_conversion(tctn,SystemLibrary.SystemLibrary.short_type,type_compare.greater_type,PascalABCCompiler.SemanticTree.basic_function_type.itos,false); SystemLibrary.SystemLibrary.make_generated_type_conversion(tctn,SystemLibrary.SystemLibrary.ushort_type,type_compare.greater_type,PascalABCCompiler.SemanticTree.basic_function_type.itous,false); diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index b2f44a5c2..0fd47d29b 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -1180,7 +1180,12 @@ namespace PascalABCCompiler.TreeConverter left_type = SystemLibrary.SystemLibrary.integer_type; left.type = left_type; } - + + if (right_type == null && right is enum_const_node) + { + right_type = SystemLibrary.SystemLibrary.integer_type; + right.type = right_type; + } if (left_type.semantic_node_type == semantic_node_type.delegated_method) { @@ -3655,7 +3660,11 @@ namespace PascalABCCompiler.TreeConverter cdn.const_value = new enum_const_node(num++, null, get_location(id)); else { - constant_node cn = convert_strong_to_constant_node(en.value,SystemLibrary.SystemLibrary.integer_type); + constant_node cn = convert_strong_to_constant_node(en.value, SystemLibrary.SystemLibrary.integer_type); + if (cn is basic_function_call_as_constant bfcc && bfcc.method_call.function_node.compile_time_executor != null) + { + cn = convert_strong_to_constant_node(bfcc.method_call.function_node.compile_time_executor(bfcc.location, bfcc.method_call.parameters.ToArray()), SystemLibrary.SystemLibrary.integer_type); + } check_for_strong_constant(cn,get_location(en.value)); cdn.const_value = new enum_const_node((cn as int_const_node).constant_value,null,get_location(id)); } @@ -3663,6 +3672,12 @@ namespace PascalABCCompiler.TreeConverter } common_type_node ctn = context.create_enum_type(null, get_location(_enum_type_definition)); //_enum_type_definition.values num = 0; + foreach (constant_definition_node cdn in cnsts) + { + cdn.const_value.type = ctn; + } + + int i = 0; foreach (SyntaxTree.enumerator en in _enum_type_definition.enumerators.enumerators) { SyntaxTree.ident id = (en.name as named_type_reference).FirstIdent; @@ -3671,14 +3686,12 @@ namespace PascalABCCompiler.TreeConverter cdn.const_value = new enum_const_node(num++, null, get_location(id)); else { - constant_node cn = convert_strong_to_constant_node(en.value,SystemLibrary.SystemLibrary.integer_type); - check_for_strong_constant(cn,get_location(en.value)); - cdn.const_value = new enum_const_node((cn as int_const_node).constant_value,null,get_location(id)); + cdn.const_value = cnsts[i].const_value; } cdn.const_value.type = ctn; + i++; } - foreach (constant_definition_node cdn in cnsts) - cdn.const_value.type = ctn; + internal_interface ii = SystemLibrary.SystemLibrary.integer_type.get_internal_interface(internal_interface_kind.ordinal_interface); ordinal_type_interface oti_old = (ordinal_type_interface)ii; enum_const_node lower_value = new enum_const_node(0, ctn, ctn.loc); @@ -3688,6 +3701,7 @@ namespace PascalABCCompiler.TreeConverter oti_old.lower_eq_method, oti_old.greater_eq_method, oti_old.lower_method, oti_old.greater_method, lower_value, upper_value, oti_old.value_to_int, oti_old.ordinal_type_to_int); ctn.add_internal_interface(oti_new); + //foreach (constant_definition_node cdn in cnsts) // cdn.const_value.type = ctn; //context.leave_block();