blob: f560e3d21abe3ede8331071b048f6ebc28a3c9fe [file] [log] [blame]
Damien429d7192013-10-04 19:53:11 +01001enum {
2 ID_INFO_KIND_GLOBAL_IMPLICIT,
3 ID_INFO_KIND_GLOBAL_EXPLICIT,
4 ID_INFO_KIND_LOCAL, // in a function f, written and only referenced by f
5 ID_INFO_KIND_CELL, // in a function f, read/written by children of f
6 ID_INFO_KIND_FREE, // in a function f, belongs to the parent of f
7};
8
9typedef struct _id_info_t {
Damien27fb45e2013-10-20 15:07:49 +010010 // TODO compress this info to make structure smaller in memory
Damien429d7192013-10-04 19:53:11 +010011 bool param;
12 int kind;
13 qstr qstr;
Damien9ecbcff2013-12-11 00:41:43 +000014
15 // when it's an ID_INFO_KIND_LOCAL this is the unique number of the local
16 // whet it's an ID_INFO_KIND_CELL/FREE this is the unique number of the closed over variable
17 int local_num;
Damien429d7192013-10-04 19:53:11 +010018} id_info_t;
19
20// taken from python source, Include/code.h
21#define SCOPE_FLAG_OPTIMISED 0x0001
22#define SCOPE_FLAG_NEWLOCALS 0x0002
23#define SCOPE_FLAG_VARARGS 0x0004
24#define SCOPE_FLAG_VARKEYWORDS 0x0008
25#define SCOPE_FLAG_NESTED 0x0010
26#define SCOPE_FLAG_GENERATOR 0x0020
27/* The SCOPE_FLAG_NOFREE flag is set if there are no free or cell variables.
28 This information is redundant, but it allows a single flag test
29 to determine whether there is any extra work to be done when the
30 call frame is setup.
31*/
32#define SCOPE_FLAG_NOFREE 0x0040
33
34// scope is a "block" in Python parlance
35typedef enum { SCOPE_MODULE, SCOPE_FUNCTION, SCOPE_LAMBDA, SCOPE_LIST_COMP, SCOPE_DICT_COMP, SCOPE_SET_COMP, SCOPE_GEN_EXPR, SCOPE_CLASS } scope_kind_t;
36typedef struct _scope_t {
37 scope_kind_t kind;
38 struct _scope_t *parent;
39 struct _scope_t *next;
40 py_parse_node_t pn;
41 qstr simple_name;
42 int id_info_alloc;
43 int id_info_len;
44 id_info_t *id_info;
45 int flags;
46 int num_params;
47 /* not needed
48 int num_default_params;
49 int num_dict_params;
50 */
51 int num_locals;
Damien9ecbcff2013-12-11 00:41:43 +000052 int num_cells;
Damien429d7192013-10-04 19:53:11 +010053 int stack_size;
Damienb05d7072013-10-05 13:37:10 +010054 uint unique_code_id;
Damien6cdd3af2013-10-05 18:08:26 +010055 uint emit_options;
Damien429d7192013-10-04 19:53:11 +010056} scope_t;
57
Damien6cdd3af2013-10-05 18:08:26 +010058scope_t *scope_new(scope_kind_t kind, py_parse_node_t pn, uint unique_code_id, uint emit_options);
Damien429d7192013-10-04 19:53:11 +010059id_info_t *scope_find_or_add_id(scope_t *scope, qstr qstr, bool *added);
60id_info_t *scope_find(scope_t *scope, qstr qstr);
61id_info_t *scope_find_global(scope_t *scope, qstr qstr);
62id_info_t *scope_find_local_in_parent(scope_t *scope, qstr qstr);
63void scope_close_over_in_parents(scope_t *scope, qstr qstr);
Damien415eb6f2013-10-05 12:19:06 +010064void scope_declare_global(scope_t *scope, qstr qstr);
65void scope_declare_nonlocal(scope_t *scope, qstr qstr);
Damien429d7192013-10-04 19:53:11 +010066void scope_print_info(scope_t *s);