blob: 67940f59695bd4f67a485770c8e71d27ba0dfeef [file] [log] [blame]
/*********************************************************************
* Copyright (c) 2008 The University of York.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
package org.eclipse.epsilon.eol.dom;
import org.eclipse.epsilon.common.module.IModule;
import org.eclipse.epsilon.common.parse.AST;
import org.eclipse.epsilon.eol.compile.context.EolCompilationContext;
import org.eclipse.epsilon.eol.exceptions.EolRuntimeException;
import org.eclipse.epsilon.eol.execute.context.IEolContext;
import org.eclipse.epsilon.eol.execute.context.Variable;
import org.eclipse.epsilon.eol.execute.introspection.IPropertySetter;
public class AssignmentStatement extends Statement {
protected Expression targetExpression;
protected Expression valueExpression;
public AssignmentStatement() {}
public AssignmentStatement(Expression targetExpression, Expression valueExpression) {
this.targetExpression = targetExpression;
this.valueExpression = valueExpression;
}
@Override
public void build(AST cst, IModule module) {
super.build(cst, module);
targetExpression = (Expression) module.createAst(cst.getFirstChild(), this);
valueExpression = (Expression) module.createAst(cst.getSecondChild(), this);
if (cst.getText().equals("+=")) {
valueExpression = new PlusOperatorExpression(targetExpression, valueExpression);
}
else if (cst.getText().equals("-=")) {
valueExpression = new MinusOperatorExpression(targetExpression, valueExpression);
}
else if (cst.getText().equals("/=")) {
valueExpression = new DivOperatorExpression(targetExpression, valueExpression);
}
else if (cst.getText().equals("*=")) {
valueExpression = new TimesOperatorExpression(targetExpression, valueExpression);
}
}
@Override
public Object execute(IEolContext context) throws EolRuntimeException{
// Executing the targetExpression can return either a Variable
// or a SetterMethod with one argument (set method)
// Executing the valueExpression will return an object
Object targetExpressionResult = null;
if (targetExpression instanceof PropertyCallExpression) {
targetExpressionResult = ((PropertyCallExpression) targetExpression).execute(context, true);
}
else if (targetExpression instanceof NameExpression) {
targetExpressionResult = ((NameExpression) targetExpression).execute(context, true);
}
else {
targetExpressionResult = context.getExecutorFactory().execute(targetExpression, context);
}
Object valueExpressionResult = context.getExecutorFactory().execute(valueExpression, context);
if (targetExpressionResult instanceof IPropertySetter){
IPropertySetter setter = (IPropertySetter) targetExpressionResult;
try {
Object value = getValueEquivalent(setter.getObject(), valueExpressionResult, context);
setter.invoke(value);
}
catch (EolRuntimeException ex){
if (ex.getAst() == null) {
ex.setAst(setter.getAst());
}
throw ex;
}
} else if (targetExpressionResult instanceof Variable){
Variable variable = (Variable) targetExpressionResult;
try {
Object value = getValueEquivalent(variable.getValue(), valueExpressionResult, context);
variable.setValue(value, context);
}
catch (EolRuntimeException ex){
ex.setAst(targetExpression);
throw ex;
}
} else {
throw new EolRuntimeException("Internall error. Expected either a SetterMethod or a Variable and got an " + targetExpressionResult + "instead", this);
}
return null;
}
public Object getValueEquivalent(Object source, Object value, IEolContext context) throws EolRuntimeException {
return value;
}
@Override
public void compile(EolCompilationContext context) {
targetExpression.compile(context);
valueExpression.compile(context);
}
public Expression getTargetExpression() {
return targetExpression;
}
public void setTargetExpression(Expression targetExpression) {
this.targetExpression = targetExpression;
}
public Expression getValueExpression() {
return valueExpression;
}
public void setValueExpression(Expression valueExpression) {
this.valueExpression = valueExpression;
}
}