public override void visit(assign_tuple asstup) { var sl = new statement_list(); sl.Add(new semantic_check_sugared_statement_node(asstup)); // Это нужно для проверок на этапе преобразования в семантику var tname = "#temp_var" + UniqueNumStr(); var tt = new var_statement(new ident(tname), asstup.expr); sl.Add(tt); var n = asstup.vars.variables.Count(); for (var i = 0; i < n; i++) { var a = new assign(asstup.vars.variables[i], new dot_node(new ident(tname), new ident("Item" + (i + 1).ToString())), Operators.Assignment, asstup.vars.variables[i].source_context); sl.Add(a); } // Замена 1 оператор на 1 оператор - всё OK ReplaceUsingParent(asstup, sl); visit(asstup.expr); }
public override void visit(assign_tuple asstup) { // тут возможно ошибка более глубокая - в semantic_check_sugared_statement_node(asstup) возможно остаются во вложенных лямбдах другие assign_tuple var sl = new statement_list(); sl.Add(new semantic_check_sugared_statement_node(typeof(assign_tuple), new List <syntax_tree_node> { asstup.vars, asstup.expr }, asstup.source_context)); // Это нужно для проверок на этапе преобразования в семантику var tname = "#temp_var" + UniqueNumStr(); var tt = new var_statement(new ident(tname), asstup.expr); sl.Add(tt); var n = asstup.vars.variables.Count(); for (var i = 0; i < n; i++) { var a = new assign(asstup.vars.variables[i], new dot_node(new ident(tname), new ident("Item" + (i + 1).ToString())), Operators.Assignment, asstup.vars.variables[i].source_context); sl.Add(a); } // Замена 1 оператор на 1 оператор - всё OK ReplaceUsingParent(asstup, sl); visit(asstup.expr); }
public override void visit(assign_var_tuple assvartup) { var sl = new List <statement>(); sl.Add(new semantic_check_sugared_statement_node(assvartup)); // Это нужно для проверок на этапе преобразования в семантику var tname = "#temp_var" + UniqueNumStr(); var tt = new var_statement(new ident(tname), assvartup.expr); // тут для assvartup.expr внутри повторно вызывается convert_strong, это плохо, но если там лямбда, то иначе - с semantic_addr_value - не работает!!! sl.Add(tt); // он же помещается в новое синтаксическое дерево var n = assvartup.vars.variables.Count(); for (var i = 0; i < n; i++) { var a = new var_statement(assvartup.vars.variables[i] as ident, new dot_node(new ident(tname), new ident("Item" + (i + 1).ToString())), assvartup.vars.variables[i].source_context); sl.Add(a); } ReplaceStatementUsingParent(assvartup, sl); visit(assvartup.expr); // В assvartup.expr могут содержаться лямбды, в которых будут другие assign_var_tuple. // И вообще другой синтаксический сахар, размещённый в этом визиторе }
public override void visit(exception_handler eh) { if (eh.variable != null) { // Вначале переименовать везде кроме как в заголовке, потом добавить в блок операторов переприсваивание var vis = new RenameOnExceptVarsVisitor(); vis.Rename(eh); var vs = new var_statement(new ident(vis.NewName /*, eh.statements.source_context*/), new ident(vis.NameForRename, eh.variable.source_context) /*, eh.statements.source_context*/); var stl = new List <statement>(); stl.Add(vs); if (eh.statements != null) { stl.Add(eh.statements); ReplaceStatementUsingParent(eh.statements, stl); } else { var s = new statement_list(stl); s.Parent = eh; s.source_context = eh.source_context; eh.statements = s; } } base.visit(eh); }
public override void visit(dot_question_node dqn) { var st = dqn.Parent; while (!(st is statement)) { st = st.Parent; } var tname = "#dqn_temp" + UniqueNumStr(); var tt = new var_statement(new ident(tname), dqn.left); tt.var_def.Parent = tt; var l = new List <statement>(); l.Add(tt); l.Add(st as statement); var qce = ConvertToQCE1(dqn, tname); var sug = sugared_addressed_value.NewP(dqn, qce, dqn.source_context); ReplaceUsingParent(dqn, sug); visit(qce); ReplaceStatementUsingParent(st as statement, l); visit(tt); }
public override void visit(var_statement vs) { if (vs.var_def.vars.idents.Any(id => id.name.StartsWith("$"))) { base.visit(vs); // SSM 17/07/16 исправление ошибки - не обходилось выражение-инициализатор return; } var newLocalNames = vs.var_def.vars.idents.Select(id => { var low = id.name /*.ToLower()*/; var newName = this.CreateNewVariableName(low); //BlockNamesStack[CurrentLevel].Add(low, newName); BlockNamesStack[CurrentLevel][low] = newName; return(new ident(newName, id.source_context)); }); var newVS = new var_statement(new var_def_statement(new ident_list(newLocalNames.ToArray()), vs.var_def.vars_type, vs.var_def.inital_value)); Replace(vs, newVS); base.visit(newVS); }
public override void visit(var_statement vs) // локальные описания внутри процедуры { LocalDeletedDefs.Add(vs.var_def); DeleteInStatementList(vs); LocalDeletedDefsNames.UnionWith(vs.var_def.vars.idents.Select(id => id.name)); }
public statement MyStmt(expression ex, statement st) { // Проверить, что в ex - целый тип // Сделать специальный узел для проверки new semantic_check("Тип проверки",params syntax_node[] ob) // Включать этот узел первым для "сахарных" узлов синтаксического дерева var sc = new semantic_check("ExprIsInteger", ex); var id = new ident("#my"); var idlist = new ident_list(id); var typ = new named_type_reference("integer"); var one = new int32_const(1); var vdef = new var_def_statement(idlist, typ, one, definition_attribute.None, false, null); var vstat = new var_statement(vdef, null); var ass = new assign(new ident("#my"), one, Operators.AssignmentAddition); var stlistwhile = new statement_list(st); stlistwhile.Add(ass); var bin = new bin_expr(id, ex, Operators.LessEqual); var wh = new while_node(bin, stlistwhile, WhileCycleType.While); var stlist = new statement_list(sc); stlist.Add(vstat); stlist.Add(wh); return(stlist); }
public override void visit(for_node fn) { ProcessNode(fn.statements); var b = HasStatementVisitor <yield_node> .Has(fn); if (!b) { return; } var gt1 = goto_statement.New; var gt2 = goto_statement.New; var endtemp = new ident(newVarName()); var ass1 = new var_statement(fn.loop_variable, fn.type_name, fn.initial_value); var ass2 = new var_statement(endtemp, fn.type_name, fn.finish_value); var if0 = new if_node(bin_expr.Greater(fn.loop_variable, fn.finish_value), gt1); var lb2 = new labeled_statement(gt2.label, if0); var lb1 = new labeled_statement(gt1.label); var Inc = new procedure_call(new method_call(new ident("Inc"), new expression_list(fn.loop_variable))); ReplaceStatement(fn, SeqStatements(ass1, ass2, lb2, fn.statements, Inc, gt2, lb1)); // в declarations ближайшего блока добавить описание labels block bl = listNodes.FindLast(x => x is block) as block; bl.defs.Add(new label_definitions(gt1.label, gt2.label)); }
public override void visit(var_statement defs) { indef = true; ProcessNode(defs.var_def.vars); // исключаем типы - // просматриваем только имена переменных indef = false; }
public override void visit(double_question_node dqn) { var st = dqn.Parent; while (!(st is statement)) { st = st.Parent; } var tname = "#temp" + UniqueNumStr(); var tt = new var_statement(new ident(tname), dqn.left); tt.var_def.Parent = tt; var l = new List <statement>(); l.Add(tt); l.Add(st as statement); expression right = dqn.right; var eq = new bin_expr(new ident(tname), new nil_const(), Operators.NotEqual, dqn.left.source_context); var qce = new question_colon_expression(eq, new ident(tname), right, dqn.source_context); ReplaceUsingParent(dqn, qce); visit(qce); ReplaceStatementUsingParent(st as statement, l); visit(tt); }
public override void visit(dot_question_node dqn) { var st = dqn.Parent; while ((st != null) && !(st is statement)) { st = st.Parent; } if (st == null) { throw new SyntaxVisitorError("?._CANNOT_BE_IN_THIS_CONTEXT", dqn.source_context); } var tname = "#dqn_temp" + UniqueNumStr(); var tt = new var_statement(new ident(tname), dqn.left); tt.var_def.Parent = tt; var l = new List <statement>(); l.Add(tt); l.Add(st as statement); var qce = ConvertToQCE1(dqn, tname); var sug = sugared_addressed_value.NewP(dqn, qce, dqn.source_context); ReplaceUsingParent(dqn, sug); visit(qce); ReplaceStatementUsingParent(st as statement, l); visit(tt); }
public override void visit(assign_var_tuple assvartup) { var tname = "#temp_var" + UniqueNumStr(); if (assvartup.Parent is declarations ds) // А когда это происходит??? { var ld = new List <declaration>(); ld.Add(new semantic_check_sugared_statement_node(typeof(assign_var_tuple), new List <syntax_tree_node> { assvartup.idents, assvartup.expr }, assvartup.source_context)); // Это нужно для проверок на этапе преобразования в семантику var vd = new variable_definitions(); var tt1 = new var_def_statement(new ident(tname, assvartup.expr.source_context), assvartup.expr, assvartup.expr.source_context); vd.Add(tt1); var nn = assvartup.idents.idents.Count(); for (var i = 0; i < nn; i++) { var a = new var_def_statement(assvartup.idents.idents[i], //new dot_node(new ident(tname), new ident("Item" + (i + 1).ToString())), new semantic_ith_element_of(new ident(tname, assvartup.expr.source_context), new int32_const(i), assvartup.expr.source_context), assvartup.idents.idents[i].source_context); vd.Add(a); } ld.Add(vd); ReplaceAssignVarTupleUsingParent(assvartup, ld); visit(assvartup.expr); return; } var sl = new List <statement>(); sl.Add(new semantic_check_sugared_statement_node(typeof(assign_var_tuple), new List <syntax_tree_node> { assvartup.idents, assvartup.expr }, assvartup.source_context)); // Это нужно для проверок на этапе преобразования в семантику var tt = new var_statement(new ident(tname, assvartup.expr.source_context), assvartup.expr, assvartup.expr.source_context); // тут для assvartup.expr внутри повторно вызывается convert_strong, это плохо, но если там лямбда, то иначе - с semantic_addr_value - не работает!!! sl.Add(tt); // он же помещается в новое синтаксическое дерево var n = assvartup.idents.idents.Count(); for (var i = 0; i < n; i++) { var sc = assvartup.idents.idents[i].source_context; var a = new var_statement(assvartup.idents.idents[i], //new dot_node(new ident(tname), new ident("Item" + (i + 1).ToString(),sc)), new semantic_ith_element_of(new ident(tname, assvartup.expr.source_context), new int32_const(i, sc), assvartup.expr.source_context), sc); //a.source_context = assvartup.idents.idents[i].source_context; sl.Add(a); } ReplaceStatementUsingParent(assvartup, sl); visit(assvartup.expr); // В assvartup.expr могут содержаться лямбды, в которых будут другие assign_var_tuple. // И вообще другой синтаксический сахар, размещённый в этом визиторе }
public override void visit(var_statement vs) { foreach (var id in vs.var_def.vars.idents) { // Проверяем есть ли такое имя выше? CheckVariableAlreadyDefined(id); BlockNamesStack[CurrentLevel].Add(id.name); } base.visit(vs); }
public override void visit(foreach_stmt fe) { if (fe.in_what.DescendantNodes().OfType <function_lambda_definition>().Count() > 0) { var id = GenIdentName(); id.Parent = fe; var ass = new var_statement(id, fe.in_what, fe.in_what.source_context); fe.in_what = id; var l = new List <statement> { ass, fe }; ReplaceStatement(fe, l); } base.visit(fe); }
public override void visit(yield_node yn) { var VarIdent = this.NewVarName(); VarIdent.source_context = yn.ex.source_context; var_statement vs; if (yn.ex is nil_const) { vs = new var_statement(VarIdent, new named_type_reference("System.Object"), yn.ex); } else { vs = new var_statement(VarIdent, yn.ex); } vs.source_context = yn.ex.source_context; ReplaceStatement(yn, SeqStatements(vs, new yield_node(VarIdent, yn.ex.source_context))); }
public override void visit(foreach_stmt fe) { //if (fe.DescendantNodes().OfType<function_lambda_definition>().Count() > 0) // из-за #1984 убрал вообще условие. Пусть будет всегда { var id = GenIdentName(); id.Parent = fe; var ass = new var_statement(id, fe.in_what, fe.in_what.source_context); id.source_context = fe.in_what.source_context; fe.in_what = id; var l = new List <statement> { ass, fe }; //ReplaceStatement(fe, l); ReplaceStatementUsingParent(fe, l); } base.visit(fe); }
public override void visit(dot_question_node dqn) { var st = dqn.Parent; while ((st != null) && !(st is statement)) { st = st.Parent; } if (st == null) { throw new SyntaxVisitorError("?._CANNOT_BE_IN_THIS_CONTEXT", dqn.source_context); } var tname = "#dqn_temp" + UniqueNumStr(); dot_question_node rif = null; var qce = ConvertToQCE1(dqn, tname); if (qce.ret_if_false is dot_question_node dn) { rif = dn; var expr = new question_colon_expression(qce.condition, qce.ret_if_true, rif.left); rif.left.ExprToQCE = expr; } var sug = sugared_addressed_value.NewP(dqn, qce, dqn.source_context); ReplaceUsingParent(dqn, sug); //Replace(dqn, sug); // Этот не подходит! var dl = (dqn.left.ExprToQCE == null ? dqn.left : dqn.left.ExprToQCE) as addressed_value; dqn.Parent = null; var tt = new var_statement(new ident(tname), dl, dqn.source_context); tt.var_def.Parent = tt; var l = new List <statement>(); l.Add(tt); l.Add(st as statement); ReplaceStatementUsingParent(st as statement, l); visit(qce); visit(tt); }
public override void visit(var_statement vs) // локальные описания внутри процедуры { LocalDeletedVS.Insert(0, vs.var_def); //DeleteInStatementList(vs); // frninja 02/03/16 - fix capturing unknown idents -> replace delete with assign if ((object)vs.var_def.inital_value == null) { DeleteInStatementList(vs); } else { // Нескольких переменных тут всё равно не будет - это ошибка ReplaceStatement(vs, SeqStatements(vs.var_def.vars.idents.Select(id => new assign(id, vs.var_def.inital_value)).ToArray())); } LocalDeletedDefsNames.UnionWith(vs.var_def.vars.idents.Select(id => id.name)); CollectedLocals.UnionWith(vs.var_def.vars.idents); }
public override void visit(var_statement vs) { var idents = vs.var_def.vars.idents; var IdentsToDeleteInVarDef = idents.FindAll(id => idsToDelete.Contains(id.name)); // найти в операторе все идентификаторы для удаления if (IdentsToDeleteInVarDef.Count != 0) { deletedIdsToDeleteInLocalScope.UnionWith(IdentsToDeleteInVarDef.Select(id => id.name.ToLower())); // добавить те идентификаторы, которые мы удаляем из данного описания LocalDeletedIds.Add(new var_def_statement(new ident_list(IdentsToDeleteInVarDef), vs.var_def.vars_type, vs.var_def.inital_value)); // добавить описание из удаленных в данном разделе описаний идентификаторов idents.RemoveAll(id => idsToDelete.Contains(id.name)); // удалить в операторе все идентификаторы для удаления idsToDelete.ExceptWith(deletedIdsToDeleteInLocalScope); if (idents.Count == 0) // то и весь var_statement надо убить { this.DeleteInStatementList(vs); } } // Здесь мы не обрабатываем вложенный var_def_statement, поэтому когда мы будем обрабатывать его в другом visit, то это будут переменные до beginа подпрограммы или основной программы }
public override void visit(assign_var_tuple assvartup) { if (assvartup.expr is tuple_node tn && tn.el.expressions.All(ex => ex is const_node) && !tn.el.expressions.Any(ex => ex is nil_const)) { var n = assvartup.idents.idents.Count(); if (n > tn.el.Count) { throw new SyntaxVisitorError("TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMENT", assvartup.idents[0]); } // Оптимизация, т.к. все - константы var sl = new List <statement>(); for (var i = 0; i < n; i++) { var a = new var_statement( assvartup.idents.idents[i], tn.el.expressions[i], assvartup.idents.idents[i].source_context); sl.Add(a); } ReplaceStatementUsingParent(assvartup, sl); }
public override void visit(yield_node yn) { if (yn.ex is function_lambda_definition) { syntax_tree_node sn = yn; do { sn = sn.Parent; } while (sn != null && !(sn is procedure_definition)); procedure_definition pd = sn as procedure_definition; if (sn == null) { // этого не будет } var fh = pd.proc_header as function_header; if (fh == null) { // этого тоже не будет } var sq = fh.return_type as sequence_type; if (sq == null) { // и этого не будет } var lst = new List <statement>(); var newid = new ident(CreateNameForLambdaInYield(), yn.ex.source_context); var vs = new var_statement(newid, sq.elements_type, yn.ex); vs.source_context = yn.ex.source_context; var newyn = new yield_node(newid, newid.source_context); lst.Add(vs); lst.Add(newyn); ReplaceStatementUsingParent(yn, lst); } }
public override void visit(var_statement node) { prepare_node(node.var_def, "var_def"); }
// frninja 21/05/16 public override void visit(foreach_stmt frch) { // Полный код Loweringа c yield_unknown_foreach_type = integer // var a: System.Collections.Generic.IEnumerable<integer>; // a := l; // var en := a.GetEnumerator(); // while en.MoveNext do // begin // var curr := en.Current; // var не нужно ставить если curr была описана раньше // Print(curr); // end; /// // var a: System.Collections.Generic.IEnumerable<yield_unknown_foreach_type> := l; var foreachCollIdent = this.NewForeachCollectionName(); var foreachCollType = new template_type_reference(new named_type_reference("System.Collections.Generic.IEnumerable"), new template_param_list(new yield_unknown_foreach_type(frch))); var foreachCollVarDef = new var_statement(foreachCollIdent, foreachCollType); var ass = new assign(foreachCollIdent, frch.in_what); // var en := a.GetEnumerator(); var enumeratorIdent = this.NewEnumeratorName(); var enumeratorVarDef = new var_statement(enumeratorIdent, new method_call(new dot_node(foreachCollIdent, new ident("GetEnumerator")), new expression_list())); //var curr := en.Current; // Переменная цикла foreach. Есть три варианта: // 1. foreach x in l do -> curr := en.Current; // 2. foreach var x in l do -> var curr := en.Current; // 3. foreach var x: T in l do -> var curr: T := en.Current; var currentIdent = frch.identifier; statement st = null; var curExpr = new dot_node(enumeratorIdent, "Current"); // С типом if (frch.type_name == null) // 1. foreach x in l do -> curr := en.Current; { st = new assign(currentIdent, curExpr); } else if (frch.type_name is no_type_foreach) // 2. foreach var x in l do -> var curr := en.Current; { // Получаем служебное имя с $ и заменяем его в теле цикла currentIdent = this.NewVarNames(frch.identifier).VarName; var replacerVis = new ReplaceVariableNameVisitor(frch.identifier, currentIdent); frch.visit(replacerVis); st = new var_statement(currentIdent, curExpr); } else // 3. foreach var x: T in l do -> var curr: T := en.Current; { // Получаем служебное имя с $ и заменяем его в теле цикла currentIdent = this.NewVarNames(frch.identifier).VarName; var replacerVis = new ReplaceVariableNameVisitor(frch.identifier, currentIdent); frch.visit(replacerVis); st = new var_statement(currentIdent, frch.type_name, curExpr); } // Добавляем тело цикла в stl var stl = new statement_list(st); ProcessNode(frch.stmt); // для обработки вложенных конструкций stl.Add(frch.stmt); var whileNode = new while_node(new method_call(new dot_node(enumeratorIdent, "MoveNext"), new expression_list()), stl, WhileCycleType.While); var sq = SeqStatements(foreachCollVarDef, ass, enumeratorVarDef, whileNode); ReplaceStatement(frch, sq); visit(whileNode); // Lowering оставшегося whileNode }
public override void visit(var_statement node) { }
/// <summary> /// Преобразует foreach в for, если коллекция это одномерный массив. /// </summary> /// <param name="_foreach_stmt"></param> /// <param name="in_what"></param> /// <returns>True - если преобразование удалось, иначе False</returns> private bool OptimizeForeachInCase1DArray(foreach_stmt _foreach_stmt, expression_node in_what) { var is1dimdynarr = false; var comptn = in_what.type as compiled_type_node; if (comptn != null && comptn.type_special_kind == type_special_kind.array_kind && comptn.rank == 1) { is1dimdynarr = true; } if (!is1dimdynarr) { var comtn = in_what.type as common_type_node; if (comtn != null && comtn.internal_type_special_kind == type_special_kind.array_kind && comtn.rank == 1) { is1dimdynarr = true; } } // SSM 23.08.16 Закомментировал оптимизацию. Не работает с лямбдами. Лямбды обходят старое дерево. А заменить foreach на for на этом этапе пока не получается - не развита инфраструктура if (is1dimdynarr) // Замена foreach на for для массива { // сгенерировать код для for и вызвать соответствующий visit var arrid = GenIdentName(); //var vdarr = new var_statement(arrid, new semantic_addr_value(in_what)); // semantic_addr_value - перевод в синтаксис для мгновенного вычисления семантического выражения, которое уже вычислено в in_what var vdarr = new var_statement(arrid, _foreach_stmt.in_what); var i = GenIdentName(); var x = _foreach_stmt.identifier; // Возможны 3 случая: // 1. _foreach_stmt.type_name = null - значит, переменная определена в другом месте // 2. _foreach_stmt.type_name = no_type_foreach - значит, это for var x in a // 3. _foreach_stmt.type_name = T - значит, это for var x: T in a statement vd; if (_foreach_stmt.type_name == null) // 1. { vd = new assign(x, arrid.indexer(i)); } else if (_foreach_stmt.type_name is no_type_foreach) // 2. { vd = new var_statement(x, arrid.indexer(i)); } else // 3. { vd = new var_statement(x, _foreach_stmt.type_name, arrid.indexer(i)); } // Превратить старое тело в statement_list и добавить к нему в начало x := a[i] или var x := a[i] var newbody = _foreach_stmt.stmt.ToStatementList(); newbody.AddFirst(vd); var high = arrid.dot_node("Length").Minus(1); var fornode = new for_node(i, 0, high, newbody, for_cycle_type.to, null, null, true); var stl = new statement_list(vdarr, fornode); // Замена 1 оператора на 1 оператор. Всё хорошо даже если оператор помечен меткой ReplaceUsingParent(_foreach_stmt, stl); visit(stl); //visit(vdarr); //visit(fornode); return(true); } /// SSM 29.07.16 return(false); }
public virtual void visit(var_statement _var_statement) { DefaultVisit(_var_statement); }
public override void visit(var_statement vs) // локальные описания внутри процедуры { LocalDeletedVS.Insert(0, vs.var_def); }
public virtual void visit(var_statement _var_statement) { }
public virtual void visit(var_statement _var_statement) { DefaultVisit(_var_statement); }
public override void visit(var_statement _var_statement) { DefaultVisit(_var_statement); pre_do_visit(_var_statement); visit(var_statement.var_def); post_do_visit(_var_statement); }
public virtual void post_do_visit(var_statement _var_statement) { }
public override void visit(var_statement _var_statement) { executer.visit(_var_statement); if (_var_statement.var_def != null) this.visit((dynamic)_var_statement.var_def); if (_var_statement.attributes != null) this.visit((dynamic)_var_statement.attributes); }
public virtual void visit(var_statement _var_statement) { }
public override void visit(var_statement _var_statement) { AddPossibleComments(_var_statement, true, false); }