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_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 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 void Process(statement st) { if (!(st is yield_node || st is labeled_statement)) { curStatList.Add(st); } if (st is yield_node) { var yn = st as yield_node; curState += 1; curStatList.AddMany( new assign(Consts.Current, yn.ex), new assign(Consts.State, curState), new assign("Result", true), new procedure_call("exit") ); curStatList = new statement_list(); case_variant cv = new case_variant(new expression_list(new int32_const(curState)), curStatList); cas.conditions.variants.Add(cv); } if (st is labeled_statement) { var ls = st as labeled_statement; curStatList = StatListAfterCase; curStatList.Add(new labeled_statement(ls.label_name)); Process(ls.to_statement); } }
public override void visit(loop_stmt loop) { // тут возможно ошибка более глубокая - в semantic_check_sugared_statement_node(asstup) возможно остаются во вложенных лямбдах другие assign_tuple var sl = new statement_list(); sl.Add(new semantic_check_sugared_statement_node(typeof(loop_stmt), new List <syntax_tree_node> { loop.count }, loop.source_context)); var tname = "#loop_var" + UniqueNumStr(); var fn = new for_node(new ident(tname), new int32_const(1), loop.count, loop.stmt, loop.source_context); sl.Add(fn); ReplaceUsingParent(loop, sl); visit(fn); }
public static statement_list CreateStatementList(params statement[] stmts) { statement_list res = new statement_list(); foreach (statement x in stmts) { res.Add(x); } return(res); }
public static statement_list BuildSimpleAssignList(List <ident> lnames, List <ident> rnames) { var sl = new statement_list(); for (int i = 0; i < lnames.Count; i++) { sl.Add(new assign(lnames[i], rnames[i])); } return(sl); }
private static SyntaxTree.program_module InternalCreateProgramModule(statement_list statements, declarations defs) { block block = new block(); if (defs != null) { block.defs = defs; } statements.Add(new SyntaxTree.empty_statement()); statements.left_logical_bracket = new token_info("begin"); statements.right_logical_bracket = new token_info("end"); block.program_code = statements; program_module res = new program_module(); res.program_block = block; //res.used_units = create_standard_uses_list(); return(res); }
private statement_list ConvertIfNode(if_node ifNode, List <statement> statementsBeforeIf, out statement elseBody) { // if e then <then> else <else> // // переводим в // // begin // statementsBeforeIf // if e then begin <then>; goto end_if end; // end // <else> // end_if: empty_statement // if e then <then> // // переводим в // // begin // statementsBeforeIf // if e then <then> // end // Добавляем, чтобы на конвертировать еще раз, если потребуется processedIfNodes.Add(ifNode); var statementsBeforeAndIf = new statement_list(); statementsBeforeAndIf.AddMany(statementsBeforeIf); statementsBeforeAndIf.Add(ifNode); if (ifNode.else_body == null) { elseBody = null; return(statementsBeforeAndIf); } else { var result = new statement_list(); result.Add(statementsBeforeAndIf); var endIfLabel = NewEndIfName(); // добавляем метку if (!(ifNode.then_body is statement_list)) { ifNode.then_body = new statement_list(ifNode.then_body, ifNode.then_body.source_context); ifNode.then_body.Parent = ifNode; } var thenBody = ifNode.then_body as statement_list; thenBody.Add(new goto_statement(endIfLabel)); // добавляем else и метку за ним result.Add(ifNode.else_body); result.Add(new labeled_statement(endIfLabel)); // Возвращаем else для обхода, т.к. он уже не входит в if elseBody = ifNode.else_body; // удаляем else из if ifNode.else_body = null; // Добавляем метку AddLabel(endIfLabel); return(result); } }
// 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 }
type_declarations GenClassesForYield(procedure_definition pd, IEnumerable <var_def_statement> fields) { var fh = (pd.proc_header as function_header); if (fh == null) { throw new SyntaxError("Only functions can contain yields", "", pd.proc_header.source_context, pd.proc_header); } var seqt = fh.return_type as sequence_type; if (seqt == null) { throw new SyntaxError("Functions with yields must return sequences", "", fh.return_type.source_context, fh.return_type); } // Теперь на месте функции генерируем класс // Захваченные переменные var cm = class_members.Public; foreach (var m in fields) { cm.Add(m); } // Параметры функции List <ident> lid = new List <ident>(); var pars = fh.parameters; if (pars != null) { foreach (var ps in pars.params_list) { if (ps.param_kind != parametr_kind.none) { throw new SyntaxError("Parameters of functions with yields must not have 'var', 'const' or 'params' modifier", "", pars.source_context, pars); } if (ps.inital_value != null) { throw new SyntaxError("Parameters of functions with yields must not have initial values", "", pars.source_context, pars); } var_def_statement vds = new var_def_statement(ps.idents, ps.vars_type); cm.Add(vds); // все параметры функции делаем полями класса lid.AddRange(vds.vars.idents); } } var stels = seqt.elements_type; // Системные поля и методы для реализации интерфейса IEnumerable cm.Add(new var_def_statement(Consts.State, "integer"), new var_def_statement(Consts.Current, stels), procedure_definition.EmptyDefaultConstructor, new procedure_definition("Reset"), new procedure_definition("MoveNext", "boolean", pd.proc_body), new procedure_definition("get_Current", "object", new assign("Result", Consts.Current)), new procedure_definition("GetEnumerator", "System.Collections.IEnumerator", new assign("Result", "Self")) ); var className = newClassName(); var classNameHelper = className + "Helper"; var interfaces = new named_type_reference_list("System.Collections.IEnumerator", "System.Collections.IEnumerable"); var td = new type_declaration(classNameHelper, SyntaxTreeBuilder.BuildClassDefinition(interfaces, cm)); // Изменение тела процедуры var stl = new statement_list(new var_statement("res", new new_expr(className))); stl.AddMany(lid.Select(id => new assign(new dot_node("res", id), id))); stl.Add(new assign("Result", "res")); pd.proc_body = new block(stl); // Второй класс var tpl = new template_param_list(stels); var IEnumeratorT = new template_type_reference("System.Collections.Generic.IEnumerator", tpl); var cm1 = class_members.Public.Add( procedure_definition.EmptyDefaultConstructor, new procedure_definition(new function_header("get_Current", stels), new assign("Result", Consts.Current)), new procedure_definition(new function_header("GetEnumerator", IEnumeratorT), new assign("Result", "Self")), new procedure_definition("Dispose") ); var interfaces1 = new named_type_reference_list(classNameHelper); var IEnumerableT = new template_type_reference("System.Collections.Generic.IEnumerable", tpl); interfaces1.Add(IEnumerableT).Add(IEnumeratorT); var td1 = new type_declaration(className, SyntaxTreeBuilder.BuildClassDefinition(interfaces1, cm1)); var cct = new type_declarations(td); cct.Add(td1); return(cct); }
private statement_list ConvertIfNode(if_node ifNode, List <statement> statementsBeforeIf, out statement elseBody) { // if e then <then> else <else> // // переводим в // // begin // var <>visitElseBranch := true; // begin // <>visitElseBranch := true; // statementsBeforeIf // if e then begin <then>; <>visitElseBranch := false; end; // end // if <>visitElseBranch then <else> // end // if e then <then> // // переводим в // // begin // statementsBeforeIf // if e then <then> // end // Добавляем объявление <>visitElseBranch если мы находимся в первом в цепочке if, который не является вложенным List <statement> visitElseStatList = null; if (ifNode.else_body != null && !(ifNode.Parent is if_node ifParentNode && ifParentNode.condition is ident ifParentNodeIdent && ifParentNodeIdent.name.Equals(GeneratedVisitElseBranchVariableName)) && !IsNestedIfWithExtendedIs(ifNode)) { visitElseStatList = new List <statement>(); visitElseStatList.Add( new var_statement( new ident(GeneratedVisitElseBranchVariableName, ifNode.source_context), new bool_const(true, ifNode.source_context), ifNode.source_context) ); } // Добавляем, чтобы на конвертировать еще раз, если потребуется processedIfNodes.Add(ifNode); if (ifNode.else_body != null) { statementsBeforeIf.Add(new assign( new ident(GeneratedVisitElseBranchVariableName, ifNode.source_context), new bool_const(true, ifNode.source_context), Operators.Assignment, ifNode.source_context)); } var statementsBeforeAndIf = new statement_list(); statementsBeforeAndIf.AddMany(statementsBeforeIf); statementsBeforeAndIf.Add(ifNode); if (ifNode.else_body == null) { elseBody = null; if (visitElseStatList != null) { visitElseStatList.Add(statementsBeforeAndIf); statementsBeforeAndIf = new statement_list(visitElseStatList); } return(statementsBeforeAndIf); } else { var result = new statement_list(); result.Add(statementsBeforeAndIf); var endIfLabel = NewEndIfName(); if (!(ifNode.then_body is statement_list)) { ifNode.then_body = new statement_list(ifNode.then_body, ifNode.then_body.source_context); ifNode.then_body.Parent = ifNode; } var thenBody = ifNode.then_body as statement_list; thenBody.Add(new assign( new ident(GeneratedVisitElseBranchVariableName, thenBody.source_context), new bool_const(false, thenBody.source_context), Operators.Assignment, thenBody.source_context)); // добавляем else result.Add( new if_node( new ident(GeneratedVisitElseBranchVariableName, ifNode.else_body.source_context), ifNode.else_body, null, ifNode.else_body.source_context)); // Возвращаем else для обхода, т.к. он уже не входит в if elseBody = ifNode.else_body; // удаляем else из if ifNode.else_body = null; if (visitElseStatList != null) { visitElseStatList.Add(result); result = new statement_list(visitElseStatList); } return(result); } }