001/* 002 * Copyright (c) 2012-2017 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 */ 009 010package org.eclipse.golo.compiler.ir; 011 012import org.eclipse.golo.compiler.parser.GoloASTNode; 013import java.util.Objects; 014 015import static org.eclipse.golo.compiler.ir.Builders.*; 016 017public final class LoopStatement extends GoloStatement implements Scope, BlockContainer { 018 019 private AssignmentStatement initStatement = null; 020 private ExpressionStatement conditionStatement = constant(false); 021 private GoloStatement postStatement = null; 022 private Block block = Block.emptyBlock();; 023 024 LoopStatement() { 025 super(); 026 } 027 028 @Override 029 public LoopStatement ofAST(GoloASTNode node) { 030 super.ofAST(node); 031 return this; 032 } 033 034 public LoopStatement init(Object assignment) { 035 if (assignment instanceof AssignmentStatement) { 036 setInitStatement((AssignmentStatement) assignment); 037 return this; 038 } 039 throw cantConvert("assignment", assignment); 040 } 041 042 public LoopStatement condition(Object expression) { 043 if (expression instanceof ExpressionStatement) { 044 setConditionStatement((ExpressionStatement) expression); 045 return this; 046 } 047 throw cantConvert("expression", expression); 048 } 049 050 public LoopStatement post(Object statement) { 051 if (statement instanceof GoloStatement) { 052 setPostStatement((GoloStatement) statement); 053 return this; 054 } 055 throw cantConvert("statement", statement); 056 } 057 058 public LoopStatement block(Block innerBlock) { 059 setBlock(innerBlock); 060 return this; 061 } 062 063 public LoopStatement block(Object... statements) { 064 return this.block(Builders.block(statements)); 065 } 066 067 public boolean hasInitStatement() { 068 return initStatement != null; 069 } 070 071 public AssignmentStatement getInitStatement() { 072 return initStatement; 073 } 074 075 public void setInitStatement(AssignmentStatement init) { 076 this.initStatement = init; 077 makeParentOf(init); 078 } 079 080 public ExpressionStatement getConditionStatement() { 081 return conditionStatement; 082 } 083 084 public void setConditionStatement(ExpressionStatement cond) { 085 conditionStatement = (cond == null ? constant(false) : cond); 086 makeParentOf(conditionStatement); 087 } 088 089 public Block getBlock() { 090 return block; 091 } 092 093 public void setBlock(Block block) { 094 this.block = (block == null ? Block.emptyBlock() : block); 095 makeParentOf(this.block); 096 } 097 098 public GoloStatement getPostStatement() { 099 return postStatement; 100 } 101 102 public void setPostStatement(GoloStatement stat) { 103 postStatement = stat; 104 makeParentOf(postStatement); 105 } 106 107 public boolean hasPostStatement() { 108 return postStatement != null; 109 } 110 111 @Override 112 public void relink(ReferenceTable table) { 113 block.relink(table); 114 } 115 116 @Override 117 public void relinkTopLevel(ReferenceTable table) { 118 block.relinkTopLevel(table); 119 } 120 121 @Override 122 public void accept(GoloIrVisitor visitor) { 123 visitor.visitLoopStatement(this); 124 } 125 126 @Override 127 public void walk(GoloIrVisitor visitor) { 128 if (initStatement != null) { 129 initStatement.accept(visitor); 130 } 131 conditionStatement.accept(visitor); 132 if (postStatement != null) { 133 postStatement.accept(visitor); 134 } 135 block.accept(visitor); 136 } 137 138 @Override 139 protected void replaceElement(GoloElement original, GoloElement newElement) { 140 if (Objects.equals(initStatement, original)) { 141 init(newElement); 142 } else if (Objects.equals(conditionStatement, original)) { 143 condition(newElement); 144 } else if (Objects.equals(postStatement, original)) { 145 post(newElement); 146 } else if (Objects.equals(block, original)) { 147 block((Block) newElement); 148 } else { 149 throw cantReplace(original, newElement); 150 } 151 } 152}