"at least two are of particular interest. Namely, `/py/`, where the python interpreter is implemented, and `/ports/`, which contains the hardware-specific files. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Constants\n",
"\n",
"In the implementation of micropython, everything revolves around objects of type `mp_obj_t`, which is defined in `obj.h`. Basically, `mp_obj_t` is nothing but an 8-byte segment of the memory, where all concrete objects are encoded. There can be various encodings, but the encoding is well-defined for a particular port. E.g., in the `A` encoding, integers are those objects, whose first bit in this 8-byte representation is set to 1, and the value of the integer can then be retrieved by shifting the 8-byte object by one to the right. Fortunately, we do not have to be concerned with the representations and the shifts, because there are pre-defined macros for such operations. So, if we want to find out, whether our object is an integer, we can inspect the value of the Boolean \n",
"\n",
"```c\n",
"MP_OBJ_IS_SMALL_INT(myobject)\n",
"```\n",
"We can get the integer value stored in `myobject` by calling \n",
"\n",
"```c\n",
"int a = MP_OBJ_SMALL_INT_VALUE(myobject);\n",
"```\n",
"Conversely, an integer in C can be turned into an object of type `mp_obj_t` by calling \n",
"\n",
"```c\n",
"\n",
"```\n",
"\n",
"So, if you want to find out, whether a particular object is a tuple, you could apply the `MP_OBJ_IS_TYPE` macro, \n",
"\n",
"```c\n",
"MP_OBJ_IS_TYPE(myobject, &mp_type_tuple)\n",
"```\n",
"\n",
"which returns a Boolean. "
]
},
{
"cell_type": "markdown",
"metadata": {},
@ -604,7 +635,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Before we can actually add the `+` operator to the class, we should note that there are two kinds of special methods (TODO: THERE ARE MORE, THIS HAS TO BE EXPLAINED A BIT), namely the unary and the binary operators. \n",
"Before we can actually add the `+` operator to the class, we should note that there are two kinds of special methods, namely the unary and the binary operators. \n",
"\n",
"In the first group are those, whose sole argument is the class instance itself. Two frequently used cases are the length operator, `len`, and `bool`. So, e.g., if your class implements the `__len__(self)` method, and the method returns an integer, then you can call the `len` function in the console\n",
"\n",
@ -612,8 +643,113 @@
"len(myclass)\n",
"```\n",
"\n",
"In the second category of operators are those, which require a left, as well as a right hand side. An example for this was the `__add__` method in our `Adder` class.\n",
"\n"
"In the second category of operators are those, which require a left, as well as a right hand side. An example for this was the `__add__` method in our `Adder` class. The complete list of unary, as well as binary operators can be found in `runtime.h`. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The module below implements five special methods altogether. Two unary, namely, `bool`, and `len`, and three binary operators, `==`, `+`, and `*`. Since the addition and multiplication will return a new instance of `myclass`, we define a new function, `create_new_class`, that, well, creates a new instance of `myclass`, and initialises the members with the two input arguments. This function will also be called in the class initialisation function, `myclass_make_new` immediately after the argument checking. \n",
"\n",
"When implementing the operators, we have to keep a couple of things in mind. First, the `specialclass_myclass_type` has to be extended with the two methods, `.unary_op`, and `.binary_op`, where `.unary_op` is equal to the function that handles the unary operation (`specialclass_unary_op` in the example below), and `.binary_op` is equal to the function that deals with binary operations (`specialclass_binary_op` below)."