Tobias Waldekranz.com 8 anos atrás
commit
afacd95649
9 arquivos alterados com 644 adições e 0 exclusões
  1. 5 0
      .gitignore
  2. 3 0
      Makefile
  3. 172 0
      node.c
  4. 85 0
      node.h
  5. 58 0
      ply.c
  6. 49 0
      sym.c
  7. 16 0
      sym.h
  8. 144 0
      type.c
  9. 112 0
      type.h

+ 5 - 0
.gitignore

@@ -0,0 +1,5 @@
1
+*~
2
+*.o
3
+
4
+ply
5
+.gdb_history

+ 3 - 0
Makefile

@@ -0,0 +1,3 @@
1
+CFLAGS ?= -Wall -Wextra -Werror -Wno-unused -O0 -g
2
+
3
+ply: node.o type.o sym.o

+ 172 - 0
node.c

@@ -0,0 +1,172 @@
1
+#include <assert.h>
2
+#include <ctype.h>
3
+#include <inttypes.h>
4
+#include <stdio.h>
5
+#include <stdlib.h>
6
+
7
+#include "node.h"
8
+
9
+void node_print_atom(node_t *n, FILE *fp)
10
+{
11
+	switch (n->atom.atype) {
12
+	case A_IDENT:
13
+		fputs(n->atom.ident, fp);
14
+		break;
15
+	case A_NUM:
16
+		fprintf(fp, "%#"PRIx64, n->atom.num);
17
+		break;
18
+	case A_STRING:
19
+		fprintf(fp, "\"%s\"", n->atom.string);
20
+		break;
21
+
22
+	default:
23
+		fputs("INVALID_ATOM", fp);
24
+	}
25
+}
26
+
27
+void node_print_expr(node_t *n, FILE *fp)
28
+{
29
+	if (!isprint(n->expr.etype)) {
30
+		fputs("INVALID_EXPR", fp);
31
+		return;
32
+	}
33
+
34
+	fputc(n->expr.etype, fp);
35
+}
36
+
37
+void node_print(node_t *n, FILE *fp)
38
+{
39
+	switch (n->ntype) {
40
+	case N_ATOM:
41
+		node_print_atom(n, fp);
42
+		break;
43
+	case N_EXPR:
44
+		node_print_expr(n, fp);
45
+		break;
46
+
47
+	default:
48
+		fputs("INVALID_NODE", fp);
49
+	}
50
+}
51
+
52
+int __node_dump_pre(node_t *n, void *_info)
53
+{
54
+	node_dump_info_t *info = _info;
55
+
56
+	fprintf(info->fp, "%*s", info->indent, "");
57
+	node_print(n, info->fp);
58
+	fputc('\n', info->fp);
59
+
60
+	if (n->ntype == N_EXPR) {
61
+		info->indent += 2;
62
+	}
63
+	return 0;
64
+}
65
+
66
+int __node_dump_post(node_t *n, void *_info)
67
+{
68
+	node_dump_info_t *info = _info;
69
+	node_t *next;
70
+
71
+	if (n->ntype == N_EXPR)
72
+		info->indent -= 2;
73
+
74
+	if (n->up && n->up->ntype == N_EXPR && n->up->expr.arg == n) {
75
+		for (next = n->next; next; next = next->next) {
76
+			node_dump(next, info);
77
+		}
78
+	}
79
+
80
+	return 0;
81
+}
82
+
83
+void node_dump(node_t *n, node_dump_info_t *info)
84
+{
85
+
86
+	node_walk(n, __node_dump_pre, __node_dump_post, info);
87
+}
88
+
89
+int node_walk(node_t *n,
90
+	      int (*pre)(node_t *, void *),
91
+	      int (*post)(node_t *, void *),
92
+	      void *ctx)
93
+{
94
+	int err = 0;
95
+	
96
+	if (pre && (err = pre(n, ctx)))
97
+		return err;
98
+
99
+	if (n->ntype == N_EXPR) {
100
+		err = node_walk(n->expr.arg, pre, post, ctx);
101
+		if (err)
102
+			return err;
103
+	}
104
+
105
+	if (post && (err = post(n, ctx)))
106
+		return err;
107
+
108
+	return 0;
109
+}
110
+
111
+static node_t *__node(ntype_t ntype)
112
+{
113
+	node_t *n = calloc(1, sizeof(*n));
114
+	assert(n);
115
+
116
+	n->ntype = ntype;
117
+	return n;
118
+}
119
+
120
+node_t *node_ident(char *name)
121
+{
122
+	node_t *n = __node(N_ATOM);
123
+
124
+	n->atom.atype = A_IDENT;
125
+	n->atom.ident = name;
126
+	return n;
127
+}
128
+
129
+node_t *node_num(int64_t num)
130
+{
131
+	node_t *n = __node(N_ATOM);
132
+
133
+	n->atom.atype = A_NUM;
134
+	n->atom.num = num;
135
+	return n;
136
+}
137
+
138
+node_t *node_string(char *string)
139
+{
140
+	node_t *n = __node(N_ATOM);
141
+
142
+	n->atom.atype = A_STRING;
143
+	n->atom.string = string;
144
+	return n;
145
+}
146
+
147
+node_t *node_expr(etype_t etype, node_t *arg)
148
+{
149
+	node_t *n = __node(N_EXPR);
150
+	node_t *next;
151
+
152
+	n->expr.etype = etype;
153
+	n->expr.arg = arg;
154
+
155
+	for (next = arg; next; next = next->next)
156
+		next->up = n;
157
+
158
+	return n;
159
+}
160
+
161
+node_t *node_cons(node_t *head, node_t *tail)
162
+{
163
+	node_t *next;
164
+
165
+	assert(!head->next);
166
+	head->next = tail;
167
+
168
+	for (next = tail; next; next = next->next)
169
+		next->up = head->up;
170
+
171
+	return head;
172
+}

+ 85 - 0
node.h

@@ -0,0 +1,85 @@
1
+#ifndef _PLY_NODE_H
2
+#define _PLY_NODE_H
3
+
4
+#include <stdint.h>
5
+
6
+typedef struct atom atom_t;
7
+typedef struct expr expr_t;
8
+typedef struct node node_t;
9
+
10
+typedef enum atype {
11
+	A_INVALID,
12
+	A_IDENT,
13
+	A_NUM,
14
+	A_STRING,
15
+} atype_t;
16
+
17
+struct atom {
18
+	atype_t atype;
19
+
20
+	union {
21
+		char *ident;
22
+		int64_t num;
23
+		char *string;
24
+	};
25
+};
26
+
27
+typedef enum etype {
28
+	E_INVALID = '\0',
29
+
30
+	E_AGG = '@',
31
+	E_CALL = '(',
32
+	E_DEREF = '*',
33
+	E_DOT = '.',
34
+	E_MAP = 'm',
35
+	E_SCOPE = '{',
36
+	
37
+} etype_t;
38
+
39
+struct expr {
40
+	etype_t etype;
41
+	node_t *arg;
42
+};
43
+
44
+typedef enum ntype {
45
+	N_INVALID,
46
+	N_ATOM,
47
+	N_EXPR,
48
+} ntype_t;
49
+
50
+struct node {
51
+	ntype_t ntype;
52
+	node_t *up;
53
+	node_t *next;
54
+
55
+	union {
56
+		atom_t atom;
57
+		expr_t expr;
58
+	};
59
+};
60
+
61
+int node_walk(node_t *n,
62
+	      int (*pre)(node_t *, void *),
63
+	      int (*post)(node_t *, void *),
64
+	      void *ctx);
65
+
66
+
67
+/* node constructors */
68
+
69
+node_t *node_ident (char *name);
70
+node_t *node_num   (int64_t num);
71
+node_t *node_string(char *string);
72
+node_t *node_expr  (etype_t etype, node_t *arg);
73
+node_t *node_cons  (node_t *head, node_t *tail);
74
+
75
+
76
+/* debug */
77
+
78
+typedef struct node_dump_info {
79
+	FILE *fp;
80
+	int indent;
81
+} node_dump_info_t;
82
+
83
+void node_dump(node_t *n, node_dump_info_t *info);
84
+
85
+#endif	/* _PLY_NODE_H */

+ 58 - 0
ply.c

@@ -0,0 +1,58 @@
1
+#include <stdio.h>
2
+#include <stdlib.h>
3
+
4
+#include "node.h"
5
+#include "sym.h"
6
+
7
+typedef struct prog {
8
+	char *probe;
9
+	node_t *ast;
10
+
11
+	symtab_t locals;
12
+	symtab_t *globals;
13
+} prog_t;
14
+
15
+symtab_t globals = { .sym = NULL, .len = 0 };
16
+
17
+prog_t *prog_get(void)
18
+{
19
+	prog_t *p;
20
+
21
+	p = calloc(1, sizeof(*p));
22
+
23
+	p->globals = &globals,
24
+
25
+	/* reads{pid()} @ quantize(arg2) */
26
+	p->ast =
27
+		node_expr('@',
28
+			  node_cons(
29
+				  node_expr('m',
30
+					    node_cons(
31
+						    node_ident("reads"),
32
+						    node_expr('(', node_ident("pid"))
33
+						    )
34
+					  ),
35
+				  node_expr('(',
36
+					    node_cons(
37
+						    node_ident("quantize"),
38
+						    node_ident("arg2")
39
+						    )
40
+					  )
41
+				  )
42
+			);
43
+
44
+	return p;
45
+}
46
+
47
+int main(void)
48
+{
49
+	node_dump_info_t info = {
50
+		.indent = 2,
51
+		.fp = stdout,
52
+	};
53
+
54
+	prog_t *p = prog_get();
55
+
56
+	node_dump(p->ast, &info);
57
+	return 0;
58
+}

+ 49 - 0
sym.c

@@ -0,0 +1,49 @@
1
+#include <assert.h>
2
+#include <errno.h>
3
+#include <stdio.h>
4
+#include <stdlib.h>
5
+#include <string.h>
6
+
7
+#include "sym.h"
8
+
9
+sym_t *sym_get(symtab_t *st, const char *name)
10
+{
11
+	size_t i;
12
+
13
+	for (i = 0; i < st->len; i++) {
14
+		if (!strcmp(st->sym[i].name, name))
15
+			return &st->sym[i];
16
+	}
17
+
18
+	return NULL;
19
+}
20
+
21
+int sym_add(symtab_t *st, const char *name, tid_t tid, sym_t **new)
22
+{
23
+	sym_t *sym;
24
+
25
+	sym = sym_get(st, name);
26
+	if (sym) {
27
+		/* if there is no type info, accept anything */
28
+		if (!sym->tid)
29
+			sym->tid = tid;
30
+		/* otherwise, if specified, it must match */
31
+		else if (tid && (sym->tid != tid))
32
+			return -EINVAL;
33
+
34
+		goto found;
35
+	}
36
+
37
+	st->sym = realloc(st->sym, ++st->len * sizeof(*st->sym));
38
+	assert(st->sym);
39
+
40
+	sym = &st->sym[st->len-1];
41
+	sym->name = name;
42
+	sym->tid = tid;
43
+
44
+found:
45
+	if (new)
46
+		*new = sym;
47
+
48
+	return 0;
49
+}

+ 16 - 0
sym.h

@@ -0,0 +1,16 @@
1
+#ifndef _PLY_SYM_H
2
+#define _PLY_SYM_H
3
+
4
+#include "type.h"
5
+
6
+typedef struct sym {
7
+	const char *name;
8
+	tid_t tid;
9
+} sym_t;
10
+
11
+typedef struct symtab {
12
+	sym_t *sym;
13
+	size_t len;
14
+} symtab_t;
15
+
16
+#endif	/* _PLY_SYM_H */

+ 144 - 0
type.c

@@ -0,0 +1,144 @@
1
+#include <assert.h>
2
+#include <stdio.h>
3
+#include <stdlib.h>
4
+
5
+#include "type.h"
6
+
7
+const type_t builtin_types[] = {
8
+	{ .type = T_NONE },
9
+#define SCALAR(_tid, _, _type) [_tid] = {			\
10
+		.tid = _tid,					\
11
+		.size = sizeof(_type),				\
12
+		.type = T_SCALAR,				\
13
+		.t = {						\
14
+			.scalar = {				\
15
+				.name = #_type,			\
16
+			},					\
17
+		},						\
18
+	},
19
+#define POINTER(_tid, _, _base) [_tid] = {			\
20
+		.tid = _tid,					\
21
+		.size = sizeof(void *),				\
22
+		.type = T_POINTER,				\
23
+		.t = {						\
24
+			.pointer = {				\
25
+				.type = _base,			\
26
+			},					\
27
+		},						\
28
+	},
29
+BUILTIN_TYPES
30
+#undef SCALAR
31
+#undef POINTER
32
+
33
+	{ .type = T_INVALID }
34
+};
35
+
36
+const type_t arch_builtin_types[] = {
37
+	{ .type = T_ALIAS, .t = { .alias = { .type = tid_c, .name = "s8" } } },
38
+	{ .type = T_ALIAS, .t = { .alias = { .type = tid_uc, .name = "u8" } } },
39
+
40
+	{ .type = T_INVALID }
41
+};
42
+
43
+static types_t types = {
44
+	.types = NULL,
45
+	.next = 0,
46
+};
47
+
48
+type_t *type_info(tid_t tid)
49
+{
50
+	assert(tid < types.next);
51
+	return &types.types[tid];
52
+}
53
+
54
+void type_dump(type_t *t, FILE *fp)
55
+{
56
+	switch (t->type){
57
+	case T_ALIAS:
58
+		fputs(t->t.alias.name, fp);
59
+		break;
60
+	case T_SCALAR:
61
+		fputs(t->t.scalar.name, fp);
62
+		break;
63
+	case T_POINTER:
64
+		type_dump(type_info(t->t.pointer.type), fp);
65
+		fputs(" *", fp);
66
+		break;
67
+	case T_ARRAY:
68
+		type_dump(type_info(t->t.array.type), fp);
69
+		fprintf(fp, "[%zu]", t->t.array.len);
70
+		break;
71
+
72
+	default:
73
+		assert(0);
74
+	}
75
+}
76
+
77
+void type_dump_cdecl(type_t *t, FILE *fp)
78
+{
79
+	switch (t->type) {
80
+	case T_ALIAS:
81
+		fputs("typedef ", fp);
82
+		type_dump(type_info(t->t.alias.type), fp);
83
+		fprintf(fp, " %s", t->t.alias.name);
84
+		break;
85
+	case T_SCALAR:
86
+	case T_POINTER:
87
+	case T_ARRAY:
88
+		type_dump(t, fp);
89
+		break;
90
+
91
+	default:
92
+		assert(0);
93
+	}
94
+}
95
+
96
+tid_t type_add(const type_t *type)
97
+{
98
+	tid_t tid = types.next++;
99
+
100
+	types.types = realloc(types.types, types.next * sizeof(type_t));
101
+	assert(types.types);
102
+
103
+	types.types[tid] = *type;
104
+	types.types[tid].tid = tid;
105
+	return tid;
106
+}
107
+
108
+tid_t type_add_list(const type_t *type)
109
+{
110
+	tid_t first = 0;
111
+
112
+	for (; type->type; type++) {
113
+		if (!first)
114
+			first = type_add(type);
115
+		else
116
+			type_add(type);
117
+	}
118
+
119
+	return first;
120
+}
121
+
122
+__attribute__((constructor))
123
+static void type_init(void)
124
+{
125
+	type_add_list(builtin_types);
126
+	type_add_list(arch_builtin_types);
127
+}
128
+
129
+/* int main(void) */
130
+/* { */
131
+/* 	tid_t tid; */
132
+
133
+/* 	type_init(); */
134
+
135
+/* 	for (tid = 0; tid < types.next; tid++) { */
136
+/* 		type_t *t = type_info(tid); */
137
+
138
+/* 		printf("tid:%3d sz:%2zx  ", t->tid, t->size);  */
139
+/* 		type_dump_cdecl(t, stdout); */
140
+/* 		putchar('\n'); */
141
+/* 	} */
142
+
143
+/* 	return 0; */
144
+/* } */

+ 112 - 0
type.h

@@ -0,0 +1,112 @@
1
+#ifndef _PLY_TYPE_H
2
+#define _PLY_TYPE_H
3
+
4
+typedef unsigned int tid_t;
5
+
6
+typedef struct alias {
7
+	tid_t type;
8
+	char *name;
9
+} alias_t;
10
+
11
+typedef struct scalar {
12
+	char *name;
13
+} scalar_t;
14
+
15
+typedef struct pointer {
16
+	tid_t type;
17
+} pointer_t;
18
+
19
+typedef struct array {
20
+	tid_t type;
21
+	size_t len;
22
+} array_t;
23
+
24
+typedef struct map {
25
+	tid_t type;
26
+	tid_t ktype;
27
+	size_t len;
28
+} map_t;
29
+
30
+typedef struct field {
31
+	struct field *next;
32
+
33
+	tid_t type;
34
+	size_t offset;
35
+	char *name;
36
+} field_t;
37
+
38
+typedef struct sou {
39
+	field_t *fields;
40
+} sou_t;
41
+
42
+typedef enum ttype {
43
+	T_INVALID,
44
+	T_NONE,
45
+	T_ALIAS,
46
+	T_SCALAR,
47
+	T_POINTER,
48
+	T_ARRAY,
49
+	T_MAP,
50
+	T_SOU,
51
+} ttype_t;
52
+
53
+typedef struct type {
54
+	tid_t tid;
55
+
56
+	size_t size;
57
+
58
+	ttype_t type;
59
+	union {
60
+		alias_t alias;
61
+		scalar_t scalar;
62
+		pointer_t pointer;
63
+		array_t array;
64
+		map_t map;
65
+		sou_t sou;
66
+	} t;
67
+} type_t;
68
+
69
+typedef struct types {
70
+	type_t *types;
71
+	tid_t next;
72
+} types_t;
73
+
74
+#define BUILTIN_TYPES				\
75
+	SCALAR(1, tid_v, void)			\
76
+	POINTER(2, tid_vp, 1)			\
77
+						\
78
+	SCALAR(3, tid_c, char)			\
79
+	POINTER(4, tid_cp, 3)			\
80
+	SCALAR(5, tid_uc, unsigned char)	\
81
+	POINTER(6, tid_ucp, 5)			\
82
+						\
83
+	SCALAR(7, tid_s, short)			\
84
+	POINTER(8, tid_sp, 7)			\
85
+	SCALAR(9, tid_us, unsigned short)	\
86
+	POINTER(10, tid_usp, 9)			\
87
+						\
88
+	SCALAR(11, tid_i, int)			\
89
+	POINTER(12, tid_ip, 11)			\
90
+	SCALAR(13, tid_ui, unsigned int)	\
91
+	POINTER(14, tid_uip, 13)		\
92
+						\
93
+	SCALAR(15, tid_l, long)			\
94
+	POINTER(16, tid_lp, 15)			\
95
+	SCALAR(17, tid_ul, unsigned long)	\
96
+	POINTER(18, tid_ulp, 17)		\
97
+						\
98
+	SCALAR(19, tid_ll, long long)		\
99
+	POINTER(20, tid_llp, 19)		\
100
+	SCALAR(21, tid_ull, unsigned long long)	\
101
+	POINTER(22, tid_ullp, 21)
102
+
103
+typedef enum builtin_type {
104
+	tid_none = 0,
105
+#define SCALAR(_tid, _name, _) _name = _tid,
106
+#define POINTER(_tid, _name, _) _name = _tid,
107
+BUILTIN_TYPES
108
+#undef SCALAR
109
+#undef POINTER
110
+} builtin_type_t;
111
+
112
+#endif	/* _PLY_TYPE_H */