diff --git a/src/gboml/semantic.py b/src/gboml/semantic.py new file mode 100644 index 0000000000000000000000000000000000000000..5b0d0528bab8b10e544159f1d83acfc558e8760a --- /dev/null +++ b/src/gboml/semantic.py @@ -0,0 +1,35 @@ +from gboml.ast import * +from gboml.scope import * +from gboml.tools.tree_modifier import visit + +# NodeDefinition(name='H', import_from=None, parameters=[], nodes=[], hyperedges=[], variables=[VariableDefinition(name='x', indices=[], scope=ScopedVariableDefinition(name='x', path=['H', 'x'], content={'x': ..., 'y': ScopedVariableDefinition(name='y', path=['H', 'y'], content={...}, ast=VariableDefinition(name='y', indices=[], scope=..., type=<VarType.continuous: 'continuous'>, bound_lower=None, bound_upper=None, import_from=None, tags=set())), 'root': ParentNodeScope(name='root', path=[], content={'global': GlobalScope(name='global', path=['global'], content={'b': ScopedDefinition(name='b', path=['global', 'b'], content={...}, ast=ConstantDefinition(name='b', value=4, tags=set()))}), 'H': DefNodeScope(name='H', path=['H'], content={...}, ast=...)})}, ast=...), type=<VarType.continuous: 'continuous'>, bound_lower=None, bound_upper=None, import_from=None, tags=set()), VariableDefinition(name='y', indices=[], scope=ScopedVariableDefinition(name='y', path=['H', 'y'], content={'x': ScopedVariableDefinition(name='x', path=['H', 'x'], content={...}, ast=VariableDefinition(name='x', indices=[], scope=..., type=<VarType.continuous: 'continuous'>, bound_lower=None, bound_upper=None, import_from=None, tags=set())), 'y': ..., 'root': ParentNodeScope(name='root', path=[], content={'global': GlobalScope(name='global', path=['global'], content={'b': ScopedDefinition(name='b', path=['global', 'b'], content={...}, ast=ConstantDefinition(name='b', value=4, tags=set()))}), 'H': DefNodeScope(name='H', path=['H'], content={...}, ast=...)})}, ast=...), type=<VarType.continuous: 'continuous'>, bound_lower=None, bound_upper=None, import_from=None, tags=set())], constraints=[StdConstraint(name=None, lhs=VarOrParam(path=[VarOrParamLeaf(name='x', indices=[])]), op=<Operator.lesser_or_equal: '<='>, rhs=ExpressionOp(operator=<Operator.unary_minus: 'u-'>, operands=[4]), loop=None, tags=set())], objectives=[Objective(type=<ObjType.max: 'max'>, name=None, expression=ExpressionOp(operator=<Operator.plus: '+'>, operands=[VarOrParam(path=[VarOrParamLeaf(name='x', indices=[])]), VarOrParam(path=[VarOrParamLeaf(name='global', indices=[]), VarOrParamLeaf(name='b', indices=[])])]), loop=None, tags=set())], activations=[], tags=set()) + + +def _appendErrors(element: GBOMLObject, defNodeScope: DefNodeScope) -> None: + + # if element.path[0].name not in defNodeScope.content and element.path[0].name not in defNodeScope.parent.content: + # print(f"SEMANTIC ERROR: {element.path[0].name} not declared in this scope {element.meta}!") + # print(defNodeScope.parent) + # else: + # print(f"semantic ok: {element.path[0].name} declared in scope {element.meta}") + + for subElement in element.path: + print(f"SubElement {subElement.name}") + # if isinstance(defNodeScope, RootScope): + # print(defNodeScope) + # break + if subElement.name not in defNodeScope.content and subElement.name not in defNodeScope.parent.content: + print(f"SEMANTIC ERROR: {subElement.name} not declared in this scope {subElement.meta}!") + print(defNodeScope.parent) + else: + print(f"semantic ok: {subElement.name} declared in scope {subElement.meta}") + # print(defNodeScope.parent) + if subElement.name in defNodeScope.parent.content: + defNodeScope = defNodeScope.parent.content[subElement.name] + print(defNodeScope) + +def _visit_nodes(nodeDef: NodeDefinition) -> None: + visit(nodeDef, {VarOrParam: lambda _: _appendErrors(_, nodeDef.scope)}) + +def semantic_check(rootScope: RootScope): + visit(rootScope.ast, {NodeDefinition: _visit_nodes})