1 A Systems Programming Language Target for Micropython
2 =====================================================
3
4 Python-compatible syntax for processing using the compiler module.
5
6 The principal focus is on specific machine code generation and not
7 analysis. Thus, only block generation, address reference generation,
8 temporary storage administration and other code generation tasks are to be
9 left to the systems programming language compiler.
10
11 Program Data and Data Structure Definition
12 ------------------------------------------
13
14 Given that micropython has already deduced object and parameter details,
15 such information must be communicated in the systems programming language
16 so that the compiler does not have to deduce it again.
17
18 Explicit constant declaration shall be done at the start of the main
19 module:
20
21 __constants__(...)
22
23 Explicit structure declaration is still performed using class statements,
24 but base classes are omitted and attributes are declared explicitly as
25 follows:
26
27 class C:
28 __instattrs__(member...)
29 __classattrs__(member...)
30
31 Other object table information, such as inherited class attributes and
32 class compatibility (to support isinstance) are also declared explicitly:
33
34 __inherited__(superclass, member...)
35 __descendants__(class...)
36
37 Other than function definitions, no other code statements shall appear in
38 class definitions; such statements will appear after classes have been
39 defined.
40
41 For classes in the module namespace or within other classes, the __main__
42 function collects together all "loose" (module-level) statements; class
43 attribute assignments will occur in the __main__ function, and where a name
44 is associated with a function definition and another object, the function will
45 also be explicitly assigned in the __main__ function using its full name.
46
47 For classes in function namespaces, the containing function could contain the
48 "loose" statements at the point at which the class appears. However, such
49 classes are not currently supported in micropython.
50
51 Any class or function defined once in a namespace need not be assigned to that
52 namespace in the __main__ function, but where multiple definitions exist and
53 program logic determines which definition prevails, such definitions must be
54 assigned in the __main__ function.
55
56 For example:
57
58 class C:
59 def method(self, ...):
60 ...
61 if something:
62 method = something
63
64 This is represented as follows:
65
66 class C:
67 ...
68 def method(self, ...):
69 ...
70
71 def __main__():
72 __globalnames__(...)
73 ...
74 if something:
75 __storeattr__(module.C, method, something)
76
77 Imports
78 -------
79
80 Imports act as invocations of module code and name assignments within a
81 particular scope and are defined as follows:
82
83 # import package
84 package.__main__()
85 package = __static__(package)
86
87 # import package.module
88 package.__main__()
89 package.module.__main__()
90 package = __static__(package)
91
92 # from package.module import cls
93 package.__main__()
94 package.module.__main__()
95 cls = __loadattribute__(package.module, cls) # see below
96
97 Since import statements can appear in code that may be executed more than
98 once, __main__ functions should test and set a flag indicating whether the
99 function has already been called.
100
101 Python would arguably be more sensible as a language if imports were
102 processed separately, but this would then rule out logic controlling the
103 use of modules.
104
105 Name and Attribute Declarations
106 -------------------------------
107
108 Assignments and name usage involve locals and globals but usage is declared
109 explicitly:
110
111 __localnames__(...)
112
113 At the function level, locals are genuine local name definitions whereas
114 globals refer to module globals:
115
116 __globalnames__(...)
117
118 At the module level, locals are effectively equivalent to module globals but
119 are declared as follows:
120
121 __moduleattrs__(...)
122
123 Each module's __main__ function will declare any referenced module globals as
124 globals. Note that the __main__ function is not a genuine attribute of any
125 module but an internal construct used to initialise modules appropriately.
126
127 Such declarations must appear first in a program unit (module, function).
128 For example:
129
130 def f(a, b):
131 __localnames__(a, b, x, y)
132 __globalnames__(f, g)
133
134 __storelocal__(x, 1)
135 __storelocal__(y, x)
136 __storelocal__(a, b)
137 __storeattr__(module, g, f)
138
139 Names and Attributes
140 --------------------
141
142 Bare names refer to locals or globals according to the __localnames__ and
143 __globalnames__ declarations, or to constants such as None, True, False and
144 NotImplemented. Storage of local or global names is done using explicit
145 functions as follows:
146
147 __storelocal__(name, value)
148 __storeattr__(module, name, value) # see below
149
150 No operator usage: all operators are converted to invocations, including
151 all attribute access except static references to modules or particular class
152 or function definitions using the following notation:
153
154 __static__(package)
155 __static__(package.module)
156 __static__(package.module.cls)
157 __static__(package.module.cls.function)
158
159 A shorthand dot notation could be employed:
160
161 package.module
162 package.module.cls
163 package.module.cls.function
164
165 Where multiple definitions of static objects occur, the dot notation cannot be
166 used, and the full name of such definitions must be quoted. For example:
167
168 __static__("package.module.cls#1.function")
169
170 In general, attribute access must use an explicit function indicating the
171 kind of access operation being performed. For example:
172
173 __loadattr__(obj, attrname) # preserve context
174 __loadattrcontext__(obj, attrname) # replace context with obj
175 __loadattrcontextcond__(obj, attrname) # run-time context decision
176 __loadattrindex__(obj, attrname) # preserve context
177 __loadattrindexcontext__(obj, attrname) # replace context with obj
178 __loadattrindexcontextcond__(obj, attrname) # run-time context decision
179
180 __storeattr__(obj, attrname, value) # preserve context
181 __storeattrcontext__(obj, attrname, value) # replace context
182 __storeattrindex__(obj, attrname, value)
183
184 Temporary variables could employ similar functions:
185
186 __loadtemp__(0)
187 __storetemp__(0, value)
188
189 Operators and Invocations
190 -------------------------
191
192 Conventional operators use the operator functions.
193
194 Special operators could also use the operator functions (where available)
195 but might as well be supported directly:
196
197 __is__(a, b)
198
199 Logical operators involving short-circuit evaluation could be represented
200 as function calls, but the evaluation semantics would be preserved:
201
202 __and__(...) # returns the first non-true value or the final value
203 __not__(obj) # returns the inverse of the boolean interpretation of obj
204 __or__(...) # returns the first true value or the final value
205
206 Comparisons could be rephrased in a verbose fashion:
207
208 a < b < c becomes lt(a, b) and lt(b, c)
209 or __and__(lt(a, b), lt(b, c))
210
211 Advanced Control-Flow
212 ---------------------
213
214 Any statements requiring control-flow definition in terms of blocks must
215 be handled in the language as the notions of labels and blocks are not
216 introduced earlier apart from the special case of jumping to another
217 callable (described below).
218
219 Special functions for low-level operations:
220
221 __check__(obj, type)
222 __jump__(callable)
223
224 Function/subroutine definition with entry points for checked and unchecked
225 parameters.
226
227 def fn_checked(self, ...):
228 __check__(self, Type) # raises a TypeError if not isinstance(self, Type)
229 __jump__(fn_unchecked) # preserves the frame and return address
230
231 def fn_unchecked(self, ...):
232 ...
233
234 The __jump__ function might also be used for inlining appropriate functions.
235
236 Exceptions must also be handled in the language.
237
238 Object Type Detection
239 ---------------------
240
241 Occasionally, the type of an object (instance of a particular class, class,
242 and so on) needs to be determined at run-time:
243
244 __isclass__(obj)