public override void visit(while_node wn) { var b = HasStatementVisitor <yield_node> .Has(wn); if (!b) { return; } var gotoBreak = goto_statement.New; var gotoContinue = goto_statement.New; ReplaceBreakContinueWithGotoLabelVisitor replaceBreakContinueVis = new ReplaceBreakContinueWithGotoLabelVisitor(gotoContinue, gotoBreak); wn.statements.visit(replaceBreakContinueVis); ProcessNode(wn.statements); statement if0; //if (wn.expr is ident && (wn.expr as ident).name.ToLower() == "true") // if0 = gotoBreak; //else if0 = new if_node(un_expr.Not(wn.expr), gotoBreak); var lb2 = new labeled_statement(gotoContinue.label, if0); // continue var lb1 = new labeled_statement(gotoBreak.label); // break ReplaceStatement(wn, SeqStatements(lb2, wn.statements, gotoContinue, lb1)); // в declarations ближайшего блока добавить описание labels block bl = listNodes.FindLast(x => x is block) as block; bl.defs.Add(new label_definitions(gotoBreak.label, gotoContinue.label)); }
public node controls_if(ControlsIfBlock block) { // If/elseif/else condition. node code = null; if (block.elseCount_ != 0) { code = statementToCode(block, "ELSE"); if (code == null) { code = new nil_node(this); } } for (var n = block.elseifCount_; n >= 0; n--) { var argument = valueToCode(block, "IF" + n); if (argument == null) { argument = new false_node(this); } var branch = statementToCode(block, "DO" + n); code = new if_node(this, argument, branch, code, false); } return(code); }
public override void visit(if_node _if_node) { var condition = _if_node.condition; if (condition is bin_expr binEpxr && HasExtendedIs(binEpxr)) { if_node rightExprIfNode = null; if_node leftExprIfNode = null; if (binEpxr.operation_type == Operators.LogicalAND) { rightExprIfNode = new if_node(binEpxr.right, (statement)_if_node.then_body?.Clone(), (statement)_if_node.else_body?.Clone(), _if_node.source_context); leftExprIfNode = new if_node(binEpxr.left, rightExprIfNode, (statement)_if_node.else_body?.Clone(), _if_node.source_context); } else if (binEpxr.operation_type == Operators.LogicalOR) { var rightExprThenBody = _if_node.else_body == null ? new empty_statement() : (statement)_if_node.else_body.Clone(); rightExprIfNode = new if_node( new un_expr(binEpxr.right, Operators.LogicalNOT, binEpxr.source_context), rightExprThenBody, (statement)_if_node.then_body?.Clone(), _if_node.source_context); leftExprIfNode = new if_node( new un_expr(binEpxr.left, Operators.LogicalNOT, binEpxr.source_context), rightExprIfNode, (statement)_if_node.then_body?.Clone(), _if_node.source_context); } ReplaceUsingParent(_if_node, leftExprIfNode); visit(leftExprIfNode); visit(rightExprIfNode); } }
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(repeat_node rn) { var b = HasStatementVisitor <yield_node> .Has(rn); if (!b) { return; } var gotoContinue = goto_statement.New; var gotoBreak = goto_statement.New; ReplaceBreakContinueWithGotoLabelVisitor replaceBreakContinueVis = new ReplaceBreakContinueWithGotoLabelVisitor(gotoContinue, gotoBreak); rn.statements.visit(replaceBreakContinueVis); ProcessNode(rn.statements); var gotoContinueIfNotCondition = new if_node(un_expr.Not(rn.expr), gotoContinue); var continueLabeledStatement = new labeled_statement(gotoContinue.label, new statement_list(rn.statements, gotoContinueIfNotCondition)); var breakLabeledStatement = new labeled_statement(gotoBreak.label); ReplaceStatement(rn, SeqStatements(gotoContinue, continueLabeledStatement, breakLabeledStatement)); // в declarations ближайшего блока добавить описание labels block bl = listNodes.FindLast(x => x is block) as block; bl.defs.Add(new label_definitions(gotoContinue.label, gotoBreak.label)); }
public override void visit(match_with matchWith) { desugaredMatchWith = null; _previousIf = null; // Кэшируем выражение для однократного вычисления //var cachedExpression = NewGeneralName(); //AddDefinitionsInUpperStatementList(matchWith, new[] { new var_statement(cachedExpression, matchWith.expr) }); // Преобразование из сахара в известную конструкцию каждого case var usedDeconstructionTypes = new HashSet <string>(); foreach (var patternCase in matchWith.case_list.elements) { if (patternCase == null) { continue; } if (patternCase.pattern is deconstructor_pattern) { // Проверяем встречался ли уже такой тип при деконструкции // SSM 02.01.19 пока закомментировал этот кусок т.к. при этом коде падает стандартный пример ArithmSimplify.cs. #1408 снова открыл /*var deconstructionType = (patternCase.pattern as deconstructor_pattern). * type as named_type_reference; * if (deconstructionType != null && * deconstructionType.names != null && * deconstructionType.names.Count != 0) * { * var deconstructionTypeName = deconstructionType.names[0].name; * if (usedDeconstructionTypes.Contains(deconstructionTypeName)) * { * throw new SyntaxVisitorError("REPEATED_DECONSTRUCTION_TYPE", * patternCase.pattern.source_context); * } * usedDeconstructionTypes.Add(deconstructionTypeName); * } */ DesugarDeconstructorPatternCase(matchWith.expr, patternCase); } } if (matchWith.defaultAction != null) { AddDefaultCase(matchWith.defaultAction as statement_list); } if (desugaredMatchWith == null) { desugaredMatchWith = new empty_statement(); } // Замена выражения match with на новое несахарное поддерево и его обход ReplaceUsingParent(matchWith, desugaredMatchWith); visit(desugaredMatchWith); }
public override void visit(if_node _if_node) { AddPossibleComments(_if_node, true, false); _if_node.condition.visit(this); _if_node.then_body.visit(this); if (_if_node.else_body != null) { _if_node.else_body.visit(this); } }
private bool IsNestedIfWithExtendedIs(if_node ifNode) { var parent = ifNode.Parent; while (parent != null) { if (parent is statement_list stList && IsVisitElseBranchStatementListDeclaration(stList)) { return(true); } parent = parent.Parent; } return(false); }
private void AddDesugaredCaseToResult(statement desugaredCase, if_node newIf) { // Если результат пустой, значит это первый case if (desugaredMatchWith == null) { desugaredMatchWith = desugaredCase; } else { _previousIf.else_body = desugaredCase; _previousIf.FillParentsInDirectChilds(); } // Запоминаем только что сгенерированный if _previousIf = newIf; }
private void VisitIf(if_node stmt) { RetVal rv = GetConstantValue(stmt.condition); VisitExpression(stmt.condition); if (rv == RetVal.False) { is_break_stmt = true; } VisitStatement(stmt.then_body); is_break_stmt = false; if (rv == RetVal.True) { is_break_stmt = true; } VisitStatement(stmt.else_body); is_break_stmt = false; }
public override void visit(if_node ifn) { ProcessNode(ifn.then_body); ProcessNode(ifn.else_body); var b = HasStatementVisitor <yield_node> .Has(ifn); if (!b) { return; } var gtAfter = goto_statement.New; var lbAfter = new labeled_statement(gtAfter.label); if ((object)ifn.else_body == null) { var if0 = new if_node(un_expr.Not(ifn.condition), gtAfter); //Replace(ifn, SeqStatements(gotoStartIfCondition, ifn.then_body, lbAfter)); ReplaceStatement(ifn, SeqStatements(if0, ifn.then_body, lbAfter)); // в declarations ближайшего блока добавить описание labels block bl = listNodes.FindLast(x => x is block) as block; bl.defs.Add(new label_definitions(gtAfter.label)); } else { var gtAlt = goto_statement.New; var lbAlt = new labeled_statement(gtAlt.label, ifn.else_body); var if0 = new if_node(un_expr.Not(ifn.condition), gtAlt); ReplaceStatement(ifn, SeqStatements(if0, ifn.then_body, gtAfter, lbAlt, lbAfter)); // в declarations ближайшего блока добавить описание labels block bl = listNodes.FindLast(x => x is block) as block; bl.defs.Add(new label_definitions(gtAfter.label, gtAlt.label)); } }
public override void visit(while_node wn) { ProcessNode(wn.statements); var gt1 = new goto_statement(newLabelName()); var gt2 = new goto_statement(newLabelName()); var gt3 = new goto_statement(newLabelName()); var if0 = new if_node(wn.expr, gt1, null); var lb3 = new labeled_statement(gt3.label, if0); var lb1 = new labeled_statement(gt1.label, wn.statements); var lb2 = new labeled_statement(gt2.label, new empty_statement()); var stl = new statement_list(lb3, gt2, lb1, gt3, lb2); Replace(wn, stl); // в declarations ближайшего блока добавить описание labels block bl = listNodes.FindLast(x => x is block) as block; var ld = new label_definitions(gt1.label, gt2.label, gt3.label); bl.defs.Add(ld); }
public override void visit(match_with matchWith) { desugaredMatchWith = null; _previousIf = null; // Кэшируем выражение для однократного вычисления //var cachedExpression = NewGeneralName(); //AddDefinitionsInUpperStatementList(matchWith, new[] { new var_statement(cachedExpression, matchWith.expr) }); // Преобразование из сахара в известную конструкцию каждого case foreach (var patternCase in matchWith.case_list.elements) { if (patternCase == null) { continue; } if (patternCase.pattern is deconstructor_pattern) { DesugarDeconstructorPatternCase(matchWith.expr, patternCase); } } if (matchWith.defaultAction != null) { AddDefaultCase(matchWith.defaultAction as statement_list); } if (desugaredMatchWith == null) { desugaredMatchWith = new empty_statement(); } // Замена выражения match with на новое несахарное поддерево и его обход ReplaceUsingParent(matchWith, desugaredMatchWith); visit(desugaredMatchWith); }
public override void visit(while_node wn) { ProcessNode(wn.statements); var b = HasStatementVisitor <yield_node> .Has(wn); if (!b) { return; } var gt1 = goto_statement.New; var gt2 = goto_statement.New; var if0 = new if_node(un_expr.Not(wn.expr), gt1); var lb2 = new labeled_statement(gt2.label, if0); var lb1 = new labeled_statement(gt1.label); ReplaceStatement(wn, SeqStatements(lb2, wn.statements, gt2, lb1)); // в declarations ближайшего блока добавить описание labels block bl = listNodes.FindLast(x => x is block) as block; bl.defs.Add(new label_definitions(gt1.label, gt2.label)); }
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); } }
public override void visit(if_node _if_node) { }
public virtual void visit(if_node _if_node) { DefaultVisit(_if_node); }
public virtual void post_do_visit(if_node _if_node) { }
public override void visit(if_node _if_node) { DefaultVisit(_if_node); pre_do_visit(_if_node); visit(if_node.condition); visit(if_node.then_body); visit(if_node.else_body); post_do_visit(_if_node); }
public virtual void visit(if_node _if_node) { }
public override void visit(if_node _if_node) { prepare_node(_if_node.condition, "condition"); prepare_node(_if_node.then_body, "then_body"); prepare_node(_if_node.else_body, "else_body"); }
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); } }
public override void visit(for_node fn) { var b = HasStatementVisitor <yield_node> .Has(fn); if (!b) { return; } var gotoContinue = goto_statement.New; var gotoBreak = goto_statement.New; var gotoStart = goto_statement.New; ReplaceBreakContinueWithGotoLabelVisitor replaceBreakContinueVis = new ReplaceBreakContinueWithGotoLabelVisitor(gotoContinue, gotoBreak); fn.statements.visit(replaceBreakContinueVis); ProcessNode(fn.statements); var newNames = this.NewVarNames(fn.loop_variable); var newLoopVar = fn.create_loop_variable ? new ident(newNames.VarName) : fn.loop_variable; // Нужно заменить fn.loop_variable -> newLoopVar в теле цикла var replacerVis = new ReplaceVariableNameVisitor(fn.loop_variable, newLoopVar); fn.visit(replacerVis); fn.loop_variable = newLoopVar; var endtemp = new ident(newNames.VarEndName); //new ident(newVarName()); //var ass1 = new var_statement(fn.loop_variable, fn.type_name, fn.initial_value); //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); // frninja 05/06/16 - фиксим для !fn.create_variable var ass1 = fn.create_loop_variable ? new var_statement(fn.loop_variable, fn.type_name, fn.initial_value) as statement : new assign(fn.loop_variable, fn.initial_value) as statement; var if0 = new if_node((fn.cycle_type == for_cycle_type.to) ? bin_expr.Greater(fn.loop_variable, fn.finish_value) : bin_expr.Less(fn.loop_variable, fn.finish_value), gotoBreak); var lb2 = new labeled_statement(gotoStart.label, if0); var lb1 = new labeled_statement(gotoBreak.label); var Inc = new procedure_call(new method_call((fn.cycle_type == for_cycle_type.to) ? new ident("Inc") : new ident("Dec"), new expression_list(fn.loop_variable))); var lbInc = new labeled_statement(gotoContinue.label, Inc); ReplaceStatement(fn, SeqStatements(ass1, lb2, fn.statements, lbInc, gotoStart, lb1)); // в declarations ближайшего блока добавить описание labels block bl = listNodes.FindLast(x => x is block) as block; bl.defs.Add(new label_definitions(gotoContinue.label, gotoBreak.label, gotoStart.label)); }
public override void visit(for_node fn) { var b = HasStatementVisitor <yield_node> .Has(fn); if (!b) { return; } var gotoContinue = goto_statement.New; var gotoBreak = goto_statement.New; var gotoStart = goto_statement.New; ReplaceBreakContinueWithGotoLabelVisitor replaceBreakContinueVis = new ReplaceBreakContinueWithGotoLabelVisitor(gotoContinue, gotoBreak); fn.statements.visit(replaceBreakContinueVis); ProcessNode(fn.statements); var newNames = this.NewVarNames(fn.loop_variable); var newLoopVar = fn.create_loop_variable ? new ident(newNames.VarName) : fn.loop_variable; // Нужно заменить fn.loop_variable -> newLoopVar в теле цикла var replacerVis = new ReplaceVariableNameVisitor(fn.loop_variable, newLoopVar); fn.visit(replacerVis); fn.loop_variable = newLoopVar; var endtemp = new ident(newNames.VarEndName); //new ident(newVarName()); //var ass1 = new var_statement(fn.loop_variable, fn.type_name, fn.initial_value); //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); // Исправления в связи с #1254 (новый алгоритм) // цикл for i:=a to b do // i := a // if i > b then goto break //Start: stmts // if i >= b then goto break //Continue: Inc(i) // goto Start //Break: // цикл for i:=a downto b do // i := a // if i < b then goto break //Start: stmts // if i <= b then goto break //Continue: Dec(i) // goto Start //Break: // frninja 05/06/16 - фиксим для !fn.create_variable var ass1 = fn.create_loop_variable ? new var_statement(fn.loop_variable, fn.type_name, fn.initial_value) as statement : new assign(fn.loop_variable, fn.initial_value) as statement; var if0 = new if_node((fn.cycle_type == for_cycle_type.to) ? bin_expr.Greater(fn.loop_variable, fn.finish_value) : bin_expr.Less(fn.loop_variable, fn.finish_value), gotoBreak); var if1 = new if_node((fn.cycle_type == for_cycle_type.to) ? bin_expr.GreaterEqual(fn.loop_variable, fn.finish_value) : bin_expr.LessEqual(fn.loop_variable, fn.finish_value), gotoBreak); var lb1 = new labeled_statement(gotoStart.label); var lb2 = new labeled_statement(gotoBreak.label); // пустой оператор var Inc = new procedure_call(new method_call((fn.cycle_type == for_cycle_type.to) ? new ident("Inc") : new ident("Dec"), new expression_list(fn.loop_variable))); var lbInc = new labeled_statement(gotoContinue.label, Inc); ReplaceStatement(fn, SeqStatements(ass1, if0, lb1, fn.statements, if1, lbInc, gotoStart, lb2)); /*var if0 = new if_node((fn.cycle_type == for_cycle_type.to) ? * bin_expr.Greater(fn.loop_variable, fn.finish_value) : * bin_expr.Less(fn.loop_variable, fn.finish_value), gotoBreak); * * var lb2 = new labeled_statement(gotoStart.label, if0); * var lb1 = new labeled_statement(gotoBreak.label); // пустой оператор * var Inc = new procedure_call(new method_call((fn.cycle_type == for_cycle_type.to) ? * new ident("Inc") : * new ident("Dec"), new expression_list(fn.loop_variable))); * * var lbInc = new labeled_statement(gotoContinue.label, Inc); * * ReplaceStatement(fn, SeqStatements(ass1, lb2, fn.statements, lbInc, gotoStart, lb1));*/ // в declarations ближайшего блока добавить описание labels block bl = listNodes.FindLast(x => x is block) as block; bl.defs.Add(new label_definitions(gotoContinue.label, gotoBreak.label, gotoStart.label)); }
public override void visit(match_with matchWith) { desugaredMatchWith = null; _previousIf = null; matchedExprVarDeclaration = new var_statement( new ident(GeneratedMatchExprVariableName, matchWith.expr.source_context), matchWith.expr.Clone() as expression, matchWith.expr.source_context); ReplaceUsingParent(matchWith.expr, new ident(GeneratedMatchExprVariableName, matchWith.expr.source_context)); /*if (matchWith.Parent is statement_list stl) * { * stl.InsertBefore(matchWith, matchedExprVarDeclaration); * } * else * { * var enclosingStl = new statement_list(matchedExprVarDeclaration, matchWith); * enclosingStl.source_context = matchWith.source_context; * ReplaceUsingParent(matchWith, enclosingStl); * }*/ // Кэшируем выражение для однократного вычисления //var cachedExpression = NewGeneralName(); //AddDefinitionsInUpperStatementList(matchWith, new[] { new var_statement(cachedExpression, matchWith.expr) }); // Преобразование из сахара в известную конструкцию каждого case var usedDeconstructionTypes = new HashSet <string>(); foreach (var patternCase in matchWith.case_list.elements) { if (patternCase == null) { continue; } DefaultDesugarPattern(matchWith.expr, patternCase); /*switch (patternCase.pattern) * { * case deconstructor_pattern pattern: * { * // Проверяем встречался ли уже такой тип при деконструкции * // SSM 02.01.19 пока закомментировал этот кусок т.к. при этом коде падает стандартный пример ArithmSimplify.cs. #1408 снова открыл * var deconstructionType = (patternCase.pattern as deconstructor_pattern). * type as named_type_reference; * if (deconstructionType != null && * deconstructionType.names != null && * deconstructionType.names.Count != 0) * { * var deconstructionTypeName = deconstructionType.names[0].name; * if (usedDeconstructionTypes.Contains(deconstructionTypeName)) * { * throw new SyntaxVisitorError("REPEATED_DECONSTRUCTION_TYPE", * patternCase.pattern.source_context); * } * usedDeconstructionTypes.Add(deconstructionTypeName); * } * * DefaultDesugarPattern(matchWith.expr, patternCase); * break; * } * case const_pattern p: * { * //DesugarConstPatternCase(matchWith.expr, patternCase); * DefaultDesugarPattern(matchWith.expr, patternCase); * break; * } * case collection_pattern p: * { * DefaultDesugarPattern(matchWith.expr, patternCase); * break; * } * case tuple_pattern p: * { * DefaultDesugarPattern(matchWith.expr, patternCase); * break; * } * }*/ } if (matchWith.defaultAction != null) { AddDefaultCase(matchWith.defaultAction as statement_list); } if (desugaredMatchWith == null) { desugaredMatchWith = new empty_statement(); } if (typeChecks.Count != 0) { typeChecks.Add(desugaredMatchWith); desugaredMatchWith = new statement_list(typeChecks); } desugaredMatchWith = new statement_list(matchedExprVarDeclaration, desugaredMatchWith); // Замена выражения match with на новое несахарное поддерево и его обход ReplaceUsingParent(matchWith, desugaredMatchWith); visit(desugaredMatchWith); }
public override void visit(if_node _if_node) { executer.visit(_if_node); if (_if_node.condition != null) this.visit((dynamic)_if_node.condition); if (_if_node.then_body != null) this.visit((dynamic)_if_node.then_body); if (_if_node.else_body != null) this.visit((dynamic)_if_node.else_body); if (_if_node.attributes != null) this.visit((dynamic)_if_node.attributes); }
// frninja 30/05/16 public override void visit(case_node csn) { var b = HasStatementVisitor <yield_node> .Has(csn); if (!b) { return; } /* * * case i of * cv1: bla1; * cv2: bla2; * .. * cvN: blaN; * else: bla_else; * * ---> * * if i satisfy cv1 * then bla1 * else if i satisfy cv2 * then bla2 * .. * else if i satisfy cvN * then blaN * else bla_else * */ if_node currentIfNode = null; statement currentIfElseClause = (csn.else_statement != null) ? csn.else_statement :new statement_list(new empty_statement());; for (int i = csn.conditions.variants.Count - 1; i >= 0; --i) { case_variant cv = csn.conditions.variants[i]; ProcessNode(cv.exec_if_true); var ifCondition = this.CreateConditionFromCaseVariant(csn.param, cv.conditions); currentIfNode = new if_node(ifCondition, new statement_list(cv.exec_if_true), new statement_list(currentIfElseClause)); currentIfElseClause = currentIfNode; } if_node finalIfNode = currentIfNode; if (finalIfNode == null) // SSM - значит, в цикл мы не заходили и у case отсутствуют все ветви кроме else - поскольку yieldы в case есть { ReplaceStatement(csn, csn.else_statement); } else { ReplaceStatement(csn, finalIfNode); } if (finalIfNode != null) { visit(finalIfNode); } }