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 in a __main__ function collecting together all "loose"
40 (module-level) statements; class attribute assignments will occur in the
41 __main__ function, and where a name is associated with a function definition
42 and another object, the function will also be explicitly assigned in the
43 __main__ function using its full name.
44
45 Any class or function defined once in a namespace need not be assigned to that
46 namespace in the __main__ function, but where multiple definitions exist and
47 program logic determines which definition prevails, such definitions must be
48 assigned in the __main__ function.
49
50 For example:
51
52 class C:
53 def method(self, ...):
54 ...
55 if something:
56 method = something
57
58 This is represented as follows:
59
60 class C:
61 ...
62 def method(self, ...):
63 ...
64
65 def __main__():
66 ...
67 method = module.C.method
68 if something:
69 __storeaddress__(module.C, something)
70
71 Imports
72 -------
73
74 Imports act as invocations of module code and name assignments within a
75 particular scope and are defined as follows:
76
77 # import package
78 package.__main__()
79 package = __module__(package)
80
81 # import package.module
82 package.__main__()
83 package.module.__main__()
84 package = __module__(package)
85
86 # from package.module import cls
87 package.__main__()
88 package.module.__main__()
89 cls = __loadattribute__(package.module, cls) # see below
90
91 Since import statements can appear in code that may be executed more than
92 once, __main__ functions should test and set a flag indicating whether the
93 function has already been called.
94
95 Python would arguably be more sensible as a language if imports were
96 processed separately, but this would then rule out logic controlling the
97 use of modules.
98
99 Name and Attribute Declarations
100 -------------------------------
101
102 Assignments and name usage involve locals and globals but usage is declared
103 explicitly:
104
105 __localnames__(...)
106
107 At the function level, locals are genuine local name definitions whereas
108 globals refer to module globals:
109
110 __globalnames__(...)
111
112 At the module level, locals are effectively equivalent to module globals but
113 are declared as follows:
114
115 __moduleattrs__(...)
116
117 Each module's __main__ function will declare any referenced module globals as
118 globals. Note that the __main__ function is not a genuine attribute of any
119 module but an internal construct used to initialise modules appropriately.
120
121 Such declarations must appear first in a program unit (module, function).
122 For example:
123
124 def f(a, b):
125 __localnames__(a, b, x, y)
126 __globalnames__(f, g)
127
128 x = 1 # local
129 y = x # locals
130 a = b # locals
131 g = f # globals
132
133 Names and Attributes
134 --------------------
135
136 No operator usage: all operators are converted to invocations, including
137 all attribute access except static references to modules or particular class
138 or function definitions using the following notation:
139
140 __static__(package)
141 __static__(package.module)
142 __static__(package.module.cls)
143 __static__(package.module.cls.function)
144
145 A shorthand dot notation could be employed:
146
147 package.module
148 package.module.cls
149 package.module.cls.function
150
151 Where multiple definitions of static objects occur, the dot notation cannot be
152 used, and the full name of such definitions must be quoted. For example:
153
154 __static__("package.module.cls#1.function")
155
156 In general, attribute access must use an explicit function indicating the
157 kind of access operation being performed. For example:
158
159 __loadaddress__(obj, attrname)
160 __loadaddresscontext__(obj, attrname)
161 __loadaddresscontextcond__(obj, attrname)
162 __loadattr__(obj, attrname)
163 __loadattrindex__(obj, attrname)
164 __loadattrindexcontext__(obj, attrname)
165 __loadattrindexcontextcond__(obj, attrname)
166
167 __storeaddress__(obj, attrname, value)
168 __storeaddresscontext__(obj, attrname, value)
169 __storeattr__(obj, attrname, value)
170 __storeattrindex__(obj, attrname, value)
171
172 Operators and Invocations
173 -------------------------
174
175 Conventional operators use the operator functions.
176
177 Special operators could also use the operator functions (where available)
178 but might as well be supported directly:
179
180 __is__(a, b)
181
182 Logical operators involving short-circuit evaluation could be represented
183 as function calls, but the evaluation semantics would be preserved:
184
185 __and__(...) # returns the first non-true value or the final value
186 __not__(obj) # returns the inverse of the boolean interpretation of obj
187 __or__(...) # returns the first true value or the final value
188
189 Comparisons could be rephrased in a verbose fashion:
190
191 a < b < c becomes lt(a, b) and lt(b, c)
192 or __and__(lt(a, b), lt(b, c))
193
194 Advanced Control-Flow
195 ---------------------
196
197 Any statements requiring control-flow definition in terms of blocks must
198 be handled in the language as the notions of labels and blocks are not
199 introduced earlier apart from the special case of jumping to another
200 callable (described below).
201
202 Special functions for low-level operations:
203
204 __check__(obj, type)
205 __jump__(callable)
206
207 Function/subroutine definition with entry points for checked and unchecked
208 parameters.
209
210 def fn_checked(self, ...):
211 __check__(self, Type) # raises a TypeError if not isinstance(self, Type)
212 __jump__(fn_unchecked) # preserves the frame and return address
213
214 def fn_unchecked(self, ...):
215 ...
216
217 Exceptions must also be handled in the language.