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