Skip to content

Commit d57eba5

Browse files
committed
Add user object to runtime.
1 parent 6ba1314 commit d57eba5

2 files changed

Lines changed: 73 additions & 0 deletions

File tree

py/runtime.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ typedef enum {
6868
O_MAP,
6969
O_CLASS,
7070
O_OBJ,
71+
O_USER,
7172
} py_obj_kind_t;
7273

7374
typedef enum {
@@ -172,6 +173,11 @@ struct _py_obj_base_t {
172173
py_obj_base_t *class; // points to a O_CLASS object
173174
py_map_t *members;
174175
} u_obj;
176+
struct { // for O_USER
177+
const py_user_info_t *info;
178+
machine_uint_t data1;
179+
machine_uint_t data2;
180+
} u_user;
175181
};
176182
};
177183

@@ -431,6 +437,34 @@ py_obj_t py_obj_new_list_iterator(py_obj_base_t *list, int cur) {
431437
return o;
432438
}
433439

440+
py_obj_t py_obj_new_user(const py_user_info_t *info, machine_uint_t data1, machine_uint_t data2) {
441+
py_obj_base_t *o = m_new(py_obj_base_t, 1);
442+
o->kind = O_USER;
443+
// TODO should probably parse the info to turn strings to qstr's, and wrap functions in O_FUN_N objects
444+
// that'll take up some memory. maybe we can lazily do the O_FUN_N: leave it a ptr to a C function, and
445+
// only when the method is looked-up do we change that to the O_FUN_N object.
446+
o->u_user.info = info;
447+
o->u_user.data1 = data1;
448+
o->u_user.data2 = data2;
449+
return o;
450+
}
451+
452+
void py_user_get_data(py_obj_t o, machine_uint_t *data1, machine_uint_t *data2) {
453+
assert(IS_O(o, O_USER));
454+
if (data1 != NULL) {
455+
*data1 = ((py_obj_base_t*)o)->u_user.data1;
456+
}
457+
if (data2 != NULL) {
458+
*data2 = ((py_obj_base_t*)o)->u_user.data2;
459+
}
460+
}
461+
462+
void py_user_set_data(py_obj_t o, machine_uint_t data1, machine_uint_t data2) {
463+
assert(IS_O(o, O_USER));
464+
((py_obj_base_t*)o)->u_user.data1 = data1;
465+
((py_obj_base_t*)o)->u_user.data2 = data2;
466+
}
467+
434468
py_obj_t rt_str_join(py_obj_t self_in, py_obj_t arg) {
435469
assert(IS_O(self_in, O_STR));
436470
py_obj_base_t *self = self_in;
@@ -812,6 +846,8 @@ const char *py_obj_get_type_str(py_obj_t o_in) {
812846
assert(IS_O(qn->value, O_STR));
813847
return qstr_str(((py_obj_base_t*)qn->value)->u_str);
814848
}
849+
case O_USER:
850+
return o->u_user.info->type_name;
815851
default:
816852
assert(0);
817853
return "UnknownType";
@@ -911,6 +947,9 @@ void py_obj_print(py_obj_t o_in) {
911947
printf("}");
912948
break;
913949
}
950+
case O_USER:
951+
o->u_user.info->print(o_in);
952+
break;
914953
default:
915954
printf("<? %d>", o->kind);
916955
assert(0);
@@ -1826,6 +1865,22 @@ void rt_load_method(py_obj_t base, qstr attr, py_obj_t *dest) {
18261865
}
18271866
}
18281867
goto no_attr;
1868+
} else if (IS_O(base, O_USER)) {
1869+
py_obj_base_t *o = base;
1870+
const py_user_method_t *meth = &o->u_user.info->methods[0];
1871+
for (; meth->name != NULL; meth++) {
1872+
if (strcmp(meth->name, qstr_str(attr)) == 0) {
1873+
if (meth->kind == 0) {
1874+
dest[1] = rt_make_function_1(meth->fun);
1875+
} else if (meth->kind == 1) {
1876+
dest[1] = rt_make_function_2(meth->fun);
1877+
} else {
1878+
assert(0);
1879+
}
1880+
dest[0] = base;
1881+
return;
1882+
}
1883+
}
18291884
}
18301885

18311886
no_attr:

py/runtime.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,21 @@ py_obj_t rt_iternext(py_obj_t o);
139139

140140
// temporary way of making C modules
141141
py_obj_t py_module_new(void);
142+
143+
// user defined objects
144+
145+
typedef struct _py_user_method_t {
146+
const char *name;
147+
machine_uint_t kind;
148+
void *fun;
149+
} py_user_method_t;
150+
151+
typedef struct _py_user_info_t {
152+
const char *type_name;
153+
void (*print)(py_obj_t);
154+
const py_user_method_t methods[];
155+
} py_user_info_t;
156+
157+
py_obj_t py_obj_new_user(const py_user_info_t *info, machine_uint_t data1, machine_uint_t data2);
158+
void py_user_get_data(py_obj_t o, machine_uint_t *data1, machine_uint_t *data2);
159+
void py_user_set_data(py_obj_t o, machine_uint_t data1, machine_uint_t data2);

0 commit comments

Comments
 (0)