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 java.util.List; 013import java.util.LinkedList; 014 015import static java.util.Collections.unmodifiableList; 016import org.eclipse.golo.compiler.parser.GoloASTNode; 017 018public final class CaseStatement extends GoloStatement implements Scope, Alternatives<Block> { 019 020 private Block otherwise; 021 private final LinkedList<WhenClause<Block>> clauses = new LinkedList<>(); 022 023 CaseStatement() { 024 super(); 025 } 026 027 public CaseStatement when(Object cond) { 028 WhenClause<Block> clause = new WhenClause<Block>((ExpressionStatement) cond, null); 029 this.clauses.add(clause); 030 makeParentOf(clause); 031 return this; 032 } 033 034 public CaseStatement then(Object action) { 035 this.clauses.getLast().setAction((Block) action); 036 return this; 037 } 038 039 public CaseStatement otherwise(Object action) { 040 otherwise = (Block) action; 041 makeParentOf(otherwise); 042 return this; 043 } 044 045 public List<WhenClause<Block>> getClauses() { 046 return unmodifiableList(this.clauses); 047 } 048 049 public Block getOtherwise() { 050 return this.otherwise; 051 } 052 053 @Override 054 public CaseStatement ofAST(GoloASTNode n) { 055 super.ofAST(n); 056 return this; 057 } 058 059 @Override 060 public void relink(ReferenceTable table) { 061 this.getOtherwise().relink(table); 062 for (WhenClause<Block> c : getClauses()) { 063 c.action().relink(table); 064 } 065 } 066 067 @Override 068 public void relinkTopLevel(ReferenceTable table) { 069 this.getOtherwise().relinkTopLevel(table); 070 for (WhenClause<Block> c : getClauses()) { 071 c.action().relinkTopLevel(table); 072 } 073 } 074 075 @Override 076 public void accept(GoloIrVisitor visitor) { 077 visitor.visitCaseStatement(this); 078 } 079 080 @Override 081 public void walk(GoloIrVisitor visitor) { 082 for (WhenClause<Block> clause : clauses) { 083 clause.accept(visitor); 084 } 085 otherwise.accept(visitor); 086 } 087 088 @Override 089 public void replaceElement(GoloElement original, GoloElement newElement) { 090 if (!(newElement instanceof Block || newElement instanceof WhenClause)) { 091 throw cantConvert("Block or WhenClause", newElement); 092 } 093 if (otherwise.equals(original)) { 094 otherwise(newElement); 095 return; 096 } 097 if (clauses.contains(original)) { 098 @SuppressWarnings("unchecked") 099 WhenClause<Block> when = (WhenClause<Block>) newElement; 100 clauses.set(clauses.indexOf(original), when); 101 makeParentOf(when); 102 return; 103 } 104 throw doesNotContain(original); 105 } 106}