blob: ea572441ba788741b03beaf9dc453e2da41c31aa [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
/*
* generated by Xtext
*/
package org.eclipse.stem.model.codegen.xtext
import java.util.List
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.stem.model.ctdl.ContextSensitiveResourceWrapper
import org.eclipse.stem.model.ctdl.ctdl.AbsoluteCompartmentValueReference
import org.eclipse.stem.model.ctdl.ctdl.BooleanLiteral
import org.eclipse.stem.model.ctdl.ctdl.CompartmentTransitionDefinitions
import org.eclipse.stem.model.ctdl.ctdl.DefStatement
import org.eclipse.stem.model.ctdl.ctdl.Div
import org.eclipse.stem.model.ctdl.ctdl.Evaluation
import org.eclipse.stem.model.ctdl.ctdl.ExternalFunctionReference
import org.eclipse.stem.model.ctdl.ctdl.FunctionCall
import org.eclipse.stem.model.ctdl.ctdl.FunctionReference
import org.eclipse.stem.model.ctdl.ctdl.GlobalVariableReference
import org.eclipse.stem.model.ctdl.ctdl.LocalVariableReference
import org.eclipse.stem.model.ctdl.ctdl.Minus
import org.eclipse.stem.model.ctdl.ctdl.ModelParamReference
import org.eclipse.stem.model.ctdl.ctdl.Multi
import org.eclipse.stem.model.ctdl.ctdl.NumberLiteral
import org.eclipse.stem.model.ctdl.ctdl.Plus
import org.eclipse.stem.model.ctdl.ctdl.PrimaryExpression
import org.eclipse.stem.model.ctdl.ctdl.RelativeCompartmentValueReference
import org.eclipse.stem.model.ctdl.ctdl.StringLiteral
import org.eclipse.stem.model.ctdl.ctdl.TransitionBlock
import org.eclipse.stem.model.ctdl.ctdl.VariableReference
import org.eclipse.stem.model.ctdl.functions.FunctionArgumentReference
import org.eclipse.stem.model.ctdl.functions.SystemArgumentReference
import org.eclipse.stem.model.ctdl.serializer.TypeSerializerFactory
import org.eclipse.xtext.generator.IFileSystemAccess
import org.eclipse.xtext.resource.XtextResource
import org.eclipse.stem.model.ctdl.ctdl.Expression
class ExpressionsClassGenerator extends ModelExpressionGenerator {
override void doGenerate(List<XtextResource> resources, IFileSystemAccess fsa) {
var fileName = modelGenClass.name +"Expressions.java"
fsa.generateFile(fileName,resources.build)
}
override void doGenerate(Resource resource, IFileSystemAccess fsa) {
var ctd = resource.allContents.toIterable.filter(typeof(CompartmentTransitionDefinitions)).head;
var mm = ctd.metamodel
var trans = mm.transition
var fname = trans.source.name +"_"+ trans.target.name;
fsa.generateFile(fname, resource.compile());
}
def build(List<XtextResource> r) {
var pkg = '''package «modelGenClass.genPackage.classPackageName»;'''
var body = '''
/**
* Generated expressions class for «modelGenClass.name».
* DO NOT EDIT DIRECTLY. Use extended class and override methods for transitions as desired.
* @generated
*/
public class «modelGenClass.name»Expressions {
public void calculate(double t, long timeDelta, «getImportedName("org.eclipse.stem.core.model.STEMTime")» time, «modelGenClass.importGenClassInterface» model, «labelGenClass.importGenClassInterface» label, «labelValueGenClass.importGenClassInterface» labelValue, «getImportedName("org.eclipse.stem.core.graph.Node")» node, «labelValueGenClass.importGenClassInterface» deltaValue) {
«FOR s:r.affectedCompartments»
double delta«s.accessorName» = 0.0;
«ENDFOR»
«FOR s:r.filter(typeof(ContextSensitiveResourceWrapper))»
// Calculate delta for transition «s.transition.formattedName»
double generated_«s.transition.methodName» = «s.transition.methodName»(t,timeDelta,time,model,label,labelValue,label.getNode());
delta«s.transition.source.accessorName» -= generated_«s.transition.methodName»;
delta«s.transition.target.accessorName» += generated_«s.transition.methodName»;
«FOR c:s.transition.forIncidence»
delta«c.accessorName» += generated_«s.transition.methodName»;
«ENDFOR»
// Stochastic exchange for «s.transition.formattedName»
«"org.eclipse.stem.core.graph.Exchange".importedName» exchange_«s.transition.methodName» = («"org.eclipse.stem.core.graph.Exchange".importedName»)«"org.eclipse.stem.core.graph.ExchangePool".importedName».POOL.get();
deltaValue.getDepartures().add(exchange_«s.transition.methodName»);
exchange_«s.transition.methodName».setType(«"org.eclipse.stem.core.graph.ExchangeType".importedName».COMPARTMENT_TRANSITION);
exchange_«s.transition.methodName».setSource(«s.transition.source.genFeature.packageAccessorName»);
exchange_«s.transition.methodName».setTarget(«s.transition.target.genFeature.packageAccessorName»);
exchange_«s.transition.methodName».setCount(generated_«s.transition.methodName»);
«FOR c:s.transition.forIncidence»
exchange_«s.transition.methodName».getForIncidence().add(«c.genFeature.packageAccessorName»);
«ENDFOR»
«ENDFOR»
«FOR s:r.affectedCompartments»
deltaValue.set«s.accessorName»(delta«s.accessorName»);
«ENDFOR»
}
«FOR e:r»
«compile(e)»
«ENDFOR»
} //'''
var imports = sortedImports
return '''«pkg»
«imports»
«body»''' as CharSequence
}
def dispatch compile(Resource r) '''«r.allContents.toIterable.filter(typeof(TransitionBlock)).head.compile()»'''
// var ret = ""; //"public class "+name+ "{"+"\n";
// return ;
def dispatch compile(TransitionBlock t) {
var ctd = t.eContainer as CompartmentTransitionDefinitions
var transition = ctd.metamodel.transition
//var Model m = (CompartmentTransitionDefinitions::)t.eContainer;
return '''
/**
* Computes delta for transition «transition.source.name» -> «transition.target.name»
* @generated
*/
protected double «transition.source.name»_«transition.target.name» (double t, long timeDelta, «getImportedName("org.eclipse.stem.core.model.STEMTime")» time, «modelGenClass.importGenClassInterface» model, «labelGenClass.importGenClassInterface» label, «labelValueGenClass.importGenClassInterface» labelValue, «getImportedName("org.eclipse.stem.core.graph.Node")» node) {
«FOR s:t.block.statements»«compile(s)»«ENDFOR»
return «compile(t.block.ret)»;
}
''' as CharSequence
}
def dispatch compile(DefStatement d)'''double «d.varname»=«compile(d.expr)»;'''
def dispatch compile(Evaluation e) '''«compile(e.expression,Double::TYPE)»'''
def dispatch compile(PrimaryExpression pe, Class<?> expectedType) {
var neg = ""
if (pe.negate) neg = "-"
return '''
(«neg»«compile(pe.exp,expectedType)»)
''' as CharSequence
}
def dispatch compile(Plus p, Class<?> expectedType) '''(«compile(p.left,Double::TYPE)»+«compile(p.right,Double::TYPE)»)'''
def dispatch compile(Minus m, Class<?> expectedType) '''(«compile(m.left,Double::TYPE)»-«compile(m.right,Double::TYPE)»)'''
def dispatch compile(Multi m, Class<?> expectedType) '''«compile(m.left,Double::TYPE)»*«compile(m.right,Double::TYPE)»'''
def dispatch compile(Div d, Class<?> expectedType) '''«compile(d.left,Double::TYPE)»/«compile(d.right,Double::TYPE)»'''
def dispatch compileReference(GlobalVariableReference rf, Class<?> expectedType) '''«rf.name»'''
def dispatch compileReference(LocalVariableReference rf, Class<?> expectedType) '''«rf.name»'''
def dispatch compileReference(AbsoluteCompartmentValueReference rf, Class<?> expectedType) {
var serializer = TypeSerializerFactory::getSerializer(rf,expectedType,labelValueGenClass);
if (serializer !== null) {
return serializer.serialize
}
return '''labelValue.get«rf.obj.name.toFirstUpper»()''' as CharSequence
}
def dispatch compileReference(RelativeCompartmentValueReference rf, Class<?> expectedType) {
var serializer = TypeSerializerFactory::getSerializer(rf,expectedType,labelValueGenClass);
if (serializer !== null) {
return serializer.serialize
}
return '''(labelValue.getPopulationCount() > 0)? (labelValue.get«rf.obj.name.toFirstUpper»()/labelValue.getPopulationCount()):0''' as CharSequence
}
def dispatch compileReference(ModelParamReference rf, Class<?> expectedType) '''model.get«rf.obj.name.toFirstUpper»()'''
def dispatch compile(VariableReference rf, Class<?> expectedType) '''«compileReference(rf.ref, expectedType)»'''
def dispatch compile(NumberLiteral nl, Class<?> expectedType) '''«nl.value»'''
def dispatch compile(StringLiteral sl, Class<?> expectedType) '''"«sl.value»"'''
def dispatch compile(BooleanLiteral bl, Class<?> expectedType) '''«bl.value»'''
def dispatch compile(Expression exp, Class<?> expectedType) '''«compile(exp.exp,expectedType)»'''
// def dispatch compile(FunctionCall fc) ''' java.lang.Math.«fc.func»(
// �FOR e:fc.args�
// �IF e==fc.args.head�
// �compile(e)�
// �ELSE�
// ,�compile(e)�
// �ENDIF�
// �ENDFOR�)'''
def dispatch compileArgument( SystemArgumentReference arg, FunctionCall fc) '''«arg.mapsFrom»'''
def dispatch compileArgument(FunctionArgumentReference arg, FunctionCall fc) '''«compile(fc.args.get(arg.argIndex), arg.javaType)»'''
def dispatch compileFunction(ExternalFunctionReference fcr, FunctionCall fc)
'''«getImportedName(fcr.func.className)».«fcr.func.methodName»(
«FOR arg:fcr.func.javaMethodArguments»
«IF arg!=fcr.func.javaMethodArguments.head»,«ENDIF»
«compileArgument(arg,fc)»
«ENDFOR»)'''
def dispatch compileFunction(FunctionReference fcr, FunctionCall fc)
'''«fcr.name»(«FOR e:fc.args»
«IF e==fc.args.head»
«compile(e)»
«ELSE»
,«compile(e)»
«ENDIF»
«ENDFOR»)'''
def dispatch compile(FunctionCall fc, Class<?> expectedType) {
'''«compileFunction(fc.ref, fc)»'''
// if (fc.ref instanceof ExternalFunctionReference) {
// '''«compile(fc.ref as ExternalFunctionReference, fc)»'''
// } else {
// '''«compile(fc.ref, fc)»'''
// }
}
//def dispatch compile(ExternalFunctionDefinition extFunc) '''«addImport(extFunc.className)».«extFunc.methodName»'''
}