Castle: The best Real-Time/Embedded/HighTech language EVER. Attempt 2
Revision | 9dc4234ea76047429e99b83e41550fbe90149aef (tree) |
---|---|
Time | 2023-02-17 23:09:29 |
Author | Albert Mietus < albert AT mietus DOT nl > |
Commiter | Albert Mietus < albert AT mietus DOT nl > |
asis
@@ -2,6 +2,7 @@ | ||
2 | 2 | |
3 | 3 | __all__ = ['CC_B_ComponentInterface', 'CC_Port', 'CC_PortDirection', 'CC_B_ComponentClass'] |
4 | 4 | |
5 | +import logging; logger = logging.getLogger(__name__) | |
5 | 6 | |
6 | 7 | from .CCbase import * |
7 | 8 | from castle.auxiliary.pack import mk_tuple |
@@ -33,9 +34,11 @@ | ||
33 | 34 | return next(p for p in self.ports if p.name=='try') |
34 | 35 | |
35 | 36 | def render(self, prepend:str="", indent:str=" ") ->str: |
36 | - return self.render_Fill_Interface(prepend=prepend, indent=indent) | |
37 | + return ( | |
38 | + self.render_Fill_Interface(prepend=prepend, indent=indent)\ | |
39 | + ) | |
37 | 40 | |
38 | - def render_Fill_Interface(self, prepend:str="", indent:str=" ") ->str: ## struct CC_B_ComponentInterface `cc_CI_$name` = ... | |
41 | + def render_Fill_Interface(self, prepend:str="", indent:str=" ") ->str: ## struct CC_B_ComponentInterface `cc_CI_$name` = ... | |
39 | 42 | name = f'cc_CI_{self.name}' |
40 | 43 | based_on_link = f'&cc_CI_{self.based_on[0].name}' if self.based_on else "NULL" |
41 | 44 |
@@ -68,28 +71,74 @@ | ||
68 | 71 | class CC_B_ComponentClass(CC_Base): |
69 | 72 | metaclass="NULL" # //NULL for now, later: meta-class |
70 | 73 | interface: CC_B_ComponentInterface |
71 | - handlers: Sequence[CC_Handler] =() # EventHanders, DataHandler, StreamHandlers, and all-other-protocolHandlers | |
72 | - methods: Sequence[CC_Method] =() # All kind of "internal only" callable(s) | |
74 | + _: KW_ONLY | |
75 | + data_members: Sequence[CC_TypedParameter]=() # (own) Data-members | |
76 | + handlers: Sequence[CC_Handler] =() # EventHanders, DataHandler, StreamHandlers, and all-other-protocolHandlers | |
77 | + methods: Sequence[CC_Method] =() # All kind of "internal only" callable(s) | |
78 | + | |
79 | + def _name(self): return self.interface.name | |
80 | + def portray_interface_name(self): return f'cc_CI_{self._name()}' | |
81 | + def portray_Typedef_CompName(self): return f'CC_C_{self._name()}' | |
82 | + def portray_methods_name(self): return f'cc_S_{self._name()}_methods' | |
73 | 83 | |
74 | 84 | def render(self, prepend:str="", indent:str=" ") ->str: |
75 | - return self.render_Fill_ComponentClass(prepend=prepend, indent=indent) | |
85 | + """.. note:: The order of generated code is relevant! | |
76 | 86 | |
87 | + As the CC_B_ComponentClass (variable) refers to CC_C_$CompName (typedef) [by sizeof()], | |
88 | + we need to call render_Typedef_CompName first!""" | |
89 | + return ( "\n"+ | |
90 | + self.render_Typedef_CompName(prepend=prepend, indent=indent) + "\n" + | |
91 | + self.render_handlers(prepend=prepend, indent=indent) + "\n" + | |
92 | + self.render_methods(prepend=prepend, indent=indent) + "\n" + | |
93 | + self.render_(prepend=prepend, indent=indent) + "\n" + | |
94 | + | |
95 | + self.render_Fill_ComponentClass(prepend=prepend, indent=indent) + "\n" + | |
96 | + "\n" ) | |
77 | 97 | |
78 | 98 | def render_Fill_ComponentClass(self, prepend:str="", indent:str=" ") ->str: ## struct CC_B_ComponentClass cc_C_$name {...} |
79 | - name = self.interface.name | |
80 | - interface_name = f'cc_CI_{name}' | |
81 | - comp_TypeName = f'CC_C_{name}' | |
82 | - methods_name = f'cc_B_{name}_methods' | |
99 | + interface_name = self.portray_interface_name() | |
100 | + Typedef_CompName = self.portray_Typedef_CompName() | |
101 | + methods_name = self.portray_methods_name() | |
83 | 102 | |
84 | 103 | retval = [] |
85 | 104 | retval.append(f'{prepend}struct CC_B_ComponentClass cc_C_{self.interface.name} = {{') |
86 | 105 | retval.append(f'{prepend}{indent}.isa = {self.metaclass},') |
87 | 106 | retval.append(f'{prepend}{indent}.interface = &{interface_name},') |
88 | - retval.append(f'{prepend}{indent}.instance_size = sizeof({comp_TypeName}),') | |
107 | + retval.append(f'{prepend}{indent}.instance_size = sizeof({Typedef_CompName}),') | |
89 | 108 | retval.append(f'{prepend}{indent}.methods = {methods_name},') |
90 | 109 | retval.append(f'{prepend}}};') |
91 | 110 | |
92 | 111 | return '\n'.join(retval)+"\n" |
93 | 112 | |
94 | - def render_CompName(self, prepend:str="", indent:str=" ") ->str: ## typedef struct CC_C_$CompName | |
95 | - pass | |
113 | + def render_Typedef_CompName(self, prepend:str="", indent:str=" ") ->str: ## typedef struct CC_C_$CompName | |
114 | + """.. note:: Asume simple inheritance | |
115 | + | |
116 | + :need:`Tools_No_MultipleInheritance-in-1compiler` | |
117 | + http://docideas.mietus.nl/en/default/CCastle/3.Design/zz.todo.html#Tools_No_MultipleInheritance-in-1compiler""" | |
118 | + Typedef_CompName = self.portray_Typedef_CompName() | |
119 | + retval = [] | |
120 | + retval.append(f'{prepend}typedef struct {{') | |
121 | + for bc in self._bases_classes(): #XXX | |
122 | + retval += bc.prerender_CompName_elements(prepend,indent) | |
123 | + retval += self.prerender_CompName_elements(prepend,indent) | |
124 | + retval.append(f'}} {Typedef_CompName};') | |
125 | + | |
126 | + return '\n'.join(retval)+"\n" | |
127 | + | |
128 | + def _bases_classes(self) ->Sequence: #XXX | |
129 | + return () #XXX WRONG | |
130 | + | |
131 | + def prerender_CompName_elements(self, prepend:str="", indent:str=" ") ->Sequence[str]: | |
132 | + retval=[] | |
133 | + logger.debug('.data_members)[%s]:: %s', len(self.data_members), self.data_members) | |
134 | + for d in self.data_members: | |
135 | + retval.append(f'{prepend}{indent}{d.type} \t {d.name};') # XXX type is not a string | |
136 | + logger.debug('.handlers)[%s]:: %s', len(self.handlers), self.handlers) | |
137 | + for h in self.handlers: | |
138 | + retval.append(f'{prepend}{indent}struct CC_B_OutPort \t {h.port.name};') | |
139 | + logger.debug('.methods)[%s]:: %s', len(self.methods), self.methods) | |
140 | + for m in self.methods: | |
141 | + retval.append(f'{prepend}{indent} /*XXXXX*/') | |
142 | + | |
143 | + logger.debug('\n'+'\n'.join(retval)) | |
144 | + return retval |
@@ -73,7 +73,7 @@ | ||
73 | 73 | f.write(sieveInterface.render()) |
74 | 74 | verify_it_compiles(f.name, tmp_path) |
75 | 75 | |
76 | -#@pytest.mark.skip(reason="sieveClass refer to ``cc_B_Sieve_methods`` and ``CC_C_Sieve`` which aren't renderable yet") | |
76 | +@pytest.mark.skip(reason="sieveClass refer to ``cc_B_Sieve_methods`` and ``CC_C_Sieve`` which aren't renderable yet") | |
77 | 77 | def test_1b_ProtoInterClass(simpleSieveProto, sieveInterface, sieveClass, tmp_path): |
78 | 78 | FILE="sieve-ProtoInterClass.c" |
79 | 79 | with open(tmp_path/FILE, 'w') as f: |