CoreDSL2JSON/com.minres.coredsl.json/src/com/minres/coredsl/json/CoreDslJsonGenerator.xtend

112 lines
4.0 KiB
Plaintext

/*
* generated by Xtext 2.13.0
*/
package com.minres.coredsl.json
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.xtext.generator.AbstractGenerator
import org.eclipse.xtext.generator.IFileSystemAccess2
import org.eclipse.xtext.generator.IGeneratorContext
import com.minres.coredsl.coreDsl.CoreDef
import com.minres.coredsl.coreDsl.Instruction
import com.minres.coredsl.coreDsl.InstructionSet
import org.apache.log4j.Logger
import com.minres.coredsl.coreDsl.Encoding
import com.minres.coredsl.coreDsl.BitField
import com.minres.coredsl.coreDsl.BitValue
import java.util.List
import com.minres.coredsl.coreDsl.ISA
import org.json.JSONObject
import org.json.JSONArray
import com.minres.coredsl.util.BigIntegerWithRadix
import com.minres.coredsl.coreDsl.Statement
import org.eclipse.xtext.resource.XtextResource
/**
* Generates code from your model files on save.
*
* See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation
*/
class CoreDslJsonGenerator extends AbstractGenerator {
val logger = Logger.getLogger(typeof(CoreDslJsonGenerator));
override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
for (e : resource.allContents.toIterable.filter(CoreDef)) {
val root = new JSONObject()
root.put('instructions', e.compile)
fsa.generateFile(e.name + ".json", root.toString(2))
}
}
def Boolean isHls(Instruction inst){
val instrSet = inst.eContainer as ISA;
!(inst.attributes.filter[it.type=='hls'].isEmpty &&
instrSet.commonInstructionAttributes.filter[it.type=='hls'].isEmpty)
}
def JSONArray compile(CoreDef coreDef) {
val insts = coreDef.allInstr
val enabled_insts = insts.filter[it.isHls]
val res = enabled_insts.map[ inst | inst.jsonDescr ].toList
return res.length>0?new JSONArray(res) :new JSONArray()
}
def JSONObject jsonDescr(Instruction inst){
val ret = new JSONObject();
ret.put("decoding", inst.encoding.fields.map[it.asString].join('|'))
ret.put("name", inst.name);
ret.put('disassembly', inst.assembly !== null? inst.name.toLowerCase + ' ' + inst.assembly.toLowerCase : inst.name)
ret.put('execution', inst.behavior.source)
ret.put('restrictions', '')
}
def String getSource(Statement stmt){
(stmt.eResource as XtextResource).serializer.serialize(stmt)
}
def Iterable<Instruction> allInstr(CoreDef core) {
val unique = newLinkedHashMap
val instrList = if (core.providedInstructionSets.size == 0)
core.instructions
else {
val instrSets = core.providedInstructionSets?.map[InstructionSet i|i.allInstructionSets].flatten
val seen = newLinkedHashSet
seen.addAll(instrSets)
seen.map[InstructionSet i|i.instructions].flatten
}
for (Instruction i : instrList) {
if (i.eContainer instanceof InstructionSet)
logger.trace("adding instruction " + i.name + " of " + (i.eContainer as InstructionSet).name)
if (i.eContainer instanceof CoreDef)
logger.trace("adding instruction " + i.name + " of " + (i.eContainer as CoreDef).name)
unique.put(i.name, i)
}
val instLut = newLinkedHashMap()
for (Instruction i : unique.values) {
logger.trace("adding encoding " + i.encoding.bitEncoding + " for instruction " + i.name)
instLut.put(i.encoding.bitEncoding, i)
}
return instLut.values
}
def List<InstructionSet> allInstructionSets(InstructionSet core) {
val s = if(core.superType !== null) core.superType.allInstructionSets else newLinkedList
s.add(core)
return s
}
def String getBitEncoding(Encoding encoding) '''«FOR field : encoding.fields»«field.regEx»«ENDFOR»'''
def dispatch getRegEx(BitField i) '''«FOR idx : i.startIndex.value.intValue .. i.endIndex.value.intValue».«ENDFOR»'''
def dispatch getRegEx(BitValue i) '''«i.value.toString(2)»'''
def dispatch asString(BitField i) '''«i.name»[«i.startIndex.value.intValue»:«i.endIndex.value.intValue»]'''
def dispatch asString(BitValue i) {
(i.value as BigIntegerWithRadix).toCString(2)
}
}