blob: 826f8bdc864df279a1d430309b8393b6753d19d9 [file] [log] [blame]
Damiend99b0522013-12-21 18:17:45 +00001#include <stdlib.h>
2#include <stdint.h>
3#include <assert.h>
4
5#include "nlr.h"
6#include "misc.h"
7#include "mpconfig.h"
Damien George71c51812014-01-04 20:21:15 +00008#include "mpqstr.h"
Damiend99b0522013-12-21 18:17:45 +00009#include "obj.h"
Damien George71c51812014-01-04 20:21:15 +000010#include "runtime.h"
Damiend99b0522013-12-21 18:17:45 +000011#include "map.h"
12
13typedef struct _mp_obj_set_t {
14 mp_obj_base_t base;
15 mp_set_t set;
16} mp_obj_set_t;
17
18void set_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
19 mp_obj_set_t *self = self_in;
20 bool first = true;
21 print(env, "{");
22 for (int i = 0; i < self->set.alloc; i++) {
23 if (self->set.table[i] != MP_OBJ_NULL) {
24 if (!first) {
25 print(env, ", ");
26 }
27 first = false;
28 mp_obj_print_helper(print, env, self->set.table[i]);
29 }
30 }
31 print(env, "}");
32}
33
Damien George71c51812014-01-04 20:21:15 +000034static mp_obj_t set_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) {
35 switch (n_args) {
36 case 0:
37 // return a new, empty set
38 return mp_obj_new_set(0, NULL);
39
40 case 1:
41 {
42 // 1 argument, an iterable from which we make a new set
43 mp_obj_t set = mp_obj_new_set(0, NULL);
44 mp_obj_t iterable = rt_getiter(args[0]);
45 mp_obj_t item;
46 while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) {
47 mp_obj_set_store(set, item);
48 }
49 return set;
50 }
51
52 default:
53 nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "set takes at most 1 argument, %d given", (void*)(machine_int_t)n_args));
54 }
55}
56
57const mp_obj_type_t set_type = {
Damiend99b0522013-12-21 18:17:45 +000058 { &mp_const_type },
59 "set",
60 set_print, // print
Damien George71c51812014-01-04 20:21:15 +000061 set_make_new, // make_new
Damiend99b0522013-12-21 18:17:45 +000062 NULL, // call_n
63 NULL, // unary_op
64 NULL, // binary_op
65 NULL, // getiter
66 NULL, // iternext
67 { { NULL, NULL }, }, // method list
68};
69
70mp_obj_t mp_obj_new_set(int n_args, mp_obj_t *items) {
71 mp_obj_set_t *o = m_new_obj(mp_obj_set_t);
72 o->base.type = &set_type;
73 mp_set_init(&o->set, n_args);
74 for (int i = 0; i < n_args; i++) {
75 mp_set_lookup(&o->set, items[i], true);
76 }
77 return o;
78}
79
80void mp_obj_set_store(mp_obj_t self_in, mp_obj_t item) {
81 assert(MP_OBJ_IS_TYPE(self_in, &set_type));
82 mp_obj_set_t *self = self_in;
83 mp_set_lookup(&self->set, item, true);
84}