Browse Source

separate ident/keyword, start on type inference

Tobias Waldekranz.com 8 years ago
parent
commit
c44a1be62e
4 changed files with 137 additions and 36 deletions
  1. 32 5
      node.c
  2. 18 4
      node.h
  3. 84 26
      ply.c
  4. 3 1
      type.c

+ 32 - 5
node.c

6
 #include <stdio.h>
6
 #include <stdio.h>
7
 #include <stdlib.h>
7
 #include <stdlib.h>
8
 
8
 
9
-#include "node.h"
9
+#include "ply.h"
10
+
11
+void __type_dump(type_t *t, FILE *fp)
12
+{
13
+	if (!t)
14
+		return;
15
+
16
+	fputs(" \e[2m<", fp);
17
+	type_dump(t, fp);
18
+	fputs(">\e[0m", fp);
19
+}
10
 
20
 
11
 void node_print(node_t *n, FILE *fp)
21
 void node_print(node_t *n, FILE *fp)
12
 {
22
 {
14
 	case N_LIST:
24
 	case N_LIST:
15
 		fputs("()", fp);
25
 		fputs("()", fp);
16
 		break;
26
 		break;
27
+	case N_KEYWORD:
28
+		fputs("\e[31m", fp);
29
+		fputc(n->keyword, fp);
30
+		fputs("\e[0m", fp);
31
+		break;
17
 	case N_IDENT:
32
 	case N_IDENT:
18
 		fputs(n->ident, fp);
33
 		fputs(n->ident, fp);
19
 		break;
34
 		break;
28
 		fputs("<INVALID>", fp);
43
 		fputs("<INVALID>", fp);
29
 	}
44
 	}
30
 
45
 
31
-	/* if (n->type) { */
32
-	/* 	fputc(' ', fp); */
33
-	/* 	type_dump(n->type, fp); */
34
-	/* } */
46
+	__type_dump(n->type, fp);
35
 }
47
 }
36
 
48
 
37
 struct node_dump_info {
49
 struct node_dump_info {
87
 	for (c = n->list; c; c = c->next) {
99
 	for (c = n->list; c; c = c->next) {
88
 		if (c->ntype == N_LIST) {
100
 		if (c->ntype == N_LIST) {
89
 			fprintf(info->fp, "\n%*s)", info->indent, "");
101
 			fprintf(info->fp, "\n%*s)", info->indent, "");
102
+			__type_dump(n->type, info->fp);
90
 			return 0;
103
 			return 0;
91
 		}
104
 		}
92
 	}
105
 	}
93
 
106
 
94
 	fputc(')', info->fp);
107
 	fputc(')', info->fp);
108
+	__type_dump(n->type, info->fp);
95
 	return 0;
109
 	return 0;
96
 }
110
 }
97
 
111
 
168
 	return n;
182
 	return n;
169
 }
183
 }
170
 
184
 
185
+node_t *node_keyword(keyword_t keyword)
186
+{
187
+	node_t *n = __node(N_KEYWORD);
188
+	n->keyword = keyword;
189
+	return n;
190
+}
191
+
171
 node_t *node_ident(char *name)
192
 node_t *node_ident(char *name)
172
 {
193
 {
173
 	node_t *n = __node(N_IDENT);
194
 	node_t *n = __node(N_IDENT);
179
 {
200
 {
180
 	node_t *n = __node(N_NUM);
201
 	node_t *n = __node(N_NUM);
181
 	n->num = num;
202
 	n->num = num;
203
+
204
+	/* TODO: handle L UL ULL and such nonsense */
205
+	n->type = &t_s64;
182
 	return n;
206
 	return n;
183
 }
207
 }
184
 
208
 
186
 {
210
 {
187
 	node_t *n = __node(N_STRING);
211
 	node_t *n = __node(N_STRING);
188
 	n->string = string;
212
 	n->string = string;
213
+
214
+	/* TODO: string type like dtrace? */
215
+	n->type = &t_cp;
189
 	return n;
216
 	return n;
190
 }
217
 }

+ 18 - 4
node.h

8
 
8
 
9
 typedef struct node node_t;
9
 typedef struct node node_t;
10
 
10
 
11
+typedef enum keyword {
12
+	KW_SUBSCRIPT = '[',
13
+	KW_ASSIGN = '=',
14
+} keyword_t;
15
+
11
 typedef enum ntype {
16
 typedef enum ntype {
12
 	N_LIST,
17
 	N_LIST,
18
+	N_KEYWORD,
13
 	N_IDENT,
19
 	N_IDENT,
14
 	N_NUM,
20
 	N_NUM,
15
 	N_STRING,
21
 	N_STRING,
21
 	ntype_t ntype;
27
 	ntype_t ntype;
22
 	union {
28
 	union {
23
 		node_t *list;
29
 		node_t *list;
30
+		keyword_t keyword;
24
 		char *ident;
31
 		char *ident;
25
 		int64_t num;
32
 		int64_t num;
26
 		char *string;
33
 		char *string;
30
 };
37
 };
31
 
38
 
32
 /* debug */
39
 /* debug */
33
-void node_dump(node_t *n, FILE *fp);
40
+void node_print(node_t *n, FILE *fp);
41
+void node_dump (node_t *n, FILE *fp);
34
 
42
 
35
 typedef int (*walk_fn)(node_t *, void *);
43
 typedef int (*walk_fn)(node_t *, void *);
36
 int node_walk(node_t *n, walk_fn pre, walk_fn post, void *ctx);
44
 int node_walk(node_t *n, walk_fn pre, walk_fn post, void *ctx);
40
 node_t *node_list  (node_t *head);
48
 node_t *node_list  (node_t *head);
41
 node_t *node_vlist (node_t *head, ...);
49
 node_t *node_vlist (node_t *head, ...);
42
 
50
 
43
-node_t *node_ident (char *name);
44
-node_t *node_num   (int64_t num);
45
-node_t *node_string(char *string);
51
+node_t *node_keyword(keyword_t keyword);
52
+node_t *node_ident  (char *name);
53
+node_t *node_num    (int64_t num);
54
+node_t *node_string (char *string);
46
 
55
 
47
 static inline node_t *node_head(node_t *n)
56
 static inline node_t *node_head(node_t *n)
48
 {
57
 {
59
 	return n ? n->prev : NULL;
68
 	return n ? n->prev : NULL;
60
 }
69
 }
61
 
70
 
71
+static inline node_t *node_next(node_t *n)
72
+{
73
+	return n ? n->next : NULL;
74
+}
75
+
62
 #endif	/* _PLY_NODE_H */
76
 #endif	/* _PLY_NODE_H */

+ 84 - 26
ply.c

56
 	prog->locals = &locals;
56
 	prog->locals = &locals;
57
 	prog->globals = &globals;
57
 	prog->globals = &globals;
58
 
58
 
59
-	/* (@ ('{' reads ((pid))) (quantize arg2)) */
60
-	prog->probe = "k:SyS_read"; /* { reads{pid()} @ quantize(arg2) } */
59
+	/* (@ ([ reads ((pid))) (quantize arg2)) */
60
+	prog->probe = "k:SyS_read"; /* { @reads[pid()] = quantize(arg2) } */
61
 	prog->ast =
61
 	prog->ast =
62
 		node_list(
62
 		node_list(
63
-			node_vlist(node_ident("@"),
64
-				   node_vlist(node_ident("{"),
65
-					      node_ident("reads"),
63
+			node_vlist(node_keyword('='),
64
+				   node_vlist(node_keyword('['),
65
+					      node_ident("@reads"),
66
 					      node_list(node_ident("pid")),
66
 					      node_list(node_ident("pid")),
67
 					      NULL),
67
 					      NULL),
68
 				   node_vlist(node_ident("quantize"),
68
 				   node_vlist(node_ident("quantize"),
76
 	return prog;
76
 	return prog;
77
 }
77
 }
78
 
78
 
79
-int is_builtin(char *ident)
80
-{
81
-	if (!strcmp("@", ident) ||
82
-	    !strcmp("{", ident))
83
-		return 1;
84
-
85
-	return 0;
86
-}
87
 
79
 
88
-int symbol_resolve(node_t *n, void *_prog)
80
+int pass_resolve_symbols(node_t *n, void *_prog)
89
 {
81
 {
90
 	prog_t *prog = _prog;
82
 	prog_t *prog = _prog;
91
 	provider_t *global = provider_get(":");
83
 	provider_t *global = provider_get(":");
96
 		return 0;
88
 		return 0;
97
 
89
 
98
 	/* .IDENT/->IDENT is a struct/union member, skip */
90
 	/* .IDENT/->IDENT is a struct/union member, skip */
99
-	op = node_prev(node_prev(n));
100
-	if (op && (op->ntype == N_IDENT) && !strcmp(".", op->ident))
101
-		return 0;
102
-
103
-	if (is_builtin(n->ident))
104
-		return 0;
91
+	/* op = node_prev(node_prev(n)); */
92
+	/* if (op && (op->ntype == N_IDENT) && !strcmp(".", op->ident)) */
93
+	/* 	return 0; */
105
 
94
 
106
 	err = prog->provider->resolve(prog, n);
95
 	err = prog->provider->resolve(prog, n);
107
 	if (!err || (err != -ENOENT))
96
 	if (!err || (err != -ENOENT))
116
 	return sym_add(prog->globals, n->ident, NULL);
105
 	return sym_add(prog->globals, n->ident, NULL);
117
 }
106
 }
118
 
107
 
119
-/* int symbol_infer(node_t *n, void *_prog) */
120
-/* { */
121
-/* 	return 0; */
122
-/* } */
108
+int infer_type_list(prog_t *prog, node_t *n)
109
+{
110
+	type_t *t;
111
+
112
+	/* list of lists (code block) => void */
113
+	if (n->list->ntype == N_LIST) {
114
+		n->type = &t_v;
115
+		return 0;
116
+	}
117
+
118
+	t = n->list->type;
119
+	if (!t)
120
+		return 0;
121
+
122
+	switch (t->ttype) {
123
+	case T_FUNC:
124
+		n->type = t->t.func.type;
125
+		break;
126
+	default:
127
+		n->type = t;
128
+	}
129
+	return 0;
130
+}
131
+
132
+int infer_type_keyword(prog_t *prog, node_t *n)
133
+{
134
+	node_t *c;
135
+
136
+	switch (n->keyword) {
137
+	case KW_SUBSCRIPT:
138
+		c = node_next(node_next(n));
139
+		assert(c);
140
+		n->type = c->type;
141
+		return 0;
142
+	case KW_ASSIGN:
143
+		/* TODO: assignment is statement for now. do we need
144
+		 * c-style assignment expressions? e.g `a = b = 2;` */
145
+		n->type = &t_v;
146
+		return 0;
147
+	}
148
+
149
+	return -ENOSYS;
150
+}
151
+
152
+int infer_type_sym(prog_t *prog, node_t *n)
153
+{
154
+	printf("WKZ\n");
155
+
156
+	return 0;
157
+}
158
+
159
+int pass_infer_types(node_t *n, void *_prog)
160
+{
161
+	prog_t *prog = _prog;
162
+
163
+	if (n->type)
164
+		return 0;
165
+
166
+	switch (n->ntype) {
167
+	case N_LIST:
168
+		return infer_type_list(prog, n);
169
+	case N_KEYWORD:
170
+		return infer_type_keyword(prog, n);
171
+	case N_IDENT:
172
+		return infer_type_sym(prog, n);
173
+	default:
174
+		break;
175
+	}
176
+
177
+	return 0;
178
+}
179
+
123
 
180
 
124
 int pass_walk(pass_t *pass, prog_t *prog)
181
 int pass_walk(pass_t *pass, prog_t *prog)
125
 {
182
 {
127
 }
184
 }
128
 
185
 
129
 pass_t passes[] = {
186
 pass_t passes[] = {
130
-	{ .run = pass_walk, .pre = symbol_resolve },
131
-	/* { .run = pass_walk, .pre = symbol_infer }, */
187
+	{ .run = pass_walk, .post = pass_resolve_symbols },
188
+	{ .run = pass_walk, .post = pass_infer_types },
189
+	{ .run = pass_walk, .post = pass_infer_types },
132
 
190
 
133
 	{ NULL }
191
 	{ NULL }
134
 };
192
 };

+ 3 - 1
type.c

200
 
200
 
201
 	if (!t->t.sou.packed && size) {
201
 	if (!t->t.sou.packed && size) {
202
 		/* align complete struct to requirements of first
202
 		/* align complete struct to requirements of first
203
-		 * member */
203
+		 * member, if struct keep going downwards */
204
 		f = t->t.sou.fields;
204
 		f = t->t.sou.fields;
205
+		while (f->type->ttype == T_STRUCT)
206
+			f = f->type->t.sou.fields;
205
 
207
 
206
 		size += size % f->type->size;
208
 		size += size % f->type->size;
207
 	}
209
 	}