blob: e97e73192986ce30be48eb94d97623c5991424c1 [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 George7b21c2d2014-01-07 16:54:58 +00009#include "mpqstr.h"
Damien George28708622014-01-02 21:30:26 +000010#include "obj.h"
11#include "runtime.h"
12#include "map.h"
13
14typedef struct _mp_obj_module_t {
15 mp_obj_base_t base;
16 qstr name;
17 mp_map_t *globals;
18} mp_obj_module_t;
19
Paul Sokolovsky76d982e2014-01-13 19:19:16 +020020static 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 +000021 mp_obj_module_t *self = self_in;
22 print(env, "<module '%s' from '-unknown-file-'>", qstr_str(self->name));
23}
24
Damien George062478e2014-01-09 20:57:50 +000025static void module_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
26 mp_obj_module_t *self = self_in;
27 mp_map_elem_t *elem = mp_map_lookup(self->globals, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP);
28 if (elem != NULL) {
Damien George20006db2014-01-18 14:10:48 +000029 dest[0] = elem->value;
Damien George062478e2014-01-09 20:57:50 +000030 }
31}
32
33static bool module_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t value) {
34 mp_obj_module_t *self = self_in;
35 // TODO CPython allows STORE_ATTR to a module, but is this the correct implementation?
36 mp_map_lookup(self->globals, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value;
37 return true;
38}
39
Damien George28708622014-01-02 21:30:26 +000040const mp_obj_type_t module_type = {
41 { &mp_const_type },
42 "module",
Damien George97209d32014-01-07 15:58:30 +000043 .print = module_print,
Damien George062478e2014-01-09 20:57:50 +000044 .load_attr = module_load_attr,
45 .store_attr = module_store_attr,
Damien George28708622014-01-02 21:30:26 +000046};
47
48mp_obj_t mp_obj_new_module(qstr module_name) {
49 mp_obj_module_t *o = m_new_obj(mp_obj_module_t);
50 o->base.type = &module_type;
51 o->name = module_name;
Damien George38a2da62014-01-08 17:33:12 +000052 o->globals = mp_map_new(1);
53 mp_map_lookup(o->globals, MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = mp_obj_new_str(module_name);
Damien George28708622014-01-02 21:30:26 +000054 return o;
55}
56
57mp_map_t *mp_obj_module_get_globals(mp_obj_t self_in) {
58 assert(MP_OBJ_IS_TYPE(self_in, &module_type));
59 mp_obj_module_t *self = self_in;
60 return self->globals;
61}