Procházet zdrojové kódy

separate ident/keyword, start on type inference

Tobias Waldekranz.com před 8 roky
rodič
revize
c44a1be62e
4 změnil soubory, kde provedl 137 přidání a 36 odebrání
  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,7 +6,17 @@
6 6
 #include <stdio.h>
7 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 21
 void node_print(node_t *n, FILE *fp)
12 22
 {
@@ -14,6 +24,11 @@ void node_print(node_t *n, FILE *fp)
14 24
 	case N_LIST:
15 25
 		fputs("()", fp);
16 26
 		break;
27
+	case N_KEYWORD:
28
+		fputs("\e[31m", fp);
29
+		fputc(n->keyword, fp);
30
+		fputs("\e[0m", fp);
31
+		break;
17 32
 	case N_IDENT:
18 33
 		fputs(n->ident, fp);
19 34
 		break;
@@ -28,10 +43,7 @@ void node_print(node_t *n, FILE *fp)
28 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 49
 struct node_dump_info {
@@ -87,11 +99,13 @@ int __node_dump_post(node_t *n, void *_info)
87 99
 	for (c = n->list; c; c = c->next) {
88 100
 		if (c->ntype == N_LIST) {
89 101
 			fprintf(info->fp, "\n%*s)", info->indent, "");
102
+			__type_dump(n->type, info->fp);
90 103
 			return 0;
91 104
 		}
92 105
 	}
93 106
 
94 107
 	fputc(')', info->fp);
108
+	__type_dump(n->type, info->fp);
95 109
 	return 0;
96 110
 }
97 111
 
@@ -168,6 +182,13 @@ node_t *node_vlist(node_t *head, ...)
168 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 192
 node_t *node_ident(char *name)
172 193
 {
173 194
 	node_t *n = __node(N_IDENT);
@@ -179,6 +200,9 @@ node_t *node_num(int64_t num)
179 200
 {
180 201
 	node_t *n = __node(N_NUM);
181 202
 	n->num = num;
203
+
204
+	/* TODO: handle L UL ULL and such nonsense */
205
+	n->type = &t_s64;
182 206
 	return n;
183 207
 }
184 208
 
@@ -186,5 +210,8 @@ node_t *node_string(char *string)
186 210
 {
187 211
 	node_t *n = __node(N_STRING);
188 212
 	n->string = string;
213
+
214
+	/* TODO: string type like dtrace? */
215
+	n->type = &t_cp;
189 216
 	return n;
190 217
 }

+ 18 - 4
node.h

@@ -8,8 +8,14 @@
8 8
 
9 9
 typedef struct node node_t;
10 10
 
11
+typedef enum keyword {
12
+	KW_SUBSCRIPT = '[',
13
+	KW_ASSIGN = '=',
14
+} keyword_t;
15
+
11 16
 typedef enum ntype {
12 17
 	N_LIST,
18
+	N_KEYWORD,
13 19
 	N_IDENT,
14 20
 	N_NUM,
15 21
 	N_STRING,
@@ -21,6 +27,7 @@ struct node {
21 27
 	ntype_t ntype;
22 28
 	union {
23 29
 		node_t *list;
30
+		keyword_t keyword;
24 31
 		char *ident;
25 32
 		int64_t num;
26 33
 		char *string;
@@ -30,7 +37,8 @@ struct node {
30 37
 };
31 38
 
32 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 43
 typedef int (*walk_fn)(node_t *, void *);
36 44
 int node_walk(node_t *n, walk_fn pre, walk_fn post, void *ctx);
@@ -40,9 +48,10 @@ int node_walk(node_t *n, walk_fn pre, walk_fn post, void *ctx);
40 48
 node_t *node_list  (node_t *head);
41 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 56
 static inline node_t *node_head(node_t *n)
48 57
 {
@@ -59,4 +68,9 @@ static inline node_t *node_prev(node_t *n)
59 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 76
 #endif	/* _PLY_NODE_H */

+ 84 - 26
ply.c

@@ -56,13 +56,13 @@ prog_t *prog_get(void)
56 56
 	prog->locals = &locals;
57 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 61
 	prog->ast =
62 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 66
 					      node_list(node_ident("pid")),
67 67
 					      NULL),
68 68
 				   node_vlist(node_ident("quantize"),
@@ -76,16 +76,8 @@ prog_t *prog_get(void)
76 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 82
 	prog_t *prog = _prog;
91 83
 	provider_t *global = provider_get(":");
@@ -96,12 +88,9 @@ int symbol_resolve(node_t *n, void *_prog)
96 88
 		return 0;
97 89
 
98 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 95
 	err = prog->provider->resolve(prog, n);
107 96
 	if (!err || (err != -ENOENT))
@@ -116,10 +105,78 @@ int symbol_resolve(node_t *n, void *_prog)
116 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 181
 int pass_walk(pass_t *pass, prog_t *prog)
125 182
 {
@@ -127,8 +184,9 @@ int pass_walk(pass_t *pass, prog_t *prog)
127 184
 }
128 185
 
129 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 191
 	{ NULL }
134 192
 };

+ 3 - 1
type.c

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