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

107 lines
3.8 KiB
Plaintext

/*
* generated by Xtext 2.13.0
*/
package com.minres.coredsl.json
import com.google.inject.Inject
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.AttributeName
import com.minres.coredsl.coreDsl.ISA
import org.json.JSONObject
import org.json.JSONArray
import com.minres.coredsl.util.BigIntegerWithRadix
/**
* 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)
}
}
def Boolean isHls(Instruction inst){
val instrSet = inst.eContainer as ISA;
!(inst.attributes.filter[it.type==AttributeName.HLS].isEmpty &&
instrSet.attributes.filter[it.type==AttributeName.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.disass!= null? inst.name.toLowerCase + ' ' + inst.disass.toLowerCase : inst.name)
ret.put('execution', inst.behavior.toString)
ret.put('restrictions', '')
}
def Iterable<Instruction> allInstr(CoreDef core) {
val unique = newLinkedHashMap
val instrList = if (core.contributingType.size == 0)
core.instructions
else {
val instrSets = core.contributingType?.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.right.value.intValue .. i.left.value.intValue».«ENDFOR»'''
def dispatch getRegEx(BitValue i) '''«i.value.toString(2)»'''
def dispatch asString(BitField i) '''«i.name»[«i.left.value.intValue»:«i.right.value.intValue»]'''
def dispatch asString(BitValue i) {
(i.value as BigIntegerWithRadix).toCString(2)
}
}