micropython/py/builtin.c

114 lines
3.2 KiB
C

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <assert.h>
#include "nlr.h"
#include "misc.h"
#include "mpyconfig.h"
#include "runtime.h"
#include "bc.h"
#include "map.h"
#include "obj.h"
#include "objprivate.h"
#include "builtin.h"
py_obj_t py_builtin___repl_print__(py_obj_t o) {
if (o != py_const_none) {
py_obj_print(o);
printf("\n");
}
return py_const_none;
}
py_obj_t py_builtin_print(int n_args, const py_obj_t* args) {
for (int i = 0; i < n_args; i++) {
if (i > 0) {
printf(" ");
}
if (IS_O(args[i], O_STR)) {
// special case, print string raw
printf("%s", qstr_str(((py_obj_base_t*)args[i])->u_str));
} else {
// print the object Python style
py_obj_print(args[i]);
}
}
printf("\n");
return py_const_none;
}
py_obj_t py_builtin_len(py_obj_t o_in) {
py_small_int_t len = 0;
if (IS_O(o_in, O_STR)) {
py_obj_base_t *o = o_in;
len = strlen(qstr_str(o->u_str));
} else if (IS_O(o_in, O_TUPLE) || IS_O(o_in, O_LIST)) {
py_obj_base_t *o = o_in;
len = o->u_tuple_list.len;
} else if (IS_O(o_in, O_MAP)) {
py_obj_base_t *o = o_in;
len = o->u_map.used;
} else {
assert(0);
}
return TO_SMALL_INT(len);
}
py_obj_t py_builtin_abs(py_obj_t o_in) {
if (IS_SMALL_INT(o_in)) {
py_small_int_t val = FROM_SMALL_INT(o_in);
if (val < 0) {
val = -val;
}
return TO_SMALL_INT(val);
#if MICROPY_ENABLE_FLOAT
} else if (IS_O(o_in, O_FLOAT)) {
py_obj_base_t *o = o_in;
// TODO check for NaN etc
if (o->u_float < 0) {
return py_obj_new_float(-o->u_float);
} else {
return o_in;
}
} else if (IS_O(o_in, O_COMPLEX)) {
py_obj_base_t *o = o_in;
return py_obj_new_float(machine_sqrt(o->u_complex.real*o->u_complex.real + o->u_complex.imag*o->u_complex.imag));
#endif
} else {
assert(0);
return py_const_none;
}
}
py_obj_t py_builtin___build_class__(py_obj_t o_class_fun, py_obj_t o_class_name) {
// we differ from CPython: we set the new __locals__ object here
py_map_t *old_locals = rt_get_map_locals();
py_map_t *class_locals = py_map_new(MAP_QSTR, 0);
rt_set_map_locals(class_locals);
// call the class code
rt_call_function_1(o_class_fun, (py_obj_t)0xdeadbeef);
// restore old __locals__ object
rt_set_map_locals(old_locals);
// create and return the new class
py_obj_base_t *o = m_new(py_obj_base_t, 1);
o->kind = O_CLASS;
o->u_class.locals = class_locals;
return o;
}
py_obj_t py_builtin_range(int n_args, const py_obj_t* args) {
switch (n_args) {
case 1: return py_obj_new_range(0, py_obj_get_int(args[0]), 1);
case 2: return py_obj_new_range(py_obj_get_int(args[0]), py_obj_get_int(args[1]), 1);
case 3: return py_obj_new_range(py_obj_get_int(args[0]), py_obj_get_int(args[1]), py_obj_get_int(args[2]));
default: nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "range expected at most 3 arguments, got %d", (void*)(machine_int_t)n_args, NULL));
}
}