Restore typeclasses
This commit is contained in:
parent
32fd1a38b0
commit
e53c926d2a
|
|
@ -2,7 +2,7 @@
|
|||
// This CSharp output file generated by Gardens Point LEX
|
||||
// Version: 1.1.3.301
|
||||
// Machine: DESKTOP-7B4K9VB
|
||||
// DateTime: 26.12.2018 0:32:41
|
||||
// DateTime: 26.12.2018 1:39:51
|
||||
// UserName: Bogdan
|
||||
// GPLEX input file <ABCPascal.lex>
|
||||
// GPLEX frame file <embedded resource>
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
// GPPG error listing for yacc source file <ABCPascal.y>
|
||||
// ==========================================================================
|
||||
// Version: 1.3.6
|
||||
// Machine: DESKTOP-A6LT9RI
|
||||
// DateTime: 10.11.2018 23:09:24
|
||||
// UserName: Станислав
|
||||
// Machine: DESKTOP-7B4K9VB
|
||||
// DateTime: 26.12.2018 1:31:13
|
||||
// UserName: Bogdan
|
||||
// ==========================================================================
|
||||
|
||||
|
||||
|
|
@ -35,6 +35,7 @@
|
|||
%using PascalABCCompiler.ParserTools;
|
||||
%using PascalABCCompiler.Errors;
|
||||
%using System.Linq;
|
||||
%using SyntaxVisitors;
|
||||
|
||||
%namespace GPPGParserScanner
|
||||
|
||||
|
|
@ -44,7 +45,7 @@
|
|||
|
||||
%token <ti> tkDirectiveName tkAmpersend tkColon tkDotDot tkPoint tkRoundOpen tkRoundClose tkSemiColon tkSquareOpen tkSquareClose tkQuestion tkQuestionPoint tkDoubleQuestion tkQuestionSquareOpen
|
||||
%token <ti> tkSizeOf tkTypeOf tkWhere tkArray tkCase tkClass tkAuto tkStatic tkConst tkConstructor tkDestructor tkElse tkExcept tkFile tkFor tkForeach tkFunction tkMatch tkWhen
|
||||
%token <ti> tkIf tkImplementation tkInherited tkInterface /* tkTypeclass tkInstance */ tkProcedure tkOperator tkProperty tkRaise tkRecord tkSet tkType tkThen tkUses tkVar tkWhile tkWith tkNil
|
||||
%token <ti> tkIf tkImplementation tkInherited tkInterface tkTypeclass tkInstance tkProcedure tkOperator tkProperty tkRaise tkRecord tkSet tkType tkThen tkUses tkVar tkWhile tkWith tkNil
|
||||
%token <ti> tkGoto tkOf tkLabel tkLock tkProgram tkEvent tkDefault tkTemplate tkPacked tkExports tkResourceString tkThreadvar tkSealed tkPartial tkTo tkDownto
|
||||
%token <ti> tkLoop
|
||||
%token <ti> tkSequence tkYield
|
||||
|
|
@ -88,7 +89,7 @@
|
|||
%type <stn> exception_handler
|
||||
%type <stn> exception_handler_list
|
||||
%type <stn> exception_identifier
|
||||
%type <stn> typed_const_list1 typed_const_list optional_expr_list elem_list optional_expr_list_with_bracket expr_list const_elem_list1 const_func_expr_list case_label_list const_elem_list optional_const_func_expr_list elem_list1
|
||||
%type <stn> typed_const_list1 typed_const_list optional_expr_list elem_list optional_expr_list_with_bracket expr_list const_elem_list1 /*const_func_expr_list*/ case_label_list const_elem_list optional_const_func_expr_list elem_list1
|
||||
%type <stn> enumeration_id expr_l1_list
|
||||
%type <stn> enumeration_id_list
|
||||
%type <ex> const_simple_expr term simple_term typed_const typed_const_plus typed_var_init_expression expr expr_with_func_decl_lambda const_expr elem range_expr const_elem array_const factor relop_expr expr_dq expr_l1 expr_l1_func_decl_lambda simple_expr range_term range_factor
|
||||
|
|
@ -104,7 +105,7 @@
|
|||
%type <id> func_name_ident param_name const_field_name func_name_with_template_args identifier_or_keyword unit_name exception_variable const_name func_meth_name_ident label_name type_decl_identifier template_identifier_with_equal
|
||||
%type <id> program_param identifier identifier_keyword_operatorname func_class_name_ident /*optional_identifier*/ visibility_specifier
|
||||
%type <id> property_specifier_directives non_reserved
|
||||
//%type <id> typeclass_restriction
|
||||
%type <id> typeclass_restriction
|
||||
%type <stn> if_stmt
|
||||
%type <stn> initialization_part
|
||||
%type <stn> template_arguments label_list ident_or_keyword_pointseparator_list ident_list param_name_list
|
||||
|
|
@ -166,7 +167,7 @@
|
|||
%type <ex> typeof_expr
|
||||
%type <stn> simple_fp_sect
|
||||
%type <stn> template_param_list template_empty_param_list template_type_params template_type_empty_params
|
||||
//%type <stn> template_type_or_typeclass_params typeclass_params
|
||||
%type <stn> template_type_or_typeclass_params typeclass_params
|
||||
%type <td> template_type
|
||||
%type <stn> try_stmt
|
||||
%type <stn> uses_clause used_units_list
|
||||
|
|
@ -174,7 +175,7 @@
|
|||
%type <stn> used_unit_name
|
||||
%type <stn> unit_header
|
||||
%type <stn> var_decl_sect
|
||||
%type <stn> var_decl var_decl_part /*var_decl_internal*/ field_definition
|
||||
%type <stn> var_decl var_decl_part /*var_decl_internal*/ field_definition var_decl_with_assign_var_tuple
|
||||
%type <stn> var_stmt
|
||||
%type <stn> where_part
|
||||
%type <stn> where_part_list optional_where_section
|
||||
|
|
@ -183,14 +184,12 @@
|
|||
%type <ex> variable_as_type dotted_identifier
|
||||
%type <ex> func_decl_lambda expl_func_decl_lambda
|
||||
%type <td> lambda_type_ref lambda_type_ref_noproctype
|
||||
%type <stn> full_lambda_fp_list lambda_simple_fp_sect lambda_function_body lambda_procedure_body optional_full_lambda_fp_list
|
||||
%type <stn> full_lambda_fp_list lambda_simple_fp_sect lambda_function_body lambda_procedure_body common_lambda_body optional_full_lambda_fp_list
|
||||
%type <ob> field_in_unnamed_object list_fields_in_unnamed_object func_class_name_ident_list rem_lambda variable_list var_ident_list
|
||||
%type <ti> tkAssignOrEqual
|
||||
%type <stn> pattern pattern_optional_var match_with pattern_case pattern_cases pattern_out_param pattern_out_param_optional_var
|
||||
%type <ob> pattern_out_param_list pattern_out_param_list_optional_var
|
||||
%%
|
||||
// Warning: NonTerminal symbol "const_func_expr_list" is unreachable
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
parse_goal
|
||||
: program_file
|
||||
|
|
@ -666,26 +665,39 @@ type_decl_sect
|
|||
}
|
||||
;
|
||||
|
||||
var_decl_with_assign_var_tuple
|
||||
: var_decl
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| tkRoundOpen identifier tkComma ident_list tkRoundClose tkAssign expr_l1 tkSemiColon
|
||||
{
|
||||
($4 as ident_list).Insert(0,$2);
|
||||
$4.source_context = LexLocation.MergeAll(@1,@2,@3,@4,@5);
|
||||
$$ = new var_tuple_def_statement($4 as ident_list, $7, @$);
|
||||
}
|
||||
;
|
||||
|
||||
var_decl_sect
|
||||
: tkVar var_decl
|
||||
: tkVar var_decl_with_assign_var_tuple
|
||||
{
|
||||
$$ = new variable_definitions($2 as var_def_statement, @$);
|
||||
}
|
||||
| tkEvent var_decl
|
||||
| tkEvent var_decl_with_assign_var_tuple
|
||||
{
|
||||
$$ = new variable_definitions($2 as var_def_statement, @$);
|
||||
($2 as var_def_statement).is_event = true;
|
||||
}
|
||||
| var_decl_sect var_decl
|
||||
| var_decl_sect var_decl_with_assign_var_tuple
|
||||
{
|
||||
$$ = ($1 as variable_definitions).Add($2 as var_def_statement, @$);
|
||||
}
|
||||
| tkVar tkRoundOpen identifier tkComma ident_list tkRoundClose tkAssign expr_l1 tkSemiColon
|
||||
/*| tkVar tkRoundOpen identifier tkComma ident_list tkRoundClose tkAssign expr_l1 tkSemiColon
|
||||
{
|
||||
($5 as ident_list).Insert(0,$3);
|
||||
$5.source_context = LexLocation.MergeAll(@1,@2,@3,@4,@5,@6);
|
||||
$$ = new assign_var_tuple($5 as ident_list, $8, @$);
|
||||
}
|
||||
}*/
|
||||
;
|
||||
|
||||
const_decl
|
||||
|
|
@ -921,7 +933,7 @@ const_variable
|
|||
{
|
||||
$$ = NewConstVariable($1, $2, @$);
|
||||
}
|
||||
| const_variable tkAmpersend template_type_params
|
||||
| const_variable tkAmpersend template_type_or_typeclass_params
|
||||
{
|
||||
$$ = new ident_with_templateparams($1 as addressed_value, $3 as template_param_list, @$);
|
||||
}
|
||||
|
|
@ -966,7 +978,7 @@ optional_const_func_expr_list
|
|||
{ $$ = null; }
|
||||
;
|
||||
|
||||
const_func_expr_list
|
||||
/*const_func_expr_list
|
||||
: const_expr
|
||||
{
|
||||
$$ = new expression_list($1, @$);
|
||||
|
|
@ -975,7 +987,7 @@ const_func_expr_list
|
|||
{
|
||||
$$ = ($1 as expression_list).Add($3, @$);
|
||||
}
|
||||
;
|
||||
;*/
|
||||
|
||||
const_elem_list
|
||||
: const_elem_list1
|
||||
|
|
@ -1146,17 +1158,19 @@ simple_type_decl
|
|||
| template_identifier_with_equal type_decl_type tkSemiColon
|
||||
{
|
||||
$$ = new type_declaration($1, $2, @$);
|
||||
}/*
|
||||
}
|
||||
| typeclass_restriction tkEqual tkTypeclass optional_base_classes optional_component_list_seq_end tkSemiColon
|
||||
{
|
||||
s {
|
||||
// Error: Syntax error, unexpected anchoredSymbol
|
||||
// ----------------------------------------------
|
||||
$$ = new type_declaration($1 as typeclass_restriction, new typeclass_definition($4 as named_type_reference_list, $5 as class_body_list, @$), @$);
|
||||
}
|
||||
| typeclass_restriction tkEqual tkInstance optional_component_list_seq_end tkSemiColon
|
||||
{
|
||||
$$ = new type_declaration($1 as typeclass_restriction, new instance_definition($4 as class_body_list, @$), @$);
|
||||
}*/
|
||||
}
|
||||
;
|
||||
/*
|
||||
|
||||
typeclass_restriction
|
||||
: simple_type_identifier typeclass_params
|
||||
{
|
||||
|
|
@ -1180,7 +1194,7 @@ template_type_or_typeclass_params
|
|||
{
|
||||
$$ = $1;
|
||||
}
|
||||
;*/
|
||||
;
|
||||
|
||||
type_decl_identifier
|
||||
: identifier
|
||||
|
|
@ -1563,108 +1577,31 @@ proc_type_decl
|
|||
object_type
|
||||
: class_attributes class_or_interface_keyword optional_base_classes optional_where_section optional_component_list_seq_end
|
||||
{
|
||||
$$ = NewObjectType((class_attribute)$1, $2, $3 as named_type_reference_list, $4 as where_definition_list, $5 as class_body_list, @$);
|
||||
class_definition cd = $$ as class_definition;
|
||||
if (cd == null || cd.body == null)
|
||||
break;
|
||||
var ccnt = cd.body.DescendantNodes().OfType<simple_property>().ToArray();
|
||||
var cm = new class_members(access_modifer.private_modifer);
|
||||
foreach (var prop in ccnt)
|
||||
var cd = NewObjectType((class_attribute)$1, $2, $3 as named_type_reference_list, $4 as where_definition_list, $5 as class_body_list, @$);
|
||||
$$ = cd;
|
||||
var tt = cd.DescendantNodes().OfType<class_definition>().Where(cld => cld.keyword == class_keyword.Record);
|
||||
if (tt.Count()>0)
|
||||
{
|
||||
var td = prop.property_type;
|
||||
var ra = prop.accessors?.read_accessor;
|
||||
if ($2.text.ToLower() == "interface" && ra != null && (ra.pr != null || ra.accessor_name != null))
|
||||
parsertools.AddErrorFromResource("INVALID_INTERFACE_MEMBER",ra.source_context);
|
||||
|
||||
if (ra != null && ra.pr != null)
|
||||
foreach (var ttt in tt)
|
||||
{
|
||||
if (prop.parameter_list != null)
|
||||
parsertools.AddErrorFromResource("EXTENDED_INDEXED_PROPERTIES",ra.source_context);
|
||||
var rapr = ra.pr as procedure_definition;
|
||||
(rapr.proc_header as function_header).return_type = td;
|
||||
cm.Add(rapr);
|
||||
if (prop.attr == definition_attribute.Static)
|
||||
{
|
||||
rapr.proc_header.class_keyword = true;
|
||||
procedure_attribute pa = new procedure_attribute(proc_attribute.attr_static);
|
||||
pa.source_context = rapr.proc_header.source_context;
|
||||
rapr.proc_header.proc_attributes = new procedure_attributes_list(pa);
|
||||
}
|
||||
}
|
||||
var wa = prop.accessors?.write_accessor;
|
||||
if ($2.text.ToLower() == "interface" && wa != null && (wa.pr != null || wa.accessor_name != null))
|
||||
parsertools.AddErrorFromResource("INVALID_INTERFACE_MEMBER",wa.source_context);
|
||||
|
||||
if (wa != null && wa.pr != null)
|
||||
{
|
||||
if (prop.parameter_list != null)
|
||||
parsertools.AddErrorFromResource("EXTENDED_INDEXED_PROPERTIES",ra.source_context);
|
||||
var wapr = wa.pr as procedure_definition;
|
||||
wapr.proc_header.parameters.params_list[0].vars_type = td;
|
||||
cm.Add(wapr);
|
||||
if (prop.attr == definition_attribute.Static)
|
||||
{
|
||||
wapr.proc_header.class_keyword = true;
|
||||
procedure_attribute pa = new procedure_attribute(proc_attribute.attr_static);
|
||||
pa.source_context = wapr.proc_header.source_context;
|
||||
wapr.proc_header.proc_attributes = new procedure_attributes_list(pa);
|
||||
}
|
||||
var sc = ttt.source_context;
|
||||
parsertools.AddErrorFromResource("NESTED_RECORD_DEFINITIONS_ARE_FORBIDDEN", new LexLocation(sc.begin_position.line_num, sc.begin_position.column_num-1, sc.end_position.line_num, sc.end_position.column_num, sc.FileName));
|
||||
}
|
||||
}
|
||||
if (cm.Count>0)
|
||||
cd.body.Insert(0, cm);
|
||||
}
|
||||
;
|
||||
|
||||
record_type
|
||||
: tkRecord optional_base_classes optional_where_section member_list_section tkEnd
|
||||
{
|
||||
$$ = NewRecordType($2 as named_type_reference_list, $3 as where_definition_list, $4 as class_body_list, @$);
|
||||
class_definition cd = $$ as class_definition;
|
||||
if (cd == null || cd.body == null)
|
||||
break;
|
||||
var ccnt = cd.body.DescendantNodes().OfType<simple_property>().ToArray();
|
||||
var cm = new class_members(access_modifer.private_modifer);
|
||||
foreach (var prop in ccnt)
|
||||
{
|
||||
var td = prop.property_type;
|
||||
var ra = prop.accessors?.read_accessor;
|
||||
|
||||
if (ra != null && ra.pr != null)
|
||||
{
|
||||
if (prop.parameter_list != null)
|
||||
parsertools.AddErrorFromResource("EXTENDED_INDEXED_PROPERTIES",ra.source_context);
|
||||
var rapr = ra.pr as procedure_definition;
|
||||
(rapr.proc_header as function_header).return_type = td;
|
||||
cm.Add(rapr);
|
||||
if (prop.attr == definition_attribute.Static)
|
||||
{
|
||||
rapr.proc_header.class_keyword = true;
|
||||
procedure_attribute pa = new procedure_attribute(proc_attribute.attr_static);
|
||||
pa.source_context = rapr.proc_header.source_context;
|
||||
rapr.proc_header.proc_attributes = new procedure_attributes_list(pa);
|
||||
}
|
||||
}
|
||||
var wa = prop.accessors?.write_accessor;
|
||||
|
||||
if (wa != null && wa.pr != null && prop.parameter_list == null)
|
||||
{
|
||||
if (prop.parameter_list != null)
|
||||
parsertools.AddErrorFromResource("EXTENDED_INDEXED_PROPERTIES",ra.source_context);
|
||||
var wapr = wa.pr as procedure_definition;
|
||||
wapr.proc_header.parameters.params_list[0].vars_type = td;
|
||||
cm.Add(wapr);
|
||||
if (prop.attr == definition_attribute.Static)
|
||||
{
|
||||
wapr.proc_header.class_keyword = true;
|
||||
procedure_attribute pa = new procedure_attribute(proc_attribute.attr_static);
|
||||
pa.source_context = wapr.proc_header.source_context;
|
||||
wapr.proc_header.proc_attributes = new procedure_attributes_list(pa);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cm.Count>0)
|
||||
cd.body.Insert(0, cm);
|
||||
var nnrt = new class_definition($2 as named_type_reference_list, $4 as class_body_list, class_keyword.Record, null, $3 as where_definition_list, class_attribute.None, false, @$);
|
||||
if (/*nnrt.body!=null && nnrt.body.class_def_blocks!=null &&
|
||||
nnrt.body.class_def_blocks.Count>0 &&*/
|
||||
nnrt.body.class_def_blocks[0].access_mod==null)
|
||||
{
|
||||
nnrt.body.class_def_blocks[0].access_mod = new access_modifer_node(access_modifer.public_modifer);
|
||||
}
|
||||
$$ = nnrt;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -1760,12 +1697,12 @@ base_class_name
|
|||
: simple_type_identifier
|
||||
{ $$ = $1; }
|
||||
| template_type
|
||||
{ $$ = $1; }/*
|
||||
{ $$ = $1; }
|
||||
| typeclass_restriction
|
||||
{
|
||||
var names = new List<ident>();
|
||||
names.Add(($1 as typeclass_restriction).name);
|
||||
$$ = new typeclass_reference(null, names, ($1 as typeclass_restriction).restriction_args); }*/
|
||||
$$ = new typeclass_reference(null, names, ($1 as typeclass_restriction).restriction_args); }
|
||||
;
|
||||
|
||||
template_arguments
|
||||
|
|
@ -1798,11 +1735,11 @@ where_part
|
|||
: tkWhere ident_list tkColon type_ref_and_secific_list tkSemiColon
|
||||
{
|
||||
$$ = new where_definition($2 as ident_list, $4 as where_type_specificator_list, @$);
|
||||
}/*
|
||||
}
|
||||
| tkWhere typeclass_restriction tkSemiColon
|
||||
{
|
||||
$$ = new where_typeclass_constraint($2 as typeclass_restriction);
|
||||
}*/
|
||||
}
|
||||
;
|
||||
|
||||
type_ref_and_secific_list
|
||||
|
|
@ -2080,12 +2017,23 @@ simple_property_definition
|
|||
{
|
||||
parsertools.AddErrorFromResource("STATIC_PROPERTIES_CANNOT_HAVE_ATTRBUTE_{0}",@7,$7.name);
|
||||
}
|
||||
| tkAuto tkProperty qualified_identifier property_interface tkSemiColon
|
||||
{
|
||||
$$ = NewSimplePropertyDefinition($3 as method_name, $4 as property_interface, null, proc_attribute.attr_none, null, @$);
|
||||
($$ as simple_property).is_auto = true;
|
||||
}
|
||||
| class_or_static tkAuto tkProperty qualified_identifier property_interface tkSemiColon
|
||||
{
|
||||
$$ = NewSimplePropertyDefinition($4 as method_name, $5 as property_interface, null, proc_attribute.attr_none, null, @$);
|
||||
($$ as simple_property).is_auto = true;
|
||||
($$ as simple_property).attr = definition_attribute.Static;
|
||||
}
|
||||
;
|
||||
|
||||
array_defaultproperty
|
||||
:
|
||||
{ $$ = null; }
|
||||
| tkDefault tkSemiColon
|
||||
| tkDefault tkSemiColon
|
||||
{
|
||||
$$ = new property_array_default();
|
||||
$$.source_context = @$;
|
||||
|
|
@ -2182,7 +2130,9 @@ property_specifiers
|
|||
procedure_definition pr = null;
|
||||
if (!parsertools.build_tree_for_formatter)
|
||||
pr = CreateAndAddToClassWriteProc($2 as statement,id,@2);
|
||||
$$ = NewPropertySpecifiersWrite($1, id, pr, $2 as statement, $3 as property_accessors, @$); // $2 ïåðåäà¸òñÿ äëÿ ôîðìàòèðîâàíèÿ
|
||||
if (parsertools.build_tree_for_formatter)
|
||||
$$ = NewPropertySpecifiersWrite($1, id, pr, $2 as statement, $3 as property_accessors, @$); // $2 ïåðåäà¸òñÿ äëÿ ôîðìàòèðîâàíèÿ
|
||||
else $$ = NewPropertySpecifiersWrite($1, id, pr, null, $3 as property_accessors, @$);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
|
@ -2205,7 +2155,9 @@ write_property_specifiers
|
|||
procedure_definition pr = null;
|
||||
if (!parsertools.build_tree_for_formatter)
|
||||
pr = CreateAndAddToClassWriteProc($2 as statement,id,@2);
|
||||
$$ = NewPropertySpecifiersWrite($1, id, pr, $2 as statement, null, @$);
|
||||
if (parsertools.build_tree_for_formatter)
|
||||
$$ = NewPropertySpecifiersWrite($1, id, pr, $2 as statement, null, @$);
|
||||
else $$ = NewPropertySpecifiersWrite($1, id, pr, null, null, @$);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
|
@ -2267,12 +2219,6 @@ var_decl_part
|
|||
{
|
||||
$$ = new var_def_statement($1 as ident_list, $3, $5, definition_attribute.None, false, @$);
|
||||
}
|
||||
/*| tkRoundOpen identifier tkComma ident_list tkRoundClose tkAssign expr_l1
|
||||
{
|
||||
($4 as ident_list).Insert(0,$2);
|
||||
$4.source_context = LexLocation.MergeAll(@1,@2,@3,@4,@5,@6);
|
||||
$$ = new assign_var_tuple($4 as ident_list, $7, @$);
|
||||
}*/
|
||||
;
|
||||
|
||||
typed_var_init_expression
|
||||
|
|
@ -3261,7 +3207,7 @@ simple_or_template_type_reference
|
|||
{
|
||||
$$ = new template_type_reference((named_type_reference)$1, (template_param_list)$2, @$);
|
||||
}
|
||||
| simple_type_identifier tkAmpersend template_type_params
|
||||
| simple_type_identifier tkAmpersend template_type_or_typeclass_params
|
||||
{
|
||||
$$ = new template_type_reference((named_type_reference)$1, (template_param_list)$3, @$);
|
||||
}
|
||||
|
|
@ -3867,7 +3813,7 @@ variable
|
|||
{
|
||||
$$ = new roof_dereference($1 as addressed_value,@$);
|
||||
}
|
||||
| variable tkAmpersend template_type_params
|
||||
| variable tkAmpersend template_type_or_typeclass_params
|
||||
{
|
||||
$$ = new ident_with_templateparams($1 as addressed_value, $3 as template_param_list, @$);
|
||||
}
|
||||
|
|
@ -4211,9 +4157,9 @@ keyword
|
|||
| tkMatch
|
||||
{ $$ = $1; }
|
||||
| tkWhen
|
||||
{ $$ = $1; }/*
|
||||
{ $$ = $1; }
|
||||
| tkInstance
|
||||
{ $$ = $1; }*/
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
reserved_keyword
|
||||
|
|
@ -4482,15 +4428,8 @@ lambda_type_ref_noproctype
|
|||
}
|
||||
;
|
||||
|
||||
lambda_function_body
|
||||
: expr_l1
|
||||
{
|
||||
//$$ = NewLambdaBody($1, @$);
|
||||
var sl = new statement_list(new assign("result",$1,@$),@$); // íàäî ïîìå÷àòü åù¸ è assign êàê àâòîñãåíåðèðîâàííûé äëÿ ëÿìáäû
|
||||
sl.expr_lambda_body = true;
|
||||
$$ = sl;
|
||||
}
|
||||
| compound_stmt
|
||||
common_lambda_body
|
||||
: compound_stmt
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
|
|
@ -4514,6 +4453,10 @@ lambda_function_body
|
|||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| loop_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| case_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
|
|
@ -4534,6 +4477,25 @@ lambda_function_body
|
|||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
lambda_function_body
|
||||
: expr_l1
|
||||
{
|
||||
var id = SyntaxVisitors.ExprHasNameVisitor.HasName($1, "Result");
|
||||
if (id != null)
|
||||
{
|
||||
parsertools.AddErrorFromResource("RESULT_IDENT_NOT_EXPECTED_IN_THIS_CONTEXT", id.source_context);
|
||||
}
|
||||
var sl = new statement_list(new assign("result",$1,@$),@$); // íàäî ïîìå÷àòü åù¸ è assign êàê àâòîñãåíåðèðîâàííûé äëÿ ëÿìáäû - ÷òîáû çàïðåòèòü ÿâíûé Result
|
||||
sl.expr_lambda_body = true;
|
||||
$$ = sl;
|
||||
}
|
||||
| common_lambda_body
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
lambda_procedure_body
|
||||
|
|
@ -4541,54 +4503,14 @@ lambda_procedure_body
|
|||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| compound_stmt
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| if_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| while_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| repeat_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| for_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| foreach_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| case_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| try_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| lock_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| yield_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| raise_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| assignment
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| common_lambda_body
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
%%// ==========================================================================
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
// GPPG version 1.3.6
|
||||
// Machine: DESKTOP-7B4K9VB
|
||||
// DateTime: 26.12.2018 0:32:42
|
||||
// DateTime: 26.12.2018 1:39:52
|
||||
// UserName: Bogdan
|
||||
// Input file <ABCPascal.y>
|
||||
|
||||
|
|
|
|||
|
|
@ -1118,6 +1118,36 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
DefaultVisit(_double_question_node);
|
||||
}
|
||||
|
||||
public virtual void visit(typeclass_restriction _typeclass_restriction)
|
||||
{
|
||||
DefaultVisit(_typeclass_restriction);
|
||||
}
|
||||
|
||||
public virtual void visit(instance_definition _instance_definition)
|
||||
{
|
||||
DefaultVisit(_instance_definition);
|
||||
}
|
||||
|
||||
public virtual void visit(typeclass_definition _typeclass_definition)
|
||||
{
|
||||
DefaultVisit(_typeclass_definition);
|
||||
}
|
||||
|
||||
public virtual void visit(where_typeclass_constraint _where_typeclass_constraint)
|
||||
{
|
||||
DefaultVisit(_where_typeclass_constraint);
|
||||
}
|
||||
|
||||
public virtual void visit(typeclass_param_list _typeclass_param_list)
|
||||
{
|
||||
DefaultVisit(_typeclass_param_list);
|
||||
}
|
||||
|
||||
public virtual void visit(typeclass_reference _typeclass_reference)
|
||||
{
|
||||
DefaultVisit(_typeclass_reference);
|
||||
}
|
||||
|
||||
public virtual void visit(pattern_node _pattern_node)
|
||||
{
|
||||
DefaultVisit(_pattern_node);
|
||||
|
|
|
|||
|
|
@ -1781,6 +1781,54 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
{
|
||||
}
|
||||
|
||||
public virtual void pre_do_visit(typeclass_restriction _typeclass_restriction)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void post_do_visit(typeclass_restriction _typeclass_restriction)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void pre_do_visit(instance_definition _instance_definition)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void post_do_visit(instance_definition _instance_definition)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void pre_do_visit(typeclass_definition _typeclass_definition)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void post_do_visit(typeclass_definition _typeclass_definition)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void pre_do_visit(where_typeclass_constraint _where_typeclass_constraint)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void post_do_visit(where_typeclass_constraint _where_typeclass_constraint)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void pre_do_visit(typeclass_param_list _typeclass_param_list)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void post_do_visit(typeclass_param_list _typeclass_param_list)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void pre_do_visit(typeclass_reference _typeclass_reference)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void post_do_visit(typeclass_reference _typeclass_reference)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void pre_do_visit(pattern_node _pattern_node)
|
||||
{
|
||||
}
|
||||
|
|
@ -3800,6 +3848,54 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
post_do_visit(_double_question_node);
|
||||
}
|
||||
|
||||
public override void visit(typeclass_restriction _typeclass_restriction)
|
||||
{
|
||||
DefaultVisit(_typeclass_restriction);
|
||||
pre_do_visit(_typeclass_restriction);
|
||||
visit(typeclass_restriction.restriction_args);
|
||||
post_do_visit(_typeclass_restriction);
|
||||
}
|
||||
|
||||
public override void visit(instance_definition _instance_definition)
|
||||
{
|
||||
DefaultVisit(_instance_definition);
|
||||
pre_do_visit(_instance_definition);
|
||||
visit(instance_definition.body);
|
||||
post_do_visit(_instance_definition);
|
||||
}
|
||||
|
||||
public override void visit(typeclass_definition _typeclass_definition)
|
||||
{
|
||||
DefaultVisit(_typeclass_definition);
|
||||
pre_do_visit(_typeclass_definition);
|
||||
visit(typeclass_definition.additional_restrictions);
|
||||
visit(typeclass_definition.body);
|
||||
post_do_visit(_typeclass_definition);
|
||||
}
|
||||
|
||||
public override void visit(where_typeclass_constraint _where_typeclass_constraint)
|
||||
{
|
||||
DefaultVisit(_where_typeclass_constraint);
|
||||
pre_do_visit(_where_typeclass_constraint);
|
||||
visit(where_typeclass_constraint.restriction);
|
||||
post_do_visit(_where_typeclass_constraint);
|
||||
}
|
||||
|
||||
public override void visit(typeclass_param_list _typeclass_param_list)
|
||||
{
|
||||
DefaultVisit(_typeclass_param_list);
|
||||
pre_do_visit(_typeclass_param_list);
|
||||
post_do_visit(_typeclass_param_list);
|
||||
}
|
||||
|
||||
public override void visit(typeclass_reference _typeclass_reference)
|
||||
{
|
||||
DefaultVisit(_typeclass_reference);
|
||||
pre_do_visit(_typeclass_reference);
|
||||
visit(typeclass_reference.restriction_args);
|
||||
post_do_visit(_typeclass_reference);
|
||||
}
|
||||
|
||||
public override void visit(pattern_node _pattern_node)
|
||||
{
|
||||
DefaultVisit(_pattern_node);
|
||||
|
|
|
|||
|
|
@ -465,32 +465,44 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
case 221:
|
||||
return new double_question_node();
|
||||
case 222:
|
||||
return new pattern_node();
|
||||
return new typeclass_restriction();
|
||||
case 223:
|
||||
return new type_pattern();
|
||||
return new instance_definition();
|
||||
case 224:
|
||||
return new is_pattern_expr();
|
||||
return new typeclass_definition();
|
||||
case 225:
|
||||
return new match_with();
|
||||
return new where_typeclass_constraint();
|
||||
case 226:
|
||||
return new pattern_case();
|
||||
return new typeclass_param_list();
|
||||
case 227:
|
||||
return new pattern_cases();
|
||||
return new typeclass_reference();
|
||||
case 228:
|
||||
return new deconstructor_pattern();
|
||||
return new pattern_node();
|
||||
case 229:
|
||||
return new pattern_deconstructor_parameter();
|
||||
return new type_pattern();
|
||||
case 230:
|
||||
return new desugared_deconstruction();
|
||||
return new is_pattern_expr();
|
||||
case 231:
|
||||
return new var_deconstructor_parameter();
|
||||
return new match_with();
|
||||
case 232:
|
||||
return new recursive_deconstructor_parameter();
|
||||
return new pattern_case();
|
||||
case 233:
|
||||
return new deconstruction_variables_definition();
|
||||
return new pattern_cases();
|
||||
case 234:
|
||||
return new var_tuple_def_statement();
|
||||
return new deconstructor_pattern();
|
||||
case 235:
|
||||
return new pattern_deconstructor_parameter();
|
||||
case 236:
|
||||
return new desugared_deconstruction();
|
||||
case 237:
|
||||
return new var_deconstructor_parameter();
|
||||
case 238:
|
||||
return new recursive_deconstructor_parameter();
|
||||
case 239:
|
||||
return new deconstruction_variables_definition();
|
||||
case 240:
|
||||
return new var_tuple_def_statement();
|
||||
case 241:
|
||||
return new semantic_check_sugared_var_def_statement_node();
|
||||
}
|
||||
return null;
|
||||
|
|
@ -3955,6 +3967,78 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
}
|
||||
|
||||
|
||||
public void visit(typeclass_restriction _typeclass_restriction)
|
||||
{
|
||||
read_typeclass_restriction(_typeclass_restriction);
|
||||
}
|
||||
|
||||
public void read_typeclass_restriction(typeclass_restriction _typeclass_restriction)
|
||||
{
|
||||
read_ident(_typeclass_restriction);
|
||||
_typeclass_restriction.restriction_args = _read_node() as template_param_list;
|
||||
}
|
||||
|
||||
|
||||
public void visit(instance_definition _instance_definition)
|
||||
{
|
||||
read_instance_definition(_instance_definition);
|
||||
}
|
||||
|
||||
public void read_instance_definition(instance_definition _instance_definition)
|
||||
{
|
||||
read_type_definition(_instance_definition);
|
||||
_instance_definition.body = _read_node() as class_body_list;
|
||||
}
|
||||
|
||||
|
||||
public void visit(typeclass_definition _typeclass_definition)
|
||||
{
|
||||
read_typeclass_definition(_typeclass_definition);
|
||||
}
|
||||
|
||||
public void read_typeclass_definition(typeclass_definition _typeclass_definition)
|
||||
{
|
||||
read_type_definition(_typeclass_definition);
|
||||
_typeclass_definition.additional_restrictions = _read_node() as named_type_reference_list;
|
||||
_typeclass_definition.body = _read_node() as class_body_list;
|
||||
}
|
||||
|
||||
|
||||
public void visit(where_typeclass_constraint _where_typeclass_constraint)
|
||||
{
|
||||
read_where_typeclass_constraint(_where_typeclass_constraint);
|
||||
}
|
||||
|
||||
public void read_where_typeclass_constraint(where_typeclass_constraint _where_typeclass_constraint)
|
||||
{
|
||||
read_where_definition(_where_typeclass_constraint);
|
||||
_where_typeclass_constraint.restriction = _read_node() as typeclass_restriction;
|
||||
}
|
||||
|
||||
|
||||
public void visit(typeclass_param_list _typeclass_param_list)
|
||||
{
|
||||
read_typeclass_param_list(_typeclass_param_list);
|
||||
}
|
||||
|
||||
public void read_typeclass_param_list(typeclass_param_list _typeclass_param_list)
|
||||
{
|
||||
read_template_param_list(_typeclass_param_list);
|
||||
}
|
||||
|
||||
|
||||
public void visit(typeclass_reference _typeclass_reference)
|
||||
{
|
||||
read_typeclass_reference(_typeclass_reference);
|
||||
}
|
||||
|
||||
public void read_typeclass_reference(typeclass_reference _typeclass_reference)
|
||||
{
|
||||
read_named_type_reference(_typeclass_reference);
|
||||
_typeclass_reference.restriction_args = _read_node() as template_param_list;
|
||||
}
|
||||
|
||||
|
||||
public void visit(pattern_node _pattern_node)
|
||||
{
|
||||
read_pattern_node(_pattern_node);
|
||||
|
|
|
|||
|
|
@ -6178,9 +6178,135 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
}
|
||||
|
||||
|
||||
public void visit(pattern_node _pattern_node)
|
||||
public void visit(typeclass_restriction _typeclass_restriction)
|
||||
{
|
||||
bw.Write((Int16)222);
|
||||
write_typeclass_restriction(_typeclass_restriction);
|
||||
}
|
||||
|
||||
public void write_typeclass_restriction(typeclass_restriction _typeclass_restriction)
|
||||
{
|
||||
write_ident(_typeclass_restriction);
|
||||
if (_typeclass_restriction.restriction_args == null)
|
||||
{
|
||||
bw.Write((byte)0);
|
||||
}
|
||||
else
|
||||
{
|
||||
bw.Write((byte)1);
|
||||
_typeclass_restriction.restriction_args.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void visit(instance_definition _instance_definition)
|
||||
{
|
||||
bw.Write((Int16)223);
|
||||
write_instance_definition(_instance_definition);
|
||||
}
|
||||
|
||||
public void write_instance_definition(instance_definition _instance_definition)
|
||||
{
|
||||
write_type_definition(_instance_definition);
|
||||
if (_instance_definition.body == null)
|
||||
{
|
||||
bw.Write((byte)0);
|
||||
}
|
||||
else
|
||||
{
|
||||
bw.Write((byte)1);
|
||||
_instance_definition.body.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void visit(typeclass_definition _typeclass_definition)
|
||||
{
|
||||
bw.Write((Int16)224);
|
||||
write_typeclass_definition(_typeclass_definition);
|
||||
}
|
||||
|
||||
public void write_typeclass_definition(typeclass_definition _typeclass_definition)
|
||||
{
|
||||
write_type_definition(_typeclass_definition);
|
||||
if (_typeclass_definition.additional_restrictions == null)
|
||||
{
|
||||
bw.Write((byte)0);
|
||||
}
|
||||
else
|
||||
{
|
||||
bw.Write((byte)1);
|
||||
_typeclass_definition.additional_restrictions.visit(this);
|
||||
}
|
||||
if (_typeclass_definition.body == null)
|
||||
{
|
||||
bw.Write((byte)0);
|
||||
}
|
||||
else
|
||||
{
|
||||
bw.Write((byte)1);
|
||||
_typeclass_definition.body.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void visit(where_typeclass_constraint _where_typeclass_constraint)
|
||||
{
|
||||
bw.Write((Int16)225);
|
||||
write_where_typeclass_constraint(_where_typeclass_constraint);
|
||||
}
|
||||
|
||||
public void write_where_typeclass_constraint(where_typeclass_constraint _where_typeclass_constraint)
|
||||
{
|
||||
write_where_definition(_where_typeclass_constraint);
|
||||
if (_where_typeclass_constraint.restriction == null)
|
||||
{
|
||||
bw.Write((byte)0);
|
||||
}
|
||||
else
|
||||
{
|
||||
bw.Write((byte)1);
|
||||
_where_typeclass_constraint.restriction.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void visit(typeclass_param_list _typeclass_param_list)
|
||||
{
|
||||
bw.Write((Int16)226);
|
||||
write_typeclass_param_list(_typeclass_param_list);
|
||||
}
|
||||
|
||||
public void write_typeclass_param_list(typeclass_param_list _typeclass_param_list)
|
||||
{
|
||||
write_template_param_list(_typeclass_param_list);
|
||||
}
|
||||
|
||||
|
||||
public void visit(typeclass_reference _typeclass_reference)
|
||||
{
|
||||
bw.Write((Int16)227);
|
||||
write_typeclass_reference(_typeclass_reference);
|
||||
}
|
||||
|
||||
public void write_typeclass_reference(typeclass_reference _typeclass_reference)
|
||||
{
|
||||
write_named_type_reference(_typeclass_reference);
|
||||
if (_typeclass_reference.restriction_args == null)
|
||||
{
|
||||
bw.Write((byte)0);
|
||||
}
|
||||
else
|
||||
{
|
||||
bw.Write((byte)1);
|
||||
_typeclass_reference.restriction_args.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void visit(pattern_node _pattern_node)
|
||||
{
|
||||
bw.Write((Int16)228);
|
||||
write_pattern_node(_pattern_node);
|
||||
}
|
||||
|
||||
|
|
@ -6192,7 +6318,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
|
||||
public void visit(type_pattern _type_pattern)
|
||||
{
|
||||
bw.Write((Int16)223);
|
||||
bw.Write((Int16)229);
|
||||
write_type_pattern(_type_pattern);
|
||||
}
|
||||
|
||||
|
|
@ -6222,7 +6348,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
|
||||
public void visit(is_pattern_expr _is_pattern_expr)
|
||||
{
|
||||
bw.Write((Int16)224);
|
||||
bw.Write((Int16)230);
|
||||
write_is_pattern_expr(_is_pattern_expr);
|
||||
}
|
||||
|
||||
|
|
@ -6252,7 +6378,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
|
||||
public void visit(match_with _match_with)
|
||||
{
|
||||
bw.Write((Int16)225);
|
||||
bw.Write((Int16)231);
|
||||
write_match_with(_match_with);
|
||||
}
|
||||
|
||||
|
|
@ -6291,7 +6417,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
|
||||
public void visit(pattern_case _pattern_case)
|
||||
{
|
||||
bw.Write((Int16)226);
|
||||
bw.Write((Int16)232);
|
||||
write_pattern_case(_pattern_case);
|
||||
}
|
||||
|
||||
|
|
@ -6330,7 +6456,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
|
||||
public void visit(pattern_cases _pattern_cases)
|
||||
{
|
||||
bw.Write((Int16)227);
|
||||
bw.Write((Int16)233);
|
||||
write_pattern_cases(_pattern_cases);
|
||||
}
|
||||
|
||||
|
|
@ -6363,7 +6489,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
|
||||
public void visit(deconstructor_pattern _deconstructor_pattern)
|
||||
{
|
||||
bw.Write((Int16)228);
|
||||
bw.Write((Int16)234);
|
||||
write_deconstructor_pattern(_deconstructor_pattern);
|
||||
}
|
||||
|
||||
|
|
@ -6405,7 +6531,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
|
||||
public void visit(pattern_deconstructor_parameter _pattern_deconstructor_parameter)
|
||||
{
|
||||
bw.Write((Int16)229);
|
||||
bw.Write((Int16)235);
|
||||
write_pattern_deconstructor_parameter(_pattern_deconstructor_parameter);
|
||||
}
|
||||
|
||||
|
|
@ -6417,7 +6543,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
|
||||
public void visit(desugared_deconstruction _desugared_deconstruction)
|
||||
{
|
||||
bw.Write((Int16)230);
|
||||
bw.Write((Int16)236);
|
||||
write_desugared_deconstruction(_desugared_deconstruction);
|
||||
}
|
||||
|
||||
|
|
@ -6447,7 +6573,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
|
||||
public void visit(var_deconstructor_parameter _var_deconstructor_parameter)
|
||||
{
|
||||
bw.Write((Int16)231);
|
||||
bw.Write((Int16)237);
|
||||
write_var_deconstructor_parameter(_var_deconstructor_parameter);
|
||||
}
|
||||
|
||||
|
|
@ -6477,7 +6603,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
|
||||
public void visit(recursive_deconstructor_parameter _recursive_deconstructor_parameter)
|
||||
{
|
||||
bw.Write((Int16)232);
|
||||
bw.Write((Int16)238);
|
||||
write_recursive_deconstructor_parameter(_recursive_deconstructor_parameter);
|
||||
}
|
||||
|
||||
|
|
@ -6498,7 +6624,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
|
||||
public void visit(deconstruction_variables_definition _deconstruction_variables_definition)
|
||||
{
|
||||
bw.Write((Int16)233);
|
||||
bw.Write((Int16)239);
|
||||
write_deconstruction_variables_definition(_deconstruction_variables_definition);
|
||||
}
|
||||
|
||||
|
|
@ -6531,7 +6657,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
|
||||
public void visit(var_tuple_def_statement _var_tuple_def_statement)
|
||||
{
|
||||
bw.Write((Int16)234);
|
||||
bw.Write((Int16)240);
|
||||
write_var_tuple_def_statement(_var_tuple_def_statement);
|
||||
}
|
||||
|
||||
|
|
@ -6543,7 +6669,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
|
||||
public void visit(semantic_check_sugared_var_def_statement_node _semantic_check_sugared_var_def_statement_node)
|
||||
{
|
||||
bw.Write((Int16)235);
|
||||
bw.Write((Int16)241);
|
||||
write_semantic_check_sugared_var_def_statement_node(_semantic_check_sugared_var_def_statement_node);
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1337,6 +1337,42 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
///<returns> Return value is void </returns>
|
||||
void visit(double_question_node _double_question_node);
|
||||
///<summary>
|
||||
///Method to visit typeclass_restriction.
|
||||
///</summary>
|
||||
///<param name="_typeclass_restriction">Node to visit</param>
|
||||
///<returns> Return value is void </returns>
|
||||
void visit(typeclass_restriction _typeclass_restriction);
|
||||
///<summary>
|
||||
///Method to visit instance_definition.
|
||||
///</summary>
|
||||
///<param name="_instance_definition">Node to visit</param>
|
||||
///<returns> Return value is void </returns>
|
||||
void visit(instance_definition _instance_definition);
|
||||
///<summary>
|
||||
///Method to visit typeclass_definition.
|
||||
///</summary>
|
||||
///<param name="_typeclass_definition">Node to visit</param>
|
||||
///<returns> Return value is void </returns>
|
||||
void visit(typeclass_definition _typeclass_definition);
|
||||
///<summary>
|
||||
///Method to visit where_typeclass_constraint.
|
||||
///</summary>
|
||||
///<param name="_where_typeclass_constraint">Node to visit</param>
|
||||
///<returns> Return value is void </returns>
|
||||
void visit(where_typeclass_constraint _where_typeclass_constraint);
|
||||
///<summary>
|
||||
///Method to visit typeclass_param_list.
|
||||
///</summary>
|
||||
///<param name="_typeclass_param_list">Node to visit</param>
|
||||
///<returns> Return value is void </returns>
|
||||
void visit(typeclass_param_list _typeclass_param_list);
|
||||
///<summary>
|
||||
///Method to visit typeclass_reference.
|
||||
///</summary>
|
||||
///<param name="_typeclass_reference">Node to visit</param>
|
||||
///<returns> Return value is void </returns>
|
||||
void visit(typeclass_reference _typeclass_reference);
|
||||
///<summary>
|
||||
///Method to visit pattern_node.
|
||||
///</summary>
|
||||
///<param name="_pattern_node">Node to visit</param>
|
||||
|
|
|
|||
|
|
@ -2863,6 +2863,105 @@
|
|||
<TagIndices />
|
||||
</Tags>
|
||||
</SyntaxNode>
|
||||
<SyntaxNode Name="typeclass_restriction" BaseName="ident">
|
||||
<Fields>
|
||||
<SyntaxField Name="restriction_args" SyntaxType="template_param_list" />
|
||||
</Fields>
|
||||
<Methods />
|
||||
<Tags>
|
||||
<CategoryIndices>
|
||||
<CategoryIndex>0</CategoryIndex>
|
||||
</CategoryIndices>
|
||||
<TagIndices>
|
||||
<TagIndex>10</TagIndex>
|
||||
</TagIndices>
|
||||
</Tags>
|
||||
</SyntaxNode>
|
||||
<SyntaxNode Name="instance_definition" BaseName="type_definition">
|
||||
<Fields>
|
||||
<SyntaxField Name="body" SyntaxType="class_body_list" />
|
||||
</Fields>
|
||||
<Methods />
|
||||
<Tags>
|
||||
<CategoryIndices>
|
||||
<CategoryIndex>0</CategoryIndex>
|
||||
<CategoryIndex>0</CategoryIndex>
|
||||
<CategoryIndex>0</CategoryIndex>
|
||||
</CategoryIndices>
|
||||
<TagIndices>
|
||||
<TagIndex>4</TagIndex>
|
||||
<TagIndex>5</TagIndex>
|
||||
<TagIndex>10</TagIndex>
|
||||
</TagIndices>
|
||||
</Tags>
|
||||
</SyntaxNode>
|
||||
<SyntaxNode Name="typeclass_definition" BaseName="type_definition">
|
||||
<Fields>
|
||||
<SyntaxField Name="additional_restrictions" SyntaxType="named_type_reference_list" />
|
||||
<SyntaxField Name="body" SyntaxType="class_body_list" />
|
||||
</Fields>
|
||||
<Methods />
|
||||
<Tags>
|
||||
<CategoryIndices>
|
||||
<CategoryIndex>0</CategoryIndex>
|
||||
<CategoryIndex>0</CategoryIndex>
|
||||
<CategoryIndex>0</CategoryIndex>
|
||||
</CategoryIndices>
|
||||
<TagIndices>
|
||||
<TagIndex>4</TagIndex>
|
||||
<TagIndex>5</TagIndex>
|
||||
<TagIndex>10</TagIndex>
|
||||
</TagIndices>
|
||||
</Tags>
|
||||
</SyntaxNode>
|
||||
<SyntaxNode Name="where_typeclass_constraint" BaseName="where_definition">
|
||||
<Fields>
|
||||
<SyntaxField Name="restriction" SyntaxType="typeclass_restriction" />
|
||||
</Fields>
|
||||
<Methods />
|
||||
<Tags>
|
||||
<CategoryIndices>
|
||||
<CategoryIndex>0</CategoryIndex>
|
||||
</CategoryIndices>
|
||||
<TagIndices>
|
||||
<TagIndex>10</TagIndex>
|
||||
</TagIndices>
|
||||
</Tags>
|
||||
</SyntaxNode>
|
||||
<SyntaxNode Name="typeclass_param_list" BaseName="template_param_list">
|
||||
<Fields />
|
||||
<Methods>
|
||||
<Method>
|
||||
<Text>public typeclass_param_list(template_param_list _template_param_list): this(_template_param_list.dereferencing_value, _template_param_list.params_list, _template_param_list.source_context)
|
||||
{
|
||||
}</Text>
|
||||
</Method>
|
||||
</Methods>
|
||||
<Tags>
|
||||
<CategoryIndices>
|
||||
<CategoryIndex>0</CategoryIndex>
|
||||
</CategoryIndices>
|
||||
<TagIndices>
|
||||
<TagIndex>10</TagIndex>
|
||||
</TagIndices>
|
||||
</Tags>
|
||||
</SyntaxNode>
|
||||
<SyntaxNode Name="typeclass_reference" BaseName="named_type_reference">
|
||||
<Fields>
|
||||
<SyntaxField Name="restriction_args" SyntaxType="template_param_list" />
|
||||
</Fields>
|
||||
<Methods />
|
||||
<Tags>
|
||||
<CategoryIndices>
|
||||
<CategoryIndex>0</CategoryIndex>
|
||||
<CategoryIndex>0</CategoryIndex>
|
||||
</CategoryIndices>
|
||||
<TagIndices>
|
||||
<TagIndex>4</TagIndex>
|
||||
<TagIndex>10</TagIndex>
|
||||
</TagIndices>
|
||||
</Tags>
|
||||
</SyntaxNode>
|
||||
<SyntaxNode Name="pattern_node" BaseName="syntax_tree_node">
|
||||
<Fields />
|
||||
<Methods />
|
||||
|
|
|
|||
|
|
@ -22,6 +22,16 @@ namespace PascalABCCompiler.SyntaxTreeConverters
|
|||
// Выносим выражения с лямбдами из заголовка foreach
|
||||
StandOutExprWithLambdaInForeachSequenceVisitor.New.ProcessNode(root);
|
||||
|
||||
// type classes - пока закомментировал SSM 20/10/18. Грязный кусок кода. FillParentsInAllChilds вызывается повторно
|
||||
|
||||
/*{
|
||||
var typeclasses = SyntaxVisitors.TypeclassVisitors.FindTypeclassesVisitor.New;
|
||||
typeclasses.ProcessNode(root);
|
||||
var instancesAndRestrictedFunctions = SyntaxVisitors.TypeclassVisitors.FindInstancesAndRestrictedFunctionsVisitor.New(typeclasses.typeclasses);
|
||||
instancesAndRestrictedFunctions.ProcessNode(root);
|
||||
SyntaxVisitors.TypeclassVisitors.ReplaceTypeclassVisitor.New(instancesAndRestrictedFunctions).ProcessNode(root);
|
||||
}*/
|
||||
//root.FillParentsInAllChilds();
|
||||
#if DEBUG
|
||||
//new SimplePrettyPrinterVisitor("E:/projs/out.txt").ProcessNode(root);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -58,6 +58,9 @@
|
|||
<Compile Include="SugarVisitors\PatternsDesugaringVisitor.cs" />
|
||||
<Compile Include="SugarVisitors\SliceDesugarVisitor.cs" />
|
||||
<Compile Include="SugarVisitors\TupleVisitor.cs" />
|
||||
<Compile Include="TypeclassVisitors\FindInstancesAndRestrictedFunctionsVisitor.cs" />
|
||||
<Compile Include="TypeclassVisitors\FindTypeclassesVisitor.cs" />
|
||||
<Compile Include="TypeclassVisitors\ReplaceTypeclassVisitor.cs" />
|
||||
<Compile Include="YieldVisitors\ObjectCopier\ObjectCopier.cs" />
|
||||
<Compile Include="Optimization\CalcConstExprs.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.Errors;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace SyntaxVisitors.TypeclassVisitors
|
||||
{
|
||||
public class FindInstancesAndRestrictedFunctionsVisitor: WalkingVisitorNew
|
||||
{
|
||||
|
||||
// (Typeclass name) -> (Type arguments count)
|
||||
public Dictionary<string, type_declaration> typeclasses;
|
||||
// (Typeclass name) -> [Instances]
|
||||
public Dictionary<string, List<typeclass_param_list>> instances = new Dictionary<string, List<typeclass_param_list>>();
|
||||
public Dictionary<string, List<string>> restrictedFunctions = new Dictionary<string, List<string>>();
|
||||
|
||||
|
||||
public FindInstancesAndRestrictedFunctionsVisitor(Dictionary<string, type_declaration> typeclasses)
|
||||
{
|
||||
this.typeclasses = typeclasses;
|
||||
|
||||
foreach (var typeclass in typeclasses)
|
||||
{
|
||||
instances.Add(typeclass.Key, new List<typeclass_param_list>());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static FindInstancesAndRestrictedFunctionsVisitor New(Dictionary<string, type_declaration> typeclasses)
|
||||
{
|
||||
return new FindInstancesAndRestrictedFunctionsVisitor(typeclasses);
|
||||
}
|
||||
|
||||
|
||||
public override void visit(type_declaration instanceDeclaration)
|
||||
{
|
||||
var instanceDefinition = instanceDeclaration.type_def as instance_definition;
|
||||
if (instanceDefinition == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var instanceName = instanceDeclaration.type_name as typeclass_restriction;
|
||||
|
||||
instances[instanceName.name].Add(instanceName.restriction_args as typeclass_param_list);
|
||||
}
|
||||
|
||||
|
||||
public override void visit(procedure_definition procedureDefinition)
|
||||
{
|
||||
bool isConstrainted = procedureDefinition.proc_header.where_defs != null &&
|
||||
procedureDefinition.proc_header.where_defs.defs.Any(x => x is where_typeclass_constraint);
|
||||
if (!isConstrainted)
|
||||
return;
|
||||
|
||||
var usedTypeclasses = procedureDefinition.proc_header.where_defs.
|
||||
defs.OfType<where_typeclass_constraint>()
|
||||
.Select(x => x.restriction.name).ToList();
|
||||
|
||||
restrictedFunctions.Add(procedureDefinition.proc_header.name.meth_name.name,
|
||||
usedTypeclasses);
|
||||
}
|
||||
}
|
||||
}
|
||||
48
SyntaxVisitors/TypeclassVisitors/FindTypeclassesVisitor.cs
Normal file
48
SyntaxVisitors/TypeclassVisitors/FindTypeclassesVisitor.cs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.Errors;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace SyntaxVisitors.TypeclassVisitors
|
||||
{
|
||||
public class FindTypeclassesVisitor: WalkingVisitorNew
|
||||
{
|
||||
//TODO: add searching typeclasses at libraries
|
||||
|
||||
// (Typeclass name) -> (Type arguments count)
|
||||
public Dictionary<string, type_declaration> typeclasses = new Dictionary<string, type_declaration>();
|
||||
|
||||
|
||||
public FindTypeclassesVisitor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static FindTypeclassesVisitor New
|
||||
{
|
||||
get
|
||||
{
|
||||
return new FindTypeclassesVisitor();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void visit(type_declaration typeclassDeclaration)
|
||||
{
|
||||
var typeclassDefinition = typeclassDeclaration.type_def as typeclass_definition;
|
||||
if (typeclassDefinition == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var typeclassName = typeclassDeclaration.type_name as typeclass_restriction;
|
||||
|
||||
typeclasses.Add(typeclassName.name, typeclassDeclaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
622
SyntaxVisitors/TypeclassVisitors/ReplaceTypeclassVisitor.cs
Normal file
622
SyntaxVisitors/TypeclassVisitors/ReplaceTypeclassVisitor.cs
Normal file
|
|
@ -0,0 +1,622 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.Errors;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
|
||||
namespace SyntaxVisitors.TypeclassVisitors
|
||||
{
|
||||
public class ReplaceTypeclassVisitor: BaseChangeVisitor
|
||||
{
|
||||
FindInstancesAndRestrictedFunctionsVisitor instancesAndRestrictedFunctions;
|
||||
|
||||
public ReplaceTypeclassVisitor(FindInstancesAndRestrictedFunctionsVisitor instancesAndRestrictedFunctions)
|
||||
{
|
||||
this.instancesAndRestrictedFunctions = instancesAndRestrictedFunctions;
|
||||
}
|
||||
|
||||
public static ReplaceTypeclassVisitor New(FindInstancesAndRestrictedFunctionsVisitor instancesAndRestrictedFunctions)
|
||||
{
|
||||
return new ReplaceTypeclassVisitor(instancesAndRestrictedFunctions);
|
||||
}
|
||||
|
||||
bool VisitInstanceDeclaration(type_declaration instanceDeclaration)
|
||||
{
|
||||
var instanceDefinition = instanceDeclaration.type_def as instance_definition;
|
||||
if (instanceDefinition == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var instanceName = instanceDeclaration.type_name as typeclass_restriction;
|
||||
|
||||
// If it is instance of derived typelass than it should have template parameters
|
||||
var templateArgs = new ident_list();
|
||||
where_definition_list whereSection = null;
|
||||
var originalTypeclass = instancesAndRestrictedFunctions.typeclasses[instanceName.name].type_def as typeclass_definition;
|
||||
var typeclassParents = originalTypeclass.additional_restrictions;
|
||||
if (typeclassParents != null && typeclassParents.Count > 0)
|
||||
{
|
||||
whereSection = new where_definition_list();
|
||||
|
||||
for (int i = 0; i < typeclassParents.Count; i++)
|
||||
{
|
||||
ident template_name;
|
||||
if (typeclassParents[i] is typeclass_reference tr)
|
||||
{
|
||||
string name = tr.names[0].name;
|
||||
template_name = TypeclassRestrctionToTemplateName(name, tr.restriction_args);
|
||||
|
||||
whereSection.Add(GetWhereRestriction(
|
||||
TypeclassReferenceToInterfaceName(name, instanceName.restriction_args),
|
||||
template_name));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException("Should be syntactic error");
|
||||
}
|
||||
templateArgs.Add(template_name);
|
||||
}
|
||||
}
|
||||
|
||||
List<type_definition> templateLists = instanceName.restriction_args.params_list.Concat(templateArgs.idents.Select(x => new named_type_reference(x.name)).OfType<type_definition>()).ToList();
|
||||
var parents = new named_type_reference_list(new List<named_type_reference> {
|
||||
new template_type_reference(instanceName.name, new template_param_list(templateLists)),
|
||||
new template_type_reference("I" + instanceName.name, instanceName.restriction_args)});
|
||||
var instanceDefTranslated =
|
||||
SyntaxTreeBuilder.BuildClassDefinition(
|
||||
parents,
|
||||
null, instanceDefinition.body.class_def_blocks.ToArray());
|
||||
instanceDefTranslated.template_args = templateArgs;
|
||||
instanceDefTranslated.where_section = whereSection;
|
||||
instanceDefTranslated.source_context = instanceDefinition.source_context;
|
||||
|
||||
for (int i = 0; i < instanceDefTranslated.body.class_def_blocks.Count; i++)
|
||||
{
|
||||
var cm = instanceDefTranslated.body.class_def_blocks[i].members;
|
||||
|
||||
for (int j = 0; j < cm.Count; j++)
|
||||
{
|
||||
procedure_header header = null;
|
||||
if (cm[j] is procedure_header ph)
|
||||
{
|
||||
cm[j] = ph;
|
||||
}
|
||||
else if (cm[j] is procedure_definition pd)
|
||||
{
|
||||
header = pd.proc_header;
|
||||
}
|
||||
header.proc_attributes.Add(new procedure_attribute("override", proc_attribute.attr_override));
|
||||
ConvertOperatorNameIdent(header);
|
||||
}
|
||||
}
|
||||
/*
|
||||
{
|
||||
// Add constructor
|
||||
var cm = instanceDefTranslated.body.class_def_blocks[0];
|
||||
var def = new procedure_definition(
|
||||
new constructor(),
|
||||
new statement_list(new empty_statement()));
|
||||
def.proc_body.Parent = def;
|
||||
def.proc_header.proc_attributes = new procedure_attributes_list();
|
||||
|
||||
cm.Add(def);
|
||||
}
|
||||
*/
|
||||
var typeName = new ident(CreateInstanceName(instanceName.restriction_args as typeclass_param_list, instanceName.name), instanceName.source_context);
|
||||
|
||||
var instanceDeclTranslated = new type_declaration(typeName, instanceDefTranslated, instanceDeclaration.source_context);
|
||||
instanceDeclTranslated.attributes = instanceDeclaration.attributes;
|
||||
AddAttribute(
|
||||
instanceDeclTranslated, "__TypeclassInstanceAttribute",
|
||||
new expression_list(new string_const(TypeclassRestrictionToString(instanceName))));
|
||||
AddAttribute(instanceDeclTranslated, "__TypeclassAttribute",
|
||||
new expression_list(new string_const(TypeclassRestrictionToString(
|
||||
(originalTypeclass.Parent as type_declaration).type_name as typeclass_restriction))));
|
||||
|
||||
Replace(instanceDeclaration, instanceDeclTranslated);
|
||||
visit(instanceDeclTranslated);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static string TypeclassRestrictionToString(typeclass_restriction instanceName)
|
||||
{
|
||||
return instanceName.name + "[" + string.Join(",", instanceName.restriction_args.params_list) + "]";
|
||||
}
|
||||
|
||||
private static string CreateInstanceName(typeclass_param_list restriction_args, string typeName)
|
||||
{
|
||||
for (int i = 0; i < restriction_args.Count; i++)
|
||||
{
|
||||
typeName += "_" + (restriction_args.params_list[i] as named_type_reference).names[0];
|
||||
}
|
||||
|
||||
return typeName;
|
||||
}
|
||||
|
||||
bool VisitTypeclassDeclaration(type_declaration typeclassDeclaration)
|
||||
{
|
||||
var typeclassDefinition = typeclassDeclaration.type_def as typeclass_definition;
|
||||
if (typeclassDefinition == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var typeclassName = typeclassDeclaration.type_name as typeclass_restriction;
|
||||
|
||||
// TODO: typeclassDefinition.additional_restrictions - translate to usual classes
|
||||
|
||||
// Creating interface
|
||||
|
||||
// Get members for typeclass interface
|
||||
var interfaceMembers = new List<class_members>();
|
||||
foreach (var cm in typeclassDefinition.body.class_def_blocks)
|
||||
{
|
||||
var cmNew = (class_members)cm.Clone();
|
||||
|
||||
for (int i = 0; i < cmNew.members.Count; i++)
|
||||
{
|
||||
var member = cmNew.members[i];
|
||||
if (member is function_header || member is procedure_header)
|
||||
{
|
||||
cmNew.members[i] = member;
|
||||
}
|
||||
else if (member is procedure_definition procDef)
|
||||
{
|
||||
cmNew.members[i] = procDef.proc_header;
|
||||
}
|
||||
AddAttribute(cmNew.members[i], "__TypeclassMemberAttribute");
|
||||
if (cmNew.members[i] is procedure_header ph)
|
||||
{
|
||||
ConvertOperatorNameIdent(ph);
|
||||
}
|
||||
}
|
||||
|
||||
interfaceMembers.Add(cmNew);
|
||||
}
|
||||
var interfaceInheritance = (named_type_reference_list)typeclassDefinition.additional_restrictions?.Clone();
|
||||
if (interfaceInheritance != null)
|
||||
{
|
||||
interfaceInheritance.source_context = null;
|
||||
for (int i = 0; i < interfaceInheritance.types.Count; i++)
|
||||
{
|
||||
if (interfaceInheritance.types[i] is typeclass_reference tr)
|
||||
{
|
||||
interfaceInheritance.types[i] = TypeclassReferenceToInterfaceName(tr.names[0].name, tr.restriction_args);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException("Syntactic Error");
|
||||
}
|
||||
}
|
||||
}
|
||||
var typeclassInterfaceDef =
|
||||
SyntaxTreeBuilder.BuildClassDefinition(
|
||||
interfaceInheritance,
|
||||
null, interfaceMembers.ToArray());
|
||||
typeclassInterfaceDef.keyword = class_keyword.Interface;
|
||||
var typeclassInterfaceName = new template_type_name("I" + typeclassName.name, RestrictionsToIdentList(typeclassName.restriction_args));
|
||||
var typeclassInterfaceDecl = new type_declaration(typeclassInterfaceName, typeclassInterfaceDef);
|
||||
typeclassInterfaceDecl.attributes = typeclassDeclaration.attributes;
|
||||
AddAttribute(
|
||||
typeclassInterfaceDecl, "__TypeclassAttribute",
|
||||
new expression_list(new string_const(TypeclassRestrictionToString(typeclassName))));
|
||||
|
||||
|
||||
// Creating class
|
||||
|
||||
var typeclassDefTranslated =
|
||||
SyntaxTreeBuilder.BuildClassDefinition(
|
||||
new named_type_reference_list(new template_type_reference(typeclassInterfaceName.name, typeclassName.restriction_args)),
|
||||
null, typeclassDefinition.body.class_def_blocks.ToArray());
|
||||
|
||||
typeclassDefTranslated.attribute = class_attribute.Abstract;
|
||||
for (int i = 0; i < typeclassDefTranslated.body.class_def_blocks.Count; i++)
|
||||
{
|
||||
var cm = typeclassDefTranslated.body.class_def_blocks[i].members;
|
||||
|
||||
for (int j = 0; j < cm.Count; j++)
|
||||
{
|
||||
procedure_header header = null;
|
||||
if (cm[j] is procedure_header ph)
|
||||
{
|
||||
header = ph;
|
||||
header.proc_attributes.Add(new procedure_attribute("abstract", proc_attribute.attr_abstract));
|
||||
}
|
||||
else if (cm[j] is procedure_definition pd)
|
||||
{
|
||||
header = pd.proc_header;
|
||||
header.proc_attributes.Add(new procedure_attribute("virtual", proc_attribute.attr_virtual));
|
||||
}
|
||||
|
||||
ConvertOperatorNameIdent(header);
|
||||
}
|
||||
}
|
||||
/*
|
||||
{
|
||||
// Add constructor
|
||||
var cm = typeclassDefTranslated.body.class_def_blocks[0];
|
||||
var def = new procedure_definition(
|
||||
new constructor(),
|
||||
new statement_list(new empty_statement()));
|
||||
def.proc_body.Parent = def;
|
||||
def.proc_header.proc_attributes = new procedure_attributes_list();
|
||||
|
||||
cm.Add(def);
|
||||
}
|
||||
*/
|
||||
// Add template parameters for typeclass class(derived typeclasses)
|
||||
ident_list templates = RestrictionsToIdentList(typeclassName.restriction_args);
|
||||
if (typeclassDefinition.additional_restrictions != null)
|
||||
{
|
||||
for (int i = 0; i < typeclassDefinition.additional_restrictions.types.Count; i++)
|
||||
{
|
||||
string name;
|
||||
string templateName;
|
||||
if (typeclassDefinition.additional_restrictions.types[i] is typeclass_reference tr)
|
||||
{
|
||||
name = tr.names[0].name;
|
||||
templateName = TypeclassRestrctionToTemplateName(name, tr.restriction_args).name;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException("SyntaxError");
|
||||
}
|
||||
|
||||
// Add template parameter
|
||||
templates.Add(templateName);
|
||||
|
||||
// Add where restriction
|
||||
if (typeclassDefTranslated.where_section == null)
|
||||
{
|
||||
typeclassDefTranslated.where_section = new where_definition_list();
|
||||
}
|
||||
typeclassDefTranslated.where_section.Add(GetWhereRestriction(
|
||||
interfaceInheritance.types[i],
|
||||
templateName));
|
||||
|
||||
// Add methods from derived typeclasses
|
||||
var body = (instancesAndRestrictedFunctions.typeclasses[name].type_def as typeclass_definition).body;
|
||||
foreach (var cdb in body.class_def_blocks)
|
||||
{
|
||||
var cdbNew = new class_members(cdb.access_mod == null ? access_modifer.none : cdb.access_mod.access_level);
|
||||
foreach (var member in cdb.members)
|
||||
{
|
||||
procedure_header memberHeaderNew;
|
||||
|
||||
if (member is procedure_header || member is function_header)
|
||||
{
|
||||
memberHeaderNew = (procedure_header)member.Clone();
|
||||
memberHeaderNew.source_context = null;
|
||||
}
|
||||
else if (member is procedure_definition procDefinition)
|
||||
{
|
||||
memberHeaderNew = (procedure_header)procDefinition.proc_header.Clone();
|
||||
memberHeaderNew.Parent = null;
|
||||
memberHeaderNew.source_context = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var variableName = templateName + "Instance";
|
||||
var parameters = memberHeaderNew.parameters.params_list.Aggregate(new expression_list(), (x, y) => new expression_list(x.expressions.Concat(y.idents.idents).ToList()));
|
||||
|
||||
expression methodCall = null;
|
||||
if (memberHeaderNew.name.meth_name is operator_name_ident oni)
|
||||
{
|
||||
ConvertOperatorNameIdent(memberHeaderNew);
|
||||
Debug.Assert(parameters.expressions.Count == 2, "Parameters count for operation should be equal to 2");
|
||||
//methodCall = new bin_expr(parameters.expressions[0], parameters.expressions[1], oni.operator_type);
|
||||
}
|
||||
var callName = new dot_node(variableName, memberHeaderNew.name.meth_name.name);
|
||||
methodCall = new method_call(callName, parameters);
|
||||
statement exec = null;
|
||||
if (memberHeaderNew is function_header)
|
||||
{
|
||||
exec = new assign("Result", methodCall);
|
||||
}
|
||||
else if (memberHeaderNew is procedure_header)
|
||||
{
|
||||
exec = new procedure_call(methodCall as method_call);
|
||||
}
|
||||
var procDef = new procedure_definition(
|
||||
memberHeaderNew,
|
||||
new statement_list(
|
||||
GetInstanceSingletonVarStatement(templateName),
|
||||
exec));
|
||||
cdbNew.Add(procDef);
|
||||
}
|
||||
typeclassDefTranslated.body.class_def_blocks.Add(cdbNew);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var typeclassNameTanslated = new template_type_name(typeclassName.name, templates, typeclassName.source_context);
|
||||
|
||||
var typeclassDeclTranslated = new type_declaration(typeclassNameTanslated, typeclassDefTranslated, typeclassDeclaration.source_context);
|
||||
typeclassDeclTranslated.attributes = typeclassDeclaration.attributes;
|
||||
AddAttribute(
|
||||
typeclassDeclTranslated, "__TypeclassAttribute",
|
||||
new expression_list(new string_const(TypeclassRestrictionToString(typeclassName))));
|
||||
|
||||
Replace(typeclassDeclaration, typeclassDeclTranslated);
|
||||
UpperNodeAs<type_declarations>().InsertBefore(typeclassDeclTranslated, typeclassInterfaceDecl);
|
||||
visit(typeclassInterfaceDecl);
|
||||
visit(typeclassDeclTranslated);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void ConvertOperatorNameIdent(procedure_header ph)
|
||||
{
|
||||
if (ph.name.meth_name is operator_name_ident oni)
|
||||
{
|
||||
var methName = "$typeclass" + PascalABCCompiler.TreeConverter.name_reflector.get_name(oni.operator_type);
|
||||
ph.name.meth_name = methName;
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddAttribute(declaration typeclassInterfaceDecl, string newAttribute, expression_list expressionList = null)
|
||||
{
|
||||
if (expressionList == null)
|
||||
{
|
||||
expressionList = new expression_list();
|
||||
}
|
||||
if (typeclassInterfaceDecl.attributes == null)
|
||||
{
|
||||
typeclassInterfaceDecl.attributes = new attribute_list();
|
||||
}
|
||||
typeclassInterfaceDecl.attributes.Add(new simple_attribute_list(new attribute(null, new named_type_reference(newAttribute), expressionList)));
|
||||
}
|
||||
|
||||
private static template_type_reference TypeclassReferenceToInterfaceName(string name, template_param_list restriction_args)
|
||||
{
|
||||
return new template_type_reference(
|
||||
new named_type_reference("I" + name), restriction_args);
|
||||
}
|
||||
|
||||
private static ident_list RestrictionsToIdentList(template_param_list restrictions)
|
||||
{
|
||||
var templates = new ident_list();
|
||||
templates.source_context = restrictions.source_context;
|
||||
for (int i = 0; i < restrictions.Count; i++)
|
||||
{
|
||||
templates.Add((restrictions.params_list[i] as named_type_reference).names[0]);
|
||||
}
|
||||
|
||||
return templates;
|
||||
}
|
||||
|
||||
public override void visit(type_declaration _type_declaration)
|
||||
{
|
||||
if (VisitInstanceDeclaration(_type_declaration))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (VisitTypeclassDeclaration(_type_declaration))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DefaultVisit(_type_declaration);
|
||||
}
|
||||
|
||||
|
||||
public override void visit(procedure_definition _procedure_definition)
|
||||
{
|
||||
bool isConstrainted = _procedure_definition.proc_header.where_defs != null &&
|
||||
_procedure_definition.proc_header.where_defs.defs.Any(x => x is where_typeclass_constraint);
|
||||
if (!isConstrainted)
|
||||
{
|
||||
DefaultVisit(_procedure_definition);
|
||||
return;
|
||||
}
|
||||
|
||||
var header = _procedure_definition.proc_header;
|
||||
var headerTranslated = header.Clone() as procedure_header;
|
||||
headerTranslated.where_defs = new where_definition_list();
|
||||
|
||||
var additionalTemplateArgs = new ident_list();
|
||||
|
||||
for (int i = 0; i < header.where_defs.defs.Count; i++)
|
||||
{
|
||||
var where = header.where_defs.defs[i];
|
||||
|
||||
if (where is where_typeclass_constraint)
|
||||
{
|
||||
var typeclassWhere = where as where_typeclass_constraint;
|
||||
var newName = TypeclassRestrctionToTemplateName(typeclassWhere.restriction.name, typeclassWhere.restriction.restriction_args);
|
||||
AddAttribute(
|
||||
newName, "__TypeclassGenericParameter",
|
||||
new expression_list(new string_const(GetInstanceSingletonName(newName.name))));
|
||||
additionalTemplateArgs.Add(newName);
|
||||
|
||||
// Create name for template that replaces typeclass(for ex. SumTC)
|
||||
headerTranslated.where_defs.defs.Add(
|
||||
GetWhereRestriction(
|
||||
new template_type_reference(new named_type_reference("I" + typeclassWhere.restriction.name), typeclassWhere.restriction.restriction_args),
|
||||
newName));
|
||||
}
|
||||
else
|
||||
{
|
||||
headerTranslated.where_defs.defs.Add(where);
|
||||
}
|
||||
}
|
||||
|
||||
// Add new templates devoted to constraints to template list
|
||||
// TODO: template_args can be empty, if there is no <T> or smth, need to check
|
||||
headerTranslated.template_args.idents.AddRange(additionalTemplateArgs.idents);
|
||||
|
||||
var blockProc = (_procedure_definition.proc_body as block);
|
||||
foreach (var arg in additionalTemplateArgs.idents)
|
||||
{
|
||||
blockProc.program_code.AddFirst(GetInstanceSingletonVarStatement(arg.name));
|
||||
}
|
||||
|
||||
//var list = _procedure_definition.proc_body.DescendantNodes().OfType<typeclass_param_list>();
|
||||
foreach (var tcr in _procedure_definition.proc_body.DescendantNodes().OfType<ident_with_templateparams>())
|
||||
{
|
||||
if (tcr.template_params is typeclass_param_list)
|
||||
{
|
||||
// TODO: Check tcr.name - typeclass from where
|
||||
// TODO: Check - that there is such typeclass with such args at where
|
||||
// TODO: Ensure that we don't replace another constraint funciton call
|
||||
var str = tcr.template_params.params_list
|
||||
.Select(x => (x as named_type_reference).names[0].name)
|
||||
.Aggregate((tcr.name as ident).name, (x, y) => x + y);
|
||||
var id = new ident(str + "Instance");
|
||||
var parent = tcr.Parent;
|
||||
parent.ReplaceDescendant((addressed_value)tcr, (addressed_value)id, Desc.All);
|
||||
}
|
||||
//var id = new ident(TypeclassRestrctionToTemplateName(tcr) + "Instance");
|
||||
|
||||
}
|
||||
|
||||
var procedureDefTranslated = new procedure_definition(
|
||||
headerTranslated, _procedure_definition.proc_body,
|
||||
_procedure_definition.is_short_definition, _procedure_definition.source_context);
|
||||
procedureDefTranslated.proc_header.attributes = _procedure_definition.proc_header.attributes;
|
||||
AddAttribute(procedureDefTranslated.proc_header, "__TypeclassRestrictedFunctionAttribute");
|
||||
Replace(_procedure_definition, procedureDefTranslated);
|
||||
visit(procedureDefTranslated);
|
||||
}
|
||||
|
||||
private static var_statement GetInstanceSingletonVarStatement(string typeName)
|
||||
{
|
||||
return new var_statement(new var_def_statement(
|
||||
GetInstanceSingletonName(typeName),
|
||||
new dot_node(
|
||||
new ident_with_templateparams(new ident("__ConceptSingleton"), new template_param_list(new List<type_definition> { new named_type_reference(typeName) })),
|
||||
new ident("Instance")
|
||||
)));
|
||||
}
|
||||
|
||||
private static string GetInstanceSingletonName(string typeName)
|
||||
{
|
||||
return typeName + "Instance";
|
||||
}
|
||||
|
||||
private static where_definition GetWhereRestriction(type_definition restriction, ident templateName)
|
||||
{
|
||||
return // where
|
||||
new where_definition(
|
||||
// ConstraintTC :
|
||||
new ident_list(templateName),
|
||||
new where_type_specificator_list(new List<type_definition> {
|
||||
// IConstraint<T, C>,
|
||||
restriction,
|
||||
// constructor
|
||||
new declaration_specificator(DeclarationSpecificator.WhereDefConstructor, "constructor")
|
||||
}));
|
||||
}
|
||||
|
||||
public override void visit(method_call methodCall)
|
||||
{
|
||||
var methodName = methodCall.dereferencing_value as ident_with_templateparams;
|
||||
if (methodName == null)
|
||||
{
|
||||
DefaultVisit(methodCall);
|
||||
return;
|
||||
}
|
||||
var typeclassRestrictions = methodName.template_params as typeclass_param_list;
|
||||
if (typeclassRestrictions == null)
|
||||
{
|
||||
DefaultVisit(methodCall);
|
||||
return;
|
||||
}
|
||||
|
||||
var paramList = new List<type_definition>();
|
||||
paramList.AddRange(typeclassRestrictions.params_list);
|
||||
|
||||
// TODO: Add template types for typeclass instances
|
||||
var methodStrName = (methodName.name as ident).name;
|
||||
var typeclasses = instancesAndRestrictedFunctions.restrictedFunctions[methodStrName];
|
||||
|
||||
List<type_definition> newParams = GetTranslatedTypeclassParameters(paramList, typeclasses);
|
||||
|
||||
paramList.AddRange(newParams);
|
||||
|
||||
var methodCallTranslated = new method_call(
|
||||
new ident_with_templateparams(methodName.name, new template_param_list(paramList), methodName.source_context),
|
||||
methodCall.parameters,
|
||||
methodCall.source_context);
|
||||
Replace(methodCall, methodCallTranslated);
|
||||
}
|
||||
|
||||
private List<type_definition> GetTranslatedTypeclassParameters(List<type_definition> paramList, IEnumerable<string> typeclasses)
|
||||
{
|
||||
var possibleOverloadingsForEachTypeclass = typeclasses.Select(x =>
|
||||
new KeyValuePair<string, List<typeclass_param_list>>(x, instancesAndRestrictedFunctions.instances[x]));
|
||||
|
||||
// Find current overloading in possible
|
||||
var newParams = new List<type_definition>();
|
||||
foreach (var typeclassOverloadings in possibleOverloadingsForEachTypeclass)
|
||||
{
|
||||
foreach (var possibleParamList in typeclassOverloadings.Value)
|
||||
{
|
||||
bool isEqual = true;
|
||||
for (int i = 0; i < possibleParamList.params_list.Count; i++)
|
||||
{
|
||||
if ((possibleParamList.params_list[i] as named_type_reference).names[0].name !=
|
||||
(paramList[i] as named_type_reference).names[0].name)
|
||||
{
|
||||
isEqual = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: need many checks
|
||||
// Typeclass params and function restriction params are mixed up
|
||||
// Fix it as soon as it possible
|
||||
// Btw for 1 argument it's ok.
|
||||
if (isEqual)
|
||||
{
|
||||
var derived_typeclass =
|
||||
(instancesAndRestrictedFunctions.typeclasses[typeclassOverloadings.Key].type_def as typeclass_definition);
|
||||
|
||||
var base_typeclasses = derived_typeclass.additional_restrictions?.types.OfType<typeclass_reference>().Select(x => x.names[0].name);
|
||||
var typeName = new named_type_reference(CreateInstanceName(possibleParamList, typeclassOverloadings.Key));
|
||||
if (base_typeclasses == null || base_typeclasses.Count() == 0)
|
||||
{
|
||||
newParams.Add(typeName);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var translatedParams = GetTranslatedTypeclassParameters(paramList, base_typeclasses);
|
||||
|
||||
newParams.Add(new template_type_reference(
|
||||
typeName,
|
||||
new template_param_list(translatedParams)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return newParams;
|
||||
}
|
||||
|
||||
private static ident TypeclassRestrctionToTemplateName(string name, template_param_list restriction_args)
|
||||
{
|
||||
|
||||
// Concatenate type constraint into new type name
|
||||
// For example:
|
||||
// Constaint[T, C] => ConstraintTC
|
||||
return RestrictionsToIdentList(restriction_args).idents.Aggregate(
|
||||
new ident(name), (x, y) => x.name + y.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -200,6 +200,8 @@ namespace PascalABCCompiler.TreeConverter
|
|||
internal List<var_definition_node> var_defs =
|
||||
new List<var_definition_node>();
|
||||
|
||||
public List<type_node> typeclassInstances = new List<type_node>();
|
||||
|
||||
internal Stack<System.Collections.Generic.List<var_definition_node>> var_defs_stack =
|
||||
new Stack<System.Collections.Generic.List<var_definition_node>>();
|
||||
|
||||
|
|
@ -331,6 +333,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
in_parameters_block = false;
|
||||
is_order_independed_method_description = false;
|
||||
_has_nested_functions = false;
|
||||
typeclassInstances.Clear();
|
||||
}
|
||||
|
||||
public void clear_type_prededinitions()
|
||||
|
|
@ -2726,6 +2729,18 @@ namespace PascalABCCompiler.TreeConverter
|
|||
}
|
||||
}
|
||||
|
||||
var testIsInstance = _ctn?.Attributes?.Any(x => x.AttributeType.name == "__TypeclassInstanceAttribute");
|
||||
if (testIsInstance is true)
|
||||
{
|
||||
if (find_method == null || (find_method.sym_info as function_node).polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract)
|
||||
{
|
||||
var instanceName = _ctn.Attributes.First(x => x.AttributeType.name == "__TypeclassInstanceAttribute").Arguments[0].value;
|
||||
var typeclassName = _ctn.Attributes.First(x => x.AttributeType.name == "__TypeclassAttribute").Arguments[0].value;
|
||||
AddError(_ctn.location, "INSTANCE_{0}_DOES_NOT_IMPLEMENT_REQUIREMENT_{1}_OF_TYPECLASS_{2}",
|
||||
instanceName.ToString(), Tools.GetFullMethodHeaderString(meth), typeclassName.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
if (find_method == null)
|
||||
{
|
||||
//Нет функции с таким именем, набором параметров и возвращаемым значением
|
||||
|
|
|
|||
|
|
@ -1081,6 +1081,46 @@ namespace PascalABCCompiler.TreeConverter
|
|||
right = null_const_node.get_const_node_with_type(left.type, (null_const_node)right);
|
||||
}
|
||||
|
||||
// voloshinbogdan Typeclasses 21.05.2018
|
||||
var testTopFunctionForTypeclassRestriction = context.func_stack.top()?.attributes?.Any(x => x.AttributeType.name == "__TypeclassRestrictedFunctionAttribute");
|
||||
if (testTopFunctionForTypeclassRestriction.HasValue && testTopFunctionForTypeclassRestriction.Value)
|
||||
{
|
||||
var func = context.func_stack.top();
|
||||
var typeclasses = func.generic_params.Where(x => x.Attributes != null && x.Attributes.Any(attr => attr.AttributeType.name == "__TypeclassGenericParameterAttribute"));
|
||||
foreach (var item in typeclasses)
|
||||
{
|
||||
var args = item.Attributes.First(x => x.AttributeType.name == "__TypeclassGenericParameterAttribute").Arguments;
|
||||
var silTmp = (item as type_node)?.find_in_type("$typeclass" + name, context.CurrentScope);
|
||||
if (silTmp != null)
|
||||
{
|
||||
var dn = new ident((args.First() as string_const_node).constant_value);
|
||||
var dns = convert_strong(dn);
|
||||
var exp = convertion_data_and_alghoritms.create_method_call(silTmp[0].sym_info as function_node, null, dns, left, right);
|
||||
return exp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var testIsTypeclass = context._ctn?.Attributes?.Any(x => x.AttributeType.name == "__TypeclassAttribute");
|
||||
var testIsInstance = context._ctn?.Attributes?.Any(x => x.AttributeType.name == "__TypeclassInstanceAttribute");
|
||||
if (testIsTypeclass.HasValue && testIsTypeclass.Value && !(testIsInstance.HasValue && testIsInstance.Value))
|
||||
{
|
||||
var type = context._ctn;
|
||||
|
||||
var silTmp = (type.ImplementingInterfaces[0] as type_node)?.find_in_type("$typeclass" + name, context.CurrentScope);
|
||||
if (silTmp != null)
|
||||
{
|
||||
var methodName = convert_strong(new ident("$typeclass" + name));
|
||||
var thisNode = convert_strong(new ident("self"));
|
||||
var exp = convertion_data_and_alghoritms.create_method_call(silTmp[0].sym_info as function_node, null, thisNode, left, right);
|
||||
|
||||
return exp;
|
||||
}
|
||||
|
||||
}
|
||||
// ! voloshinbogdan Typeclasses 21.05.2018
|
||||
|
||||
|
||||
type_node left_type = left.type;
|
||||
type_node right_type = right.type;
|
||||
|
||||
|
|
@ -3505,6 +3545,12 @@ namespace PascalABCCompiler.TreeConverter
|
|||
|
||||
public override void visit(SyntaxTree.class_definition _class_definition)
|
||||
{
|
||||
var testIsTypeclassInstance = context._ctn?.Attributes?.Any(a => a.AttributeType.name == "__TypeclassInstanceAttribute");
|
||||
if (testIsTypeclassInstance.HasValue && testIsTypeclassInstance.Value)
|
||||
{
|
||||
context.typeclassInstances.Add(context._ctn);
|
||||
}
|
||||
|
||||
if (_class_definition.attribute != class_attribute.None && _class_definition.body == null)
|
||||
AddError(new SimpleSemanticError(get_location(_class_definition), "CLASS_ATTRIBUTE_NOT_ALLOWED_IN_CLASS_PREDEFINTIONS"));
|
||||
if ((_class_definition.attribute & PascalABCCompiler.SyntaxTree.class_attribute.Sealed) == SyntaxTree.class_attribute.Sealed)
|
||||
|
|
@ -5068,6 +5114,28 @@ namespace PascalABCCompiler.TreeConverter
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Typeclasses voloshinbogdan 2018.21.05 - search methods at typeclasses
|
||||
if (sil == null)
|
||||
{
|
||||
var testTopFunctionForTypeclassRestriction = context.func_stack.top()?.attributes?.Any(x => x.AttributeType.name == "__TypeclassRestrictedFunctionAttribute");
|
||||
if (testTopFunctionForTypeclassRestriction.HasValue && testTopFunctionForTypeclassRestriction.Value && sil == null)
|
||||
{
|
||||
var func = context.func_stack.top();
|
||||
var typeclasses = func.generic_params.Where(x => x.Attributes != null && x.Attributes.Any(attr => attr.AttributeType.name == "__TypeclassGenericParameterAttribute"));
|
||||
foreach (var item in typeclasses)
|
||||
{
|
||||
var args = item.Attributes.First(x => x.AttributeType.name == "__TypeclassGenericParameterAttribute").Arguments;
|
||||
var silTmp = (item as type_node)?.find_in_type(id.name, context.CurrentScope);
|
||||
if (silTmp != null)
|
||||
{
|
||||
deref_value = new dot_node((args.First() as string_const_node).constant_value, id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// ! Typeclasses
|
||||
}
|
||||
if (sil == null)
|
||||
{
|
||||
|
|
@ -12949,7 +13017,8 @@ namespace PascalABCCompiler.TreeConverter
|
|||
if (context.top_function is common_method_node)
|
||||
{
|
||||
common_method_node cmmn = context.top_function as common_method_node;
|
||||
if (cmmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
|
||||
var testIsTypeclass = context._ctn?.Attributes?.Any(x => x.AttributeType.name == "__TypeclassAttribute");
|
||||
if (cmmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && !(testIsTypeclass.HasValue && testIsTypeclass.Value))
|
||||
{
|
||||
AddError(get_location(_function_header), "OVERLOADED_OPERATOR_MUST_BE_STATIC_FUNCTION");
|
||||
}
|
||||
|
|
@ -12994,7 +13063,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
if (ptn == cmmn.cont_type)
|
||||
has_types = true;
|
||||
}
|
||||
if (!has_types)
|
||||
if (!has_types && !(testIsTypeclass.HasValue && testIsTypeclass.Value))
|
||||
AddError(new SimpleSemanticError(cmmn.loc, "LEAST_ONE_PARAMETER_TYPE_SHOULD_EQ_DECLARING_TYPE_{0}",cmmn.cont_type.name));
|
||||
}
|
||||
}
|
||||
|
|
@ -13631,7 +13700,9 @@ namespace PascalABCCompiler.TreeConverter
|
|||
}
|
||||
first_param = false;
|
||||
common_method_node cnode = context.top_function as common_method_node;
|
||||
if (cnode != null && cnode.IsOperator)
|
||||
// Typeclasses voloshinbogdan 2018.05.21
|
||||
var testIsTypeclass = context._ctn?.Attributes?.Any(x => x.AttributeType.name == "__TypeclassAttribute");
|
||||
if (cnode != null && cnode.IsOperator && !(testIsTypeclass.HasValue && testIsTypeclass.Value))
|
||||
{
|
||||
parameter_list pars = context.top_function.parameters;
|
||||
if (cnode.name != compiler_string_consts.implicit_operator_name && cnode.name != compiler_string_consts.explicit_operator_name)
|
||||
|
|
@ -16822,6 +16893,17 @@ namespace PascalABCCompiler.TreeConverter
|
|||
expression_node left = convert_strong(_bin_expr.left);
|
||||
expression_node right = convert_strong(_bin_expr.right);
|
||||
expression_node res = find_operator(_bin_expr.operation_type, left, right, get_location(_bin_expr));
|
||||
// voloshinbogdan 22.05.2018 Typeclasses
|
||||
var testTopFunctionForTypeclassRestriction = context.func_stack.top()?.attributes?.Any(x => x.AttributeType.name == "__TypeclassRestrictedFunctionAttribute");
|
||||
var testIsTypeclass = context._ctn?.Attributes?.Any(x => x.AttributeType.name == "__TypeclassAttribute");
|
||||
if (
|
||||
(testTopFunctionForTypeclassRestriction.HasValue && testTopFunctionForTypeclassRestriction.Value) ||
|
||||
(testIsTypeclass.HasValue && testIsTypeclass.Value))
|
||||
{
|
||||
return_value(res);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (res.type is undefined_type)
|
||||
AddError(get_location(_bin_expr), "OPERATOR_RETURN_TYPE_UNDEFINED_{0}", name_reflector.get_name(_bin_expr.operation_type));
|
||||
|
|
|
|||
|
|
@ -837,6 +837,9 @@ namespace PascalABCCompiler.TreeRealization
|
|||
var continue_trying_to_infer_types = true;
|
||||
Dictionary<string, delegate_internal_interface> formal_delegates = null;
|
||||
|
||||
var testIsTypeclassRestricted = func.Attributes?.Any(x => x.AttributeType.name == "__TypeclassRestrictedFunctionAttribute");
|
||||
var isTypeclassRestricted = testIsTypeclassRestricted.HasValue && testIsTypeclassRestricted.Value;
|
||||
var typeclasses = func.get_generic_params_list().Where(t => t.Attributes != null && t.Attributes.Any(a => a.AttributeType != null && a.AttributeType.name == "__TypeclassGenericParameterAttribute")); // Typeclasses
|
||||
while (continue_trying_to_infer_types) //Продолжаем пытаться вычислить типы до тех пор пока состояние о выведенных типах не будет отличаться от состояния на предыдущей итерации
|
||||
{
|
||||
var previous_deduce_state = deduced // Текущее состояние выведенных на данный момент типов. Простой список индексов с уже выведенными типами из массива deduced
|
||||
|
|
@ -919,7 +922,37 @@ namespace PascalABCCompiler.TreeRealization
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (isTypeclassRestricted)
|
||||
{
|
||||
foreach (var tc in typeclasses)
|
||||
{
|
||||
var instances = context.typeclassInstances.Where(ti =>
|
||||
(ti.ImplementingInterfaces[0] as common_generic_instance_type_node).original_generic ==
|
||||
(tc.ImplementingInterfaces[0] as common_generic_instance_type_node).original_generic);
|
||||
|
||||
var appropriateInstances = instances.Where(ti =>
|
||||
(ti.ImplementingInterfaces[0] as common_generic_instance_type_node).instance_params.SequenceEqual(
|
||||
(tc.ImplementingInterfaces[0] as common_generic_instance_type_node).instance_params.Select(ip => deduced[ip.generic_param_index])));
|
||||
|
||||
if (appropriateInstances.Count() == 1)
|
||||
{
|
||||
var foundInstance = appropriateInstances.First() as common_type_node;
|
||||
if (foundInstance.generic_params?.Count > 0 is true)
|
||||
{
|
||||
type_node[] deducedInstances = new type_node[foundInstance.generic_params.Count];
|
||||
DeduceTypeclassInstances(context, deducedInstances, foundInstance.generic_params.OfType<type_node>());
|
||||
|
||||
deduced[tc.generic_param_index] = foundInstance.get_instance(deducedInstances.ToList());
|
||||
}
|
||||
else
|
||||
{
|
||||
deduced[tc.generic_param_index] = appropriateInstances.First();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var current_deduce_state = deduced //текущее состояние выведенных типов
|
||||
.Select((t, ii) => new {Type = t, Index = ii})
|
||||
.Where(t => t.Type != null)
|
||||
|
|
@ -987,6 +1020,38 @@ namespace PascalABCCompiler.TreeRealization
|
|||
return func.get_instance(deduced_list, alone, loc);
|
||||
}
|
||||
|
||||
private static void DeduceTypeclassInstances(compilation_context context, type_node[] deduced, IEnumerable<type_node> typeclasses)
|
||||
{
|
||||
foreach (var tc in typeclasses)
|
||||
{
|
||||
var instances = context.typeclassInstances.Where(ti =>
|
||||
(ti.ImplementingInterfaces[0] as common_generic_instance_type_node).original_generic ==
|
||||
(tc.ImplementingInterfaces[0] as common_generic_instance_type_node).original_generic);
|
||||
|
||||
var appropriateInstances = instances.Where(ti =>
|
||||
(ti.ImplementingInterfaces[0] as common_generic_instance_type_node).instance_params.SequenceEqual(
|
||||
(tc.ImplementingInterfaces[0] as common_generic_instance_type_node).instance_params));
|
||||
|
||||
if (appropriateInstances.Count() == 1)
|
||||
{
|
||||
var foundInstance = appropriateInstances.First() as common_type_node;
|
||||
if (foundInstance.generic_params?.Count > 0 is true)
|
||||
{
|
||||
List<type_node> instanceTypes = null;
|
||||
deduced[tc.generic_param_index] = foundInstance.get_instance(instanceTypes);
|
||||
}
|
||||
else
|
||||
{
|
||||
deduced[tc.generic_param_index] = appropriateInstances.First();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: typeclasses add error message
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Выведение типов
|
||||
public static bool DeduceInstanceTypes(type_node formal_type, type_node fact_type, type_node[] deduced, List<int> nils)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue