bug fix #223
This commit is contained in:
parent
b8e0f0fc56
commit
b96edffd7e
|
|
@ -1562,5 +1562,15 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
}
|
||||
}
|
||||
|
||||
public partial class function_lambda_definition
|
||||
{
|
||||
public override string ToString()
|
||||
{
|
||||
return "" + this._ident_list.ToString() + " -> lambda_body";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
12
TestSuite/YieldLambdasInYield.pas
Normal file
12
TestSuite/YieldLambdasInYield.pas
Normal file
|
|
@ -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.
|
||||
|
|
@ -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)
|
||||
{
|
||||
// Неверно работает. Пока не используется. Доделать
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
|
|
|
|||
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue