diff --git a/SyntaxTree/tree/TreeHelper.cs b/SyntaxTree/tree/TreeHelper.cs index b7e7a8bde..b67c7aa8d 100644 --- a/SyntaxTree/tree/TreeHelper.cs +++ b/SyntaxTree/tree/TreeHelper.cs @@ -1562,5 +1562,15 @@ namespace PascalABCCompiler.SyntaxTree } } + public partial class function_lambda_definition + { + public override string ToString() + { + return "" + this._ident_list.ToString() + " -> lambda_body"; + } + } + + + } diff --git a/TestSuite/YieldLambdasInYield.pas b/TestSuite/YieldLambdasInYield.pas new file mode 100644 index 000000000..571f43f58 --- /dev/null +++ b/TestSuite/YieldLambdasInYield.pas @@ -0,0 +1,12 @@ +var a := 1; + +function f: sequence of integer; +begin + var ii: integer->integer := x->x; + for var i:=1 to 5 do + yield SeqGen(5,x->x+a).First; +end; + +begin + Assert(f.Println.SequenceEqual(Seq(1,1,1,1,1))); +end. \ No newline at end of file diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 5e2ace954..2f5735ac3 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -19142,6 +19142,11 @@ namespace PascalABCCompiler.TreeConverter t.visit(this); } + public override void visit(SyntaxTree.yield_node yn) + { + // подузлы не обходим! + } + /*public SyntaxTree.question_colon_expression ConvertToQCE(dot_question_node dqn) { // Неверно работает. Пока не используется. Доделать diff --git a/Yield/SyntaxVisitors/UniversalVisitors/SimplePrettyPrinterVisitor.cs b/Yield/SyntaxVisitors/UniversalVisitors/SimplePrettyPrinterVisitor.cs index 5ddf80d76..729b2e515 100644 --- a/Yield/SyntaxVisitors/UniversalVisitors/SimplePrettyPrinterVisitor.cs +++ b/Yield/SyntaxVisitors/UniversalVisitors/SimplePrettyPrinterVisitor.cs @@ -68,6 +68,12 @@ namespace SyntaxVisitors Println(""+st); } + public void PrintNode(syntax_tree_node st) + { + if (printNodeType) + PrintNoOffset(st.GetType().Name + ": "); + Print(""+st); + } public virtual void Enter(syntax_tree_node st) { @@ -172,6 +178,13 @@ namespace SyntaxVisitors Println("while " + wn.expr.ToString() + " do"); off += 2; } + else if (st is for_node) + { + var fn = st as for_node; + + Println("for var " + fn.loop_variable + " := "+fn.initial_value+" to "+fn.finish_value + " do "); + off += 2; + } else if (st is foreach_stmt) { var wn = st as foreach_stmt; @@ -208,7 +221,10 @@ namespace SyntaxVisitors } else if (st is statement || st is variable_definitions || st is label_definitions) { - PrintlnNode(st); + PrintNode(st); + if (st is statement) + PrintlnNoOffset(";"); + else PrintlnNoOffset(""); if (st is labeled_statement) visitNode = false; } @@ -219,6 +235,12 @@ namespace SyntaxVisitors return; PrintlnNode(st); } + else if (st is function_lambda_definition) + { + var f = st as function_lambda_definition; + //PrintNoOffset(f.ToString()); + visitNode = false; + } /*else if (st is named_type_reference) { var s = st.ToString(); diff --git a/Yield/SyntaxVisitors/YieldVisitors/MarkMethodHasYieldVisitor.cs b/Yield/SyntaxVisitors/YieldVisitors/MarkMethodHasYieldVisitor.cs index 5eb36f5ac..e7ad94566 100644 --- a/Yield/SyntaxVisitors/YieldVisitors/MarkMethodHasYieldVisitor.cs +++ b/Yield/SyntaxVisitors/YieldVisitors/MarkMethodHasYieldVisitor.cs @@ -24,7 +24,7 @@ namespace SyntaxVisitors throw new SyntaxError("Лямбда-выражения не могут содержать yield", "", ld.source_context, ld); } - base.visit(ld); + //base.visit(ld); // SSM 15/07/16 - незачем обходить внутренности лямбды - мы и так ищем внутри них yield - этого в этом визиторе достаточно } public override void visit(with_statement ws) @@ -36,6 +36,7 @@ namespace SyntaxVisitors base.visit(ws); } + public override void visit(procedure_definition pd) { //this.CurrentMethod = pd; diff --git a/Yield/SyntaxVisitors/YieldVisitors/ProcessYieldsCapturedVars.cs b/Yield/SyntaxVisitors/YieldVisitors/ProcessYieldsCapturedVars.cs index 1837af858..72a7dc9f5 100644 --- a/Yield/SyntaxVisitors/YieldVisitors/ProcessYieldsCapturedVars.cs +++ b/Yield/SyntaxVisitors/YieldVisitors/ProcessYieldsCapturedVars.cs @@ -909,6 +909,9 @@ namespace SyntaxVisitors pd.visit(checkVarRedefVisitor); */ + // Выносим выражение с лямбдой из yield + ReplaceYieldWithLamdasVisitor.Accept(pd); + // frninja 31/05/16 - добавляем метод-хелпер, возьмет на себя проверку разных ошибок уже существующим бэкендом CreateErrorCheckerHelper(pd); // SSM 14/07/16 - переставил до переименования переменных чтобы отлавливались ошибки одинаковых имен в разных пространствах имен // SSM - можно сделать спец визитор, который бы отлавливал дубли имен - тогда этого не надо @@ -916,9 +919,6 @@ namespace SyntaxVisitors // Переименовываем одинаковые имена в мини-ПИ: begin var a := 1 end; begin var a := 1 end; RenameSameBlockLocalVarsVisitor.Accept(pd); - // Выносим выражение с лямбдой из yield - ReplaceYieldWithLamdasVisitor.Accept(pd); - // Теперь lowering LoweringVisitor.Accept(pd); @@ -1100,7 +1100,7 @@ namespace SyntaxVisitors var yn = st as yield_node; curState += 1; res.AddMany( - new assign(YieldConsts.Current, yn.ex), + new assign(YieldConsts.Current, yn.ex, yn.source_context), new assign(YieldConsts.State, curState), new assign("Result", true), new procedure_call("exit"), diff --git a/Yield/SyntaxVisitors/YieldVisitors/ReplaceYieldWithLamdasVisitor.cs b/Yield/SyntaxVisitors/YieldVisitors/ReplaceYieldWithLamdasVisitor.cs index 9d597bf57..f2f14e62b 100644 --- a/Yield/SyntaxVisitors/YieldVisitors/ReplaceYieldWithLamdasVisitor.cs +++ b/Yield/SyntaxVisitors/YieldVisitors/ReplaceYieldWithLamdasVisitor.cs @@ -36,8 +36,8 @@ namespace SyntaxVisitors if (lambdaSearcher.CheckIfContainsLambdas()) { var lambdaVarIdent = this.NewLamdaVarName(); - var_statement lambdaVS = new var_statement(lambdaVarIdent, yn.ex) { source_context = yn.source_context }; - ReplaceStatement(yn, SeqStatements(lambdaVS, new yield_node(lambdaVarIdent, yn.source_context))); + var_statement lambdaVS = new var_statement(lambdaVarIdent, yn.ex) { source_context = yn.ex.source_context }; + ReplaceStatement(yn, SeqStatements(lambdaVS, new yield_node(lambdaVarIdent, yn.ex.source_context))); } } }