blob: 791932dc7f2fb7c27d322475918bb66cb5c3bd90 [file] [log] [blame]
Damien George28708622014-01-02 21:30:26 +00001#include <stdlib.h>
2#include <stdint.h>
3#include <string.h>
4#include <assert.h>
5
6#include "nlr.h"
7#include "misc.h"
8#include "mpconfig.h"
Damien George55baff42014-01-21 21:40:13 +00009#include "qstr.h"
Damien George28708622014-01-02 21:30:26 +000010#include "obj.h"
11#include "runtime.h"
12#include "map.h"
Damien George0c36da02014-03-08 15:24:39 +000013#include "builtin.h"
Damien George28708622014-01-02 21:30:26 +000014
Paul Sokolovskyd5df6cd2014-02-12 18:15:40 +020015STATIC void module_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
Damien George28708622014-01-02 21:30:26 +000016 mp_obj_module_t *self = self_in;
17 print(env, "<module '%s' from '-unknown-file-'>", qstr_str(self->name));
18}
19
Paul Sokolovskyd5df6cd2014-02-12 18:15:40 +020020STATIC void module_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
Damien George062478e2014-01-09 20:57:50 +000021 mp_obj_module_t *self = self_in;
22 mp_map_elem_t *elem = mp_map_lookup(self->globals, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP);
23 if (elem != NULL) {
Damien George20006db2014-01-18 14:10:48 +000024 dest[0] = elem->value;
Damien George062478e2014-01-09 20:57:50 +000025 }
26}
27
Paul Sokolovskyd5df6cd2014-02-12 18:15:40 +020028STATIC bool module_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t value) {
Damien George062478e2014-01-09 20:57:50 +000029 mp_obj_module_t *self = self_in;
30 // TODO CPython allows STORE_ATTR to a module, but is this the correct implementation?
31 mp_map_lookup(self->globals, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value;
32 return true;
33}
34
Damien George0c36da02014-03-08 15:24:39 +000035const mp_obj_type_t mp_type_module = {
Damien Georgec5966122014-02-15 16:10:44 +000036 { &mp_type_type },
Damien Georgea71c83a2014-02-15 11:34:50 +000037 .name = MP_QSTR_module,
Damien George97209d32014-01-07 15:58:30 +000038 .print = module_print,
Damien George062478e2014-01-09 20:57:50 +000039 .load_attr = module_load_attr,
40 .store_attr = module_store_attr,
Damien George28708622014-01-02 21:30:26 +000041};
42
43mp_obj_t mp_obj_new_module(qstr module_name) {
Damien George0c36da02014-03-08 15:24:39 +000044 mp_map_elem_t *el = mp_map_lookup(rt_loaded_modules_get(), MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND);
Paul Sokolovskyd720ab52014-01-20 00:03:34 +020045 // We could error out if module already exists, but let C extensions
46 // add new members to existing modules.
47 if (el->value != MP_OBJ_NULL) {
48 return el->value;
49 }
50
Damien George0c36da02014-03-08 15:24:39 +000051 // create new module object
Damien George28708622014-01-02 21:30:26 +000052 mp_obj_module_t *o = m_new_obj(mp_obj_module_t);
Damien George0c36da02014-03-08 15:24:39 +000053 o->base.type = &mp_type_module;
Damien George28708622014-01-02 21:30:26 +000054 o->name = module_name;
Damien George38a2da62014-01-08 17:33:12 +000055 o->globals = mp_map_new(1);
Damien George0c36da02014-03-08 15:24:39 +000056
57 // store __name__ entry in the module
Damien George5fa93b62014-01-22 14:35:10 +000058 mp_map_lookup(o->globals, MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = MP_OBJ_NEW_QSTR(module_name);
Damien George0c36da02014-03-08 15:24:39 +000059
60 // store the new module into the slot in the global dict holding all modules
61 el->value = o;
62
63 // return the new module
Damien George28708622014-01-02 21:30:26 +000064 return o;
65}
66
Paul Sokolovskyd720ab52014-01-20 00:03:34 +020067mp_obj_t mp_obj_module_get(qstr module_name) {
Damien George0c36da02014-03-08 15:24:39 +000068 // lookup module
Damien George0d028742014-01-22 23:59:20 +000069 mp_map_elem_t *el = mp_map_lookup(rt_loaded_modules_get(), MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP);
Damien George0c36da02014-03-08 15:24:39 +000070
71 // module found, return it
72 if (el != NULL) {
73 return el->value;
Paul Sokolovskyd720ab52014-01-20 00:03:34 +020074 }
Damien George0c36da02014-03-08 15:24:39 +000075
76 // module not found, look for builtin module names
77#if MICROPY_ENABLE_FLOAT
78 if (module_name == MP_QSTR_math) {
79 return (mp_obj_t)&mp_module_math;
80 }
81#endif
82
83 // no module found, return NULL object
84 return MP_OBJ_NULL;
Paul Sokolovskyd720ab52014-01-20 00:03:34 +020085}
86
Damien George28708622014-01-02 21:30:26 +000087mp_map_t *mp_obj_module_get_globals(mp_obj_t self_in) {
Damien George0c36da02014-03-08 15:24:39 +000088 assert(MP_OBJ_IS_TYPE(self_in, &mp_type_module));
Damien George28708622014-01-02 21:30:26 +000089 mp_obj_module_t *self = self_in;
90 return self->globals;
91}