This commit is contained in:
Ivan Bondarev 2024-08-13 13:49:30 +02:00
parent d396c4a9fe
commit e3ee0fed4c
6 changed files with 58 additions and 12 deletions

View file

@ -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;

View file

@ -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 };

19
TestSuite/enum9.pas Normal file
View file

@ -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.

View file

@ -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));
}

View file

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

View file

@ -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();