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
|