From 75d938d2bec1a775431249f190b8404d53c94381 Mon Sep 17 00:00:00 2001 From: Joeri Exelmans Date: Tue, 5 Nov 2024 13:58:40 +0100 Subject: [PATCH] OD parser: use ODAPI instead of 'OD' service + support ActionCode-typed attributes --- api/od.py | 8 +++++--- concrete_syntax/textual_od/parser.py | 26 +++++++++----------------- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/api/od.py b/api/od.py index aee5961..c641f4f 100644 --- a/api/od.py +++ b/api/od.py @@ -117,7 +117,7 @@ class ODAPI: return self.get_value(self.get_slot(obj, attr_name)) # 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) link_name = f"{obj_name}_{attr_name}" @@ -129,12 +129,14 @@ class ODAPI: # if old_target != None: 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) new_link = self.od._create_link(link_name, slot_type, obj, new_target) self.__recompute_mappings() 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): tgt = self.create_boolean_value(name, value) elif isinstance(value, int): @@ -160,4 +162,4 @@ class ODAPI: return link_id def create_object(self, object_name: Optional[str], class_name: str): - return self.od.create_object(object_name, class_name) \ No newline at end of file + return self.od.create_object(object_name, class_name) diff --git a/concrete_syntax/textual_od/parser.py b/concrete_syntax/textual_od/parser.py index ec791bc..5dda904 100644 --- a/concrete_syntax/textual_od/parser.py +++ b/concrete_syntax/textual_od/parser.py @@ -2,7 +2,7 @@ from lark import Lark, logger from lark.indenter import Indenter -from services.od import OD +from api.od import ODAPI from services.scd import SCD from concrete_syntax.common import _Code, TBase from uuid import UUID @@ -45,11 +45,11 @@ def parse_od(state, m_text, mm): tree = parser.parse(m_text) m = state.create_node() - od = OD(mm, m, state) + od = ODAPI(state, m, mm) primitive_types = { 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): @@ -83,23 +83,15 @@ def parse_od(state, m_text, mm): if state.read_dict(m, tgt) == None: scd = SCD(m, state) 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 for attr_name, value in slots: - value_name = f"{obj_name}.{attr_name}" - # watch out: in Python, 'bool' is subtype of 'int' - # 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) + if isinstance(value, _Code): + od.set_slot_value(obj_node, attr_name, value.code, is_code=True) else: - raise Exception("Unimplemented type "+value) - od.create_slot(attr_name, obj_name, value_name) + od.set_slot_value(obj_node, attr_name, value) return obj_name