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.runtime.OperatorType;
013
014public final class BinaryOperation extends ExpressionStatement {
015  private final OperatorType type;
016  private ExpressionStatement leftExpression;
017  private ExpressionStatement rightExpression;
018
019  BinaryOperation(OperatorType type) {
020    super();
021    this.type = type;
022  }
023
024  public static BinaryOperation of(Object type) {
025    if (type instanceof OperatorType) {
026      return new BinaryOperation((OperatorType) type);
027    }
028    if (type instanceof String) {
029      return new BinaryOperation(OperatorType.fromString((String) type));
030    }
031    throw cantConvert("BinaryOperation", type);
032  }
033
034  public OperatorType getType() {
035    return type;
036  }
037
038  public ExpressionStatement getLeftExpression() {
039    return leftExpression;
040  }
041
042  public BinaryOperation left(Object expr) {
043    leftExpression = (ExpressionStatement) expr;
044    makeParentOf(leftExpression);
045    return this;
046  }
047
048  public BinaryOperation right(Object expr) {
049    rightExpression = (ExpressionStatement) expr;
050    makeParentOf(rightExpression);
051    return this;
052  }
053
054  public ExpressionStatement getRightExpression() {
055    return rightExpression;
056  }
057
058  @Override
059  public String toString() {
060    return String.format("%s %s %s", leftExpression, type, rightExpression);
061  }
062
063  public boolean isMethodCall() {
064    return this.getType() == OperatorType.METHOD_CALL
065      || this.getType() == OperatorType.ELVIS_METHOD_CALL
066      || this.getType() == OperatorType.ANON_CALL;
067  }
068
069  @Override
070  public void accept(GoloIrVisitor visitor) {
071    visitor.visitBinaryOperation(this);
072  }
073
074  @Override
075  public void walk(GoloIrVisitor visitor) {
076    leftExpression.accept(visitor);
077    rightExpression.accept(visitor);
078  }
079
080  @Override
081  protected void replaceElement(GoloElement original, GoloElement newElement) {
082    if (!(newElement instanceof ExpressionStatement)) {
083      throw cantConvert("ExpressionStatement", newElement);
084    }
085    if (leftExpression.equals(original)) {
086      left(newElement);
087    } else if (rightExpression.equals(original)) {
088      right(newElement);
089    } else {
090      throw cantReplace(original, newElement);
091    }
092  }
093
094}