From e5a67d305325d08d8ae7164dbfc069dd8fc04300 Mon Sep 17 00:00:00 2001 From: Mario Welzig Date: Fri, 24 Sep 2021 13:36:31 +0200 Subject: [PATCH 01/14] Add graph visualizer (#7) --- .../inputs/sqrt.core_desc | 2 +- .../services/visualization/GraphBuilder.java | 14 + .../services/visualization/VisualElement.java | 134 +++++ .../services/visualization/VisualGraph.java | 18 + .../services/visualization/Visualizer.xtend | 529 ++++++++++++++++++ .../visualization/VisualizerMain.xtend | 79 +++ .../visualization/dot/DotBuilder.java | 191 +++++++ 7 files changed, 966 insertions(+), 1 deletion(-) create mode 100644 com.minres.coredsl/src/com/minres/coredsl/services/visualization/GraphBuilder.java create mode 100644 com.minres.coredsl/src/com/minres/coredsl/services/visualization/VisualElement.java create mode 100644 com.minres.coredsl/src/com/minres/coredsl/services/visualization/VisualGraph.java create mode 100644 com.minres.coredsl/src/com/minres/coredsl/services/visualization/Visualizer.xtend create mode 100644 com.minres.coredsl/src/com/minres/coredsl/services/visualization/VisualizerMain.xtend create mode 100644 com.minres.coredsl/src/com/minres/coredsl/services/visualization/dot/DotBuilder.java diff --git a/com.minres.coredsl.tests/inputs/sqrt.core_desc b/com.minres.coredsl.tests/inputs/sqrt.core_desc index 3752cc4f..d8c075c9 100644 --- a/com.minres.coredsl.tests/inputs/sqrt.core_desc +++ b/com.minres.coredsl.tests/inputs/sqrt.core_desc @@ -9,7 +9,7 @@ InstructionSet Vec2D { } ISAXRegFile[32]; struct simd{ unsigned a1; - unsigned a1; + unsigned a2; unsigned a3; unsigned a4; }; diff --git a/com.minres.coredsl/src/com/minres/coredsl/services/visualization/GraphBuilder.java b/com.minres.coredsl/src/com/minres/coredsl/services/visualization/GraphBuilder.java new file mode 100644 index 00000000..b911a4af --- /dev/null +++ b/com.minres.coredsl/src/com/minres/coredsl/services/visualization/GraphBuilder.java @@ -0,0 +1,14 @@ +package com.minres.coredsl.services.visualization; + +import java.io.PrintWriter; + +public interface GraphBuilder { + /** + * Exports a {@link VisualGraph}. + * + * @param graph The {@link VisualGraph} to be exported + * @param out A {@link PrintWriter} to write the output to + * @param decorate Whether to print references (requires the graph to be generated with decorate = true as well) + */ + void buildGraph(VisualGraph graph, PrintWriter out, boolean decorate); +} diff --git a/com.minres.coredsl/src/com/minres/coredsl/services/visualization/VisualElement.java b/com.minres.coredsl/src/com/minres/coredsl/services/visualization/VisualElement.java new file mode 100644 index 00000000..57eef8d2 --- /dev/null +++ b/com.minres.coredsl/src/com/minres/coredsl/services/visualization/VisualElement.java @@ -0,0 +1,134 @@ +package com.minres.coredsl.services.visualization; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +import org.eclipse.emf.ecore.EObject; + + +/** + * - VisualElement
+ * . - VisualNode
+ * . . - SimpleNode (contains VisualNode output)
+ * . . - PortNode (contains List<NodeElement> children)
+ * . - Literal (leaf node)
+ * . . - DeclarationLiteral (potential target of a back edge)
+ * . . - ReferenceLiteral (source of a back edge)
+ * . - NodeElement
+ * . . - Port (contains VisualNode output)
+ * . . - PortGroup (contains List<NodeElement> children)
+ */ +public abstract class VisualElement { + public final String label; + + protected VisualElement(String label) { + this.label = label; + } + + /** A visual node (derived by {@link SimpleNode}, {@link PortNode} and {@link Literal}) **/ + public static abstract class VisualNode extends VisualElement { + protected VisualNode(String label) { super(label); } + + public abstract VisualNodeType type(); + } + + /** A simple node with at most one output **/ + public static final class SimpleNode extends VisualNode { + public final VisualNode output; + + public SimpleNode(String label, VisualNode output) { + super(label); + this.output = output; + } + + @Override public VisualNodeType type() { + return VisualNodeType.simple; + } + } + + /** A node with multiple labeled outputs **/ + public static final class PortNode extends VisualNode { + public final List children; + + public PortNode(String label) { this(label, new ArrayList<>()); } + + public PortNode(String label, List children) { + super(label); + this.children = children; + } + + @Override public VisualNodeType type() { + return VisualNodeType.port; + } + } + + /** An element that may be part of a {@link PortNode} (derived by {@link Port} and {@link PortGroup}) **/ + public static abstract class NodeElement extends VisualElement { + protected NodeElement(String label) { + super(label); + } + } + + /** Exit port of a {@link PortNode} **/ + public static final class Port extends NodeElement { + public final VisualNode output; + + public Port(String label, VisualNode output) { + super(label); + this.output = output; + } + } + + /** A group of {@link NodeElement}s, used to group multiple ports within a {@link PortNode} **/ + public static final class PortGroup extends NodeElement { + public final List children; + + public PortGroup(String label, List children) { + super(label); + this.children = children; + } + } + + /** A literal (leaf) node with no outgoing edges **/ + public static class Literal extends VisualNode { + public Literal(String label) { + super(label); + } + + @Override public VisualNodeType type() { + return VisualNodeType.literal; + } + } + + /** A literal node that can be referred to by a {@link ReferenceLiteral} **/ + public static final class DeclarationLiteral extends Literal { + public DeclarationLiteral(String label) { + super(label); + } + + @Override public VisualNodeType type() { + return VisualNodeType.declaration; + } + } + + /** A literal node with a reference to a {@link DeclarationLiteral} (used in decorated ASTs) **/ + public static final class ReferenceLiteral extends Literal { + public final Supplier resolver; + public DeclarationLiteral declaration; + + public ReferenceLiteral(String label, Supplier resolver) { + super(label); + this.resolver = resolver; + } + + @Override public VisualNodeType type() { + return VisualNodeType.reference; + } + } + + /** Enumeration of different node types, so I can use a switch instead of chained if instanceof checks **/ + public enum VisualNodeType { + simple, port, literal, declaration, reference + } +} diff --git a/com.minres.coredsl/src/com/minres/coredsl/services/visualization/VisualGraph.java b/com.minres.coredsl/src/com/minres/coredsl/services/visualization/VisualGraph.java new file mode 100644 index 00000000..7b8000fb --- /dev/null +++ b/com.minres.coredsl/src/com/minres/coredsl/services/visualization/VisualGraph.java @@ -0,0 +1,18 @@ +package com.minres.coredsl.services.visualization; + +import java.util.List; +import java.util.Map; + +import org.eclipse.emf.ecore.EObject; + +public class VisualGraph { + public final VisualElement.VisualNode rootNode; + public final List visualNodes; + public final Map astToVisual; + + public VisualGraph(VisualElement.VisualNode root, List visualNodes, Map astToVisual) { + this.rootNode = root; + this.visualNodes = visualNodes; + this.astToVisual = astToVisual; + } +} diff --git a/com.minres.coredsl/src/com/minres/coredsl/services/visualization/Visualizer.xtend b/com.minres.coredsl/src/com/minres/coredsl/services/visualization/Visualizer.xtend new file mode 100644 index 00000000..3bb102b9 --- /dev/null +++ b/com.minres.coredsl/src/com/minres/coredsl/services/visualization/Visualizer.xtend @@ -0,0 +1,529 @@ +package com.minres.coredsl.services.visualization + +import com.minres.coredsl.coreDsl.Assignment +import com.minres.coredsl.coreDsl.AssignmentExpression +import com.minres.coredsl.coreDsl.Attribute +import com.minres.coredsl.coreDsl.BitField +import com.minres.coredsl.coreDsl.BitValue +import com.minres.coredsl.coreDsl.BoolConstant +import com.minres.coredsl.coreDsl.CompositeType +import com.minres.coredsl.coreDsl.CompoundStatement +import com.minres.coredsl.coreDsl.CoreDef +import com.minres.coredsl.coreDsl.Declaration +import com.minres.coredsl.coreDsl.DescriptionContent +import com.minres.coredsl.coreDsl.DesignatedInitializer +import com.minres.coredsl.coreDsl.Designator +import com.minres.coredsl.coreDsl.DirectDeclarator +import com.minres.coredsl.coreDsl.Encoding +import com.minres.coredsl.coreDsl.Expression +import com.minres.coredsl.coreDsl.ExpressionStatement +import com.minres.coredsl.coreDsl.FloatingConstant +import com.minres.coredsl.coreDsl.FunctionDefinition +import com.minres.coredsl.coreDsl.IfStatement +import com.minres.coredsl.coreDsl.Import +import com.minres.coredsl.coreDsl.InfixExpression +import com.minres.coredsl.coreDsl.InitDeclarator +import com.minres.coredsl.coreDsl.Initializer +import com.minres.coredsl.coreDsl.Instruction +import com.minres.coredsl.coreDsl.InstructionSet +import com.minres.coredsl.coreDsl.IntegerConstant +import com.minres.coredsl.coreDsl.IterationStatement +import com.minres.coredsl.coreDsl.JumpStatement +import com.minres.coredsl.coreDsl.LabeledStatement +import com.minres.coredsl.coreDsl.ParameterDeclaration +import com.minres.coredsl.coreDsl.ParameterList +import com.minres.coredsl.coreDsl.Postfix +import com.minres.coredsl.coreDsl.PostfixExpression +import com.minres.coredsl.coreDsl.PrefixExpression +import com.minres.coredsl.coreDsl.PrimaryExpression +import com.minres.coredsl.coreDsl.PrimitiveType +import com.minres.coredsl.coreDsl.SpawnStatement +import com.minres.coredsl.coreDsl.StringLiteral +import com.minres.coredsl.coreDsl.StructDeclaration +import com.minres.coredsl.coreDsl.StructDeclarationSpecifier +import com.minres.coredsl.coreDsl.StructOrUnion +import com.minres.coredsl.coreDsl.SwitchStatement +import com.minres.coredsl.services.visualization.VisualElement.DeclarationLiteral +import com.minres.coredsl.services.visualization.VisualElement.Literal +import com.minres.coredsl.services.visualization.VisualElement.NodeElement +import com.minres.coredsl.services.visualization.VisualElement.Port +import com.minres.coredsl.services.visualization.VisualElement.PortGroup +import com.minres.coredsl.services.visualization.VisualElement.PortNode +import com.minres.coredsl.services.visualization.VisualElement.ReferenceLiteral +import com.minres.coredsl.services.visualization.VisualElement.VisualNode +import java.util.ArrayList +import java.util.IdentityHashMap +import java.util.List +import java.util.Map +import java.util.function.Supplier +import org.eclipse.emf.ecore.EObject + +class Visualizer { + + List visualNodes; + Map astToVisual; + Map declarationLiterals; + + synchronized def VisualGraph buildVisualGraph(EObject rootNode, boolean decorate) { + visualNodes = new ArrayList(); + astToVisual = new IdentityHashMap(); + declarationLiterals = new IdentityHashMap(); + var VisualNode root = visit(rootNode); + if(decorate) decorate(); + var VisualGraph graph = new VisualGraph(root, visualNodes, astToVisual); + visualNodes = null; + astToVisual = null; + declarationLiterals = null; + return graph; + } + + private def void decorate() { + for(VisualNode visual : visualNodes) { + if(visual instanceof ReferenceLiteral) { + var ReferenceLiteral reference = visual as ReferenceLiteral; + // only resolve references in decorate() to avoid errors if executed before context analysis + var EObject targetNode = reference.resolver.get(); + reference.declaration = declarationLiterals.get(targetNode); + } + } + } + + private def VisualNode visit(EObject node) { + return genNode(node); + } + + /* ****************** + * Helper functions * + ****************** */ + + private def void registerNode(VisualNode visual, EObject ast) { + visualNodes.add(visual); + if(ast !== null) astToVisual.put(ast, visual); + } + + private def VisualNode makeNode(EObject astNode, String label, NodeElement... children) { + if(astNode === null) return null; + var list = new ArrayList(children.length); + for (child : children) { + if(child !== null) + list.add(child); + } + var VisualNode node = new PortNode(label, list); + registerNode(node, astNode); + return node; + } + + private def VisualNode makeNode(EObject astNode, String label, List children) { + if(astNode === null) return null; + var List elements = new ArrayList(children.size()); + for(var int i = 0; i < children.size(); i++) { + var child = children.get(i); + if(child !== null) + elements.add(makeChild(Integer.toString(i + 1), child)); + } + var node = new PortNode(label, elements); + registerNode(node, astNode); + return node; + } + + private def VisualNode makeImmediateLiteral(String content) { + var Literal literal = new Literal(content); + registerNode(literal, null); + return literal; + } + + private def NodeElement makeNamedLiteral(String label, String content) { + if(content === null) return null; + var Literal literal = new Literal(content); + registerNode(literal, null); + return new Port(label, literal); + } + + private def NodeElement makeDeclaration(String label, String content, EObject owner) { + if(content === null) return null; + var DeclarationLiteral literal = new DeclarationLiteral(content); + registerNode(literal, null); + declarationLiterals.put(owner, literal); + return new Port(label, literal); + } + + private def NodeElement makeReference(String label, String content, Supplier referenceResolver) { + if(content === null) return null; + var ReferenceLiteral literal = new ReferenceLiteral(content, referenceResolver); + registerNode(literal, null); + return new Port(label, literal); + } + + private def NodeElement makeChild(String label, EObject node) { + if(node === null) return null; + return new Port(label, visit(node)); + } + + private def NodeElement makeGroup(String label, List children) { + if(children === null || children.size == 0) return null; + var List elements = new ArrayList(children.size()); + for(var int i = 0; i < children.size(); i++) { + var child = children.get(i); + if(child !== null) + elements.add(makeChild(Integer.toString(i + 1), child)); + } + return new PortGroup(label, elements); + } + + private def NodeElement makePortGroup(String label, List children) { + if(children === null || children.size == 0) return null; + var List elements = new ArrayList(children.size()); + for(var int i = 0; i < children.size(); i++) { + var child = children.get(i); + if(child !== null) + elements.add(new Port(Integer.toString(i + 1), child)); + } + return new PortGroup(label, elements); + } + + /* ***************** + * Visitor methods * + ***************** */ + + private def dispatch VisualNode genNode(EObject node) { + throw new RuntimeException("generator for type " + node.getClass().getSimpleName() + " not implemented"); + } + + // module + + private def dispatch VisualNode genNode(DescriptionContent node) { + return makeNode(node, "Core Description", + makeGroup("Imports", node.imports), + makeGroup("Definitions", node.definitions) + ) + } + + private def dispatch VisualNode genNode(Import node) { + return makeNode(node, "Import", + makeNamedLiteral("URI", node.importURI) + ); + } + + private def dispatch VisualNode genNode(InstructionSet node) { + return makeNode(node, "Instruction Set", + makeNamedLiteral("Name", node.name), + makeNamedLiteral("Super Type", node.superType?.name), + makeGroup("Declarations", node.declarations), + makeGroup("Functions", node.functions), + makeGroup("Attributes", node.attributes), + makeGroup("Instructions", node.instructions) + ); + } + + private def dispatch VisualNode genNode(CoreDef node) { + return makeNode(node, "Instruction Set", + makeNamedLiteral("Name", node.name), + makeGroup("Contributing Type", node.contributingType), + makeGroup("Declarations", node.declarations), + makeGroup("Functions", node.functions), + makeGroup("Attributes", node.attributes), + makeGroup("Instructions", node.instructions) + ) + } + + private def dispatch VisualNode genNode(Instruction node) { + return makeNode(node, "Instruction", + makeNamedLiteral("Name", node.name), + makeChild("Encoding", node.encoding), + makeNamedLiteral("Disassembly Format", node.disass), + makeChild("Behavior", node.behavior) + ); + } + + private def dispatch VisualNode genNode(Encoding node) { + return makeNode(node, "Encoding", node.fields); + } + + private def dispatch VisualNode genNode(BitField node) { + return makeNode(node, "Bit Field", + makeNamedLiteral("Name", node.name), + makeChild("Left", node.left), + makeChild("Right", node.right) + ) + } + + private def dispatch VisualNode genNode(BitValue node) { + return makeNode(node, "Bit Value", + makeNamedLiteral("Value", node.value.toString) + ) + } + + private def dispatch VisualNode genNode(FunctionDefinition node) { + return node.extern + ? makeNode(node, "Function (extern)", + makeChild("Return Type", node.type), + makeNamedLiteral("Name", node.name), + makeGroup("Parameters", node.params) + ) + : makeNode(node, "Function", + makeChild("Return Type", node.type), + makeNamedLiteral("Name", node.name), + makeGroup("Parameters", node.params), + makeChild("Body", node.statement) + ); + } + + private def dispatch VisualNode genNode(ParameterList node) { + return makeNode(node, "Parameter List", node.params); + } + + private def dispatch VisualNode genNode(ParameterDeclaration node) { + return makeNode(node, "Parameter", + makeChild("Type", node.type), + makeChild("Declarator", node.declarator) + ); + } + + // statements + + private def dispatch VisualNode genNode(LabeledStatement node) { + return makeNode(node, node.constExpr !== null ? "Case" : "Default", node.items); + } + + private def dispatch VisualNode genNode(CompoundStatement node) { + return makeNode(node, "Compound Statement", node.items); + } + + private def dispatch VisualNode genNode(ExpressionStatement node) { + return makeNode(node, "Expression Statement", + makeChild("Expression", node.expr) + ); + } + + private def dispatch VisualNode genNode(IfStatement node) { + return makeNode(node, "If Statement", + makeChild("Condition", node.cond), + makeChild("Then Branch", node.thenStmt), + makeChild("Else Branch", node.elseStmt) + ); + } + + private def dispatch VisualNode genNode(SwitchStatement node) { + return makeNode(node, "Switch Statement", + makeChild("Condition", node.cond), + makeGroup("Branches", node.items) + ); + } + + private def dispatch VisualNode genNode(IterationStatement node) { + return makeNode(node, "Loop (" + node.type + ")", + makeChild("Condition", node.cond), + makeChild("Start Declaration", node.startDecl), + makeChild("Start Assignment", node.startExpr), + makeChild("Condition", node.endExpr), + makeGroup("Loop Assignments", node.loopExprs), + makeChild("Body", node.stmt) + ); + } + + private def dispatch VisualNode genNode(JumpStatement node) { + return makeNode(node, "Jump (" + node.type + ")", + makeChild("Return Value", node.expr) + ); + } + + private def dispatch VisualNode genNode(SpawnStatement node) { + return makeNode(node, "Spawn Statement", + makeChild("Body", node.stmt) + ); + } + + // declarations + + private def dispatch VisualNode genNode(Declaration node) { + return makeNode(node, "Declaration", + makePortGroup("Storage", node.storage.map[specifier | makeImmediateLiteral(specifier.toString)]), + makePortGroup("Qualifiers", node.qualifiers.map[qualifier | makeImmediateLiteral(qualifier.toString)]), + makeGroup("Attributes", node.attributes), + makeChild("Type", node.type), + makeNamedLiteral("Ptr", node.ptr), + makeGroup("Declarators", node.init) + ); + } + + private def dispatch VisualNode genNode(Attribute node) { + return makeNode(node, "Attribute", + makeNamedLiteral("Type", node.type.toString), + makeChild("Value", node.value) + ); + } + + private def dispatch VisualNode genNode(PrimitiveType node) { + return node.dataType.size == 1 + ? makeNode(node, "Primitive Type", + makeNamedLiteral("Data Type", node.dataType.get(0).toString), + makeGroup("Bit Size", node.size) + ) + : makeNode(node, "Primitive Type", + makePortGroup("Data Type", node.dataType.map[type | makeImmediateLiteral(type.toString)]), + makeGroup("Bit Size", node.size) + ); + } + + private def dispatch VisualNode genNode(CompositeType node) { + return makeNode(node, node.composeType == StructOrUnion.STRUCT ? "Struct Type" : "Union Type", + makeNamedLiteral("Name", node.name), + makeGroup("Declarations", node.declaration) + ) + } + + private def dispatch VisualNode genNode(StructDeclaration node) { + return makeNode(node, "Struct Declaration", + makeChild("Specifier", node.specifier), + makeGroup("Declarators", node.declarator) + ) + } + + private def dispatch VisualNode genNode(StructDeclarationSpecifier node) { + return makeNode(node, "Struct Declaration Specifier", + makeChild("Type", node.type), + makePortGroup("Qualifiers", node.qualifiers.map[qualifier | makeImmediateLiteral(qualifier.toString)]) + ) + } + + private def dispatch VisualNode genNode(InitDeclarator node) { + return makeNode(node, "Init Declarator", + makeChild("Declarator", node.declarator), + makeGroup("Attributes", node.attributes), + makeChild("Initializer", node.initializer) + ) + } + + private def dispatch VisualNode genNode(DirectDeclarator node) { + return makeNode(node, "Direct Declarator", + makeDeclaration("Name", node.name, node), + makeChild("Index", node.index), + makeGroup("Size", node.size), + makeGroup("Parameters", node.params) + ); + } + + private def dispatch VisualNode genNode(Initializer node) { + return node.expr !== null + ? visit(node.expr) + : makeNode(node, "Initializer", node.init); + } + + private def dispatch VisualNode genNode(DesignatedInitializer node) { + return makeNode(node, "Designated Initializer", + makeGroup("Designators", node.designators), + makeChild("Initializer", node.init) + ); + } + + private def dispatch VisualNode genNode(Designator node) { + return makeNode(node, "Designator", + makeChild("Index", node.idx), + makeNamedLiteral("Property", node.prop) + ); + } + + // expressions + + private def dispatch VisualNode genNode(IntegerConstant node) { + return makeImmediateLiteral(node.value.toString) + /*return makeNode(node, "Integer", + makeNamedLiteral("Value", node.value.toString) + );*/ + } + + private def dispatch VisualNode genNode(FloatingConstant node) { + return makeImmediateLiteral(node.value.toString) + /*return makeNode(node, "Float", + makeNamedLiteral("Value", node.value.toString) + );*/ + } + + private def dispatch VisualNode genNode(BoolConstant node) { + return makeImmediateLiteral(node.value.toString) + /*return makeNode(node, "Bool", + makeNamedLiteral("Value", node.value.toString) + );*/ + } + + private def dispatch VisualNode genNode(StringLiteral node) { + return makeImmediateLiteral(node.value) + } + + private def dispatch VisualNode genNode(InfixExpression node) { + return makeNode(node, "Infix Expression (" + node.op + ")", + makeChild("Left", node.left), + makeChild("Right", node.right) + ); + } + + private def dispatch VisualNode genNode(PrefixExpression node) { + return makeNode(node, "Prefix Expression (" + node.op + ")", + makeChild("Operand", node.left) + ); + } + + private def dispatch VisualNode genNode(PostfixExpression node) { + return makeNode(node, "Postfix Expression", + makeChild("Operand", node.left), + makeChild("Operator", node.postOp) + ); + } + + private def dispatch VisualNode genNode(Postfix node) { + return switch node.op { + case "(": + makeNode(node, "Method Invocation", node.args) + case "[": + makeNode(node, "Indexer", node.args) + case ".", + case "->": + makeNode(node, "Member Access (" + node.op + ")", + makeReference("Member", node.declarator?.name, [node.declarator]) + ) + case "++", + case "--": + makeNode(node, "Postfix Operator (" + node.op + ")") + } + } + + private def dispatch VisualNode genNode(PrimaryExpression node) { + if(node.left !== null) + return visit(node.left); + + if(node.ref instanceof FunctionDefinition) + return makeNode(node, "Function Reference", makeReference("Function", (node.ref as FunctionDefinition).name, [node.ref])); + + if(node.ref instanceof DirectDeclarator) + return makeNode(node, "Declarator Reference", makeReference("Declarator", (node.ref as DirectDeclarator).name, [node.ref])); + + if(node.ref instanceof BitField) + return makeNode(node, "Field Reference", makeReference("Field", (node.ref as BitField).name, [node.ref])); + + if(node.constant !== null) + return visit(node.constant); + + if(node.literal.size == 1) + return visit(node.literal.get(0)); + + return makeNode(node, "Compound String Literal", + makeGroup("Literals", node.literal) + ); + } + + private def dispatch VisualNode genNode(Expression node) { + if(node.expressions.size != 1) + throw new RuntimeException("Expected exactly one expression"); + return visit(node.expressions.get(0)); + } + + private def dispatch VisualNode genNode(AssignmentExpression node) { + return makeNode(node, "Assignment Expression", node.assignments); + } + + private def dispatch VisualNode genNode(Assignment node) { + return makeNode(node, "Assignment (" + node.type + ")", + makeChild("Value", node.right) + ); + } +} diff --git a/com.minres.coredsl/src/com/minres/coredsl/services/visualization/VisualizerMain.xtend b/com.minres.coredsl/src/com/minres/coredsl/services/visualization/VisualizerMain.xtend new file mode 100644 index 00000000..313867e4 --- /dev/null +++ b/com.minres.coredsl/src/com/minres/coredsl/services/visualization/VisualizerMain.xtend @@ -0,0 +1,79 @@ +package com.minres.coredsl.services.visualization; + +import com.google.inject.Inject +import com.google.inject.Provider +import com.minres.coredsl.CoreDslStandaloneSetup +import org.eclipse.emf.common.util.URI +import org.eclipse.emf.ecore.resource.ResourceSet +import org.eclipse.xtext.generator.JavaIoFileSystemAccess +import org.eclipse.xtext.util.CancelIndicator +import org.eclipse.xtext.validation.CheckMode +import org.eclipse.xtext.validation.IResourceValidator +import java.nio.file.Paths +import java.io.ByteArrayOutputStream +import java.io.PrintWriter +import com.minres.coredsl.services.visualization.dot.DotBuilder + +class VisualizerMain { + def static main(String[] args) { + val injector = new CoreDslStandaloneSetup().createInjectorAndDoEMFRegistration() + val main = injector.getInstance(VisualizerMain) + main.run(args) + } + + @Inject Provider resourceSetProvider + + @Inject IResourceValidator validator + + @Inject JavaIoFileSystemAccess fileAccess + + def private static String changeExtension(String path, String ext) { + val full = Paths.get(path) + var name = full.fileName.toString() + val pos = name.lastIndexOf(".") + if (pos > 0) { + name = name.substring(0, pos) + } + if (ext !== null && ext.length > 0) { + val char period = '.' + if (ext.charAt(0) == period) { + name += ext + } else { + name += '.' + ext + } + } + return full.resolveSibling(name).toString(); + } + + def protected run(String[] args) { + if (args.length < 1 || args.length > 2) { + System.err.println("Usage: visualizer in-path [out-path]") + return; + } + + val inPath = args.get(0) + val outPath = Paths.get(args.length > 1 ? args.get(1) : changeExtension(inPath, ".dot")) + + val set = resourceSetProvider.get() + val resource = set.getResource(URI.createFileURI(inPath), true) + + val issues = validator.validate(resource, CheckMode.ALL, CancelIndicator.NullImpl) + if (!issues.empty) { + issues.forEach[System.err.println(it)] + return + } + + if (resource.contents.size != 1) + throw new RuntimeException("Expected exactly one root node") + + val out = new ByteArrayOutputStream() + val VisualGraph graph = new Visualizer().buildVisualGraph(resource.contents.get(0), true) + new DotBuilder().buildGraph(graph, new PrintWriter(out), true) + val dotCode = out.toString() + + fileAccess.outputPath = outPath.parent.toString() + fileAccess.generateFile(outPath.fileName.toString(), dotCode); + + println("Done.") + } +} diff --git a/com.minres.coredsl/src/com/minres/coredsl/services/visualization/dot/DotBuilder.java b/com.minres.coredsl/src/com/minres/coredsl/services/visualization/dot/DotBuilder.java new file mode 100644 index 00000000..3148aa11 --- /dev/null +++ b/com.minres.coredsl/src/com/minres/coredsl/services/visualization/dot/DotBuilder.java @@ -0,0 +1,191 @@ +package com.minres.coredsl.services.visualization.dot; + +import com.minres.coredsl.services.visualization.GraphBuilder; +import com.minres.coredsl.services.visualization.VisualElement.*; +import com.minres.coredsl.services.visualization.VisualGraph; + +import java.io.PrintWriter; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class DotBuilder implements GraphBuilder { + + private static final String dotPrologue = "digraph {\n" + + "node [shape=Mrecord, style=filled, fillcolor=white, fontname=\"Calibri\"];\n" + + "graph [ordering=out, nodesep=0.3, ranksep=1];\n\n"; + private static final String dotEpilogue = "}\n"; + + /** {0} -> node name, {1} -> label **/ + private static final String simpleNodeFormat = "%s [label=\"%s\", tooltip=\"%s\"]\n"; + + /** {0} -> node name, {1} -> label, {2} -> port list **/ + private static final String portNodeFormat = "%s [label=\"{%s|{%s}}\", tooltip=\"%s\"]\n"; + + /** {0} -> node name, {1} -> label, {2} -> fill color **/ + private static final String literalNodeFormat = "%s [shape=box, label=\"%s\", fillcolor=\"%s\", tooltip=\"%s\"]\n"; + + /** {0} -> source node, {1} -> target **/ + private static final String simpleEdgeFormat = "%s:s -> %s:n"; + + /** {0} -> source node, {1} -> source port, {2} -> target **/ + private static final String portEdgeFormat = "%s:%s:s -> %s:n"; + + /** {0} -> source, {1} -> target **/ + private static final String backEdgeFormat = "%s -> %s [style=dashed, constraint=false, color=\"%s\"]"; + + @Override public void buildGraph(VisualGraph graph, PrintWriter out, boolean decorate) { + Map nodeNames = new HashMap<>(); + Map nodeColors = new HashMap<>(); + + for(VisualNode node : graph.visualNodes) { + nodeNames.put(node, "node" + nodeNames.size()); + } + + out.print(dotPrologue); + for(VisualNode node : graph.visualNodes) { + buildNode(node, out, decorate, nodeNames, nodeColors); + } + out.print(dotEpilogue); + out.flush(); + } + + private void buildNode(VisualNode node, PrintWriter out, boolean decorate, Map nodeNames, Map nodeColors) { + out.println("# " + node.getClass().getSimpleName() + " " + node.label); + String name = nodeNames.get(node); + String label = node.label + .replace("\"", "\\\"") + .replace("<", "<") + .replace(">", ">"); + + // generate edges and port list + StringBuilder sb = new StringBuilder(); + boolean first = true; + + switch(node.type()) { + case simple: + VisualNode output = ((SimpleNode) node).output; + if(output != null) { + // add regular edge if the node's output is not null + String targetName = nodeNames.get(output); + out.println(String.format(simpleEdgeFormat, name, targetName)); + } + out.println(String.format(simpleNodeFormat, name, label, label)); + break; + + case port: + List elements = ((PortNode) node).children; + for(int i = 0; i < elements.size(); i++) { + NodeElement child = elements.get(i); + if(!first) sb.append('|'); + sb.append(buildNodeElement(child, name, "p" + i, out, nodeNames)); + first = false; + } + out.println(String.format(portNodeFormat, name, label, sb.toString(), label)); + break; + + case reference: + if(decorate) { + ReferenceLiteral reference = (ReferenceLiteral) node; + DeclarationLiteral declaration = reference.declaration; + // declaration might be null (e.g. for runtime functions) + if(declaration != null) { + ColorPair color = nodeColors.get(declaration); + if(color == null) { + color = getColor(); + nodeColors.put(declaration, color); + } + // add back edge + String target = nodeNames.get(declaration); + out.println(String.format(backEdgeFormat, name, target, color.strokeColor)); + out.println(String.format(literalNodeFormat, name, label, color.fillColor, label)); + break; + } + } + out.println(String.format(literalNodeFormat, name, label, "#cccccc", label)); + break; + + case declaration: + if(decorate) { + DeclarationLiteral declaration = (DeclarationLiteral) node; + ColorPair color = nodeColors.get(declaration); + if(color == null) { + color = getColor(); + nodeColors.put(declaration, color); + } + out.println(String.format(literalNodeFormat, name, label, color.fillColor, label)); + break; + } + out.println(String.format(literalNodeFormat, name, label, "#cccccc", label)); + break; + + case literal: + out.println(String.format(literalNodeFormat, name, label, "#cccccc", label)); + break; + } + } + + private String buildNodeElement(NodeElement element, String node, String port, PrintWriter out, Map nodeNames) { + if(element instanceof Port) { + VisualNode child = ((Port) element).output; + assert child != null; + + // get name of the target node + String targetName = nodeNames.get(child); + assert targetName != null; + + // add regular edge + out.println(String.format(portEdgeFormat, node, port, targetName)); + return "<" + port + ">" + element.label; + } + + if(element instanceof PortGroup) { + int id = 0; + StringBuilder sb = new StringBuilder("{").append(element.label).append("|{"); + for(NodeElement child : ((PortGroup) element).children) { + assert child instanceof Port || child instanceof PortGroup; + if(id > 0) sb.append('|'); + String subPort = port + "_" + id++; + sb.append(buildNodeElement(child, node, subPort, out, nodeNames)); + } + return sb.append("}}").toString(); + } + + assert false; + return null; + } + + // colorStep and colors.size() must be coprime (no common factors)! + // otherwise not all colors will be used. + private static final int colorStep = 5; + private static final List colors = Arrays.asList( + new ColorPair("#FFC6C6", "#FF0000"), + new ColorPair("#FFE0C6", "#FF7400"), + new ColorPair("#FFECC6", "#FFAA00"), + new ColorPair("#FFF5C6", "#C5A300"), + new ColorPair("#FFFFC6", "#C5C500"), + new ColorPair("#EAFDC5", "#7BB800"), + new ColorPair("#C2FAC2", "#00CC00"), + new ColorPair("#BEF5F5", "#009999"), + new ColorPair("#C6D4F7", "#1240AB"), + new ColorPair("#D2C6F7", "#3914AF"), + new ColorPair("#E4C3F7", "#7109AA"), + new ColorPair("#FAC2E2", "#CD0074")); + + private int colorCount; + + private ColorPair getColor() { + return colors.get(colorStep * colorCount++ % colors.size()); + } + + private static class ColorPair { + public final String fillColor; + public final String strokeColor; + + public ColorPair(String fillColor, String strokeColor) { + this.fillColor = fillColor; + this.strokeColor = strokeColor; + } + } +} From dd310c3e92e359236b5355a7e606ca632e9b3f42 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sat, 25 Sep 2021 13:59:41 +0200 Subject: [PATCH 02/14] add hls attribute --- com.minres.coredsl.repository/pom.xml | 71 ++-- .../src/com/minres/coredsl/CoreDsl.xtext | 11 +- .../com/minres/coredsl/util/ModelUtil.xtend | 10 +- .../coredsl/validation/CoreDslValidator.xtend | 357 +++++++++--------- pom.xml | 10 + 5 files changed, 252 insertions(+), 207 deletions(-) diff --git a/com.minres.coredsl.repository/pom.xml b/com.minres.coredsl.repository/pom.xml index 715a6dfc..a5dc2341 100644 --- a/com.minres.coredsl.repository/pom.xml +++ b/com.minres.coredsl.repository/pom.xml @@ -1,3 +1,4 @@ + @@ -6,7 +7,7 @@ com.minres.coredsl com.minres.coredsl.parent 2.0.1-SNAPSHOT - .. + .. com.minres.coredsl.repository eclipse-repository @@ -37,7 +38,7 @@ - + @@ -46,6 +47,15 @@ + + + + + org.apache.maven.wagon + wagon-ftp + 1.0-beta-6 + + @@ -54,6 +64,14 @@ false + + + ftp://your.server.com + /yourpath + + ${project.build.directory}/repository/ + + @@ -69,43 +87,38 @@ - - com.carrotgarden.maven - bintray-maven-plugin - 1.5.20191113165555 - - false - - minres - - eclipse - - CoreDSL - ${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion} - https://github.com/Minres/CoreDSL.git - - ${project.build.directory}/repository - - CoreDSL/${parsedVersion.majorVersion}.${parsedVersion.minorVersion} - - - bintray-minres-deploy - + - package + upload-repo + install upload + + ${repo.path} + ** + ${ftp.toDir} + ${ftp.url} + p2Repo + Points to your settings.xml where the connection settings are stored as shown below + + p2Repo + username + password + + - + --> - - + + diff --git a/com.minres.coredsl/src/com/minres/coredsl/CoreDsl.xtext b/com.minres.coredsl/src/com/minres/coredsl/CoreDsl.xtext index 066b3ef4..16de20ce 100644 --- a/com.minres.coredsl/src/com/minres/coredsl/CoreDsl.xtext +++ b/com.minres.coredsl/src/com/minres/coredsl/CoreDsl.xtext @@ -395,7 +395,16 @@ enum TypeQualifier: CONST='const' | VOLATILE='volatile'; enum StorageClassSpecifier: EXTERN='extern' | STATIC='static' | REGISTER='register'; -enum AttributeName: NONE | IS_PC='is_pc' | IS_INTERLOCK_FOR='is_interlock_for' | DO_NOT_SYNTHESIZE="do_not_synthesize" | ENABLE="enable" | NO_CONT='no_cont' | COND='cond' | FLUSH='flush'; +enum AttributeName: NONE + | IS_PC='is_pc' + | IS_INTERLOCK_FOR='is_interlock_for' + | DO_NOT_SYNTHESIZE="do_not_synthesize" + | ENABLE="enable" + | NO_CONT='no_cont' + | COND='cond' + | FLUSH='flush' + | HLS='hls' +; enum StructOrUnion: STRUCT='struct'|UNION='union'; diff --git a/com.minres.coredsl/src/com/minres/coredsl/util/ModelUtil.xtend b/com.minres.coredsl/src/com/minres/coredsl/util/ModelUtil.xtend index ed6c4f58..e1e0e92a 100644 --- a/com.minres.coredsl/src/com/minres/coredsl/util/ModelUtil.xtend +++ b/com.minres.coredsl/src/com/minres/coredsl/util/ModelUtil.xtend @@ -13,6 +13,7 @@ import java.util.List import com.minres.coredsl.coreDsl.Encoding import com.minres.coredsl.coreDsl.BitField import com.minres.coredsl.coreDsl.BitValue +import com.minres.coredsl.coreDsl.Statement class ModelUtil { @@ -22,6 +23,9 @@ class ModelUtil { isa.declarations.filter[it instanceof Declaration].map[it as Declaration] } + static def Iterable getStateStatements(ISA isa) { + isa.declarations.filter[it instanceof Statement].map[it as Statement] + } static def Iterable getStateConstDeclarations(ISA isa) { isa.declarations.filter[ @@ -67,7 +71,11 @@ class ModelUtil { static def DirectDeclarator effectiveDeclarator(ISA isa, String name){ if(isa instanceof CoreDef) { - val decl = isa.stateDeclarations.findFirst[it.init.findFirst[it.declarator.name==name && it.initializer!==null]!==null] + val decl = isa.stateDeclarations.findFirst[ + it.init.findFirst[ + it.declarator.name==name && it.initializer!==null + ]!==null + ] if(decl!==null) return decl.init.findFirst[it.declarator.name==name].declarator for(contrib:isa.contributingType.reverse) { diff --git a/com.minres.coredsl/src/com/minres/coredsl/validation/CoreDslValidator.xtend b/com.minres.coredsl/src/com/minres/coredsl/validation/CoreDslValidator.xtend index 2d397ea3..c827f291 100644 --- a/com.minres.coredsl/src/com/minres/coredsl/validation/CoreDslValidator.xtend +++ b/com.minres.coredsl/src/com/minres/coredsl/validation/CoreDslValidator.xtend @@ -30,189 +30,194 @@ import com.minres.coredsl.coreDsl.FunctionDefinition */ class CoreDslValidator extends AbstractCoreDslValidator { - /*TODO: - * * check for cycles in structs - * * check for member selection - * * check for return statements - * * check for duplicate fields - * - */ - protected static val ISSUE_CODE_PREFIX = "com.minres.coredsl." - public static val TYPE_MISMATCH = ISSUE_CODE_PREFIX + "TypeMismatch" - public static val TYPE_ILLEGAL = ISSUE_CODE_PREFIX + "TypeIllegal" - - //@Check - def checkType(Expression e) { - switch (e) { - case PrimaryExpression, - case PostfixExpression, - case PrefixExpression: - if (e.typeFor === null) - error( - "incompatible types used", - CoreDslPackage.Literals.EXPRESSION__EXPRESSIONS, - TYPE_MISMATCH - ) - case CastExpression: { - if ((e as CastExpression).type.typeFor === null) - error( - "illegal type used", - CoreDslPackage.Literals.CAST_EXPRESSION__TYPE, - TYPE_ILLEGAL - ) - } - case InfixExpression: { - val infix = e as InfixExpression - switch (infix.op) { - case '<', - case '>', - case '<=', - case '>=', - case '==', - case '!=': - if (!e.left.typeFor.isComparable((e as InfixExpression).right.typeFor)) - error( - "incompatible types used", - CoreDslPackage.Literals.EXPRESSION__EXPRESSIONS, - TYPE_MISMATCH - ) - case '||', - case '&&', - case '<<', - case '>>', - case '+', - case '-', - case '*', - case '/', - case '%', - case '|', - case '^', - case '&': - if (!e.left.typeFor.isComputable((e as InfixExpression).right.typeFor)) - error( - "incompatible types used", - CoreDslPackage.Literals.EXPRESSION__EXPRESSIONS, - TYPE_MISMATCH - ) - default: { - } // '::' - } - } + /*TODO: + * * check for cycles in structs + * * check for member selection + * * check for return statements + * * check for duplicate fields + * + */ + protected static val ISSUE_CODE_PREFIX = "com.minres.coredsl." + public static val TYPE_MISMATCH = ISSUE_CODE_PREFIX + "TypeMismatch" + public static val TYPE_ILLEGAL = ISSUE_CODE_PREFIX + "TypeIllegal" + + // @Check + def checkType(Expression e) { + switch (e) { + case PrimaryExpression, + case PostfixExpression, + case PrefixExpression: + if (e.typeFor === null) + error( + "incompatible types used", + CoreDslPackage.Literals.EXPRESSION__EXPRESSIONS, + TYPE_MISMATCH + ) + case CastExpression: { + if ((e as CastExpression).type.typeFor === null) + error( + "illegal type used", + CoreDslPackage.Literals.CAST_EXPRESSION__TYPE, + TYPE_ILLEGAL + ) + } + case InfixExpression: { + val infix = e as InfixExpression + switch (infix.op) { + case '<', + case '>', + case '<=', + case '>=', + case '==', + case '!=': + if (!e.left.typeFor.isComparable((e as InfixExpression).right.typeFor)) + error( + "incompatible types used", + CoreDslPackage.Literals.EXPRESSION__EXPRESSIONS, + TYPE_MISMATCH + ) + case '||', + case '&&', + case '<<', + case '>>', + case '+', + case '-', + case '*', + case '/', + case '%', + case '|', + case '^', + case '&': + if (!e.left.typeFor.isComputable((e as InfixExpression).right.typeFor)) + error( + "incompatible types used", + CoreDslPackage.Literals.EXPRESSION__EXPRESSIONS, + TYPE_MISMATCH + ) + default: { + } // '::' + } + } // case ConditionalExpression: { // } // case AssignmentExpression: { // } - } - } + } + } - //@Check - def checkType(TypeSpecifier e) { - switch (e) { + // @Check + def checkType(TypeSpecifier e) { + switch (e) { // case CompositeType: { // } // case EnumType: { // } - case PrimitiveType: { - if (e.typeFor === new DataType(DataType.Type.COMPOSITE, 0)) - error( - "incompatible types used", - CoreDslPackage.Literals.PRIMITIVE_TYPE__DATA_TYPE, - TYPE_MISMATCH - ) - } - } - } - @Check - def checkAttributeNames(ISA isa) { - for(Attribute a: isa.attributes) { - switch(a.type) { - case ENABLE: if(a.value===null) - error( - "enable requires a condition", - CoreDslPackage.Literals.ISA__ATTRIBUTES, - ISSUE_CODE_PREFIX + "MissingValue" - ) - default: - error( - "illegal attribute name", - CoreDslPackage.Literals.ISA__ATTRIBUTES, - ISSUE_CODE_PREFIX + "IllegalAttribute" - ) - } - } - - } - - @Check - def checkAttributeNames(Instruction instr) { - for(Attribute a: instr.attributes) { - switch(a.type) { - case NO_CONT, - case COND, - case FLUSH: - return - default: - error( - "illegal attribute name", - CoreDslPackage.Literals.INSTRUCTION__ATTRIBUTES, - ISSUE_CODE_PREFIX + "IllegalAttribute" - ) - } - } - - } - - @Check - def checkAttributeNames(Declaration decl) { - for(Attribute a: decl.attributes) { - switch(a.type) { - case IS_PC, - case IS_INTERLOCK_FOR: - return - default: - error( - "illegal attribute name", - CoreDslPackage.Literals.INIT_DECLARATOR__ATTRIBUTES, - ISSUE_CODE_PREFIX + "IllegalAttribute" - ) - } - } - - } - - @Check - def checkAttributeNames(InitDeclarator decl) { - for(Attribute a: decl.attributes) { - switch(a.type) { - case IS_PC, - case IS_INTERLOCK_FOR: - return - default: - error( - "illegal attribute name", - CoreDslPackage.Literals.INIT_DECLARATOR__ATTRIBUTES, - ISSUE_CODE_PREFIX + "IllegalAttribute" - ) - } - } - - } - - @Check - def checkAttributeNames(FunctionDefinition decl) { - for(Attribute a: decl.attributes) { - switch(a.type) { - case DO_NOT_SYNTHESIZE: - return - default: - error( - "illegal attribute name", - CoreDslPackage.Literals.FUNCTION_DEFINITION__ATTRIBUTES, - ISSUE_CODE_PREFIX + "IllegalAttribute" - ) - } - } - - } - + case PrimitiveType: { + if (e.typeFor === new DataType(DataType.Type.COMPOSITE, 0)) + error( + "incompatible types used", + CoreDslPackage.Literals.PRIMITIVE_TYPE__DATA_TYPE, + TYPE_MISMATCH + ) + } + } + } + + @Check + def checkAttributeNames(ISA isa) { + for (Attribute a : isa.attributes) { + switch (a.type) { + case ENABLE: + if (a.value === null) + error( + "enable requires a condition", + CoreDslPackage.Literals.ISA__ATTRIBUTES, + ISSUE_CODE_PREFIX + "MissingValue" + ) + case HLS: + return + default: + error( + "illegal attribute name", + CoreDslPackage.Literals.ISA__ATTRIBUTES, + ISSUE_CODE_PREFIX + "IllegalAttribute" + ) + } + } + + } + + @Check + def checkAttributeNames(Instruction instr) { + for (Attribute a : instr.attributes) { + switch (a.type) { + case NO_CONT, + case COND, + case HLS, + case FLUSH: + return + default: + error( + "illegal attribute name", + CoreDslPackage.Literals.INSTRUCTION__ATTRIBUTES, + ISSUE_CODE_PREFIX + "IllegalAttribute" + ) + } + } + + } + + @Check + def checkAttributeNames(Declaration decl) { + for (Attribute a : decl.attributes) { + switch (a.type) { + case IS_PC, + case IS_INTERLOCK_FOR: + return + default: + error( + "illegal attribute name", + CoreDslPackage.Literals.INIT_DECLARATOR__ATTRIBUTES, + ISSUE_CODE_PREFIX + "IllegalAttribute" + ) + } + } + + } + + @Check + def checkAttributeNames(InitDeclarator decl) { + for (Attribute a : decl.attributes) { + switch (a.type) { + case IS_PC, + case IS_INTERLOCK_FOR: + return + default: + error( + "illegal attribute name", + CoreDslPackage.Literals.INIT_DECLARATOR__ATTRIBUTES, + ISSUE_CODE_PREFIX + "IllegalAttribute" + ) + } + } + + } + + @Check + def checkAttributeNames(FunctionDefinition decl) { + for (Attribute a : decl.attributes) { + switch (a.type) { + case DO_NOT_SYNTHESIZE: + return + default: + error( + "illegal attribute name", + CoreDslPackage.Literals.FUNCTION_DEFINITION__ATTRIBUTES, + ISSUE_CODE_PREFIX + "IllegalAttribute" + ) + } + } + + } + } diff --git a/pom.xml b/pom.xml index 79d75380..c9509ef9 100644 --- a/pom.xml +++ b/pom.xml @@ -283,6 +283,11 @@ false + + com.devexperts.bintray + bintray-maven-plugin + 1.2 + @@ -311,6 +316,11 @@ false + + bintray-devexperts-Maven + bintray-plugins + https://dl.bintray.com/devexperts/Maven + From 1aaf2d8d598c469b3bc6656c12055f593e14559a Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 26 Sep 2021 14:18:58 +0200 Subject: [PATCH 03/14] add upload script --- com.minres.coredsl.repository/pom.xml | 33 ++++++++++++++++++++----- com.minres.coredsl.repository/upload.sh | 22 +++++++++++++++++ pom.xml | 1 + 3 files changed, 50 insertions(+), 6 deletions(-) create mode 100755 com.minres.coredsl.repository/upload.sh diff --git a/com.minres.coredsl.repository/pom.xml b/com.minres.coredsl.repository/pom.xml index a5dc2341..ba2a2ab8 100644 --- a/com.minres.coredsl.repository/pom.xml +++ b/com.minres.coredsl.repository/pom.xml @@ -70,6 +70,7 @@ /yourpath ${project.build.directory}/repository/ + false @@ -87,7 +88,7 @@ - + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + deploy-to-artifactory + deploy + + exec + + + false + false + ${project.basedir} + sh + ${project.basedir}/upload.sh + + + - --> + diff --git a/com.minres.coredsl.repository/upload.sh b/com.minres.coredsl.repository/upload.sh new file mode 100755 index 00000000..f49e0606 --- /dev/null +++ b/com.minres.coredsl.repository/upload.sh @@ -0,0 +1,22 @@ +#!/bin/bash +## + +cd target/repository + +baseurls="https://artifactory.minres.com/artifactory/test-repo/CoreDSL/2.0 https://artifactory.minres.com/artifactory/test-repo/CoreDSL/latest" +file_list=`find . -type f | grep -v p2.index` + +for artifact_name in $file_list; do + for URL in $BASEURLS; do + sha256=$(openssl dgst -sha256 ${artifact_name}|sed 's/^SHA256.*= //') + sha1=$(openssl dgst -sha1 ${artifact_name}|sed 's/^SHA.*= //') + md5=$(openssl dgst -md5 ${artifact_name}|sed 's/^MD5.*= //') + # Upload artifact to artifactory + curl -sSf -u${USERNAME}:${PASSWORD} -T ${artifact_name} \ + -H "X-Checksum-Sha256:${sha256}" \ + -H "X-Checksum-Sha1:${sha1}" \ + -H "X-Checksum-md5:${md5}" \ + $URL/$f > /dev/null + done +done + diff --git a/pom.xml b/pom.xml index c9509ef9..b69abaf4 100644 --- a/pom.xml +++ b/pom.xml @@ -19,6 +19,7 @@ + true com.minres.coredsl.target From d13297fe3805b44ef870cb8319df4d7ae44fa4e1 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 26 Sep 2021 14:18:58 +0200 Subject: [PATCH 04/14] add upload script --- README.md | 8 +++- com.minres.coredsl.repository/pom.xml | 51 +++++++++++++++++++++---- com.minres.coredsl.repository/upload.sh | 29 ++++++++++++++ pom.xml | 1 + 4 files changed, 81 insertions(+), 8 deletions(-) create mode 100755 com.minres.coredsl.repository/upload.sh diff --git a/README.md b/README.md index e3d566d4..52f3d563 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,12 @@ # CoreDSL -This repo contains the XText bundles/plugins for CoreDSL. The bundles can be installed from https://minres.com/download/repository/CoreDSL +This repo contains the XText bundles/plugins for CoreDSL. The bundles can be installed from + +| Version | URL | +|---------|-------------------------------------------------------------------| +| Latest | https://artifactory.minres.com/artifactory/eclipse/CoreDSL/latest | +| 2.0.x | https://artifactory.minres.com/artifactory/eclipse/CoreDSL/2.0 | + ## References diff --git a/com.minres.coredsl.repository/pom.xml b/com.minres.coredsl.repository/pom.xml index a5dc2341..b698e338 100644 --- a/com.minres.coredsl.repository/pom.xml +++ b/com.minres.coredsl.repository/pom.xml @@ -11,6 +11,12 @@ com.minres.coredsl.repository eclipse-repository + + + artifactory + https://artifactory.minres.com/artifactory + + @@ -60,7 +66,7 @@ - release-composite + deploy-remote false @@ -70,6 +76,7 @@ /yourpath ${project.build.directory}/repository/ + false @@ -87,7 +94,7 @@ - + + org.apache.maven.plugins + maven-deploy-plugin + + true + - --> + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + deploy-to-artifactory + deploy + + exec + + + false + false + ${project.basedir} + bash + + ${project.basedir}/upload.sh + ${parsedVersion.majorVersion}.${parsedVersion.minorVersion} + + + + + + diff --git a/com.minres.coredsl.repository/upload.sh b/com.minres.coredsl.repository/upload.sh new file mode 100755 index 00000000..5c2f42a6 --- /dev/null +++ b/com.minres.coredsl.repository/upload.sh @@ -0,0 +1,29 @@ +#!/bin/bash +## + +[ -f $HOME/.upload.sh.cfg ] && . $HOME/.upload.sh.cfg + + +cd target/repository +artifactory_url='https://artifactory.minres.com/artifactory' +repo_module='eclipse/CoreDSL' +baseurls="h/test-repo/CoreDSL/$1 https://artifactory.minres.com/artifactory/test-repo/CoreDSL/latest" +file_list=`find . -type f | grep -v p2.index` + +echo Uploading P2 artifacts to ${artifactory_url}/${repo_module}/${1} + +for artifact_name in $file_list; do + echo Processing $artifact_name + for version in $1 latest; do + sha256=$(openssl dgst -sha256 ${artifact_name}|sed 's/^SHA256.*= //') + sha1=$(openssl dgst -sha1 ${artifact_name}|sed 's/^SHA.*= //') + md5=$(openssl dgst -md5 ${artifact_name}|sed 's/^MD5.*= //') + # Upload artifact to artifactory + curl -sSf -u${USERNAME}:${PASSWORD} -T ${artifact_name} \ + -H "X-Checksum-Sha256:${sha256}" \ + -H "X-Checksum-Sha1:${sha1}" \ + -H "X-Checksum-md5:${md5}" \ + ${artifactory_url}/${repo_module}/${version}/$f > /dev/null + done +done + diff --git a/pom.xml b/pom.xml index c9509ef9..b69abaf4 100644 --- a/pom.xml +++ b/pom.xml @@ -19,6 +19,7 @@ + true com.minres.coredsl.target From 2d779385394d71c8bd832d24aaf5a94d76343164 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 26 Sep 2021 15:28:36 +0200 Subject: [PATCH 05/14] fix missing directory in upload --- com.minres.coredsl.repository/upload.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.minres.coredsl.repository/upload.sh b/com.minres.coredsl.repository/upload.sh index 5c2f42a6..03e5a945 100755 --- a/com.minres.coredsl.repository/upload.sh +++ b/com.minres.coredsl.repository/upload.sh @@ -23,7 +23,7 @@ for artifact_name in $file_list; do -H "X-Checksum-Sha256:${sha256}" \ -H "X-Checksum-Sha1:${sha1}" \ -H "X-Checksum-md5:${md5}" \ - ${artifactory_url}/${repo_module}/${version}/$f > /dev/null + ${artifactory_url}/${repo_module}/${version}/$artifact_name > /dev/null done done From 77288b674c3e371bfe8318c08389cd9025b3b87c Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Tue, 28 Sep 2021 21:44:07 +0200 Subject: [PATCH 06/14] extend Interpreter to support simple assignments in arch state --- .../interpreter/CoreDSLInterpreter.xtend | 476 ++++++++++-------- .../com/minres/coredsl/util/ModelUtil.xtend | 17 + 2 files changed, 278 insertions(+), 215 deletions(-) diff --git a/com.minres.coredsl/src/com/minres/coredsl/interpreter/CoreDSLInterpreter.xtend b/com.minres.coredsl/src/com/minres/coredsl/interpreter/CoreDSLInterpreter.xtend index 01836970..d6c2b94a 100644 --- a/com.minres.coredsl/src/com/minres/coredsl/interpreter/CoreDSLInterpreter.xtend +++ b/com.minres.coredsl/src/com/minres/coredsl/interpreter/CoreDSLInterpreter.xtend @@ -30,222 +30,268 @@ import java.math.BigInteger import static extension com.minres.coredsl.typing.TypeProvider.* import static extension com.minres.coredsl.util.ModelUtil.* import com.minres.coredsl.coreDsl.ISA +import com.minres.coredsl.coreDsl.CoreDef +import com.minres.coredsl.coreDsl.InstructionSet +import com.minres.coredsl.coreDsl.ExpressionStatement class CoreDSLInterpreter { - /* TODO: - * - * - */ - - def static Value evaluate(DirectDeclarator decl, EvaluationContext ctx){ - if(decl.eContainer instanceof InitDeclarator){ - val initDecl = (decl.eContainer as InitDeclarator) - if(initDecl.initializer!==null) - initDecl.initializer.expr.valueFor(ctx) - else - null - } - } - - def static dispatch Value valueFor(TypeSpecifier e, EvaluationContext ctx) { - return new Value(e.typeFor(ctx.definitionContext), null) - } - - def dispatch static Value valueFor(Expression e, EvaluationContext ctx) { - return null - } - - def static dispatch Value valueFor(AssignmentExpression e, EvaluationContext ctx) { - return e.assignments.last.valueFor(ctx) - } - - def static dispatch Value valueFor(ConditionalExpression e, EvaluationContext ctx) { - return e.left.valueFor(ctx) - } - - def static dispatch Value valueFor(InfixExpression e, EvaluationContext ctx) { - switch(e.op){ - case "||", case "&&", - case "==", case "!=", case "<", case ">", case "<=", case ">=": new Value(boolType, null) - case '|', case "&", case "^", - case "<<", case ">>": { - val l = e.left.valueFor(ctx) - l.type.isIntegral ? l : null - } - case '+', case '-', - case '*', case '/': { - val l = e.left.valueFor(ctx) - val r = e.right.valueFor(ctx) - !l.isComputable(r)? null : switch(e.op){ - case '+': new Value(l.type, l.value.add(r.value)) - case '-': new Value(l.type, l.value.sub(r.value)) - case '*': new Value(l.type, l.value.mul(r.value)) - case '/': new Value(l.type, l.value.div(r.value)) - } - } - case '%': { - val l = e.left.valueFor(ctx) - val r = e.right.valueFor(ctx) - l.type.isIntegral && l.type.isIntegral ? new Value(l.type, l.value.mod(r.value)) : null - } - default: null - } - } - - def static dispatch Value valueFor(CastExpression e, EvaluationContext ctx) { - return e.type.valueFor(ctx) - } - - def static dispatch Value valueFor(PrefixExpression e, EvaluationContext ctx) { - switch(e.op){ - case "++", - case "--": e.left.valueFor(ctx) - case "~": e.left.valueFor(ctx) - case "!": new Value(boolType, e.left.valueFor(ctx).value) - case "sizeof": new Value(new DataType(DataType.Type.INTEGRAL_UNSIGNED, 32), -1) // TODO: fix it - default: // missing 'case "&", case "*", case "+" , case "-":' - null - } - } - - def static dispatch Value valueFor(PostfixExpression e, EvaluationContext ctx) { - switch(e.postOp.op){ - case ".", - case "->":e.postOp.valueFor(ctx) - default: - e.left.valueFor(ctx)?:e.postOp.valueFor(ctx) - } - } - - def static dispatch Value valueFor(Postfix e, EvaluationContext ctx) { - if(e.right!==null) - switch(e.right.op){ - case ".", case "->": return e.right.valueFor(ctx) - } - switch(e.op){ - case ".", case "->":e.declarator.valueFor(ctx) - default: - null - } - } - - def static dispatch Value valueFor(PrimaryExpression e, EvaluationContext ctx) { - if(e.constant !== null) { - e.constant.valueFor(ctx) - } else if(e.ref !== null ){ - e.ref.valueFor(ctx) - } else - return null - } - - def static dispatch Value valueFor(Variable e, EvaluationContext ctx) { - null - } - - def static dispatch Value valueFor(FunctionDefinition e, EvaluationContext ctx) { - e.type.valueFor(ctx) - } - - def static dispatch Value valueFor(DirectDeclarator e, EvaluationContext ctx) { - ctx.getValue(e) ?: calculateValue(e, ctx) - } - - private static def Value calculateValue(DirectDeclarator e, EvaluationContext ctx) { - if (e.eContainer instanceof InitDeclarator) { - if((e.eContainer as InitDeclarator).initializer!==null){ - return ctx.newValue(e, (e.eContainer as InitDeclarator).initializer.expr.valueFor(ctx)) - } else if(e.eContainer.eContainer.eContainer instanceof ISA){ - val directDecl = ctx.definitionContext .effectiveDeclarator(e.name) - if((directDecl.eContainer as InitDeclarator).initializer!==null) - return ctx.newValue(e, (directDecl.eContainer as InitDeclarator).initializer.expr.valueFor(ctx)) - } - } - null - } - - def static dispatch Value valueFor(BitField e, EvaluationContext ctx) { - new Value( new DataType(DataType.Type.INTEGRAL_UNSIGNED, e.left.value.intValue), null) // bitfield cannot be evaluated - } - - def static dispatch Value valueFor(BitValue e, EvaluationContext ctx) { - new Value( new DataType(DataType.Type.INTEGRAL_UNSIGNED, 1), 0) - } - - def static dispatch Value valueFor(IntegerConstant e, EvaluationContext ctx) { - new Value(e.typeFor(ctx.definitionContext), e.value as BigIntegerWithRadix) - } - - def static dispatch Value valueFor(FloatingConstant e, EvaluationContext ctx) { - new Value(e.typeFor(ctx.definitionContext), e.value as BigDecimalWithSize) - } - - def static dispatch Value valueFor(BoolConstant e, EvaluationContext ctx) { - new Value(boolType, e.isValue?1:0) - } - - def static dispatch Value valueFor(CharacterConstant e, EvaluationContext ctx) { - new Value(new DataType(DataType.Type.INTEGRAL_SIGNED, 8), BigInteger.valueOf(e.value.charAt(0))) - } - - def static dispatch Value valueFor(StringLiteral e, EvaluationContext ctx) { - new Value(new DataType(DataType.Type.INTEGRAL_SIGNED, 0), null) - } - - def static boolean isComparable(Value left, Value right){ - true - } - - def static boolean isAssignable(Value to, Value from){ - true - } - - def static boolean isComputable(Value left, Value right){ - left!==null && right!==null && left.type==right.type - } - - def static Number add(Number a, Number b) { - if (a instanceof BigDecimal && b instanceof BigDecimal) - (a as BigDecimal).add(b as BigDecimal) - else if (a instanceof BigInteger && b instanceof BigInteger) - (a as BigInteger).add(b as BigInteger) - else - null - } - - def static Number sub(Number a, Number b) { - if (a instanceof BigDecimal && b instanceof BigDecimal) - (a as BigDecimal).subtract(b as BigDecimal) - else if (a instanceof BigInteger && b instanceof BigInteger) - (a as BigInteger).subtract(b as BigInteger) - else - null - } - - def static Number mul(Number a, Number b) { - if (a instanceof BigDecimal && b instanceof BigDecimal) - (a as BigDecimal).multiply(b as BigDecimal) - else if (a instanceof BigInteger && b instanceof BigInteger) - (a as BigInteger).multiply(b as BigInteger) - else - null - } - - def static Number div(Number a, Number b) { - if (a instanceof BigDecimal && b instanceof BigDecimal) - (a as BigDecimal).divide(b as BigDecimal) - else if (a instanceof BigInteger && b instanceof BigInteger) - (a as BigInteger).divide(b as BigInteger) - else - null - } - - def static Number mod(Number a, Number b) { - if (a instanceof BigDecimal && b instanceof BigDecimal) - (a as BigDecimal).mod(b as BigDecimal) - else if (a instanceof BigInteger && b instanceof BigInteger) - (a as BigInteger).mod(b as BigInteger) - else - null - } + /* TODO: + * + * + */ + def static Value evaluate(DirectDeclarator decl, EvaluationContext ctx) { + if (decl.eContainer instanceof InitDeclarator) { + val context = ctx.definitionContext + val stmts = switch (context) { + CoreDef: { + context.allDefinitions + } + InstructionSet: { + context.allDefinitions + } + } + val assignments = stmts + .filter[it instanceof ExpressionStatement] + .map [(it as ExpressionStatement).expr.expressions + .filter[it instanceof AssignmentExpression]] + .flatten + val declAssignment = assignments.filter [ + it.left instanceof PrimaryExpression && (it.left as PrimaryExpression).ref == decl + ].last + if (declAssignment === null) { + val initDecl = (decl.eContainer as InitDeclarator) + if (initDecl.initializer !== null) + initDecl.initializer.expr.valueFor(ctx) + else + new Value(new DataType(DataType.Type.COMPOSITE, 0), 0) + } else + (declAssignment as AssignmentExpression).assignments.get(0).right.valueFor(ctx) + } else + new Value(new DataType(DataType.Type.COMPOSITE, 0), 0) + } + + def static dispatch Value valueFor(TypeSpecifier e, EvaluationContext ctx) { + return new Value(e.typeFor(ctx.definitionContext), null) + } + + def dispatch static Value valueFor(Expression e, EvaluationContext ctx) { + return null + } + + def static dispatch Value valueFor(AssignmentExpression e, EvaluationContext ctx) { + return e.assignments.last.valueFor(ctx) + } + + def static dispatch Value valueFor(ConditionalExpression e, EvaluationContext ctx) { + return e.left.valueFor(ctx) + } + + def static dispatch Value valueFor(InfixExpression e, EvaluationContext ctx) { + switch (e.op) { + case "||", + case "&&", + case "==", + case "!=", + case "<", + case ">", + case "<=", + case ">=": + new Value(boolType, null) + case '|', + case "&", + case "^", + case "<<", + case ">>": { + val l = e.left.valueFor(ctx) + l.type.isIntegral ? l : null + } + case '+', + case '-', + case '*', + case '/': { + val l = e.left.valueFor(ctx) + val r = e.right.valueFor(ctx) + !l.isComputable(r) + ? null + : switch (e.op) { + case '+': new Value(l.type, l.value.add(r.value)) + case '-': new Value(l.type, l.value.sub(r.value)) + case '*': new Value(l.type, l.value.mul(r.value)) + case '/': new Value(l.type, l.value.div(r.value)) + } + } + case '%': { + val l = e.left.valueFor(ctx) + val r = e.right.valueFor(ctx) + l.type.isIntegral && l.type.isIntegral ? new Value(l.type, l.value.mod(r.value)) : null + } + default: + null + } + } + + def static dispatch Value valueFor(CastExpression e, EvaluationContext ctx) { + return e.type.valueFor(ctx) + } + + def static dispatch Value valueFor(PrefixExpression e, EvaluationContext ctx) { + switch (e.op) { + case "++", + case "--": + e.left.valueFor(ctx) + case "~": + e.left.valueFor(ctx) + case "!": + new Value(boolType, e.left.valueFor(ctx).value) + case "sizeof": + new Value(new DataType(DataType.Type.INTEGRAL_UNSIGNED, 32), -1) // TODO: fix it + default: // missing 'case "&", case "*", case "+" , case "-":' + null + } + } + + def static dispatch Value valueFor(PostfixExpression e, EvaluationContext ctx) { + switch (e.postOp.op) { + case ".", + case "->": + e.postOp.valueFor(ctx) + default: + e.left.valueFor(ctx) ?: e.postOp.valueFor(ctx) + } + } + + def static dispatch Value valueFor(Postfix e, EvaluationContext ctx) { + if (e.right !== null) + switch (e.right.op) { + case ".", + case "->": return e.right.valueFor(ctx) + } + switch (e.op) { + case ".", + case "->": + e.declarator.valueFor(ctx) + default: + null + } + } + + def static dispatch Value valueFor(PrimaryExpression e, EvaluationContext ctx) { + if (e.constant !== null) { + e.constant.valueFor(ctx) + } else if (e.ref !== null) { + e.ref.valueFor(ctx) + } else + return null + } + + def static dispatch Value valueFor(Variable e, EvaluationContext ctx) { + null + } + + def static dispatch Value valueFor(FunctionDefinition e, EvaluationContext ctx) { + e.type.valueFor(ctx) + } + + def static dispatch Value valueFor(DirectDeclarator e, EvaluationContext ctx) { + ctx.getValue(e) ?: calculateValue(e, ctx) + } + + private static def Value calculateValue(DirectDeclarator e, EvaluationContext ctx) { + if (e.eContainer instanceof InitDeclarator) { + if ((e.eContainer as InitDeclarator).initializer !== null) { + return ctx.newValue(e, (e.eContainer as InitDeclarator).initializer.expr.valueFor(ctx)) + } else if (e.eContainer.eContainer.eContainer instanceof ISA) { + val directDecl = ctx.definitionContext.effectiveDeclarator(e.name) + if ((directDecl.eContainer as InitDeclarator).initializer !== null) + return ctx.newValue(e, (directDecl.eContainer as InitDeclarator).initializer.expr.valueFor(ctx)) + } + } + null + } + + def static dispatch Value valueFor(BitField e, EvaluationContext ctx) { + new Value(new DataType(DataType.Type.INTEGRAL_UNSIGNED, e.left.value.intValue), null) // bitfield cannot be evaluated + } + + def static dispatch Value valueFor(BitValue e, EvaluationContext ctx) { + new Value(new DataType(DataType.Type.INTEGRAL_UNSIGNED, 1), 0) + } + + def static dispatch Value valueFor(IntegerConstant e, EvaluationContext ctx) { + new Value(e.typeFor(ctx.definitionContext), e.value as BigIntegerWithRadix) + } + + def static dispatch Value valueFor(FloatingConstant e, EvaluationContext ctx) { + new Value(e.typeFor(ctx.definitionContext), e.value as BigDecimalWithSize) + } + + def static dispatch Value valueFor(BoolConstant e, EvaluationContext ctx) { + new Value(boolType, e.isValue ? 1 : 0) + } + + def static dispatch Value valueFor(CharacterConstant e, EvaluationContext ctx) { + new Value(new DataType(DataType.Type.INTEGRAL_SIGNED, 8), BigInteger.valueOf(e.value.charAt(0))) + } + + def static dispatch Value valueFor(StringLiteral e, EvaluationContext ctx) { + new Value(new DataType(DataType.Type.INTEGRAL_SIGNED, 0), null) + } + + def static boolean isComparable(Value left, Value right) { + true + } + + def static boolean isAssignable(Value to, Value from) { + true + } + + def static boolean isComputable(Value left, Value right) { + left !== null && right !== null && left.type == right.type + } + + def static Number add(Number a, Number b) { + if (a instanceof BigDecimal && b instanceof BigDecimal) + (a as BigDecimal).add(b as BigDecimal) + else if (a instanceof BigInteger && b instanceof BigInteger) + (a as BigInteger).add(b as BigInteger) + else + null + } + + def static Number sub(Number a, Number b) { + if (a instanceof BigDecimal && b instanceof BigDecimal) + (a as BigDecimal).subtract(b as BigDecimal) + else if (a instanceof BigInteger && b instanceof BigInteger) + (a as BigInteger).subtract(b as BigInteger) + else + null + } + + def static Number mul(Number a, Number b) { + if (a instanceof BigDecimal && b instanceof BigDecimal) + (a as BigDecimal).multiply(b as BigDecimal) + else if (a instanceof BigInteger && b instanceof BigInteger) + (a as BigInteger).multiply(b as BigInteger) + else + null + } + + def static Number div(Number a, Number b) { + if (a instanceof BigDecimal && b instanceof BigDecimal) + (a as BigDecimal).divide(b as BigDecimal) + else if (a instanceof BigInteger && b instanceof BigInteger) + (a as BigInteger).divide(b as BigInteger) + else + null + } + + def static Number mod(Number a, Number b) { + if (a instanceof BigDecimal && b instanceof BigDecimal) + (a as BigDecimal).mod(b as BigDecimal) + else if (a instanceof BigInteger && b instanceof BigInteger) + (a as BigInteger).mod(b as BigInteger) + else + null + } } diff --git a/com.minres.coredsl/src/com/minres/coredsl/util/ModelUtil.xtend b/com.minres.coredsl/src/com/minres/coredsl/util/ModelUtil.xtend index e1e0e92a..815df7f3 100644 --- a/com.minres.coredsl/src/com/minres/coredsl/util/ModelUtil.xtend +++ b/com.minres.coredsl/src/com/minres/coredsl/util/ModelUtil.xtend @@ -14,6 +14,7 @@ import com.minres.coredsl.coreDsl.Encoding import com.minres.coredsl.coreDsl.BitField import com.minres.coredsl.coreDsl.BitValue import com.minres.coredsl.coreDsl.Statement +import com.minres.coredsl.coreDsl.BlockItem class ModelUtil { @@ -95,6 +96,22 @@ class ModelUtil { } + static def Iterable allDefinitions(CoreDef core){ + val blockItemList = if(core.contributingType.size == 0) core.declarations else { + val instrSets = core.contributingType?.map[InstructionSet i| i.allInstructionSets].flatten + val seen = newLinkedHashSet + seen.addAll(instrSets) + seen.add(core) + seen.map[ISA i| i.declarations].flatten + } + return blockItemList + } + + static def Iterable allDefinitions(InstructionSet core){ + val blockItemList = core.allInstructionSets.map[ISA i| i.declarations].flatten + return blockItemList + } + static def Iterable allInstr(CoreDef core){ val unique = newLinkedHashMap val instrList = if(core.contributingType.size == 0) core.instructions else { From 3a849ac98fafa4ce636324dba1d6a4d734733ea3 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Tue, 28 Sep 2021 21:55:17 +0200 Subject: [PATCH 07/14] fix interpreter execution if context has not ISA --- .../coredsl/interpreter/CoreDSLInterpreter.xtend | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/com.minres.coredsl/src/com/minres/coredsl/interpreter/CoreDSLInterpreter.xtend b/com.minres.coredsl/src/com/minres/coredsl/interpreter/CoreDSLInterpreter.xtend index d6c2b94a..62f78f8f 100644 --- a/com.minres.coredsl/src/com/minres/coredsl/interpreter/CoreDSLInterpreter.xtend +++ b/com.minres.coredsl/src/com/minres/coredsl/interpreter/CoreDSLInterpreter.xtend @@ -43,6 +43,13 @@ class CoreDSLInterpreter { def static Value evaluate(DirectDeclarator decl, EvaluationContext ctx) { if (decl.eContainer instanceof InitDeclarator) { val context = ctx.definitionContext + if(context === null){ + val initDecl = (decl.eContainer as InitDeclarator) + return if(initDecl.initializer!==null) + initDecl.initializer.expr.valueFor(ctx) + else + null + } val stmts = switch (context) { CoreDef: { context.allDefinitions @@ -50,7 +57,7 @@ class CoreDSLInterpreter { InstructionSet: { context.allDefinitions } - } + }.toList val assignments = stmts .filter[it instanceof ExpressionStatement] .map [(it as ExpressionStatement).expr.expressions @@ -68,7 +75,7 @@ class CoreDSLInterpreter { } else (declAssignment as AssignmentExpression).assignments.get(0).right.valueFor(ctx) } else - new Value(new DataType(DataType.Type.COMPOSITE, 0), 0) + null } def static dispatch Value valueFor(TypeSpecifier e, EvaluationContext ctx) { From e26d4e15ddc9a1c854f54ff55542c98f7987fe13 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Wed, 29 Sep 2021 00:21:04 +0200 Subject: [PATCH 08/14] fix handling of declarators --- .../coredsl/interpreter/CoreDSLInterpreter.xtend | 3 +-- .../src/com/minres/coredsl/util/ModelUtil.xtend | 13 ++++++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/com.minres.coredsl/src/com/minres/coredsl/interpreter/CoreDSLInterpreter.xtend b/com.minres.coredsl/src/com/minres/coredsl/interpreter/CoreDSLInterpreter.xtend index 62f78f8f..1b1f10af 100644 --- a/com.minres.coredsl/src/com/minres/coredsl/interpreter/CoreDSLInterpreter.xtend +++ b/com.minres.coredsl/src/com/minres/coredsl/interpreter/CoreDSLInterpreter.xtend @@ -210,8 +210,7 @@ class CoreDSLInterpreter { return ctx.newValue(e, (e.eContainer as InitDeclarator).initializer.expr.valueFor(ctx)) } else if (e.eContainer.eContainer.eContainer instanceof ISA) { val directDecl = ctx.definitionContext.effectiveDeclarator(e.name) - if ((directDecl.eContainer as InitDeclarator).initializer !== null) - return ctx.newValue(e, (directDecl.eContainer as InitDeclarator).initializer.expr.valueFor(ctx)) + return directDecl.evaluate(ctx); } } null diff --git a/com.minres.coredsl/src/com/minres/coredsl/util/ModelUtil.xtend b/com.minres.coredsl/src/com/minres/coredsl/util/ModelUtil.xtend index 815df7f3..9798305c 100644 --- a/com.minres.coredsl/src/com/minres/coredsl/util/ModelUtil.xtend +++ b/com.minres.coredsl/src/com/minres/coredsl/util/ModelUtil.xtend @@ -72,14 +72,13 @@ class ModelUtil { static def DirectDeclarator effectiveDeclarator(ISA isa, String name){ if(isa instanceof CoreDef) { - val decl = isa.stateDeclarations.findFirst[ - it.init.findFirst[ - it.declarator.name==name && it.initializer!==null - ]!==null + val decl = isa.allDefinitions.filter[it instanceof Declaration].findFirst[ + (it as Declaration).init.findFirst[it.declarator.name==name]!==null ] - if(decl!==null) - return decl.init.findFirst[it.declarator.name==name].declarator - for(contrib:isa.contributingType.reverse) { + if(decl!==null) { + return (decl as Declaration).init.findFirst[it.declarator.name==name].declarator + } + for(contrib:isa.contributingType.reverseView) { val contribDecl = contrib.effectiveDeclarator(name) if(contribDecl!==null) return contribDecl From 2b49ccec2893a1b62034db12fd42f905e4e127a7 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Wed, 29 Sep 2021 00:59:10 +0200 Subject: [PATCH 09/14] fix wrong test input --- .../src/com/minres/coredsl/tests/CoreDslTypeTest.xtend | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.minres.coredsl.tests/src/com/minres/coredsl/tests/CoreDslTypeTest.xtend b/com.minres.coredsl.tests/src/com/minres/coredsl/tests/CoreDslTypeTest.xtend index ed17f48b..415f724a 100644 --- a/com.minres.coredsl.tests/src/com/minres/coredsl/tests/CoreDslTypeTest.xtend +++ b/com.minres.coredsl.tests/src/com/minres/coredsl/tests/CoreDslTypeTest.xtend @@ -38,7 +38,7 @@ class CoreDslTypeTest { } Core TestCore provides TestISA { architectural_state { - unsigned XLEN=32; + XLEN=32; } } '''.parse From cedd97e25556af42a3920541792f939ecc956400 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Wed, 29 Sep 2021 01:11:46 +0200 Subject: [PATCH 10/14] add badge to README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e3d566d4..3662425f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![Java CI with Maven](https://github.com/Minres/CoreDSL/actions/workflows/maven.yml/badge.svg)](https://github.com/Minres/CoreDSL/actions/workflows/maven.yml) + # CoreDSL This repo contains the XText bundles/plugins for CoreDSL. The bundles can be installed from https://minres.com/download/repository/CoreDSL From e1a30ec8a5784ba61222c4946041bfb156fe62e7 Mon Sep 17 00:00:00 2001 From: Mario Welzig Date: Tue, 5 Oct 2021 20:53:15 +0200 Subject: [PATCH 11/14] [Proposal] More flexible attribute implementation (#11) --- .../CoreDslAttributeValidationTest.xtend | 167 ++++++++++++++++++ .../src/com/minres/coredsl/CoreDsl.xtext | 17 +- .../minres/coredsl/CoreDslRuntimeModule.xtend | 1 - .../services/visualization/Visualizer.xtend | 21 +-- .../coredsl/validation/CoreDslValidator.xtend | 100 +++-------- .../coredsl/validation/KnownAttributes.java | 61 +++++++ 6 files changed, 260 insertions(+), 107 deletions(-) create mode 100644 com.minres.coredsl.tests/src/com/minres/coredsl/tests/CoreDslAttributeValidationTest.xtend create mode 100644 com.minres.coredsl/src/com/minres/coredsl/validation/KnownAttributes.java diff --git a/com.minres.coredsl.tests/src/com/minres/coredsl/tests/CoreDslAttributeValidationTest.xtend b/com.minres.coredsl.tests/src/com/minres/coredsl/tests/CoreDslAttributeValidationTest.xtend new file mode 100644 index 00000000..68143faf --- /dev/null +++ b/com.minres.coredsl.tests/src/com/minres/coredsl/tests/CoreDslAttributeValidationTest.xtend @@ -0,0 +1,167 @@ +/* + * generated by Xtext 2.10.0 + */ +package com.minres.coredsl.tests + +import com.google.inject.Inject +import com.minres.coredsl.coreDsl.DescriptionContent +import org.eclipse.xtext.testing.InjectWith +import org.eclipse.xtext.testing.extensions.InjectionExtension +import org.eclipse.xtext.testing.util.ParseHelper +import org.eclipse.xtext.testing.validation.ValidationTestHelper +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.^extension.ExtendWith + +import static org.junit.jupiter.api.Assertions.assertEquals +import static org.junit.jupiter.api.Assertions.assertNotNull +import static org.junit.jupiter.api.Assertions.assertTrue + +import com.minres.coredsl.validation.KnownAttributes +import com.minres.coredsl.validation.CoreDslValidator + +@ExtendWith(InjectionExtension) +@InjectWith(CoreDslInjectorProvider) +class CoreDslAttributeValidationTest { + + @Inject extension ParseHelper parseHelper + + @Inject ValidationTestHelper validator + + @Test + def void validAttributes() { + val createValidAttribString = [ KnownAttributes.AttributeUsage usage | + KnownAttributes.all.filter[it.allowedUsage.contains(usage)].map [ + "[[" + it.name + (it.paramCount > 0 ? "(" + ", 0".repeat(it.paramCount).substring(2) + ")" : "") + "]]" + ].join(" ") + ]; + + val funcAttribString = createValidAttribString.apply(KnownAttributes.AttributeUsage.function); + val declAttribString = createValidAttribString.apply(KnownAttributes.AttributeUsage.declaration); + val instrAttribString = createValidAttribString.apply(KnownAttributes.AttributeUsage.instruction); + + val content = ''' + InstructionSet AttributeValidationTestInstructionSet { + architectural_state { + unsigned XLEN; + unsigned field «declAttribString»; + } + functions { + void fun() «funcAttribString» {} + } + instructions «instrAttribString» { + test «instrAttribString» { + encoding: 0; + args_disass: ""; + behavior: {} + } + } + } + Core AttributeValidationTestCore provides AttributeValidationTestInstructionSet { + architectural_state { + XLEN=32; + } + } + '''.parse(); + + val issues = validator.validate(content); + for (issue : issues) { + println(issue); + } + + assertTrue(issues.isEmpty()); + } + + @Test + def void invalidAttributePlacement() { + val attribString = KnownAttributes.all.map [ + "[[" + it.name + (it.paramCount > 0 ? "(" + ", 0".repeat(it.paramCount).substring(2) + ")" : "" + ) + "]]" + ].join(" "); + + val content = ''' + InstructionSet AttributeValidationTestInstructionSet { + architectural_state { + unsigned XLEN; + unsigned field «attribString»; + } + functions { + void fun() «attribString» {} + } + instructions «attribString» { + test «attribString» { + encoding: 0; + args_disass: ""; + behavior: {} + } + } + } + Core AttributeValidationTestCore provides AttributeValidationTestInstructionSet { + architectural_state { + XLEN=32; + } + } + '''.parse(); + + val issues = validator.validate(content); + for (issue : issues) { + println(issue); + assertEquals(issue.code, CoreDslValidator.ILLEGAL_ATTRIBUTE); + } + + // Every attribute appears in every possible location, so we expect + // * - issues. + val validPlacementCount = + KnownAttributes.all.map[it.allowedUsage.size].reduce[a, b|a + b] + + KnownAttributes.all.filter[it.allowedUsage.contains(KnownAttributes.AttributeUsage.instruction)].size; + assertEquals(issues.size, 4 * KnownAttributes.all.size - validPlacementCount); + } + + @Test + def void invalidAttributeParameters() { + val createInvalidAttribString = [ KnownAttributes.AttributeUsage usage | + KnownAttributes.all.filter[it.allowedUsage.contains(usage)].map [ + "[[" + it.name + "(" + ", 0".repeat(it.paramCount + 1).substring(2) + ")]]" + ].join(" ") + ]; + + val funcAttribString = createInvalidAttribString.apply(KnownAttributes.AttributeUsage.function); + val declAttribString = createInvalidAttribString.apply(KnownAttributes.AttributeUsage.declaration); + val instrAttribString = createInvalidAttribString.apply(KnownAttributes.AttributeUsage.instruction); + + val content = ''' + InstructionSet AttributeValidationTestInstructionSet { + architectural_state { + unsigned XLEN; + unsigned field «declAttribString»; + } + functions { + void fun() «funcAttribString» {} + } + instructions «instrAttribString» { + test «instrAttribString» { + encoding: 0; + args_disass: ""; + behavior: {} + } + } + } + Core AttributeValidationTestCore provides AttributeValidationTestInstructionSet { + architectural_state { + XLEN=32; + } + } + '''.parse(); + + val issues = validator.validate(content); + for (issue : issues) { + println(issue); + assertEquals(issue.code, CoreDslValidator.INVALID_ATTRIBUTE_PARAMETERS); + } + + // we expect an issue for every valid attribute placement + val validPlacementCount = + KnownAttributes.all.map[it.allowedUsage.size].reduce[a, b|a + b] + + KnownAttributes.all.filter[it.allowedUsage.contains(KnownAttributes.AttributeUsage.instruction)].size; + assertEquals(issues.size, validPlacementCount); + } +} diff --git a/com.minres.coredsl/src/com/minres/coredsl/CoreDsl.xtext b/com.minres.coredsl/src/com/minres/coredsl/CoreDsl.xtext index 16de20ce..51562c9b 100644 --- a/com.minres.coredsl/src/com/minres/coredsl/CoreDsl.xtext +++ b/com.minres.coredsl/src/com/minres/coredsl/CoreDsl.xtext @@ -44,7 +44,7 @@ fragment SectionFunctions returns ISA: ; fragment SectionInstructions returns ISA: - 'instructions' attributes+=Attribute* '{' instructions+=Instruction+ '}' + 'instructions' commonInstructionAttributes+=Attribute* '{' instructions+=Instruction+ '}' ; Instruction: @@ -160,7 +160,7 @@ fragment DeclarationSpecifier ; Attribute - : DoubleLeftBracket type=AttributeName ('=' value=ConditionalExpression)? DoubleRightBracket + : DoubleLeftBracket type=ID ('=' params+=ConditionalExpression | '(' params+=ConditionalExpression (',' params+=ConditionalExpression)* ')')? DoubleRightBracket ; TypeSpecifier @@ -377,7 +377,7 @@ CharacterConstant : value=CHARCONST ; -// the follwoing 2 rules are needed so that XText does not generate a terminal symbol '[[' and '&&' +// the following 2 rules are needed so that XText does not generate a terminal symbol '[[' and '&&' // which is always eaten by the Lexer so that a[b[3]] is not recognized DoubleLeftBracket hidden(WS, ML_COMMENT, SL_COMMENT): LEFT_BR LEFT_BR; DoubleRightBracket hidden(WS, ML_COMMENT, SL_COMMENT): RIGHT_BR RIGHT_BR; @@ -395,17 +395,6 @@ enum TypeQualifier: CONST='const' | VOLATILE='volatile'; enum StorageClassSpecifier: EXTERN='extern' | STATIC='static' | REGISTER='register'; -enum AttributeName: NONE - | IS_PC='is_pc' - | IS_INTERLOCK_FOR='is_interlock_for' - | DO_NOT_SYNTHESIZE="do_not_synthesize" - | ENABLE="enable" - | NO_CONT='no_cont' - | COND='cond' - | FLUSH='flush' - | HLS='hls' -; - enum StructOrUnion: STRUCT='struct'|UNION='union'; terminal LEFT_BR: '['; diff --git a/com.minres.coredsl/src/com/minres/coredsl/CoreDslRuntimeModule.xtend b/com.minres.coredsl/src/com/minres/coredsl/CoreDslRuntimeModule.xtend index c42f8702..aa186c2f 100644 --- a/com.minres.coredsl/src/com/minres/coredsl/CoreDslRuntimeModule.xtend +++ b/com.minres.coredsl/src/com/minres/coredsl/CoreDslRuntimeModule.xtend @@ -8,7 +8,6 @@ import org.eclipse.xtext.scoping.IGlobalScopeProvider import com.minres.coredsl.converter.CoreDslTerminalConverters import com.minres.coredsl.scoping.CoreDslResourceDescriptionStrategy import org.eclipse.xtext.resource.IDefaultResourceDescriptionStrategy -import com.minres.coredsl.scoping.CoreDslGlobalScopeProvider import org.eclipse.xtext.scoping.impl.ImportUriGlobalScopeProvider /** diff --git a/com.minres.coredsl/src/com/minres/coredsl/services/visualization/Visualizer.xtend b/com.minres.coredsl/src/com/minres/coredsl/services/visualization/Visualizer.xtend index 3bb102b9..a4325707 100644 --- a/com.minres.coredsl/src/com/minres/coredsl/services/visualization/Visualizer.xtend +++ b/com.minres.coredsl/src/com/minres/coredsl/services/visualization/Visualizer.xtend @@ -210,7 +210,7 @@ class Visualizer { makeNamedLiteral("Super Type", node.superType?.name), makeGroup("Declarations", node.declarations), makeGroup("Functions", node.functions), - makeGroup("Attributes", node.attributes), + makeGroup("Attributes", node.commonInstructionAttributes), makeGroup("Instructions", node.instructions) ); } @@ -221,7 +221,7 @@ class Visualizer { makeGroup("Contributing Type", node.contributingType), makeGroup("Declarations", node.declarations), makeGroup("Functions", node.functions), - makeGroup("Attributes", node.attributes), + makeGroup("Attributes", node.commonInstructionAttributes), makeGroup("Instructions", node.instructions) ) } @@ -258,13 +258,15 @@ class Visualizer { ? makeNode(node, "Function (extern)", makeChild("Return Type", node.type), makeNamedLiteral("Name", node.name), - makeGroup("Parameters", node.params) + makeGroup("Parameters", node.params), + makeGroup("Attributes", node.attributes) ) : makeNode(node, "Function", makeChild("Return Type", node.type), makeNamedLiteral("Name", node.name), makeGroup("Parameters", node.params), - makeChild("Body", node.statement) + makeChild("Body", node.statement), + makeGroup("Attributes", node.attributes) ); } @@ -349,7 +351,7 @@ class Visualizer { private def dispatch VisualNode genNode(Attribute node) { return makeNode(node, "Attribute", makeNamedLiteral("Type", node.type.toString), - makeChild("Value", node.value) + makeGroup("Params", node.params) ); } @@ -427,23 +429,14 @@ class Visualizer { private def dispatch VisualNode genNode(IntegerConstant node) { return makeImmediateLiteral(node.value.toString) - /*return makeNode(node, "Integer", - makeNamedLiteral("Value", node.value.toString) - );*/ } private def dispatch VisualNode genNode(FloatingConstant node) { return makeImmediateLiteral(node.value.toString) - /*return makeNode(node, "Float", - makeNamedLiteral("Value", node.value.toString) - );*/ } private def dispatch VisualNode genNode(BoolConstant node) { return makeImmediateLiteral(node.value.toString) - /*return makeNode(node, "Bool", - makeNamedLiteral("Value", node.value.toString) - );*/ } private def dispatch VisualNode genNode(StringLiteral node) { diff --git a/com.minres.coredsl/src/com/minres/coredsl/validation/CoreDslValidator.xtend b/com.minres.coredsl/src/com/minres/coredsl/validation/CoreDslValidator.xtend index c827f291..83ec0697 100644 --- a/com.minres.coredsl/src/com/minres/coredsl/validation/CoreDslValidator.xtend +++ b/com.minres.coredsl/src/com/minres/coredsl/validation/CoreDslValidator.xtend @@ -22,6 +22,9 @@ import com.minres.coredsl.coreDsl.Instruction import com.minres.coredsl.coreDsl.InitDeclarator import com.minres.coredsl.coreDsl.Declaration import com.minres.coredsl.coreDsl.FunctionDefinition +import com.minres.coredsl.validation.KnownAttributes.AttributeUsage +import org.eclipse.emf.common.util.EList +import org.eclipse.emf.ecore.EStructuralFeature /** * This class contains custom validation rules. @@ -40,6 +43,8 @@ class CoreDslValidator extends AbstractCoreDslValidator { protected static val ISSUE_CODE_PREFIX = "com.minres.coredsl." public static val TYPE_MISMATCH = ISSUE_CODE_PREFIX + "TypeMismatch" public static val TYPE_ILLEGAL = ISSUE_CODE_PREFIX + "TypeIllegal" + public static val ILLEGAL_ATTRIBUTE = ISSUE_CODE_PREFIX + "IllegalAttribute" + public static val INVALID_ATTRIBUTE_PARAMETERS = ISSUE_CODE_PREFIX + "InvalidAttributeParameters" // @Check def checkType(Expression e) { @@ -122,102 +127,41 @@ class CoreDslValidator extends AbstractCoreDslValidator { } } } + + def checkAttributes(EList attributes, KnownAttributes.AttributeUsage expectedUsage, EStructuralFeature feature) { + for(Attribute attribute : attributes) { + val info = KnownAttributes.byName(attribute.type); + + if(info === null || !info.allowedUsage.contains(expectedUsage)) + error("unexpected attribute '" + attribute.type + "'", feature, ILLEGAL_ATTRIBUTE); + + if(attribute.params.size() !== info.paramCount) + error("attribute '" + info.name + "' requires exactly " + info.paramCount + " parameter(s)", feature, INVALID_ATTRIBUTE_PARAMETERS); + } + } @Check def checkAttributeNames(ISA isa) { - for (Attribute a : isa.attributes) { - switch (a.type) { - case ENABLE: - if (a.value === null) - error( - "enable requires a condition", - CoreDslPackage.Literals.ISA__ATTRIBUTES, - ISSUE_CODE_PREFIX + "MissingValue" - ) - case HLS: - return - default: - error( - "illegal attribute name", - CoreDslPackage.Literals.ISA__ATTRIBUTES, - ISSUE_CODE_PREFIX + "IllegalAttribute" - ) - } - } - + checkAttributes(isa.commonInstructionAttributes, KnownAttributes.AttributeUsage.instruction, CoreDslPackage.Literals.ISA__COMMON_INSTRUCTION_ATTRIBUTES); } @Check def checkAttributeNames(Instruction instr) { - for (Attribute a : instr.attributes) { - switch (a.type) { - case NO_CONT, - case COND, - case HLS, - case FLUSH: - return - default: - error( - "illegal attribute name", - CoreDslPackage.Literals.INSTRUCTION__ATTRIBUTES, - ISSUE_CODE_PREFIX + "IllegalAttribute" - ) - } - } - + checkAttributes(instr.attributes, KnownAttributes.AttributeUsage.instruction, CoreDslPackage.Literals.INSTRUCTION__ATTRIBUTES); } @Check def checkAttributeNames(Declaration decl) { - for (Attribute a : decl.attributes) { - switch (a.type) { - case IS_PC, - case IS_INTERLOCK_FOR: - return - default: - error( - "illegal attribute name", - CoreDslPackage.Literals.INIT_DECLARATOR__ATTRIBUTES, - ISSUE_CODE_PREFIX + "IllegalAttribute" - ) - } - } - + checkAttributes(decl.attributes, KnownAttributes.AttributeUsage.declaration, CoreDslPackage.Literals.INIT_DECLARATOR__ATTRIBUTES); } @Check def checkAttributeNames(InitDeclarator decl) { - for (Attribute a : decl.attributes) { - switch (a.type) { - case IS_PC, - case IS_INTERLOCK_FOR: - return - default: - error( - "illegal attribute name", - CoreDslPackage.Literals.INIT_DECLARATOR__ATTRIBUTES, - ISSUE_CODE_PREFIX + "IllegalAttribute" - ) - } - } - + checkAttributes(decl.attributes, KnownAttributes.AttributeUsage.declaration, CoreDslPackage.Literals.INIT_DECLARATOR__ATTRIBUTES); } @Check def checkAttributeNames(FunctionDefinition decl) { - for (Attribute a : decl.attributes) { - switch (a.type) { - case DO_NOT_SYNTHESIZE: - return - default: - error( - "illegal attribute name", - CoreDslPackage.Literals.FUNCTION_DEFINITION__ATTRIBUTES, - ISSUE_CODE_PREFIX + "IllegalAttribute" - ) - } - } - + checkAttributes(decl.attributes, KnownAttributes.AttributeUsage.function, CoreDslPackage.Literals.FUNCTION_DEFINITION__ATTRIBUTES); } - } diff --git a/com.minres.coredsl/src/com/minres/coredsl/validation/KnownAttributes.java b/com.minres.coredsl/src/com/minres/coredsl/validation/KnownAttributes.java new file mode 100644 index 00000000..4b37d29c --- /dev/null +++ b/com.minres.coredsl/src/com/minres/coredsl/validation/KnownAttributes.java @@ -0,0 +1,61 @@ +package com.minres.coredsl.validation; + +import static com.minres.coredsl.validation.KnownAttributes.AttributeUsage.*; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public final class KnownAttributes { + private KnownAttributes() {} + + private static final Map registeredAttributes = new HashMap(); + + static { + register("enable", 1, instruction); + register("hls", 0, instruction); + register("no_cont", 0, instruction); + register("cond", 0, instruction); + register("flush", 0, instruction); + register("do_not_synthesize", 0, function); + register("is_pc", 0, declaration); + register("is_main_reg", 0, declaration); + register("is_main_mem", 0, declaration); + register("is_interlock_for", 1, declaration); + } + + public static void register(String name, int paramCount, AttributeUsage... allowedUsage) { + register(new AttributeInfo(name, paramCount, allowedUsage)); + } + + public static void register(AttributeInfo attrib) { + registeredAttributes.put(attrib.name, attrib); + } + + public static AttributeInfo byName(String name) { + return registeredAttributes.getOrDefault(name, null); + } + + public static Collection getAll() { + return registeredAttributes.values(); + } + + public enum AttributeUsage { + instruction, function, declaration + } + + public static final class AttributeInfo { + public final String name; + public final int paramCount; // TODO allow multiple signatures? + public final List allowedUsage; + + public AttributeInfo(String name, int paramCount, AttributeUsage... allowedUsage) { + this.name = name; + this.paramCount = paramCount; + this.allowedUsage = Collections.unmodifiableList(Arrays.asList(allowedUsage)); + } + } +} From fb8988304fbde1b23abde39af0392d6c2f080e0e Mon Sep 17 00:00:00 2001 From: Julian Oppermann Date: Mon, 22 Nov 2021 13:12:00 +0100 Subject: [PATCH 12/14] s/CoreDef/Core in Pygments lexer. --- contrib/CoreDSL2Lexer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/CoreDSL2Lexer.py b/contrib/CoreDSL2Lexer.py index 38c3d321..b9c53e84 100644 --- a/contrib/CoreDSL2Lexer.py +++ b/contrib/CoreDSL2Lexer.py @@ -22,7 +22,7 @@ class CustomLexer(CLexer): tokens = { 'statements': [ (r'import', Comment.Preproc), - (r'(InstructionSet|CoreDef)(\s+)', bygroups(Keyword, Text), 'classname'), + (r'(InstructionSet|Core)(\s+)', bygroups(Keyword, Text), 'classname'), (r'(extends|provides)(\s+)', bygroups(Keyword, Text), 'classname'), (r'(instructions|architectural_state|functions)', Keyword), From c20ca375475faaa2c8ca8264c73d6b48d63509e9 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 28 Nov 2021 12:05:50 +0100 Subject: [PATCH 13/14] gh-pages integration --- .../packaging-p2-composite.ant | 104 ++++++++++++++++++ com.minres.coredsl.repository/pom.xml | 104 ++++++++++-------- .../minres/coredsl/CoreDslRuntimeModule.xtend | 12 ++ pom.xml | 1 + 4 files changed, 178 insertions(+), 43 deletions(-) create mode 100644 com.minres.coredsl.repository/packaging-p2-composite.ant diff --git a/com.minres.coredsl.repository/packaging-p2-composite.ant b/com.minres.coredsl.repository/packaging-p2-composite.ant new file mode 100644 index 00000000..cbfff8ab --- /dev/null +++ b/com.minres.coredsl.repository/packaging-p2-composite.ant @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + version=1 +metadata.repository.factory.order=compositeContent.xml,\! +artifact.repository.factory.order=compositeArtifacts.xml,\! + + + + + + + diff --git a/com.minres.coredsl.repository/pom.xml b/com.minres.coredsl.repository/pom.xml index 91372ea3..ff05bb66 100644 --- a/com.minres.coredsl.repository/pom.xml +++ b/com.minres.coredsl.repository/pom.xml @@ -87,64 +87,82 @@ - - - org.apache.maven.plugins - maven-deploy-plugin - - true - + + bash + + ${software.download.area} + + -c + if [ -d CoreDSL-gh ]; then cd CoreDSL-gh; git pull; else git clone --branch gh-pages https://github.com/Minres/CoreDSL.git CoreDSL-gh; fi + + + en_US + + - - org.codehaus.mojo - exec-maven-plugin - 1.2.1 + + org.eclipse.tycho.extras + tycho-eclipserun-plugin + ${tycho-version} + + + -application org.eclipse.ant.core.antRunner -buildfile packaging-p2-composite.ant p2.composite.add -Dsite.label="CoreDSL Software Repository" -Dproject.build.directory=${project.build.directory} -DunqualifiedVersion=${unqualifiedVersion} -Dsoftware.download.area="${software.download.area}/CoreDSL-gh/repository" + + + 2020-03 + p2 + http://download.eclipse.org/releases/2020-03/ + + + + + org.eclipse.ant.core + eclipse-plugin + + + org.apache.ant + eclipse-plugin + + + org.eclipse.equinox.p2.repository.tools + eclipse-plugin + + + org.eclipse.equinox.p2.core.feature + eclipse-feature + + + org.eclipse.equinox.p2.extras.feature + eclipse-feature + + + org.eclipse.equinox.ds + eclipse-plugin + + + - deploy-to-artifactory - deploy + add-p2-composite-repository + package - exec + eclipse-run - - false - false - ${project.basedir} - bash - - ${project.basedir}/upload.sh - ${parsedVersion.majorVersion}.${parsedVersion.minorVersion} - - - diff --git a/com.minres.coredsl/src/com/minres/coredsl/CoreDslRuntimeModule.xtend b/com.minres.coredsl/src/com/minres/coredsl/CoreDslRuntimeModule.xtend index c42f8702..23543d32 100644 --- a/com.minres.coredsl/src/com/minres/coredsl/CoreDslRuntimeModule.xtend +++ b/com.minres.coredsl/src/com/minres/coredsl/CoreDslRuntimeModule.xtend @@ -10,6 +10,7 @@ import com.minres.coredsl.scoping.CoreDslResourceDescriptionStrategy import org.eclipse.xtext.resource.IDefaultResourceDescriptionStrategy import com.minres.coredsl.scoping.CoreDslGlobalScopeProvider import org.eclipse.xtext.scoping.impl.ImportUriGlobalScopeProvider +import org.eclipse.xtext.xtext.XtextResourceDescriptionStrategy /** * Use this class to register components to be used at runtime / without the Equinox extension registry. @@ -19,11 +20,22 @@ class CoreDslRuntimeModule extends AbstractCoreDslRuntimeModule { return CoreDslTerminalConverters } +// override configureIScopeProviderDelegate(com.google.inject.Binder binder) { +// binder.bind(org.eclipse.xtext.scoping.IScopeProvider) +// .annotatedWith(com.google.inject.name.Names.named(org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.NAMED_DELEGATE)) +// .to(org.eclipse.xtext.scoping.impl.SimpleLocalScopeProvider); +// } + override Class bindIGlobalScopeProvider() { return ImportUriGlobalScopeProvider } + +// override Class bindIQualifiedNameProvider() { +// return org.eclipse.xtext.naming.SimpleNameProvider; +// } def Class bindIDefaultResourceDescriptionStrategy() { return CoreDslResourceDescriptionStrategy + //return XtextResourceDescriptionStrategy } } diff --git a/pom.xml b/pom.xml index b69abaf4..5b2258cc 100644 --- a/pom.xml +++ b/pom.xml @@ -20,6 +20,7 @@ true + ${project.basedir}/../../.. com.minres.coredsl.target From a72b853dbe9ae04d1aceedab5b6ed09242052fe3 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 28 Nov 2021 12:44:44 +0100 Subject: [PATCH 14/14] implement gh-pages deploy step --- README.md | 13 ++++--------- com.minres.coredsl.repository/pom.xml | 14 +++----------- pom.xml | 7 +------ 3 files changed, 8 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index c0dffe3f..429c7c2d 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,11 @@ # CoreDSL -This repo contains the XText bundles/plugins for CoreDSL. The bundles can be installed from +This repo contains the XText bundles/plugins for [CoreDSL](https://minres.github.io/CoreDSL). The OSGI bundles can be installed from https://minres.github.io/CoreDSL/repository. -| Version | URL | -|---------|-------------------------------------------------------------------| -| Latest | https://artifactory.minres.com/artifactory/eclipse/CoreDSL/latest | -| 2.0.x | https://artifactory.minres.com/artifactory/eclipse/CoreDSL/2.0 | +## Language documentation + +[Programmer's manual](https://github.com/Minres/CoreDSL/wiki/CoreDSL-2-programmer's-manual) ## References @@ -17,7 +16,3 @@ https://www.lysator.liu.se/c/ANSI-C-grammar-y.html ## EBNF The generated ANTLR grammar (DebugInternalCoreDsl.g) can be converted into EBNF using https://bottlecaps.de/convert/ to create a formal specification of the language - -## Language documentation - -[Programmer's manual](https://github.com/Minres/CoreDSL/wiki/CoreDSL-2-programmer's-manual) diff --git a/com.minres.coredsl.repository/pom.xml b/com.minres.coredsl.repository/pom.xml index ff05bb66..1590396a 100644 --- a/com.minres.coredsl.repository/pom.xml +++ b/com.minres.coredsl.repository/pom.xml @@ -59,19 +59,10 @@ - deploy-remote + release-composite false - - - ftp://your.server.com - /yourpath - - ${project.build.directory}/repository/ - false - - @@ -118,7 +109,7 @@ ${tycho-version} - -application org.eclipse.ant.core.antRunner -buildfile packaging-p2-composite.ant p2.composite.add -Dsite.label="CoreDSL Software Repository" -Dproject.build.directory=${project.build.directory} -DunqualifiedVersion=${unqualifiedVersion} -Dsoftware.download.area="${software.download.area}/CoreDSL-gh/repository" + -application org.eclipse.ant.core.antRunner -buildfile packaging-p2-composite.ant p2.composite.add -Dsite.label="CoreDSL Software Repository" -Dproject.build.directory=${project.build.directory} -DunqualifiedVersion=${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion} -Dsoftware.download.area="${software.download.area}/CoreDSL-gh/repository" 2020-03 @@ -163,6 +154,7 @@ + diff --git a/pom.xml b/pom.xml index 5b2258cc..fa6b74d6 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ true - ${project.basedir}/../../.. + ${project.basedir}/../.. com.minres.coredsl.target @@ -318,11 +318,6 @@ false - - bintray-devexperts-Maven - bintray-plugins - https://dl.bintray.com/devexperts/Maven -