This commit is contained in:
miks1965 2016-07-16 11:28:06 +03:00
parent b8e0f0fc56
commit b96edffd7e
7 changed files with 58 additions and 8 deletions

View file

@ -1562,5 +1562,15 @@ namespace PascalABCCompiler.SyntaxTree
}
}
public partial class function_lambda_definition
{
public override string ToString()
{
return "" + this._ident_list.ToString() + " -> lambda_body";
}
}
}

View 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.

View file

@ -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)
{
// Неверно работает. Пока не используется. Доделать

View file

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

View file

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

View file

@ -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"),

View file

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