Compare commits

...

24 commits

Author SHA1 Message Date
Bogan Voloshin 12012b7e4d Remove test 2021-01-04 19:23:58 +03:00
Bogan Voloshin 283e030613 test 2021-01-04 19:01:27 +03:00
Bogan Voloshin 9933458caf Update typeclass errors 2021-01-04 18:14:16 +03:00
Bogan Voloshin 8c5cb25295 Update gitignore 2021-01-04 17:59:03 +03:00
Bogan Voloshin aec3fb4874 Add error interface cannot implement instance 2020-11-20 03:42:50 +03:00
Bogan Voloshin dc93588518 Add error for undefined restrictions in instance 2020-11-14 16:01:20 +03:00
Bogan Voloshin 4fb04698be Add error for short functions with typeclasses 2020-11-12 06:03:25 +03:00
Bogan Voloshin 8054f57e92 Fix error "can not find instance for typeclass" 2020-11-10 09:24:23 +03:00
Bogan Voloshin 554a08b844 Uncomment typeclasses attributes in PABCSystem 2020-11-10 06:28:46 +03:00
Bogan Voloshin 43dc4b25dd Add tests without intellisense 2020-11-05 18:52:07 +03:00
Bogan Voloshin 6f11b069d5 Merge branch 'master' into features/typeclasses-another-approach 2020-11-05 17:52:57 +03:00
Bogan Voloshin 1c4c5d538c Update syntax Tree 2020-11-05 15:11:03 +03:00
Bogan Voloshin 233744ccc7 Merge branch 'master' into features/typeclasses-another-approach 2020-10-18 23:38:40 +03:00
Voloshin Bogdan e812ff520b Merge branch 'master' into features/typeclasses-another-approach
# Conflicts:
#	Parsers/PascalABCParserNewSaushkin/ABCPascal.cs
#	Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs
#	SyntaxTree/tree/SyntaxTreeStreamReader.cs
#	SyntaxTree/tree/SyntaxTreeStreamWriter.cs
#	SyntaxTreeConverters/StandardSyntaxConverter.cs
#	SyntaxVisitors/SyntaxVisitors.csproj
#	TreeConverter/TreeConversion/compilation_context.cs
#	TreeConverter/TreeRealization/generics.cs
2019-10-24 02:17:43 +03:00
Voloshin Bogdan 0b9f9cbc63 Merge branch 'master' into features/typeclasses-another-approach
# Conflicts:
#	Parsers/PascalABCParserNewSaushkin/ABCPascal.cs
#	Parsers/PascalABCParserNewSaushkin/ABCPascal.lst
#	Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs
#	TreeConverter/TreeConversion/syntax_tree_visitor.cs
2019-04-03 02:41:54 +03:00
Voloshin Bogdan 42bfa72b59 Fix recursive typeclass instances deduction 2019-02-28 01:38:15 +03:00
Voloshin Bogdan 7fe98d826c Add description for instance not implemented error. 2019-02-27 02:57:11 +03:00
Voloshin Bogdan e0cf9f4a8f Refactor Typeclasses semantics 2019-02-27 02:56:23 +03:00
Voloshin Bogdan cdcf5af995 Uncomment typeclass syntax desugaring 2019-02-27 00:39:53 +03:00
Voloshin Bogdan 2a6108d374 Merge branch 'master' into features/typeclasses-another-approach
# Conflicts:
#	Parsers/PascalABCParserNewSaushkin/ABCPascal.cs
#	Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs
2019-02-26 21:22:55 +03:00
Voloshin Bogdan e53c926d2a Restore typeclasses 2018-12-26 02:06:19 +03:00
Voloshin Bogdan 32fd1a38b0 Merge branch 'master' into features/typeclasses-another-approach
# Conflicts:
#	Parsers/PascalABCParserNewSaushkin/ABCPascal.cs
#	Parsers/PascalABCParserNewSaushkin/ABCPascal.lex
#	Parsers/PascalABCParserNewSaushkin/ABCPascal.y
#	Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs
#	Parsers/PascalABCParserNewSaushkin/Keywords.cs
2018-12-26 00:33:12 +03:00
Voloshin Bogdan 525546e8c7 Fix unclosed comment 2018-10-03 21:05:18 +03:00
Voloshin Bogdan ce056a8068 Restore typeclasses 2018-10-03 20:40:55 +03:00
33 changed files with 10945 additions and 3501 deletions

24
.gitignore vendored
View file

@ -50,3 +50,27 @@ bin/System.dll.txt
bin/mscorlib.txt
bin/pabcnetc.exe
bin/pabcnetcclear.exe
AddIns/ICSharpCode.SharpDevelop.addin
TestSuite/CompilationSamples/NUnitABC.pas
TestSuite/CompilationSamples/OpenCLABCBase.pas
TestSuite/CompilationSamples/OpenGLABCBase.pas
TestSuite/CompilationSamples/Turtle.pas
TestSuite/CompilationSamples/TwoPanelsWindow.pas
TestSuite/errors/err0259.exe
TestSuite/errors/err0303.exe
TestSuite/errors/err0345_marshal.exe
CodeExamples/Typeclasses/log.txt
CodeExamples/Typeclasses/Others/log.txt
CodeExamples/Typeclasses/TypeClassErrors/log.txt

View file

@ -0,0 +1,13 @@
type
tc1[T] = typeclass
end;
I1=interface
end;
tc1[I1] = instance
end;//не должно компилироваться
begin
end.

View file

@ -0,0 +1,9 @@
type
tc1[T]=typeclass end;
tc1[integer]=instance
function f1: integer := 1;
end;
begin
end.

View file

@ -1,9 +1,9 @@
//
// This CSharp output file generated by Gardens Point LEX
// Version: 1.1.3.301
// Machine: DESKTOP-G8V08V4
// DateTime: 01.10.2020 18:49:53
// UserName: ?????????
// Machine: LAPTOP-BKFKGP2K
// DateTime: 18.10.2020 22:42:10
// UserName: yabov
// GPLEX input file <ABCPascal.lex>
// GPLEX frame file <embedded resource>
//
@ -1964,6 +1964,8 @@ string cur_yytext = yytext;
case (int)Tokens.tkExternal:
case (int)Tokens.tkYield:
case (int)Tokens.tkSequence:
case (int)Tokens.tkTypeclass:
case (int)Tokens.tkInstance:
case (int)Tokens.tkMatch:
case (int)Tokens.tkWhen:
case (int)Tokens.tkStatic:

View file

@ -367,6 +367,8 @@ UNICODEARROW \x890
case (int)Tokens.tkExternal:
case (int)Tokens.tkYield:
case (int)Tokens.tkSequence:
case (int)Tokens.tkTypeclass:
case (int)Tokens.tkInstance:
case (int)Tokens.tkMatch:
case (int)Tokens.tkWhen:
case (int)Tokens.tkStatic:

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,9 @@
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
// SSM 21/11/16 Лямбда выражения вынесены на верхний уровень (п.ч. присваивания и параметры)
// SSM 21/11/16 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28>.<2E>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
%{
// Эти объявления добавляются в класс GPPGParser, представляющий собой парсер, генерируемый системой gppg
public syntax_tree_node root; // Корневой узел синтаксического дерева
// <EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> GPPGParser, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> gppg
public syntax_tree_node root; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
public List<Error> errors;
public string current_file_name;
@ -34,7 +34,7 @@
%token <ti> tkDirectiveName tkAmpersend tkColon tkDotDot tkPoint tkRoundOpen tkRoundClose tkSemiColon tkSquareOpen tkSquareClose tkQuestion tkUnderscore 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 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 tkShortProgram tkVertParen tkShortSFProgram
@ -95,6 +95,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 <stn> if_stmt
%type <stn> initialization_part
%type <stn> template_arguments label_list ident_or_keyword_pointseparator_list ident_list param_name_list
@ -157,6 +158,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 <td> template_type
%type <stn> try_stmt
%type <stn> uses_clause used_units_list
@ -260,7 +262,7 @@ program_file
}
;
/* это нужно для intellisensа чтобы строилось дерево при отсутствии точки в конце */
/* <EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> intellisens<6E> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> */
optional_tk_point
: tkPoint
{ $$ = $1; }
@ -555,7 +557,7 @@ decl_sect
{ $$ = $1; }
;
/* SSM 2.1.13 упрощение грамматики */
/* SSM 2.1.13 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
proc_func_constr_destr_decl
: proc_func_decl
{ $$ = $1; }
@ -876,7 +878,7 @@ const_factor
}
| sign const_factor
{
// ручнаЯ коррекциЯ целых констант
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if ($1.type == Operators.Minus)
{
var i64 = $2 as int64_const;
@ -896,7 +898,7 @@ const_factor
parsertools.AddErrorFromResource("BAD_INT2",@$);
break;
}
// можно сделать вычисление константы с вмонтированным минусом
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
$$ = new un_expr($2, $1.type, @$);
}
@ -929,7 +931,7 @@ sign
const_variable
: identifier
{ $$ = $1; }
| literal // SSM 02.10.18 для '123'.Length при инициализации констант
| literal // SSM 02.10.18 <EFBFBD><EFBFBD><EFBFBD> '123'.Length <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{ $$ = $1; }
| unsigned_number
{ $$ = $1; }
@ -954,7 +956,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, @$);
}
@ -1180,8 +1182,41 @@ simple_type_decl
{
$$ = new type_declaration($1, $2, @$);
}
| typeclass_restriction tkEqual tkTypeclass optional_base_classes optional_component_list_seq_end tkSemiColon
{
$$ = 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
{
$$ = new typeclass_restriction(($1 as named_type_reference).ToString(), $2 as template_param_list, @$);
}
;
typeclass_params
: tkSquareOpen template_param_list tkSquareClose
{
$$ = new typeclass_param_list($2 as template_param_list);
}
;
template_type_or_typeclass_params
: template_type_params
{
$$ = $1;
}
| typeclass_params
{
$$ = $1;
}
;
type_decl_identifier
: identifier
{ $$ = $1; }
@ -1540,7 +1575,7 @@ proc_type_decl
{
$$ = new function_header($2 as formal_parameters, null, null, null, $4 as type_definition, @$);
}
| simple_type_identifier tkArrow template_param // эти 2 правила нельзя объединять в одно template_param - будет конфликт
| simple_type_identifier tkArrow template_param // <EFBFBD><EFBFBD><EFBFBD> 2 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD> template_param - <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
$$ = new modern_proc_type($1,null,$3,@$);
}
@ -1556,7 +1591,7 @@ proc_type_decl
{
$$ = new modern_proc_type(null,$2 as enumerator_list,$5,@$);
}
| simple_type_identifier tkArrow tkRoundOpen tkRoundClose // эти 2 правила нельзя объединять в одно template_param - будет конфликт
| simple_type_identifier tkArrow tkRoundOpen tkRoundClose // <EFBFBD><EFBFBD><EFBFBD> 2 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD> template_param - <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
$$ = new modern_proc_type($1,null,null,@$);
}
@ -1689,6 +1724,11 @@ base_class_name
{ $$ = $1; }
| template_type
{ $$ = $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); }
;
template_arguments
@ -1722,6 +1762,10 @@ where_part
{
$$ = 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
@ -2088,17 +2132,17 @@ property_specifiers
:
| tkRead optional_read_expr write_property_specifiers
{
if ($2 == null || $2 is ident) // стандартные свойства
if ($2 == null || $2 is ident) // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
$$ = NewPropertySpecifiersRead($1, $2 as ident, null, null, $3 as property_accessors, @$);
}
else // расширенные свойства
else // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
var id = NewId("#GetGen", @2);
procedure_definition pr = null;
if (!parsertools.build_tree_for_formatter)
pr = CreateAndAddToClassReadFunc($2, id, @2);
$$ = NewPropertySpecifiersRead($1, id, pr, $2, $3 as property_accessors, @$); // $2 передаётся для форматирования
$$ = NewPropertySpecifiersRead($1, id, pr, $2, $3 as property_accessors, @$); // $2 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
}
| tkWrite unlabelled_stmt read_property_specifiers
@ -2108,19 +2152,19 @@ property_specifiers
$$ = NewPropertySpecifiersWrite($1, null, null, null, $3 as property_accessors, @$);
}
else if ($2 is procedure_call && ($2 as procedure_call).is_ident) // стандартные свойства
else if ($2 is procedure_call && ($2 as procedure_call).is_ident) // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
$$ = NewPropertySpecifiersWrite($1, ($2 as procedure_call).func_name as ident, null, null, $3 as property_accessors, @$); // старые свойства - с идентификатором
$$ = NewPropertySpecifiersWrite($1, ($2 as procedure_call).func_name as ident, null, null, $3 as property_accessors, @$); // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
else // расширенные свойства
else // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
var id = NewId("#SetGen", @2);
procedure_definition pr = null;
if (!parsertools.build_tree_for_formatter)
pr = CreateAndAddToClassWriteProc($2 as statement,id,@2);
if (parsertools.build_tree_for_formatter)
$$ = NewPropertySpecifiersWrite($1, id, pr, $2 as statement, $3 as property_accessors, @$); // $2 передаётся для форматирования
$$ = NewPropertySpecifiersWrite($1, id, pr, $2 as statement, $3 as property_accessors, @$); // $2 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
else $$ = NewPropertySpecifiersWrite($1, id, pr, null, $3 as property_accessors, @$);
}
}
@ -2136,7 +2180,7 @@ write_property_specifiers
}
else if ($2 is procedure_call && ($2 as procedure_call).is_ident)
{
$$ = NewPropertySpecifiersWrite($1, ($2 as procedure_call).func_name as ident, null, null, null, @$); // старые свойства - с идентификатором
$$ = NewPropertySpecifiersWrite($1, ($2 as procedure_call).func_name as ident, null, null, null, @$); // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
else
{
@ -2208,7 +2252,7 @@ var_decl_part
{
$$ = new var_def_statement($1 as ident_list, null, $3, definition_attribute.None, false, @$);
}*/
| ident_list tkColon type_ref tkAssignOrEqual typed_var_init_expression // typed_const_plus уже давно не константа :) Но сюда не попали Tuples, поскольку они конкурируют с дурацкими старыми инициализаторами массивов
| ident_list tkColon type_ref tkAssignOrEqual typed_var_init_expression // typed_const_plus <EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> :) <20><> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Tuples, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
$$ = new var_def_statement($1 as ident_list, $3, $5, definition_attribute.None, false, @$);
}
@ -3274,7 +3318,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, @$);
}
@ -3370,7 +3414,7 @@ list_fields_in_unnamed_object
/*array_name_for_new_expr
: simple_type_identifier
{ $$ = $1; }
// | unsized_array_type - и кому такое приснилось
// | unsized_array_type - <EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// { $$ = $1; }
;*/
@ -3921,7 +3965,7 @@ default_expr
;
tuple
: tkRoundOpen expr_l1 tkComma expr_l1_list lambda_type_ref optional_full_lambda_fp_list tkRoundClose // lambda_type_ref optional_full_lambda_fp_list нужно оставить чтобы не было конфликтов с грамматикой лямбд
: tkRoundOpen expr_l1 tkComma expr_l1_list lambda_type_ref optional_full_lambda_fp_list tkRoundClose // lambda_type_ref optional_full_lambda_fp_list <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
{
/*if ($5 != null)
parsertools.AddErrorFromResource("BAD_TUPLE",@5);
@ -3981,7 +4025,7 @@ factor
parsertools.AddErrorFromResource("BAD_INT2",@$);
break;
}
// можно сделать вычисление константы с вмонтированным минусом
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
$$ = new un_expr($2, $1.type, @$);
}
@ -4151,7 +4195,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, @$);
}
@ -4500,6 +4544,8 @@ keyword
{ $$ = $1; }
| tkWhen
{ $$ = $1; }
| tkInstance
{ $$ = $1; }
| tkPartial
{ $$ = $1; }
| tkAbstract
@ -4601,16 +4647,16 @@ func_decl_lambda
var idList = new ident_list($1, @1);
var formalPars = new formal_parameters(new typed_parameters(idList, new lambda_inferred_type(new PascalABCCompiler.TreeRealization.lambda_any_type_node(), @1), parametr_kind.none, null, @1), @1);
//var sl = $3 as statement_list;
//if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName($3, "Result") != null) // если это было выражение или есть переменная Result, то автовывод типа
//if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName($3, "Result") != null) // <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Result, <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, new lambda_inferred_type(new PascalABCCompiler.TreeRealization.lambda_any_type_node(), @1), $3 as statement_list, @$);
//else
//$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, null, $3 as statement_list, @$);
}
| tkRoundOpen tkRoundClose lambda_type_ref_noproctype tkArrow lambda_function_body
{
// Здесь надо анализировать по телу и либо оставлять lambda_inferred_type, либо делать его null!
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> lambda_inferred_type, <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> null!
var sl = $5 as statement_list;
if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // то надо выводить
if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, $3, sl, @$);
else $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, null, sl, @$);
}
@ -4620,7 +4666,7 @@ func_decl_lambda
var loc = LexLocation.MergeAll(@2,@3,@4);
var formalPars = new formal_parameters(new typed_parameters(idList, $4, parametr_kind.none, null, loc), loc);
var sl = $8 as statement_list;
if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // то надо выводить
if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, $6, sl, @$);
else $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, null, sl, @$);
}
@ -4631,7 +4677,7 @@ func_decl_lambda
for (int i = 0; i < ($4 as formal_parameters).Count; i++)
formalPars.Add(($4 as formal_parameters).params_list[i]);
var sl = $8 as statement_list;
if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // то надо выводить
if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, $6, sl, @$);
else $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, null, sl, @$);
}
@ -4643,7 +4689,7 @@ func_decl_lambda
for (int i = 0; i < ($6 as formal_parameters).Count; i++)
formalPars.Add(($6 as formal_parameters).params_list[i]);
var sl = $10 as statement_list;
if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // то надо выводить
if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, $8, sl, @$);
else $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, null, sl, @$);
}
@ -4678,7 +4724,7 @@ func_decl_lambda
formal_pars.source_context = LexLocation.MergeAll(@2,@3,@4,@5);
var sl = pair.exprs;
if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // то надо выводить
if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formal_pars, pair.tn, pair.exprs, @$);
else $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formal_pars, null, pair.exprs, @$);
}
@ -4708,7 +4754,7 @@ func_decl_lambda
formalPars.Add(($6 as formal_parameters).params_list[i]);
var sl = pair.exprs;
if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // то надо выводить
if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, pair.tn, pair.exprs, @$);
else $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, null, pair.exprs, @$);
}
@ -4735,7 +4781,7 @@ rem_lambda
;
expl_func_decl_lambda
: tkFunction lambda_type_ref_noproctype tkArrow lambda_function_body // SSM 11.08.20 добавил _noproctype в 3 подправилах
: tkFunction lambda_type_ref_noproctype tkArrow lambda_function_body // SSM 11.08.20 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> _noproctype <20> 3 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, $2, $4 as statement_list, 1, @$);
}
@ -4876,7 +4922,7 @@ lambda_function_body
{
parsertools.AddErrorFromResource("RESULT_IDENT_NOT_EXPECTED_IN_THIS_CONTEXT", id.source_context);
}
var sl = new statement_list(new assign("result",$1,@$),@$); // надо помечать ещё и assign как автосгенерированный для лямбды - чтобы запретить явный Result
var sl = new statement_list(new assign("result",$1,@$),@$); // <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20> assign <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> Result
sl.expr_lambda_body = true;
$$ = sl;
}

File diff suppressed because it is too large Load diff

View file

@ -145,6 +145,8 @@ namespace GPPGParserScanner
keywords.Add(Convert("when"), (int)Tokens.tkWhen);
keywords.Add(Convert("namespace"), (int)Tokens.tkNamespace);
keywords.Add(Convert("static"), (int)Tokens.tkStatic);
keywords.Add(Convert("typeclass"), (int)Tokens.tkTypeclass);
keywords.Add(Convert("instance"), (int)Tokens.tkInstance);
}
static Keywords()

View file

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

View file

@ -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)
{
}
@ -3952,6 +4000,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);

View file

@ -465,70 +465,82 @@ 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_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 semantic_check_sugared_var_def_statement_node();
return new pattern_parameter();
case 236:
return new const_pattern();
return new desugared_deconstruction();
case 237:
return new tuple_pattern_wild_card();
return new var_deconstructor_parameter();
case 238:
return new const_pattern_parameter();
return new recursive_deconstructor_parameter();
case 239:
return new wild_card_deconstructor_parameter();
return new deconstruction_variables_definition();
case 240:
return new collection_pattern();
return new var_tuple_def_statement();
case 241:
return new collection_pattern_gap_parameter();
return new semantic_check_sugared_var_def_statement_node();
case 242:
return new collection_pattern_wild_card();
return new const_pattern();
case 243:
return new collection_pattern_var_parameter();
return new tuple_pattern_wild_card();
case 244:
return new recursive_collection_parameter();
return new const_pattern_parameter();
case 245:
return new recursive_pattern_parameter();
return new wild_card_deconstructor_parameter();
case 246:
return new tuple_pattern();
return new collection_pattern();
case 247:
return new tuple_pattern_var_parameter();
return new collection_pattern_gap_parameter();
case 248:
return new recursive_tuple_parameter();
return new collection_pattern_wild_card();
case 249:
return new diapason_expr_new();
return new collection_pattern_var_parameter();
case 250:
return new if_expr_new();
return new recursive_collection_parameter();
case 251:
return new simple_expr_with_deref();
return new recursive_pattern_parameter();
case 252:
return new index();
return new tuple_pattern();
case 253:
return new array_const_new();
return new tuple_pattern_var_parameter();
case 254:
return new recursive_tuple_parameter();
case 255:
return new diapason_expr_new();
case 256:
return new if_expr_new();
case 257:
return new simple_expr_with_deref();
case 258:
return new index();
case 259:
return new array_const_new();
case 260:
return new semantic_ith_element_of();
}
return null;
@ -3994,6 +4006,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);

View file

@ -6179,9 +6179,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);
}
@ -6214,7 +6340,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(type_pattern _type_pattern)
{
bw.Write((Int16)223);
bw.Write((Int16)229);
write_type_pattern(_type_pattern);
}
@ -6244,7 +6370,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);
}
@ -6274,7 +6400,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(match_with _match_with)
{
bw.Write((Int16)225);
bw.Write((Int16)231);
write_match_with(_match_with);
}
@ -6313,7 +6439,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(pattern_case _pattern_case)
{
bw.Write((Int16)226);
bw.Write((Int16)232);
write_pattern_case(_pattern_case);
}
@ -6352,7 +6478,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(pattern_cases _pattern_cases)
{
bw.Write((Int16)227);
bw.Write((Int16)233);
write_pattern_cases(_pattern_cases);
}
@ -6385,7 +6511,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(deconstructor_pattern _deconstructor_pattern)
{
bw.Write((Int16)228);
bw.Write((Int16)234);
write_deconstructor_pattern(_deconstructor_pattern);
}
@ -6415,7 +6541,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(pattern_parameter _pattern_parameter)
{
bw.Write((Int16)229);
bw.Write((Int16)235);
write_pattern_parameter(_pattern_parameter);
}
@ -6427,7 +6553,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(desugared_deconstruction _desugared_deconstruction)
{
bw.Write((Int16)230);
bw.Write((Int16)236);
write_desugared_deconstruction(_desugared_deconstruction);
}
@ -6457,7 +6583,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);
}
@ -6488,7 +6614,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);
}
@ -6500,7 +6626,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);
}
@ -6533,7 +6659,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);
}
@ -6545,7 +6671,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);
}
@ -6579,7 +6705,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(const_pattern _const_pattern)
{
bw.Write((Int16)236);
bw.Write((Int16)242);
write_const_pattern(_const_pattern);
}
@ -6600,7 +6726,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(tuple_pattern_wild_card _tuple_pattern_wild_card)
{
bw.Write((Int16)237);
bw.Write((Int16)243);
write_tuple_pattern_wild_card(_tuple_pattern_wild_card);
}
@ -6612,7 +6738,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(const_pattern_parameter _const_pattern_parameter)
{
bw.Write((Int16)238);
bw.Write((Int16)244);
write_const_pattern_parameter(_const_pattern_parameter);
}
@ -6633,7 +6759,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(wild_card_deconstructor_parameter _wild_card_deconstructor_parameter)
{
bw.Write((Int16)239);
bw.Write((Int16)245);
write_wild_card_deconstructor_parameter(_wild_card_deconstructor_parameter);
}
@ -6645,7 +6771,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(collection_pattern _collection_pattern)
{
bw.Write((Int16)240);
bw.Write((Int16)246);
write_collection_pattern(_collection_pattern);
}
@ -6657,7 +6783,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(collection_pattern_gap_parameter _collection_pattern_gap_parameter)
{
bw.Write((Int16)241);
bw.Write((Int16)247);
write_collection_pattern_gap_parameter(_collection_pattern_gap_parameter);
}
@ -6669,7 +6795,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(collection_pattern_wild_card _collection_pattern_wild_card)
{
bw.Write((Int16)242);
bw.Write((Int16)248);
write_collection_pattern_wild_card(_collection_pattern_wild_card);
}
@ -6681,7 +6807,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(collection_pattern_var_parameter _collection_pattern_var_parameter)
{
bw.Write((Int16)243);
bw.Write((Int16)249);
write_collection_pattern_var_parameter(_collection_pattern_var_parameter);
}
@ -6711,7 +6837,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(recursive_collection_parameter _recursive_collection_parameter)
{
bw.Write((Int16)244);
bw.Write((Int16)250);
write_recursive_collection_parameter(_recursive_collection_parameter);
}
@ -6723,7 +6849,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(recursive_pattern_parameter _recursive_pattern_parameter)
{
bw.Write((Int16)245);
bw.Write((Int16)251);
write_recursive_pattern_parameter(_recursive_pattern_parameter);
}
@ -6744,7 +6870,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(tuple_pattern _tuple_pattern)
{
bw.Write((Int16)246);
bw.Write((Int16)252);
write_tuple_pattern(_tuple_pattern);
}
@ -6756,7 +6882,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(tuple_pattern_var_parameter _tuple_pattern_var_parameter)
{
bw.Write((Int16)247);
bw.Write((Int16)253);
write_tuple_pattern_var_parameter(_tuple_pattern_var_parameter);
}
@ -6786,7 +6912,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(recursive_tuple_parameter _recursive_tuple_parameter)
{
bw.Write((Int16)248);
bw.Write((Int16)254);
write_recursive_tuple_parameter(_recursive_tuple_parameter);
}
@ -6798,7 +6924,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(diapason_expr_new _diapason_expr_new)
{
bw.Write((Int16)249);
bw.Write((Int16)255);
write_diapason_expr_new(_diapason_expr_new);
}
@ -6828,7 +6954,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(if_expr_new _if_expr_new)
{
bw.Write((Int16)250);
bw.Write((Int16)256);
write_if_expr_new(_if_expr_new);
}
@ -6867,7 +6993,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(simple_expr_with_deref _simple_expr_with_deref)
{
bw.Write((Int16)251);
bw.Write((Int16)257);
write_simple_expr_with_deref(_simple_expr_with_deref);
}
@ -6889,7 +7015,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(index _index)
{
bw.Write((Int16)252);
bw.Write((Int16)258);
write_index(_index);
}
@ -6911,7 +7037,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(array_const_new _array_const_new)
{
bw.Write((Int16)253);
bw.Write((Int16)259);
write_array_const_new(_array_const_new);
}
@ -6932,7 +7058,7 @@ namespace PascalABCCompiler.SyntaxTree
public void visit(semantic_ith_element_of _semantic_ith_element_of)
{
bw.Write((Int16)254);
bw.Write((Int16)260);
write_semantic_ith_element_of(_semantic_ith_element_of);
}

File diff suppressed because it is too large Load diff

View file

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

View file

@ -2864,6 +2864,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>
<ExtendedField Name="parameters" Type="List&lt;pattern_parameter&gt;" CreateVariable="true" DeleteVariable="false" />

View file

@ -37,6 +37,15 @@ namespace PascalABCCompiler.SyntaxTreeConverters
StandOutExprWithLambdaInForeachSequenceVisitor.New.ProcessNode(root);
VarNamesInMethodsWithSameNameAsClassGenericParamsReplacer.New.ProcessNode(root); // SSM bug fix #1147
FindOnExceptVarsAndApplyRenameVisitor.New.ProcessNode(root);
{
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

View file

@ -65,6 +65,9 @@
<Compile Include="SugarVisitors\NewRangeDesugarVisitor.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="VisitorsForLambdas\RenameOnExceptVarsVisitor.cs" />
<Compile Include="VisitorsForLambdas\RenameSameVarNamesVisitor.cs" />
<Compile Include="VisitorsForLambdas\StandOutExprWithLambdaInForeachSequenceVisitor.cs" />

View file

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

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

View file

@ -0,0 +1,628 @@
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, cm[j].source_context));
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",
string_consts(
TypeclassRestrictionToString(instanceName),
((originalTypeclass.Parent as type_declaration).type_name as typeclass_restriction).name));
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",
string_consts(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",
string_consts(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",
string_consts(GetInstanceSingletonName(newName.name), typeclassWhere.restriction.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);
}
private static expression_list string_consts(params string[] strs)
{
return new expression_list(
strs.Select(x => (new string_const(x)) as expression).ToList());
}
}
}

View file

@ -2653,7 +2653,7 @@ type
class _instance: T;
class inited: boolean := false;
public
class function Instance: T;
class function &Instance: T;
begin
if inited = false then
begin
@ -3887,7 +3887,7 @@ begin
while t <> typeof(Object) do
begin
meth := t.GetMethod('ToString', System.Reflection.BindingFlags.Public or
System.Reflection.BindingFlags.Instance or
System.Reflection.BindingFlags.&Instance or
System.Reflection.BindingFlags.DeclaredOnly, nil, new System.Type[0], nil);
if meth <> nil then
break;
@ -3986,8 +3986,8 @@ begin
else
while t <> typeof(object) do
begin
var ff := t.GetFields(System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.Instance or System.Reflection.BindingFlags.DeclaredOnly);
var pp := t.GetProperties(System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.Instance or System.Reflection.BindingFlags.DeclaredOnly);
var ff := t.GetFields(System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.&Instance or System.Reflection.BindingFlags.DeclaredOnly);
var pp := t.GetProperties(System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.&Instance or System.Reflection.BindingFlags.DeclaredOnly);
for var i := ff.Length - 1 downto 0 do
sb.Insert(1, StructuredObjectToString(ff[i].GetValue(o), n + 1) + ',');
@ -13112,7 +13112,7 @@ begin
begin
variable.GetType.InvokeMember('$Init$',
System.Reflection.BindingFlags.InvokeMethod or
System.Reflection.BindingFlags.Instance or
System.Reflection.BindingFlags.&Instance or
System.Reflection.BindingFlags.Public, nil, variable, nil);
result := variable;
end;

View file

@ -2649,7 +2649,7 @@ type
class _instance: T;
class inited: boolean := false;
public
class function Instance: T;
class function &Instance: T;
begin
if inited = false then
begin
@ -3872,7 +3872,7 @@ begin
while t <> typeof(Object) do
begin
meth := t.GetMethod('ToString', System.Reflection.BindingFlags.Public or
System.Reflection.BindingFlags.Instance or
System.Reflection.BindingFlags.&Instance or
System.Reflection.BindingFlags.DeclaredOnly, nil, new System.Type[0], nil);
if meth <> nil then
break;
@ -3971,8 +3971,8 @@ begin
else
while t <> typeof(object) do
begin
var ff := t.GetFields(System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.Instance or System.Reflection.BindingFlags.DeclaredOnly);
var pp := t.GetProperties(System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.Instance or System.Reflection.BindingFlags.DeclaredOnly);
var ff := t.GetFields(System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.&Instance or System.Reflection.BindingFlags.DeclaredOnly);
var pp := t.GetProperties(System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.&Instance or System.Reflection.BindingFlags.DeclaredOnly);
for var i := ff.Length - 1 downto 0 do
sb.Insert(1, StructuredObjectToString(ff[i].GetValue(o), n + 1) + ',');
@ -13090,7 +13090,7 @@ begin
begin
variable.GetType.InvokeMember('$Init$',
System.Reflection.BindingFlags.InvokeMethod or
System.Reflection.BindingFlags.Instance or
System.Reflection.BindingFlags.&Instance or
System.Reflection.BindingFlags.Public, nil, variable, nil);
result := variable;
end;

View file

@ -2649,7 +2649,7 @@ type
class _instance: T;
class inited: boolean := false;
public
class function Instance: T;
class function &Instance: T;
begin
if inited = false then
begin
@ -3872,7 +3872,7 @@ begin
while t <> typeof(Object) do
begin
meth := t.GetMethod('ToString', System.Reflection.BindingFlags.Public or
System.Reflection.BindingFlags.Instance or
System.Reflection.BindingFlags.&Instance or
System.Reflection.BindingFlags.DeclaredOnly, nil, new System.Type[0], nil);
if meth <> nil then
break;
@ -3971,8 +3971,8 @@ begin
else
while t <> typeof(object) do
begin
var ff := t.GetFields(System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.Instance or System.Reflection.BindingFlags.DeclaredOnly);
var pp := t.GetProperties(System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.Instance or System.Reflection.BindingFlags.DeclaredOnly);
var ff := t.GetFields(System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.&Instance or System.Reflection.BindingFlags.DeclaredOnly);
var pp := t.GetProperties(System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.&Instance or System.Reflection.BindingFlags.DeclaredOnly);
for var i := ff.Length - 1 downto 0 do
sb.Insert(1, StructuredObjectToString(ff[i].GetValue(o), n + 1) + ',');
@ -13090,7 +13090,7 @@ begin
begin
variable.GetType.InvokeMember('$Init$',
System.Reflection.BindingFlags.InvokeMethod or
System.Reflection.BindingFlags.Instance or
System.Reflection.BindingFlags.&Instance or
System.Reflection.BindingFlags.Public, nil, variable, nil);
result := variable;
end;

View file

@ -0,0 +1,93 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PascalABCCompiler.TreeRealization;
using PascalABCCompiler.SemanticTree;
namespace PascalABCCompiler.TreeConverter
{
public static class TypeclassHelper
{
public static bool HasRestrictions(function_node fn)
{
var hasRestriction = fn?.attributes?.Any(x => x.AttributeType.name == "__TypeclassRestrictedFunctionAttribute");
return hasRestriction.HasValue && hasRestriction.Value;
}
public static IEnumerable<type_node> GetRestrictedGenerics(function_node fn)
{
return fn.get_generic_params_list().Where(x => x.Attributes != null && x.Attributes.Any(attr => attr.AttributeType.name == "__TypeclassGenericParameterAttribute"));
}
public static bool IsInstance(type_node ctn)
{
var isInstance = ctn?.attributes?.Any(x => x.AttributeType.name == "__TypeclassInstanceAttribute");
return isInstance.HasValue && isInstance.Value;
}
public static bool IsInstance(SyntaxTree.type_declaration td)
{
var attributes = td?.attributes?.attributes;
if (attributes == null || attributes.Count == 0)
return false;
var isInstance = attributes[0]?.attributes?.Any(x => x.type.FirstIdent.name == "__TypeclassInstanceAttribute");
return isInstance.HasValue && isInstance.Value;
}
public static common_type_node GetTopClass(compilation_context context)
{
return (context.CurrentScope.TopScope as SymbolTable.ClassScope)?.class_type;
}
public static bool IsTypeclass(type_node ctn)
{
var isTypeclass = ctn?.attributes?.Any(x => x.AttributeType.name == "__TypeclassAttribute");
return isTypeclass.HasValue && isTypeclass.Value;
}
public static bool IsInInstanceContext(compilation_context context)
{
return IsInstance(GetTopClass(context));
}
public static bool IsInTypeclassContext(compilation_context context)
{
return IsTypeclass(GetTopClass(context));
}
public static string OperatorName(string op)
{
return "$typeclass" + op;
}
public static string GetInstanceName(type_node ctn)
{
return ctn?.attributes?.First(x => x.AttributeType.name == "__TypeclassInstanceAttribute")?.Arguments[0]?.value?.ToString();
}
public static string GetTypeclassName(type_node ctn)
{
var att = ctn?.attributes;
string res = null;
res = att.FirstOrDefault(x => x.AttributeType.name == "__TypeclassAttribute")?.Arguments[0]?.value?.ToString();
if (res == null)
res = att.FirstOrDefault(x => x.AttributeType.name == "__TypeclassGenericParameterAttribute")?.Arguments[1]?.value?.ToString();
if (res == null)
res = att.FirstOrDefault(x => x.AttributeType.name == "__TypeclassInstanceAttribute")?.Arguments[1]?.value?.ToString();
return res;
}
public static string ResugarMethodName(string name)
{
string newName = name;
if(name.StartsWith("$typeclass"))
{
newName = name.Replace("$typeclass", "operator");
}
return newName;
}
}
}

View file

@ -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()
@ -2747,6 +2750,17 @@ namespace PascalABCCompiler.TreeConverter
}
}
if (TypeclassHelper.IsInstance(_ctn))
{
if (find_method == null || (find_method.sym_info as function_node).polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract)
{
var instanceName = TypeclassHelper.GetInstanceName(_ctn);
var typeclassName = TypeclassHelper.GetTypeclassName(_ctn);
AddError(_ctn.location, "INSTANCE_{0}_DOES_NOT_IMPLEMENT_REQUIREMENT_{1}_OF_TYPECLASS_{2}",
instanceName, TypeclassHelper.ResugarMethodName(Tools.GetFullMethodHeaderString(meth)), typeclassName);
}
}
if (find_method == null)
{
//Нет функции с таким именем, набором параметров и возвращаемым значением
@ -3743,8 +3757,16 @@ namespace PascalABCCompiler.TreeConverter
{
cmn.polymorphic_state = SemanticTree.polymorphic_state.ps_virtual;
cmn.overrided_method = FindMethodToOverride(cmn);
if (cmn.overrided_method == null)
AddError(cmn.loc, "NO_METHOD_TO_OVERRIDE");
{
var instance = TypeclassHelper.GetTopClass(this);
if (TypeclassHelper.IsInstance(instance))
AddError(cmn.loc, "NO_RESTRICTION_{0}_IN_TYPECLASS_{1}", cmn.name, TypeclassHelper.GetTypeclassName(instance));
else
AddError(cmn.loc, "NO_METHOD_TO_OVERRIDE");
}
cmn.SetName(cmn.overrided_method.name);
}

View file

@ -1097,6 +1097,42 @@ namespace PascalABCCompiler.TreeConverter
if (right.conversion_type == null)
right = null_const_node.get_const_node_with_type(left.type, (null_const_node)right);
}
// voloshinbogdan Typeclasses 21.05.2018
if (TypeclassHelper.HasRestrictions(context.func_stack.top()))
{
var func = context.func_stack.top();
foreach (var item in TypeclassHelper.GetRestrictedGenerics(func))
{
var args = item.Attributes.First(x => x.AttributeType.name == "__TypeclassGenericParameterAttribute").Arguments;
var silTmp = (item as type_node)?.find_in_type(TypeclassHelper.OperatorName(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;
}
}
}
if (TypeclassHelper.IsTypeclass(context._ctn) && !TypeclassHelper.IsInstance(context._ctn))
{
var type = context._ctn;
var silTmp = (type.ImplementingInterfaces[0] as type_node)?.find_in_type(TypeclassHelper.OperatorName(name), context.CurrentScope);
if (silTmp != null)
{
var methodName = convert_strong(new ident(TypeclassHelper.OperatorName(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
/*if (left.semantic_node_type == semantic_node_type.null_const_node)
{
@ -3620,6 +3656,11 @@ namespace PascalABCCompiler.TreeConverter
public override void visit(SyntaxTree.class_definition _class_definition)
{
if (TypeclassHelper.IsInstance(context._ctn))
{
context.typeclassInstances.Add(context._ctn);
}
if (_class_definition.keyword == class_keyword.Record && _class_definition.Parent is var_def_statement) // безымянная запись
{
// SSM 27.02.12 - всё это перенес в синтаксический визитор UnnamedRecordsCheckVisitor
@ -3707,6 +3748,17 @@ namespace PascalABCCompiler.TreeConverter
AddError(get_location(_class_definition), "STATIC_CLASS_CANNOT_HAVE_PARENT");
type_node tn = ret.visit(_class_definition.class_parents.types[0]);
//if (tn == context.converted_type)
//(voloshin) Typeclasses проверка, если параметр инстанса не является интерфейсом
if (TypeclassHelper.IsInstance(_class_definition.Parent as SyntaxTree.type_declaration))
{
var cgtn = tn as common_generic_instance_type_node;
if (cgtn.generic_parameters.Any(x => x.IsInterface))
{
AddError(get_location(_class_definition), "INTERFACE_CANNOT_IMPLEMENT_INSTANCE");
}
}
if (type_table.original_types_equals(tn, context.converted_type))
AddError(new UndefinedNameReference(tn.name, get_location(_class_definition.class_parents.types[0])));
if (tn.IsSealed)
@ -5307,6 +5359,26 @@ namespace PascalABCCompiler.TreeConverter
}
}
}
// Typeclasses voloshinbogdan 2018.21.05 - search methods at typeclasses
if (sil == null)
{
if (TypeclassHelper.HasRestrictions(context.func_stack.top()) && sil == null)
{
var func = context.func_stack.top();
foreach (var item in TypeclassHelper.GetRestrictedGenerics(func))
{
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)
{
@ -13381,7 +13453,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 isTypeclass = TypeclassHelper.IsTypeclass(context._ctn);
if (cmmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && !isTypeclass)
{
AddError(get_location(_function_header), "OVERLOADED_OPERATOR_MUST_BE_STATIC_FUNCTION");
}
@ -13426,7 +13499,7 @@ namespace PascalABCCompiler.TreeConverter
if (ptn == cmmn.cont_type)
has_types = true;
}
if (!has_types)
if (!has_types && !isTypeclass)
AddError(new SimpleSemanticError(cmmn.loc, "LEAST_ONE_PARAMETER_TYPE_SHOULD_EQ_DECLARING_TYPE_{0}",cmmn.cont_type.name));
}
}
@ -13886,7 +13959,16 @@ namespace PascalABCCompiler.TreeConverter
common_function_node ccfn = context.top_function;
if (ccfn.return_value_type is undefined_type)
{
AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "OVERRIDE_NOT_ALLOWED_FOR_SHORT_FUNCTIONS");
//(voloshin) Typeclasses Пока override не реализован для короких функций, короткие функции не будут поддерживаться в классах типах
if (TypeclassHelper.IsInInstanceContext(context))
{
AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "SHORT_FUNCTIONS_NOT_ALLOWED_IN_TYPECLASSES");
}
else
{
AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "OVERRIDE_NOT_ALLOWED_FOR_SHORT_FUNCTIONS");
}
}
if (ccfn.semantic_node_type != semantic_node_type.common_method_node)
{
@ -14087,7 +14169,8 @@ namespace PascalABCCompiler.TreeConverter
first_param = false;
common_method_node cnode = context.top_function as common_method_node;
parameter_list pars = context.top_function.parameters;
if (cnode != null && cnode.IsOperator)
// Typeclasses voloshinbogdan 2018.05.21
if (cnode != null && cnode.IsOperator && !TypeclassHelper.IsTypeclass(context._ctn))
{
if (cnode.name != compiler_string_consts.implicit_operator_name && cnode.name != compiler_string_consts.explicit_operator_name)
@ -17369,6 +17452,14 @@ namespace PascalABCCompiler.TreeConverter
if (_bin_expr.operation_type == Operators.In)
try_convert_typed_expression_to_function_call(ref left);
expression_node res = find_operator(_bin_expr.operation_type, left, right, get_location(_bin_expr));
// voloshinbogdan 22.05.2018 Typeclasses
if (TypeclassHelper.HasRestrictions(context.func_stack.top()) ||
TypeclassHelper.IsTypeclass(context._ctn))
{
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));

View file

@ -173,6 +173,7 @@
<Compile Include="TreeConversion\syntax_tree_visitor.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="TreeConversion\TypeclassesHelper.cs" />
<Compile Include="TreeConversion\type_constructor.cs" />
<Compile Include="TreeRealization\attributes.cs" />
<Compile Include="TreeRealization\events.cs" />

View file

@ -867,6 +867,8 @@ namespace PascalABCCompiler.TreeRealization
var continue_trying_to_infer_types = true;
Dictionary<string, delegate_internal_interface> formal_delegates = null;
var isTypeclassRestricted = TypeclassHelper.HasRestrictions(func);
var typeclasses = TypeclassHelper.GetRestrictedGenerics(func);
while (continue_trying_to_infer_types) //Продолжаем пытаться вычислить типы до тех пор пока состояние о выведенных типах не будет отличаться от состояния на предыдущей итерации
{
var previous_deduce_state = deduced // Текущее состояние выведенных на данный момент типов. Простой список индексов с уже выведенными типами из массива deduced
@ -949,7 +951,12 @@ namespace PascalABCCompiler.TreeRealization
}
}
}
if (isTypeclassRestricted)
{
DeduceTypeclassInstances(context, deduced, typeclasses, loc);
}
var current_deduce_state = deduced //текущее состояние выведенных типов
.Select((t, ii) => new {Type = t, Index = ii})
.Where(t => t.Type != null)
@ -1017,6 +1024,54 @@ 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, location loc)
{
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 =>
{
if (ip.is_generic_parameter)
return deduced[ip.generic_param_index];
else
return ip;
})));
if (appropriateInstances.Count() == 1)
{
var foundInstance = appropriateInstances.First() as common_type_node;
if (foundInstance.generic_params?.Count > 0 is true)
{
type_node[] instanceTypes = new type_node[foundInstance.generic_params.Count];
DeduceTypeclassInstances(context, instanceTypes, foundInstance.generic_params.OfType<type_node>(), loc);
deduced[tc.generic_param_index] = foundInstance.get_instance(instanceTypes.ToList());
}
else
{
deduced[tc.generic_param_index] = appropriateInstances.First();
}
}
else
{
if (appropriateInstances.Count() == 0)
{
throw new SimpleSemanticError(loc, "NO_INSTANCES_FOR_TYPECLASS_{0}", TypeclassHelper.GetTypeclassName(tc));
}
else
{
throw new SimpleSemanticError(loc, "TC_SEVERAL_INSTANCES_FOR_TYPECLASS_{0}", TypeclassHelper.GetTypeclassName(tc));
}
}
}
}
//Выведение типов
public static bool DeduceInstanceTypes(type_node formal_type, type_node fact_type, type_node[] deduced, List<int> nils, List<type_node> generic_params)
{

View file

@ -0,0 +1,37 @@
call Studio.bat /t:rebuild "/property:Configuration=Release" "/p:Platform=Any CPU" PascalABCNET.sln
@IF %ERRORLEVEL% NEQ 0 GOTO ERROR
cd ReleaseGenerators
..\bin\pabcnetc RebuildStandartModules.pas /rebuild
@IF %ERRORLEVEL% NEQ 0 GOTO ERROR
cd PABCRtl
..\..\bin\pabcnetc PABCRtl.pas /rebuild
@IF %ERRORLEVEL% NEQ 0 GOTO ERROR
..\sn.exe -Vr PABCRtl.dll
..\sn.exe -R PABCRtl.dll KeyPair.snk
..\sn.exe -Vu PABCRtl.dll
copy PABCRtl.dll ..\..\bin\Lib
cd ..
ExecHide.exe gacutil.exe /u PABCRtl
ExecHide.exe gacutil.exe /i ..\bin\Lib\PABCRtl.dll
..\bin\pabcnetc RebuildStandartModules.pas /rebuild
@IF %ERRORLEVEL% NEQ 0 GOTO ERROR
cd ..\bin
REM MPGORunner.exe
TestRunner.exe 1
TestRunner.exe 2
TestRunner.exe 3
TestRunner.exe 4
TestRunner.exe 5
cd ..
GOTO EXIT
:ERROR
PAUSE
:EXIT

View file

@ -2653,7 +2653,7 @@ type
class _instance: T;
class inited: boolean := false;
public
class function Instance: T;
class function &Instance: T;
begin
if inited = false then
begin
@ -2666,7 +2666,7 @@ type
end;
{type
type
///--
__TypeclassRestrictedFunctionAttribute = class(Attribute)
public
@ -2679,7 +2679,7 @@ type
///--
__TypeclassGenericParameterAttribute = class(Attribute)
public
constructor(instanceName: string);
constructor(instanceName: string; originalTypeclassName: string);
begin
end;
end;
@ -2703,10 +2703,10 @@ type
///--
__TypeclassInstanceAttribute = class(Attribute)
public
constructor(instanceName: string);
constructor(instanceName: string; originalTypeclassName: string);
begin
end;
end;}
end;
type
// Смысл полей Num, Width и Fmt соответствует
@ -3887,7 +3887,7 @@ begin
while t <> typeof(Object) do
begin
meth := t.GetMethod('ToString', System.Reflection.BindingFlags.Public or
System.Reflection.BindingFlags.Instance or
System.Reflection.BindingFlags.&Instance or
System.Reflection.BindingFlags.DeclaredOnly, nil, new System.Type[0], nil);
if meth <> nil then
break;
@ -3986,8 +3986,8 @@ begin
else
while t <> typeof(object) do
begin
var ff := t.GetFields(System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.Instance or System.Reflection.BindingFlags.DeclaredOnly);
var pp := t.GetProperties(System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.Instance or System.Reflection.BindingFlags.DeclaredOnly);
var ff := t.GetFields(System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.&Instance or System.Reflection.BindingFlags.DeclaredOnly);
var pp := t.GetProperties(System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.&Instance or System.Reflection.BindingFlags.DeclaredOnly);
for var i := ff.Length - 1 downto 0 do
sb.Insert(1, StructuredObjectToString(ff[i].GetValue(o), n + 1) + ',');
@ -13112,7 +13112,7 @@ begin
begin
variable.GetType.InvokeMember('$Init$',
System.Reflection.BindingFlags.InvokeMethod or
System.Reflection.BindingFlags.Instance or
System.Reflection.BindingFlags.&Instance or
System.Reflection.BindingFlags.Public, nil, variable, nil);
result := variable;
end;

View file

@ -0,0 +1,6 @@
%PREFIX%=SEMANTICERROR_
INSTANCE_{0}_DOES_NOT_IMPLEMENT_REQUIREMENT_{1}_OF_TYPECLASS_{2}=Instance {0} doesn't implement {1}
NO_INSTANCES_FOR_TYPECLASS_{0}=Can't infer instance for typeclass {0}, please specify instance explicitly
SHORT_FUNCTIONS_NOT_ALLOWED_IN_TYPECLASSES=It's not allowed to use short functions with typeclasses
NO_RESTRICTION_{0}_IN_TYPECLASS_{1}=There is no restriction {0} in typeclass {1}
INTERFACE_CANNOT_IMPLEMENT_INSTANCE=Interface can not implement typeclass

View file

@ -0,0 +1,6 @@
%PREFIX%=SEMANTICERROR_
INSTANCE_{0}_DOES_NOT_IMPLEMENT_REQUIREMENT_{1}_OF_TYPECLASS_{2}=Инстанс {0} не переопределяет {1}
NO_INSTANCES_FOR_TYPECLASS_{0}=Невозможно вывести инстанс для класса типа {0}, пожалуйста укажите его явно
SHORT_FUNCTIONS_NOT_ALLOWED_IN_TYPECLASSES=Короткие функции нельзя использовать с классами типов
NO_RESTRICTION_{0}_IN_TYPECLASS_{1}=Нет ограничения {0} в классе типов {1}
INTERFACE_CANNOT_IMPLEMENT_INSTANCE=Интерфейс не может реализовывать класс типа