diff --git a/src/gboml/ast/__init__.py b/src/gboml/ast/__init__.py index be4da11911fda64d808d7a09d793473f7633fa02..fa27dbea0206990074b5f599883fdbea3f82f96f 100644 --- a/src/gboml/ast/__init__.py +++ b/src/gboml/ast/__init__.py @@ -8,7 +8,7 @@ __all__ = [ "ExpressionOp", "GBOMLGraph", "ImplicitLoop", "RValue", "RValueWithGen", "GeneratedRValue", "Range", "MultiLoop", "DictEntry", "Dictionary", "NodeGenerator", "HyperEdgeGenerator", "DefinitionType", "FunctionDefinition", "ConstantDefinition", "ExpressionDefinition", - "CtrActivation", "ObjActivation", "ActivationType", "Activation" + "CtrActivation", "ObjActivation", "ActivationType", "Activation", "Extends" ] from gboml.ast.arrays import * diff --git a/src/gboml/ast/hyperedges.py b/src/gboml/ast/hyperedges.py index f6fdeb73e2f0a0d930890590925e8ee552edc3f2..bbeeedddf26df94a7b4bc3fa5e236e462e86bdf9 100644 --- a/src/gboml/ast/hyperedges.py +++ b/src/gboml/ast/hyperedges.py @@ -1,6 +1,8 @@ from dataclasses import dataclass, field +from typing import Optional -from gboml.ast import Loop +from gboml.ast.importable import Extends +from gboml.ast.loops import Loop from gboml.ast.base import GBOMLObject from gboml.ast.constraints import Constraint, CtrActivation from gboml.ast.path import VarOrParam @@ -15,6 +17,7 @@ class HyperEdge(GBOMLObject): @dataclass class HyperEdgeDefinition(HyperEdge): name: str + import_from: Optional[Extends] = None parameters: list[Definition] = field(default_factory=list) constraints: list[Constraint] = field(default_factory=list) activations: list[CtrActivation] = field(default_factory=list) @@ -25,6 +28,7 @@ class HyperEdgeDefinition(HyperEdge): class HyperEdgeGenerator(HyperEdge): name: VarOrParam loop: Loop + import_from: Optional[Extends] = None parameters: list[Definition] = field(default_factory=list) constraints: list[Constraint] = field(default_factory=list) activations: list[CtrActivation] = field(default_factory=list) diff --git a/src/gboml/ast/importable.py b/src/gboml/ast/importable.py new file mode 100644 index 0000000000000000000000000000000000000000..7a3c16421d3b60779dc8235c541a3eb5ff45d314 --- /dev/null +++ b/src/gboml/ast/importable.py @@ -0,0 +1,11 @@ +from dataclasses import dataclass +from typing import Optional + +from gboml.ast.base import GBOMLObject +from gboml.ast.variables import VarOrParam + + +@dataclass +class Extends(GBOMLObject): + name: VarOrParam + filename: Optional[str] diff --git a/src/gboml/ast/nodes.py b/src/gboml/ast/nodes.py index 25dbef1db3652c7532e3317a8af6a66db77e8696..1ed435a8b1cdcfa8995af8f9f74b5c57eb9ab96a 100644 --- a/src/gboml/ast/nodes.py +++ b/src/gboml/ast/nodes.py @@ -1,8 +1,11 @@ from dataclasses import dataclass, field +from typing import Optional -from gboml.ast import Loop, Activation +from gboml.ast.loops import Loop +from gboml.ast.activation import Activation from gboml.ast.base import GBOMLObject from gboml.ast.constraints import Constraint +from gboml.ast.importable import Extends from gboml.ast.path import VarOrParam from gboml.ast.hyperedges import HyperEdge from gboml.ast.objectives import Objective @@ -17,6 +20,7 @@ class Node(GBOMLObject): @dataclass class NodeDefinition(Node): name: str + import_from: Optional[Extends] = None parameters: list[Definition] = field(default_factory=list) nodes: list[Node] = field(default_factory=list) hyperedges: list[HyperEdge] = field(default_factory=list) @@ -31,6 +35,7 @@ class NodeDefinition(Node): class NodeGenerator(Node): name: VarOrParam loop: Loop + import_from: Optional[Extends] = None parameters: list[Definition] = field(default_factory=list) nodes: list[Node] = field(default_factory=list) hyperedges: list[HyperEdge] = field(default_factory=list) diff --git a/src/gboml/gboml.lark b/src/gboml/gboml.lark index 361c1f10609b23dce6ac0f4d2aa32998321587cc..49597aaad8d3164f99877cb2afd3b00dcfdb1c65 100644 --- a/src/gboml/gboml.lark +++ b/src/gboml/gboml.lark @@ -31,10 +31,13 @@ _program: node | hyperedge tags: TAG* TAG: /@[a-zA-Z\-_]+/ +// Extends +extends: "extends" var_or_param ["from" STRING] + // NODES ?node: node_definition | node_import node_definition: _block_shortcut{_node_header, _node_content} -_node_header: "#NODE" var_or_param [loop] tags +_node_header: "#NODE" var_or_param [extends] [loop] tags _node_content: parameters_block program_block variables_block constraints_block objectives_block parameters_block: (_block_repeat_or_pass{_opt_param_header,definition})? @@ -54,7 +57,7 @@ variable_scope_change: ID SCOPE ";" ?hyperedge: hyperedge_definition | hyperedge_import hyperedge_definition: _block_shortcut{_hyperedge_header, _hyperedge_content} -_hyperedge_header: "#HYPEREDGE" var_or_param [loop] tags +_hyperedge_header: "#HYPEREDGE" var_or_param [extends] [loop] tags _hyperedge_content: parameters_block constraints_block hyperedge_import: "#HYPEREDGE" ID "=" "import" var_or_param "from" STRING hyperedge_redefs diff --git a/src/gboml/parsing.py b/src/gboml/parsing.py index c37a3413adc8582f502671c42a5a9d764e77ef31..2cff83189cf6da690165b3e4b31dee81c0c6f6ea 100644 --- a/src/gboml/parsing.py +++ b/src/gboml/parsing.py @@ -93,7 +93,8 @@ def _lark_to_gboml(tree: Tree, filename: Optional[str] = None) -> GBOMLGraph: "ctr_activate": lambda *x, meta: CtrActivation(ActivationType.activate, *x, meta=meta), "ctr_deactivate": lambda *x, meta: CtrActivation(ActivationType.deactivate, *x, meta=meta), "obj_activate": lambda *x, meta: ObjActivation(ActivationType.activate, *x, meta=meta), - "obj_deactivate": lambda *x, meta: ObjActivation(ActivationType.deactivate, *x, meta=meta) + "obj_deactivate": lambda *x, meta: ObjActivation(ActivationType.deactivate, *x, meta=meta), + "extends": Extends } def __default__(self, data, children, _): @@ -125,26 +126,25 @@ def _lark_to_gboml(tree: Tree, filename: Optional[str] = None) -> GBOMLGraph: def program_block(self, meta: Meta, *childrens: list[Node | HyperEdge]) -> NodesAndHyperEdges: return self.NodesAndHyperEdges([x for x in childrens if isinstance(x, Node)], [x for x in childrens if isinstance(x, HyperEdge)]) - def hyperedge_definition(self, meta: Meta, name: VarOrParam, loop: Optional[Loop], tags: list[str], - param_block: list[Definition] = None, + def hyperedge_definition(self, meta: Meta, name: VarOrParam, extends: Optional[Extends], + loop: Optional[Loop], tags: list[str], param_block: list[Definition] = None, constraint_block: list[Constraint | CtrActivation] = None): - if constraint_block is None: - constraint_block = [] + constraint_block = constraint_block or [] activations = [x for x in constraint_block if isinstance(x, CtrActivation)] constraint_block = [x for x in constraint_block if isinstance(x, Constraint)] - if param_block is None: - param_block = [] + param_block = param_block or [] if loop is None: if len(name.path) != 1 or len(name.path[0].indices) != 0: raise Exception(f"Invalid name for node: {name}") - return HyperEdgeDefinition(name.path[0].name, param_block, constraint_block, + return HyperEdgeDefinition(name.path[0].name, extends, param_block, constraint_block, activations, tags, meta=meta) else: - return HyperEdgeGenerator(name, loop, param_block, constraint_block, + return HyperEdgeGenerator(name, loop, extends, param_block, constraint_block, activations, tags, meta=meta) - def node_definition(self, meta: Meta, name: VarOrParam, loop: Optional[Loop], tags: list[str], + def node_definition(self, meta: Meta, name: VarOrParam, extends: Optional[Extends], + loop: Optional[Loop], tags: list[str], param_block: list[Definition] = None, subprogram_block: NodesAndHyperEdges = None, variable_block: list[VariableDefinition] = None, constraint_block: list[Constraint | CtrActivation] = None, @@ -162,14 +162,12 @@ def _lark_to_gboml(tree: Tree, filename: Optional[str] = None) -> GBOMLGraph: if loop is None: if len(name.path) != 1 or len(name.path[0].indices) != 0: raise Exception(f"Invalid name for node: {name}") - return NodeDefinition(name.path[0].name, - param_block, + return NodeDefinition(name.path[0].name, extends, param_block, subprogram_block.nodes, subprogram_block.hyperedges, variable_block, constraint_block, objectives_block, activations, tags, meta=meta) else: - return NodeGenerator(name, loop, - param_block, + return NodeGenerator(name, loop, extends, param_block, subprogram_block.nodes, subprogram_block.hyperedges, variable_block, constraint_block, objectives_block, activations, tags, meta=meta)