File: scope.h

package info (click to toggle)
harec 0.26.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,480 kB
  • sloc: ansic: 20,054; asm: 335; makefile: 116; lisp: 80; sh: 45
file content (96 lines) | stat: -rw-r--r-- 2,208 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#ifndef HAREC_SCOPE_H
#define HAREC_SCOPE_H
#include "expr.h"
#include "identifier.h"

#define SCOPE_BUCKETS 4096

enum object_type {
	O_BIND,
	O_CONST,
	O_DECL,
	O_SCAN,
	O_TYPE,
};

enum scope_object_flags {
	SO_THREADLOCAL = 1 << 0,
	SO_FOR_EACH_SUBJECT = 1 << 1,
};

struct scope_object {
	enum object_type otype;
	// name is the name of the object within this scope (for lookups)
	// ident is the global identifier (these may be different in some cases)
	struct ident *name;
	struct ident *ident;
	enum scope_object_flags flags;

	union {
		const struct type *type;
		struct expression *value; // For O_CONST
	};
	 // Cannot be in union because type and idecl are needed at the same time
	struct incomplete_decl *idecl;

	struct scope_object *lnext; // Linked list
	struct scope_object *mnext; // Hash map
};

enum scope_class {
	SCOPE_COMPOUND,
	SCOPE_DEFER,
	SCOPE_ENUM,
	SCOPE_FUNC,
	SCOPE_LOOP,
	SCOPE_MATCH,
	SCOPE_SUBUNIT,
	SCOPE_UNIT,
	SCOPE_DEFINES,
};

struct yield { // and break
	struct expression **expression;
	struct yield *next;
};

struct scope {
	enum scope_class class;
	const char *label;
	struct scope *parent;

	const struct type *hint;
	struct type_tagged_union results;
	struct yield *yields;

	// Linked list in insertion order
	// Used for function parameters and enum values, where order matters
	struct scope_object *objects;
	struct scope_object **next;

	// Hash map in reverse insertion order
	// Used for lookups, and accounts for shadowing
	struct scope_object *buckets[SCOPE_BUCKETS];
};

struct scopes {
	struct scope *scope;
	struct scopes *next;
};

struct scope *scope_push(struct scope **stack, enum scope_class class);
struct scope *scope_pop(struct scope **stack);

struct scope *scope_lookup_class(struct scope *scope, enum scope_class class);
struct scope *scope_lookup_label(struct scope *scope, const char *label);

void scope_free(struct scope *scope);
void scope_free_all(struct scopes *scopes);

struct scope_object *scope_insert(struct scope *scope,
	enum object_type otype, struct ident *ident, struct ident *name,
	const struct type *type, struct expression *value);

struct scope_object *scope_lookup(struct scope *scope, struct ident *ident);

#endif