~pixelherodev/c3lib

ref: ddd789667e0b3f1f92a636752601943924d590c9 c3lib/c3.h -rw-r--r-- 2.5 KiB
ddd78966Noam Preil tmp 3 months ago
                                                                                
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
#pragma pack on

typedef struct{
	uint32_t index;
	uint32_t length;
} c3string;

#pragma pack off

typedef struct{
	uint32_t version;
	c3string *strings;
	char *chars;
} c3core;

#pragma pack on
typedef union{
	uint32_t node_index;
	uint32_t string_index;
	struct{
		uint16_t tag;
		uint16_t kids;
	};
} c3node;

#pragma pack off

typedef struct{
	c3node *nodes;
} c3ast;

// Maps a node to some arbitrary u32, whose meaning depends on the map.
// Primarily useful for mapping nodes to other nodes
typedef struct{
	uint32_t key;
	uint32_t value;
} c3nodemap;

typedef struct{
	uint32_t *tests;
	uint32_t *exports;
	uint32_t *fns;
	// Maps functions to the functions they call. Each target node is a C3_DEP node whose children form the list of callees
	// Bottom nodes (functions which call no other functions) map to -1. Since all functions are present in the graph,
	// we can iterate over the keys for a full list of functions, which is useful for e.g. codegen.
	c3nodemap *callgraph;
	c3nodemap *types;
	c3nodemap *deps;
	c3nodemap *names;
} c3analysis;

typedef struct {
	c3nodemap *linenumbers;
	c3nodemap *columnnumbers;
	c3nodemap *linestrings;
} c3debug;

// Used to track pieces of the tree for deduplication
typedef struct {
	uint32_t *types;
} c3dedup;

typedef struct{
	c3core core;
	c3ast ast;
	c3dedup dedup;
	c3analysis analysis;
	// Optional. Might be all NULL if debug info isn't requested
	c3debug debug;
} c3ctx;

// All functions which take in an index require bounds checking to be handled by
// the caller.
void c3init(c3ctx *);
void c3free(c3ctx *);
int c3read(c3ctx*, int fd);
int c3write(c3ctx*, int fd);

// If there is not sufficient space, this attempts to reserve space at a rate expanding exponentially
// This returns the new index, or -1 on failure
// Node-related functions (e.g. append, nodedump) interact with whichever node tree is active (AST or IR)
// String-related functions (e.g. interning) interact with the core
uint32_t c3append(c3ctx *, c3tag tag, uint16_t kid_count, ...);
uint32_t c3appendarr(c3ctx *, c3tag tag, uint16_t kid_count, uint32_t *kids);
uint32_t c3intern(c3ctx *, char *, uint32_t len);
char *h_c3str(c3ctx, uint32_t string_handle);

void c3nodedump(c3ctx tree, uint32_t index, uint32_t indent, int recurse);
void c3dump(c3ctx tree);

c3tag c3nodetag(c3ctx, uint32_t index);
uint16_t c3nodekids(c3ctx, uint32_t index);
uint32_t c3nodechild(c3ctx, uint32_t index, uint32_t child);
void c3nodeset(c3ctx, uint32_t index, c3tag tag, uint16_t kid_count);