From 490ddaa43a1435f9eb98978e6278a391934c97d0 Mon Sep 17 00:00:00 2001 From: Mikhalkovich Stanislav Date: Wed, 12 Aug 2020 15:22:16 +0300 Subject: [PATCH] var q := (a,b: integer; c: real) -> begin end; MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit теперь работает --- Configuration/GlobalAssemblyInfo.cs | 2 +- Configuration/Version.defs | 2 +- InstallerSamples/Games/PifTableExam.pas | 61 + InstallerSamples/Games/PifTableExam1.pas | 63 + .../PascalABCParserNewSaushkin/ABCPascal.cs | 2 +- .../PascalABCParserNewSaushkin/ABCPascal.y | 56 +- .../ABCPascalYacc.cs | 1283 +++++++++-------- Parsers/PascalABCParserNewSaushkin/PABC.ymc | 3 + Release/pabcversion.txt | 2 +- ReleaseGenerators/PascalABCNET_version.nsh | 2 +- .../BaseVisitors/SmallHelperVisitors.cs | 12 +- TestSuite/LambdaWithExplicitType.pas | 9 + TestSuite/asT.pas | 4 + .../TreeConversion/syntax_tree_visitor.cs | 26 +- bin/Lib/Controls.pas | 118 +- 15 files changed, 962 insertions(+), 683 deletions(-) create mode 100644 InstallerSamples/Games/PifTableExam.pas create mode 100644 InstallerSamples/Games/PifTableExam1.pas create mode 100644 TestSuite/LambdaWithExplicitType.pas diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index 797a8a0a2..d014c72ef 100644 --- a/Configuration/GlobalAssemblyInfo.cs +++ b/Configuration/GlobalAssemblyInfo.cs @@ -15,7 +15,7 @@ internal static class RevisionClass public const string Major = "3"; public const string Minor = "6"; public const string Build = "3"; - public const string Revision = "2617"; + public const string Revision = "2629"; public const string MainVersion = Major + "." + Minor; public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision; diff --git a/Configuration/Version.defs b/Configuration/Version.defs index f02796822..94f7f4e85 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ %MINOR%=6 -%REVISION%=2617 +%REVISION%=2629 %COREVERSION%=3 %MAJOR%=3 diff --git a/InstallerSamples/Games/PifTableExam.pas b/InstallerSamples/Games/PifTableExam.pas new file mode 100644 index 000000000..0ca2d64ce --- /dev/null +++ b/InstallerSamples/Games/PifTableExam.pas @@ -0,0 +1,61 @@ +uses GraphWPF,Controls,Sounds; + +var x, y: integer; + +procedure NextQuestion; +begin + Window.Clear; + (x, y) := Random2(2, 9); + DrawText(GraphWindow.ClientRect,$'{x} × {y} = ?'); +end; + +function Оценка(ВерныхОтветов: integer): integer; +begin + case ВерныхОтветов of + 10, 9: Оценка := 5; + 8, 7: Оценка := 4; + 4..6: Оценка := 3; + else Оценка := 2; + end; +end; + +begin + Window.Title := 'Проверка таблицы умножения'; + Font.Size := 40; + var l := LeftPanel(200); + l.FontSize := 16; + var sb := StatusBar; + NextQuestion; + + var Результат := IntegerBox('Введите ответ:',0,100); + var b := Button('Ответить'); + var КоличествоОтветов := IntegerBlock('Ответов:'); + var ВерныхОтветов := IntegerBlock('Верных ответов:'); + + b.Click := procedure → begin + if x * y = Результат then + begin + sb.Text := 'Верно!'; + ВерныхОтветов += 1; + end + else + begin + sb.Text := 'Неверно :('; + end; + КоличествоОтветов += 1; + Результат := 0; + if КоличествоОтветов = 10 then // Конец опроса + begin + MessageBox.Show('Тест окончен.'#10#10'Верных ответов: ' + + ВерныхОтветов.Value + #10#10 + 'Оценка: ' + Оценка(ВерныхОтветов)); + // Переход к следующему тесту + ВерныхОтветов := 0; + КоличествоОтветов := 0; + end; + NextQuestion; + end; + OnResize := procedure → begin + Window.Clear; + DrawText(GraphWindow.ClientRect,$'{x} × {y} = ?'); + end; +end. \ No newline at end of file diff --git a/InstallerSamples/Games/PifTableExam1.pas b/InstallerSamples/Games/PifTableExam1.pas new file mode 100644 index 000000000..92279260a --- /dev/null +++ b/InstallerSamples/Games/PifTableExam1.pas @@ -0,0 +1,63 @@ +uses GraphWPF,Controls,Sounds; + +function Оценка(ВерныхОтветов: integer): integer; +begin + case ВерныхОтветов of + 10, 9: Оценка := 5; + 8, 7: Оценка := 4; + 4..6: Оценка := 3; + else Оценка := 2; + end; +end; + +begin + Window.Title := 'Проверка таблицы умножения'; + Font.Size := 60; + var l := LeftPanel(200); + l.FontSize := 16; + var sb := StatusBar; + + var Результат := IntegerBox('Введите ответ:',0,100); + var b := Button('Ответить'); + var КоличествоОтветов := IntegerBlock('Ответов:'); + var ВерныхОтветов := IntegerBlock('Верных ответов:'); + + var ТестОкончен := procedure → begin + MessageBox.Show('Тест окончен.'+#10#10+'Верных ответов: ' + + ВерныхОтветов.Value + #10#10 + 'Оценка: ' + Оценка(ВерныхОтветов)); + // Переход к следующему тесту + ВерныхОтветов := 0; + КоличествоОтветов := 0; + end; + + var x, y: integer; // сомножители + + var НарисоватьТест := procedure → begin + Window.Clear; + DrawText(GraphWindow.ClientRect,$'{x} × {y} = ?'); + end; + + var СледующийВопрос := procedure → begin + (x, y) := Random2(2, 9); + НарисоватьТест; + end; + СледующийВопрос; + + b.Click := procedure → begin + if x * y = Результат then + begin + sb.Text := 'Верно!'; + ВерныхОтветов += 1; + end + else + begin + sb.Text := 'Неверно :('; + end; + КоличествоОтветов += 1; + Результат := 0; + if КоличествоОтветов = 10 then // Конец опроса + ТестОкончен; + СледующийВопрос; + end; + OnResize := НарисоватьТест; +end. \ No newline at end of file diff --git a/Parsers/PascalABCParserNewSaushkin/ABCPascal.cs b/Parsers/PascalABCParserNewSaushkin/ABCPascal.cs index 46d40d6fc..79f6384de 100644 --- a/Parsers/PascalABCParserNewSaushkin/ABCPascal.cs +++ b/Parsers/PascalABCParserNewSaushkin/ABCPascal.cs @@ -2,7 +2,7 @@ // This CSharp output file generated by Gardens Point LEX // Version: 1.1.3.301 // Machine: DESKTOP-G8V08V4 -// DateTime: 29.07.2020 11:15:11 +// DateTime: 12.08.2020 15:06:56 // UserName: ????????? // GPLEX input file // GPLEX frame file diff --git a/Parsers/PascalABCParserNewSaushkin/ABCPascal.y b/Parsers/PascalABCParserNewSaushkin/ABCPascal.y index 9ac01f4f0..184892c18 100644 --- a/Parsers/PascalABCParserNewSaushkin/ABCPascal.y +++ b/Parsers/PascalABCParserNewSaushkin/ABCPascal.y @@ -2188,10 +2188,14 @@ var_decl_part { $$ = new var_def_statement($1 as ident_list, $3, null, definition_attribute.None, false, @$); } - | ident_list tkAssign expr + | ident_list tkAssign expr_with_func_decl_lambda { $$ = new var_def_statement($1 as ident_list, null, $3, definition_attribute.None, false, @$); } + /*| ident_list tkAssign expl_func_decl_lambda + { + $$ = 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, { $$ = new var_def_statement($1 as ident_list, $3, $5, definition_attribute.None, false, @$); @@ -4579,18 +4583,29 @@ 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); - $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, new lambda_inferred_type(new PascalABCCompiler.TreeRealization.lambda_any_type_node(), @1), $3 as statement_list, @$); + //var sl = $3 as statement_list; + //if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName($3, "Result") != null) // Result, + $$ = 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 { - $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, $3, $5 as statement_list, @$); + // lambda_inferred_type, null! + var sl = $5 as statement_list; + if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // + $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, $3, sl, @$); + else $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, null, sl, @$); } | tkRoundOpen identifier tkColon fptype tkRoundClose lambda_type_ref_noproctype tkArrow lambda_function_body { var idList = new ident_list($2, @2); var loc = LexLocation.MergeAll(@2,@3,@4); var formalPars = new formal_parameters(new typed_parameters(idList, $4, parametr_kind.none, null, loc), loc); - $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, $6, $8 as statement_list, @$); + var sl = $8 as statement_list; + if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // + $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, $6, sl, @$); + else $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, null, sl, @$); } | tkRoundOpen identifier tkSemiColon full_lambda_fp_list tkRoundClose lambda_type_ref_noproctype tkArrow lambda_function_body { @@ -4598,7 +4613,10 @@ func_decl_lambda var formalPars = new formal_parameters(new typed_parameters(idList, new lambda_inferred_type(new PascalABCCompiler.TreeRealization.lambda_any_type_node(), null), parametr_kind.none, null, @2), LexLocation.MergeAll(@2,@3,@4)); for (int i = 0; i < ($4 as formal_parameters).Count; i++) formalPars.Add(($4 as formal_parameters).params_list[i]); - $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, $6, $8 as statement_list, @$); + var sl = $8 as statement_list; + if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // + $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, $6, sl, @$); + else $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, null, sl, @$); } | tkRoundOpen identifier tkColon fptype tkSemiColon full_lambda_fp_list tkRoundClose lambda_type_ref_noproctype tkArrow lambda_function_body { @@ -4607,7 +4625,10 @@ func_decl_lambda var formalPars = new formal_parameters(new typed_parameters(idList, $4, parametr_kind.none, null, loc), LexLocation.MergeAll(@2,@3,@4,@5,@6)); for (int i = 0; i < ($6 as formal_parameters).Count; i++) formalPars.Add(($6 as formal_parameters).params_list[i]); - $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, $8, $10 as statement_list, @$); + var sl = $10 as statement_list; + if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // + $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, $8, sl, @$); + else $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, null, sl, @$); } | tkRoundOpen expr_l1 tkComma expr_l1_list lambda_type_ref optional_full_lambda_fp_list tkRoundClose rem_lambda { @@ -4638,7 +4659,11 @@ func_decl_lambda formal_pars.Add(($6 as formal_parameters).params_list[i]); formal_pars.source_context = LexLocation.MergeAll(@2,@3,@4,@5); - $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formal_pars, pair.tn, pair.exprs, @$); + + var sl = pair.exprs; + if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // + $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formal_pars, pair.tn, pair.exprs, @$); + else $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formal_pars, null, pair.exprs, @$); } else { @@ -4664,13 +4689,16 @@ func_decl_lambda if ($6 != null) for (int i = 0; i < ($6 as formal_parameters).Count; i++) formalPars.Add(($6 as formal_parameters).params_list[i]); - - $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, pair.tn, pair.exprs, @$); + + var sl = pair.exprs; + if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // + $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, pair.tn, pair.exprs, @$); + else $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, null, pair.exprs, @$); } } | expl_func_decl_lambda { - $$ = $1; + $$ = $1; } ; @@ -4690,15 +4718,15 @@ rem_lambda ; expl_func_decl_lambda - : tkFunction lambda_type_ref tkArrow lambda_function_body + : tkFunction lambda_type_ref_noproctype tkArrow lambda_function_body // SSM 11.08.20 _noproctype 3 { $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, $2, $4 as statement_list, 1, @$); } - | tkFunction tkRoundOpen tkRoundClose lambda_type_ref tkArrow lambda_function_body + | tkFunction tkRoundOpen tkRoundClose lambda_type_ref_noproctype tkArrow lambda_function_body { $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, $4, $6 as statement_list, 1, @$); } - | tkFunction tkRoundOpen full_lambda_fp_list tkRoundClose lambda_type_ref tkArrow lambda_function_body + | tkFunction tkRoundOpen full_lambda_fp_list tkRoundClose lambda_type_ref_noproctype tkArrow lambda_function_body { $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), $3 as formal_parameters, $5, $7 as statement_list, 1, @$); } @@ -4826,7 +4854,7 @@ common_lambda_body lambda_function_body : expr_l1_for_lambda { - var id = SyntaxVisitors.ExprHasNameVisitor.HasName($1, "Result"); + var id = SyntaxVisitors.HasNameVisitor.HasName($1, "Result"); if (id != null) { parsertools.AddErrorFromResource("RESULT_IDENT_NOT_EXPECTED_IN_THIS_CONTEXT", id.source_context); diff --git a/Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs b/Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs index 82564329c..36f946e2d 100644 --- a/Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs +++ b/Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs @@ -2,7 +2,7 @@ // GPPG version 1.3.6 // Machine: DESKTOP-G8V08V4 -// DateTime: 29.07.2020 11:15:12 +// DateTime: 12.08.2020 15:06:57 // UserName: ????????? // Input file @@ -296,37 +296,37 @@ public partial class GPPGParser: ShiftReduceParser ident_list, tkAssign, expr + case 400: // var_decl_part -> ident_list, tkAssign, expr_with_func_decl_lambda { CurrentSemanticValue.stn = new var_def_statement(ValueStack[ValueStack.Depth-3].stn as ident_list, null, ValueStack[ValueStack.Depth-1].ex, definition_attribute.None, false, CurrentLocationSpan); } @@ -7048,13 +7048,21 @@ public partial class GPPGParser: ShiftReduceParser tkRoundOpen, tkRoundClose, lambda_type_ref_noproctype, // tkArrow, lambda_function_body { - CurrentSemanticValue.ex = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, ValueStack[ValueStack.Depth-3].td, ValueStack[ValueStack.Depth-1].stn as statement_list, CurrentLocationSpan); + // ����� ���� ������������� �� ���� � ���� ��������� lambda_inferred_type, ���� ������ ��� null! + var sl = ValueStack[ValueStack.Depth-1].stn as statement_list; + if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // �� ���� �������� + CurrentSemanticValue.ex = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, ValueStack[ValueStack.Depth-3].td, sl, CurrentLocationSpan); + else CurrentSemanticValue.ex = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, null, sl, CurrentLocationSpan); } break; case 938: // func_decl_lambda -> tkRoundOpen, identifier, tkColon, fptype, tkRoundClose, @@ -7063,7 +7071,10 @@ public partial class GPPGParser: ShiftReduceParser tkRoundOpen, identifier, tkSemiColon, full_lambda_fp_list, @@ -7074,7 +7085,10 @@ public partial class GPPGParser: ShiftReduceParser tkRoundOpen, identifier, tkColon, fptype, tkSemiColon, @@ -7086,7 +7100,10 @@ public partial class GPPGParser: ShiftReduceParser tkRoundOpen, expr_l1, tkComma, expr_l1_list, @@ -7120,7 +7137,11 @@ public partial class GPPGParser: ShiftReduceParser expl_func_decl_lambda { - CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; + CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; } break; case 943: // optional_full_lambda_fp_list -> /* empty */ @@ -7169,20 +7193,21 @@ public partial class GPPGParser: ShiftReduceParser tkFunction, lambda_type_ref, tkArrow, + case 946: // expl_func_decl_lambda -> tkFunction, lambda_type_ref_noproctype, tkArrow, // lambda_function_body { CurrentSemanticValue.ex = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, ValueStack[ValueStack.Depth-3].td, ValueStack[ValueStack.Depth-1].stn as statement_list, 1, CurrentLocationSpan); } break; - case 947: // expl_func_decl_lambda -> tkFunction, tkRoundOpen, tkRoundClose, lambda_type_ref, - // tkArrow, lambda_function_body + case 947: // expl_func_decl_lambda -> tkFunction, tkRoundOpen, tkRoundClose, + // lambda_type_ref_noproctype, tkArrow, + // lambda_function_body { CurrentSemanticValue.ex = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, ValueStack[ValueStack.Depth-3].td, ValueStack[ValueStack.Depth-1].stn as statement_list, 1, CurrentLocationSpan); } break; case 948: // expl_func_decl_lambda -> tkFunction, tkRoundOpen, full_lambda_fp_list, - // tkRoundClose, lambda_type_ref, tkArrow, + // tkRoundClose, lambda_type_ref_noproctype, tkArrow, // lambda_function_body { CurrentSemanticValue.ex = new function_lambda_definition(lambdaHelper.CreateLambdaName(), ValueStack[ValueStack.Depth-5].stn as formal_parameters, ValueStack[ValueStack.Depth-3].td, ValueStack[ValueStack.Depth-1].stn as statement_list, 1, CurrentLocationSpan); @@ -7317,7 +7342,7 @@ public partial class GPPGParser: ShiftReduceParser expr_l1_for_lambda { - var id = SyntaxVisitors.ExprHasNameVisitor.HasName(ValueStack[ValueStack.Depth-1].ex, "Result"); + var id = SyntaxVisitors.HasNameVisitor.HasName(ValueStack[ValueStack.Depth-1].ex, "Result"); if (id != null) { parsertools.AddErrorFromResource("RESULT_IDENT_NOT_EXPECTED_IN_THIS_CONTEXT", id.source_context); diff --git a/Parsers/PascalABCParserNewSaushkin/PABC.ymc b/Parsers/PascalABCParserNewSaushkin/PABC.ymc index ee2f89ed5..dcc3ad542 100644 --- a/Parsers/PascalABCParserNewSaushkin/PABC.ymc +++ b/Parsers/PascalABCParserNewSaushkin/PABC.ymc @@ -274,6 +274,9 @@ script= + + + diff --git a/Release/pabcversion.txt b/Release/pabcversion.txt index 79e193b03..c996fbd23 100644 --- a/Release/pabcversion.txt +++ b/Release/pabcversion.txt @@ -1 +1 @@ -3.6.3.2617 +3.6.3.2629 diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 3fe1c1a74..243326825 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.6.3.2617' +!define VERSION '3.6.3.2629' diff --git a/SyntaxVisitors/BaseVisitors/SmallHelperVisitors.cs b/SyntaxVisitors/BaseVisitors/SmallHelperVisitors.cs index 03783e391..00388813c 100644 --- a/SyntaxVisitors/BaseVisitors/SmallHelperVisitors.cs +++ b/SyntaxVisitors/BaseVisitors/SmallHelperVisitors.cs @@ -50,17 +50,19 @@ namespace SyntaxVisitors } } - public class ExprHasNameVisitor : WalkingVisitorNew // есть ли в выражении переменная с данным именем (не включая вложенные лямбды) (используется для поиска Result) + // есть ли в выражении переменная с данным именем (не включая вложенные лямбды) + // (используется для поиска Result) + public class HasNameVisitor : WalkingVisitorNew { private string varname; public ident id = null; - public static ident HasName(expression ex, string varname) + public static ident HasName(syntax_tree_node sn, string varname) { - var v = new ExprHasNameVisitor(varname); - v.ProcessNode(ex); + var v = new HasNameVisitor(varname); + v.ProcessNode(sn); return v.id; } - public ExprHasNameVisitor(string varname) + public HasNameVisitor(string varname) { this.varname = varname.ToLower(); } diff --git a/TestSuite/LambdaWithExplicitType.pas b/TestSuite/LambdaWithExplicitType.pas new file mode 100644 index 000000000..927f5b088 --- /dev/null +++ b/TestSuite/LambdaWithExplicitType.pas @@ -0,0 +1,9 @@ +begin + var q := procedure(a,b: integer; c: real) -> begin + //Print(a,b,c); + end; + var b := function(i: integer): integer -> i * 2; + + q(2,3,4); + Assert(b(2)=4) +end. \ No newline at end of file diff --git a/TestSuite/asT.pas b/TestSuite/asT.pas index 38ce3ee49..18c6d9cef 100644 --- a/TestSuite/asT.pas +++ b/TestSuite/asT.pas @@ -6,6 +6,10 @@ begin var a := new t1; var b := a as T; Assert(b <> nil); + + var a1: T; + var b1 := a as t1; + Assert(b1 <> nil); end; begin diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 61e9c81de..ab5cffed9 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -10513,6 +10513,16 @@ namespace PascalABCCompiler.TreeConverter type_node case_expr_type = en.type; internal_interface ii = en.type.get_internal_interface(internal_interface_kind.ordinal_interface); + if (ii == null) + { + // Попытка воспользоваться неявным преобразованием + if (convertion_data_and_alghoritms.can_convert_type(en, SystemLibrary.SystemLibrary.integer_type)) + en = convertion_data_and_alghoritms.convert_type(en, SystemLibrary.SystemLibrary.integer_type); + ii = en.type.get_internal_interface(internal_interface_kind.ordinal_interface); + if (ii == null) + if (convertion_data_and_alghoritms.can_convert_type(en, SystemLibrary.SystemLibrary.string_type)) + en = convertion_data_and_alghoritms.convert_type(en, SystemLibrary.SystemLibrary.string_type); + } if (ii == null && en.type != SystemLibrary.SystemLibrary.string_type) { AddError(new OrdinalOrStringTypeExpected(en.location)); @@ -16365,8 +16375,20 @@ namespace PascalABCCompiler.TreeConverter } - if (_var_def_statement.vars_type == null && _var_def_statement.inital_value is SyntaxTree.function_lambda_definition) - AddError(get_location(_var_def_statement.inital_value), "IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA"); //lroman// + if (_var_def_statement.vars_type == null && _var_def_statement.inital_value is SyntaxTree.function_lambda_definition fld) + { + if (fld.formal_parameters != null && fld.formal_parameters.params_list.Select(x => x.vars_type).Any(x=>x is lambda_inferred_type)) + AddError(get_location(_var_def_statement.inital_value), "IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA"); + if (fld.return_type is lambda_inferred_type) + AddError(get_location(_var_def_statement.inital_value), "IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA"); + if (fld.return_type == null) + _var_def_statement.vars_type = new procedure_header(fld.formal_parameters, null, null, false, false, null, null, _var_def_statement.source_context); + else + _var_def_statement.vars_type = new function_header(fld.formal_parameters, null, null, null, fld.return_type, _var_def_statement.source_context); + //else + // AddError(get_location(_var_def_statement.inital_value), "IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA"); //lroman// + } + if (_var_def_statement.vars_type == null && _var_def_statement.inital_value is SyntaxTree.pascal_set_constant pc) { diff --git a/bin/Lib/Controls.pas b/bin/Lib/Controls.pas index 2387f7283..c8d19c896 100644 --- a/bin/Lib/Controls.pas +++ b/bin/Lib/Controls.pas @@ -47,6 +47,8 @@ type ///!# /// Базовый класс для панелей PanelWPF = class + public + fsize: real := 12; private p: StackPanel; bb: Border; @@ -73,6 +75,7 @@ type MainDockPanel.children.Insert(0, bb); //ActivePanel := p; __SetActivePanelInternal(p); + p.Tag := Self; end; procedure SetColorP(c: GColor); begin @@ -80,9 +83,28 @@ type bb.Background := p.Background end; function GetColorP := (p.Background as SolidColorBrush).Color; - procedure SetTTP(s: string); + procedure SetTTP(s: string) := p.ToolTip := s; + static procedure SetFSzPP(p: GPanel; value: real); begin - p.ToolTip := s; + if value<=0 then exit; + foreach var c: FrameworkElement in p.Children do + SetFSzElement(c,value); + end; + static procedure SetFSzElement(c: FrameworkElement; value: real); + begin + if value<=0 then exit; + if c is GControl then + (c as GControl).FontSize := value + else if c is GTextBlock then + (c as GTextBlock).FontSize := value + else if c is GPanel then + SetFSzPP(c as GPanel,value); + end; + procedure SetFSzP(value: real); + begin + if value<=0 then exit; + fsize := value; + SetFSzPP(Self.p,value); end; public constructor Create(wh: real := 150; d: Dock := Dock.Left; c: Color := PanelsColor; internalMargin: real := 10); @@ -97,6 +119,10 @@ type write Invoke(procedure -> p.Margin := new System.Windows.Thickness(internalMargin), value); /// Всплывающая подсказка property Tooltip: string read Invokestring(()->p.ToolTip as string) write Invoke(SetTTP, value); + /// Размер шрифта + property FontSize: real read fsize write Invoke(SetFSzP, value); virtual; + /// Имя шрифта + //property FontName: string write Invoke(SetFontNameP, value); virtual; end; /// Класс левой панели @@ -138,6 +164,8 @@ type if width>0 then element.Width := width; __ActivePanelInternal.Children.Add(element); + if __ActivePanelInternal.Tag is PanelWPF(var pwpf) then + PanelWPF.SetFSzElement(element,pwpf.fsize); end; procedure SetWP(w: real) := element.Width := w; @@ -161,7 +189,7 @@ type CommonControlWPF = class(CommonElementWPF) private property Control: GControl read element as GControl; - procedure SetFSzP(size: real) := control.FontSize := size; + procedure SetFSzP(size: real) := if size > 0 then control.FontSize := size; procedure SetFontNameP(name: string) := control.FontFamily := new FontFamily(name); public /// Размер шрифта @@ -249,7 +277,7 @@ type /// Элемент управления "Кнопка" ButtonWPF = class(ClickableControlWPF) - private + public property b: GButton read element as GButton; procedure CreatePXY(x,y: real; Txt: string; width: real; fontSize: real); @@ -263,8 +291,8 @@ type procedure SetTextP(t: string) := b.Content := t; public - constructor Create(Txt: string; fontSize: real := 12) := Invoke(CreateP, Txt, fontSize); - constructor Create(x, y: real; Txt: string; width: real := 0; fontSize: real := 12) := Invoke(CreatePXY, x, y, Txt, width, fontSize); + constructor Create(Txt: string; fontSize: real := 0) := Invoke(CreateP, Txt, fontSize); + constructor Create(x, y: real; Txt: string; width: real := 0; fontSize: real := 0) := Invoke(CreatePXY, x, y, Txt, width, fontSize); /// Текст на кнопке property Text: string read InvokeString(()->b.Content as string) write Invoke(SetTextP, value); @@ -285,13 +313,13 @@ type procedure CreateP(text: string; fontSize: real) := CreatePXY(-1,-1,text,0,fontSize); procedure SetTextP(t: string) := tb.Text := t; - procedure SetFontSizeP(sz: real) := tb.FontSize := sz; + procedure SetFontSizeP(sz: real) := if sz>0 then tb.FontSize := sz; procedure SetFontNameP(name: string) := tb.FontFamily := new FontFamily(name); procedure SetTextWrappingP(value: boolean) := if value then tb.TextWrapping := TextWrapping.Wrap else tb.TextWrapping := TextWrapping.NoWrap; public - constructor Create(Txt: string; fontsize: real := 12):= Invoke(CreateP, Txt, fontsize); - constructor Create(x, y: real; Txt: string; width: real := 0; fontSize: real := 12):= Invoke(CreatePXY, x, y, Txt, width, fontSize); + constructor Create(Txt: string; fontsize: real := 0):= Invoke(CreateP, Txt, fontsize); + constructor Create(x, y: real; Txt: string; width: real := 0; fontSize: real := 0):= Invoke(CreatePXY, x, y, Txt, width, fontSize); /// Текст блока текста property Text: string read InvokeString(()->tb.Text) write Invoke(SetTextP, value); @@ -309,19 +337,33 @@ type private val := 0; message: string; - procedure CreatePXY(x, y: real; message: string; width: real; initValue: integer := 0; fontSize: real := 12); + procedure CreatePXY(x, y: real; message: string; width: real; initValue: integer := 0; fontSize: real := 0); begin inherited CreatePXY(x,y,message + ' ' + initValue, width, fontSize); Self.message := message; val := initValue; end; - procedure CreateP(message: string; initValue: integer := 0; fontSize: real := 12) := CreatePXY(-1,-1,message,0,initValue,fontSize); + procedure CreateP(message: string; initValue: integer := 0; fontSize: real := 0) := CreatePXY(-1,-1,message,0,initValue,fontSize); public - constructor Create(message: string; initValue: integer := 0; fontSize: real := 12) := Invoke(CreateP, message, initValue, fontSize); - constructor Create(x, y: real; message: string; width: real := 0; initValue: integer := 0; fontSize: real := 12) := Invoke(CreatePXY, x, y, message, width, initValue, fontSize); + constructor Create(message: string; initValue: integer := 0; fontSize: real := 0) := Invoke(CreateP, message, initValue, fontSize); + constructor Create(x, y: real; message: string; width: real := 0; initValue: integer := 0; fontSize: real := 0) := Invoke(CreatePXY, x, y, message, width, initValue, fontSize); /// Значение целого property Value: integer read val write begin val := value; Text := message + ' ' + val; end; + static function operator implicit(ib: IntegerBlockWPF) := ib.Value; + static function operator=(ib: IntegerBlockWPF; v: integer) := ib.Value = v; + static function operator=(v: integer; ib: IntegerBlockWPF) := ib.Value = v; + static function operator<>(ib: IntegerBlockWPF; v: integer) := ib.Value <> v; + static function operator<>(v: integer; ib: IntegerBlockWPF) := ib.Value <> v; + static procedure operator+=(ib: IntegerBlockWPF; v: integer); + begin + ib.Value += v; + end; + static procedure operator-=(ib: IntegerBlockWPF; v: integer); + begin + ib.Value -= v; + end; + static procedure operator:=(ib: IntegerBlockWPF; v: integer) := ib.Value := v; end; /// Элемент управления "Вещественное число" @@ -329,21 +371,35 @@ type private val := 0.0; message: string; - procedure CreatePXY(x, y: real; message: string; width: real; initValue: real := 0; fontSize: real := 12); + procedure CreatePXY(x, y: real; message: string; width: real; initValue: real := 0; fontSize: real := 0); begin inherited CreatePXY(x,y,message + ' ' + initValue.ToString(FracDigits), width, fontSize); Self.message := message; val := initValue; end; - procedure CreateP(message: string; initValue: real := 0; fontSize: real := 12) := CreatePXY(-1,-1,message,0,initValue,fontSize); + procedure CreateP(message: string; initValue: real := 0; fontSize: real := 0) := CreatePXY(-1,-1,message,0,initValue,fontSize); public - constructor Create(message: string; initValue: real := 0; fontSize: real := 12) := Invoke(CreateP, message, initValue, fontSize); - constructor Create(x, y: real; message: string; width: real := 0; initValue: real := 0; fontSize: real := 12) := Invoke(CreatePXY, x, y, message, width, initValue, fontSize); + constructor Create(message: string; initValue: real := 0; fontSize: real := 0) := Invoke(CreateP, message, initValue, fontSize); + constructor Create(x, y: real; message: string; width: real := 0; initValue: real := 0; fontSize: real := 0) := Invoke(CreatePXY, x, y, message, width, initValue, fontSize); /// Значение вещественного property Value: real read val write begin val := value; Text := message + ' ' + val.ToString(FracDigits); end; /// Количество цифр после десятичной точки auto property FracDigits: integer := 1; + static function operator implicit(ib: RealBlockWPF) := ib.Value; + static function operator=(ib: RealBlockWPF; v: real) := ib.Value = v; + static function operator=(v: real; ib: RealBlockWPF) := ib.Value = v; + static function operator<>(ib: RealBlockWPF; v: real) := ib.Value <> v; + static function operator<>(v: real; ib: RealBlockWPF) := ib.Value <> v; + static procedure operator+=(rb: RealBlockWPF; v: real); + begin + rb.Value += v; + end; + static procedure operator-=(rb: RealBlockWPF; v: real); + begin + rb.Value -= v; + end; + static procedure operator:=(rb: RealBlockWPF; v: real) := rb.Value := v; end; /// Элемент управления "Текстовое поле" @@ -443,6 +499,8 @@ type end; procedure SetFSzP(size: real); begin + if size<=0 then + exit; tb.FontSize := size; MainElement.FontSize := size; end; @@ -552,6 +610,13 @@ type auto property Maximum: integer := 100; /// Текущее значение текстового поля property Value: integer read GetValue write SetValue; + + static function operator implicit(ib: IntegerBoxWPF) := ib.Value; + static function operator=(ib: IntegerBoxWPF; v: integer) := ib.Value = v; + static function operator=(v: integer; ib: IntegerBoxWPF) := ib.Value = v; + static function operator<>(ib: IntegerBoxWPF; v: integer) := ib.Value <> v; + static function operator<>(v: integer; ib: IntegerBoxWPF) := ib.Value <> v; + static procedure operator:=(ib: IntegerBoxWPF; v: integer) := ib.Value := v; end; /// Элемент управления "Список" @@ -1074,24 +1139,24 @@ type // Panel - вспомогательная, нужна только для создания LeftPanel, RightPanel /// Элемент управления "Кнопка" -function Button(Txt: string; fontSize: real := 12): ButtonWPF; +function Button(Txt: string; fontSize: real := 0): ButtonWPF; /// Элемент управления "Кнопка" с заданными координатами -function Button(x, y: real; Txt: string; width: real := 0; fontSize: real := 12): ButtonWPF; +function Button(x, y: real; Txt: string; width: real := 0; fontSize: real := 0): ButtonWPF; /// Элемент управления "Текст" -function TextBlock(Txt: string; fontSize: real := 12): TextBlockWPF; +function TextBlock(Txt: string; fontSize: real := 0): TextBlockWPF; /// Элемент управления "Текст" с заданными координатами -function TextBlock(x, y: real; Txt: string; width: real := 0; fontSize: real := 12): TextBlockWPF; +function TextBlock(x, y: real; Txt: string; width: real := 0; fontSize: real := 0): TextBlockWPF; /// Элемент управления "Целое число" -function IntegerBlock(message: string; initValue: integer := 0; fontSize: real := 12): IntegerBlockWPF; +function IntegerBlock(message: string; initValue: integer := 0; fontSize: real := 0): IntegerBlockWPF; /// Элемент управления "Целое число" с заданными координатами -function IntegerBlock(x, y: real; message: string; width: real := 0; initValue: integer := 0; fontSize: real := 12): IntegerBlockWPF; +function IntegerBlock(x, y: real; message: string; width: real := 0; initValue: integer := 0; fontSize: real := 0): IntegerBlockWPF; /// Элемент управления "Вещественное число" -function RealBlock(message: string; initValue: real := 0; fontSize: real := 12): RealBlockWPF; +function RealBlock(message: string; initValue: real := 0; fontSize: real := 0): RealBlockWPF; /// Элемент управления "Вещественное число" с заданными координатами -function RealBlock(x, y: real; message: string; width: real := 0; initValue: real := 0; fontSize: real := 12): RealBlockWPF; +function RealBlock(x, y: real; message: string; width: real := 0; initValue: real := 0; fontSize: real := 0): RealBlockWPF; /// Элемент управления "Флажок" function CheckBox(text: string): CheckBoxWPF; @@ -1109,8 +1174,6 @@ function TextBox(text: string := ''): TextBoxWPF; /// Элемент управления "Текстовое поле с заголовком" с заданными координатами function TextBox(x, y: real; text: string := ''; width: real := 0): TextBoxWPF; -/// Элемент управления "Целое поле" -function IntegerBox(title: string; max: integer := 10): IntegerBoxWPF; /// Элемент управления "Целое поле" с заданным диапазоном значений function IntegerBox(title: string; min,max: integer): IntegerBoxWPF; /// Элемент управления "Целое поле" с заданными координатами @@ -1207,7 +1270,6 @@ function RadioButton(x, y: real; text: string; width: real): RadioButtonWPF := R function TextBox(text: string): TextBoxWPF := TextBoxWPF.Create(text); function TextBox(x, y: real; text: string; width: real): TextBoxWPF := TextBoxWPF.Create(x,y,text,width); -function IntegerBox(title: string; max: integer): IntegerBoxWPF := IntegerBoxWPF.Create(title,0,max); function IntegerBox(title: string; min,max: integer): IntegerBoxWPF := IntegerBoxWPF.Create(title,min,max); function IntegerBox(x, y: real; title: string; min,max: integer; width: real) := IntegerBoxWPF.Create(x,y,title,min,max,width);