OD parser: use ODAPI instead of 'OD' service + support ActionCode-typed attributes

This commit is contained in:
Joeri Exelmans 2024-11-05 13:58:40 +01:00
parent 16604d0f0b
commit 75d938d2be
2 changed files with 14 additions and 20 deletions

View file

@ -117,7 +117,7 @@ class ODAPI:
return self.get_value(self.get_slot(obj, attr_name)) return self.get_value(self.get_slot(obj, attr_name))
# create or update slot value # create or update slot value
def set_slot_value(self, obj: UUID, attr_name: str, new_value: any): def set_slot_value(self, obj: UUID, attr_name: str, new_value: any, is_code=False):
obj_name = self.get_name(obj) obj_name = self.get_name(obj)
link_name = f"{obj_name}_{attr_name}" link_name = f"{obj_name}_{attr_name}"
@ -129,12 +129,14 @@ class ODAPI:
# if old_target != None: # if old_target != None:
self.bottom.delete_element(old_target) # this also deletes the slot-link self.bottom.delete_element(old_target) # this also deletes the slot-link
new_target = self.create_primitive_value(target_name, new_value) new_target = self.create_primitive_value(target_name, new_value, is_code)
slot_type = self.cd.find_attribute_type(self.get_type_name(obj), attr_name) slot_type = self.cd.find_attribute_type(self.get_type_name(obj), attr_name)
new_link = self.od._create_link(link_name, slot_type, obj, new_target) new_link = self.od._create_link(link_name, slot_type, obj, new_target)
self.__recompute_mappings() self.__recompute_mappings()
def create_primitive_value(self, name: str, value: any, is_code=False): def create_primitive_value(self, name: str, value: any, is_code=False):
# watch out: in Python, 'bool' is subtype of 'int'
# so we must check for 'bool' first
if isinstance(value, bool): if isinstance(value, bool):
tgt = self.create_boolean_value(name, value) tgt = self.create_boolean_value(name, value)
elif isinstance(value, int): elif isinstance(value, int):

View file

@ -2,7 +2,7 @@
from lark import Lark, logger from lark import Lark, logger
from lark.indenter import Indenter from lark.indenter import Indenter
from services.od import OD from api.od import ODAPI
from services.scd import SCD from services.scd import SCD
from concrete_syntax.common import _Code, TBase from concrete_syntax.common import _Code, TBase
from uuid import UUID from uuid import UUID
@ -45,11 +45,11 @@ def parse_od(state, m_text, mm):
tree = parser.parse(m_text) tree = parser.parse(m_text)
m = state.create_node() m = state.create_node()
od = OD(mm, m, state) od = ODAPI(state, m, mm)
primitive_types = { primitive_types = {
type_name : UUID(state.read_value(state.read_dict(state.read_root(), type_name))) type_name : UUID(state.read_value(state.read_dict(state.read_root(), type_name)))
for type_name in ["Integer", "String", "Boolean"] for type_name in ["Integer", "String", "Boolean", "ActionCode"]
} }
class T(TBase): class T(TBase):
@ -83,23 +83,15 @@ def parse_od(state, m_text, mm):
if state.read_dict(m, tgt) == None: if state.read_dict(m, tgt) == None:
scd = SCD(m, state) scd = SCD(m, state)
scd.create_model_ref(tgt, primitive_types[tgt]) scd.create_model_ref(tgt, primitive_types[tgt])
od.create_link(obj_name, type_name, src, tgt) src_obj = od.get(src)
tgt_obj = od.get(tgt)
obj_node = od.create_link(obj_name, type_name, src_obj, tgt_obj)
# Create slots # Create slots
for attr_name, value in slots: for attr_name, value in slots:
value_name = f"{obj_name}.{attr_name}" if isinstance(value, _Code):
# watch out: in Python, 'bool' is subtype of 'int' od.set_slot_value(obj_node, attr_name, value.code, is_code=True)
# so we must check for 'bool' first
if isinstance(value, bool):
od.create_boolean_value(value_name, value)
elif isinstance(value, int):
od.create_integer_value(value_name, value)
elif isinstance(value, str):
od.create_string_value(value_name, value)
elif isinstance(value, _Code):
od.create_actioncode_value(value_name, value.code)
else: else:
raise Exception("Unimplemented type "+value) od.set_slot_value(obj_node, attr_name, value)
od.create_slot(attr_name, obj_name, value_name)
return obj_name return obj_name