Browse Source

first tiny program's types are all inferred

Tobias Waldekranz.com 8 years ago
parent
commit
f112feac82
9 changed files with 86 additions and 21 deletions
  1. 1 1
      global.c
  2. 1 1
      kprobe.c
  3. 2 0
      node.c
  4. 8 1
      node.h
  5. 34 8
      ply.c
  6. 6 2
      sym.c
  7. 6 3
      sym.h
  8. 27 5
      type.c
  9. 1 0
      type.h

+ 1 - 1
global.c

86
 	}
86
 	}
87
 
87
 
88
 	n->type = t;
88
 	n->type = t;
89
-	return sym_add(prog->locals, n->ident, t);
89
+	return sym_add(prog->locals, n->ident, t, &n->sym);
90
 }
90
 }
91
 
91
 
92
 int global_probe(prog_t *prog)
92
 int global_probe(prog_t *prog)

+ 1 - 1
kprobe.c

29
 		return -ENOENT;
29
 		return -ENOENT;
30
 
30
 
31
 	n->type = t;
31
 	n->type = t;
32
-	return sym_add(prog->locals, n->ident, t);
32
+	return sym_add(prog->locals, n->ident, t, &n->sym);
33
 }
33
 }
34
 
34
 
35
 int kprobe_probe(prog_t *prog)
35
 int kprobe_probe(prog_t *prog)

+ 2 - 0
node.c

162
 	node_t *n = __node(N_LIST);
162
 	node_t *n = __node(N_LIST);
163
 
163
 
164
 	n->list = head;
164
 	n->list = head;
165
+	head->up = n;
165
 	return n;
166
 	return n;
166
 }
167
 }
167
 
168
 
175
         va_start(ap, head);
176
         va_start(ap, head);
176
         while ((next = va_arg(ap, node_t *))) {
177
         while ((next = va_arg(ap, node_t *))) {
177
 		insque(next, head);
178
 		insque(next, head);
179
+		next->up = n;
178
 		head = next;
180
 		head = next;
179
         }
181
         }
180
         va_end(ap);
182
         va_end(ap);

+ 8 - 1
node.h

4
 #include <stdint.h>
4
 #include <stdint.h>
5
 #include <stdio.h>
5
 #include <stdio.h>
6
 
6
 
7
+#include "sym.h"
7
 #include "type.h"
8
 #include "type.h"
8
 
9
 
9
 typedef struct node node_t;
10
 typedef struct node node_t;
22
 } ntype_t;
23
 } ntype_t;
23
 
24
 
24
 struct node {
25
 struct node {
25
-	node_t *next, *prev;
26
+	node_t *next, *prev, *up;
26
 
27
 
27
 	ntype_t ntype;
28
 	ntype_t ntype;
28
 	union {
29
 	union {
34
 	};
35
 	};
35
 
36
 
36
 	type_t *type;
37
 	type_t *type;
38
+	sym_t *sym;
37
 };
39
 };
38
 
40
 
39
 /* debug */
41
 /* debug */
73
 	return n ? n->next : NULL;
75
 	return n ? n->next : NULL;
74
 }
76
 }
75
 
77
 
78
+static inline node_t *node_up(node_t *n)
79
+{
80
+	return n ? n->up : NULL;
81
+}
82
+
76
 #endif	/* _PLY_NODE_H */
83
 #endif	/* _PLY_NODE_H */

+ 34 - 8
ply.c

102
 
102
 
103
 	/* neither provider identifier nor global ditto => user
103
 	/* neither provider identifier nor global ditto => user
104
 	 * variable, add it as a global symbol of unknown type. */
104
 	 * variable, add it as a global symbol of unknown type. */
105
-	return sym_add(prog->globals, n->ident, NULL);
105
+	return sym_add(prog->globals, n->ident, NULL, &n->sym);
106
 }
106
 }
107
 
107
 
108
 int infer_type_list(prog_t *prog, node_t *n)
108
 int infer_type_list(prog_t *prog, node_t *n)
131
 
131
 
132
 int infer_type_keyword(prog_t *prog, node_t *n)
132
 int infer_type_keyword(prog_t *prog, node_t *n)
133
 {
133
 {
134
-	node_t *c;
134
+	node_t *dst, *src;
135
 
135
 
136
 	switch (n->keyword) {
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:
137
 	case KW_ASSIGN:
138
+		dst = node_next(n);
139
+		src = node_next(dst);
140
+		assert(dst && src);
141
+
142
+		if (!src->type)
143
+			return 0;
144
+
145
+		if (!dst->type)
146
+			dst->type = src->type;
147
+
143
 		/* TODO: assignment is statement for now. do we need
148
 		/* TODO: assignment is statement for now. do we need
144
 		 * c-style assignment expressions? e.g `a = b = 2;` */
149
 		 * c-style assignment expressions? e.g `a = b = 2;` */
145
 		n->type = &t_v;
150
 		n->type = &t_v;
146
 		return 0;
151
 		return 0;
152
+
153
+	default:
154
+		return 0;
147
 	}
155
 	}
148
 
156
 
149
 	return -ENOSYS;
157
 	return -ENOSYS;
151
 
159
 
152
 int infer_type_sym(prog_t *prog, node_t *n)
160
 int infer_type_sym(prog_t *prog, node_t *n)
153
 {
161
 {
154
-	printf("WKZ\n");
162
+	node_t *parent, *key;
163
+
164
+	if (n->sym->type)
165
+		return 0;
166
+
167
+	parent = node_up(n);
168
+	key = node_next(n);
169
+
170
+	/* match `somemap[somekey]` where the type of the entire
171
+	 * expression and the type of the key is known, since that
172
+	 * means the type of the map itself is also known. */
173
+	if (parent && parent->type
174
+	    && (parent->list->ntype == N_KEYWORD)
175
+	    && (parent->list->keyword == KW_SUBSCRIPT)
176
+	    && key && key->type) {
177
+		n->type = type_get_map_of(key->type, parent->type);
178
+
179
+		return sym_add(n->sym->st, n->ident, n->type, NULL);
180
+	}
155
 
181
 
156
 	return 0;
182
 	return 0;
157
 }
183
 }

+ 6 - 2
sym.c

18
 	return NULL;
18
 	return NULL;
19
 }
19
 }
20
 
20
 
21
-int sym_add(symtab_t *st, const char *name, type_t *type)
21
+int sym_add(symtab_t *st, const char *name, type_t *type, sym_t **new)
22
 {
22
 {
23
 	sym_t *sym;
23
 	sym_t *sym;
24
 
24
 
31
 		else if (type && !type_equal(sym->type, type))
31
 		else if (type && !type_equal(sym->type, type))
32
 			return -EINVAL;
32
 			return -EINVAL;
33
 
33
 
34
-		return 0;
34
+		goto found;
35
 	}
35
 	}
36
 
36
 
37
 	st->sym = realloc(st->sym, ++st->len * sizeof(*st->sym));
37
 	st->sym = realloc(st->sym, ++st->len * sizeof(*st->sym));
38
 	assert(st->sym);
38
 	assert(st->sym);
39
 
39
 
40
 	sym = &st->sym[st->len-1];
40
 	sym = &st->sym[st->len-1];
41
+	sym->st   = st;
41
 	sym->name = name;
42
 	sym->name = name;
42
 	sym->type = type;
43
 	sym->type = type;
44
+found:
45
+	if (new)
46
+		*new = sym;
43
 	return 0;
47
 	return 0;
44
 }
48
 }
45
 
49
 

+ 6 - 3
sym.h

3
 
3
 
4
 #include "type.h"
4
 #include "type.h"
5
 
5
 
6
+typedef struct symtab symtab_t;
7
+
6
 typedef struct sym {
8
 typedef struct sym {
9
+	symtab_t *st;
7
 	const char *name;
10
 	const char *name;
8
 	type_t *type;
11
 	type_t *type;
9
 } sym_t;
12
 } sym_t;
10
 
13
 
11
-typedef struct symtab {
14
+struct symtab {
12
 	sym_t *sym;
15
 	sym_t *sym;
13
 	size_t len;
16
 	size_t len;
14
-} symtab_t;
17
+};
15
 
18
 
16
 sym_t *sym_get(symtab_t *st, const char *name);
19
 sym_t *sym_get(symtab_t *st, const char *name);
17
-int    sym_add(symtab_t *st, const char *name, type_t *type);
20
+int    sym_add(symtab_t *st, const char *name, type_t *type, sym_t **new);
18
 
21
 
19
 void sym_dump(sym_t *sym, FILE *fp);
22
 void sym_dump(sym_t *sym, FILE *fp);
20
 void symtab_dump(symtab_t *st, FILE *fp);
23
 void symtab_dump(symtab_t *st, FILE *fp);

+ 27 - 5
type.c

116
 		type_dump_func(t, fp);
116
 		type_dump_func(t, fp);
117
 		break;
117
 		break;
118
 	case T_MAP:
118
 	case T_MAP:
119
-		/* TODO */
120
-		assert(0);
119
+		fputs("map [", fp);
120
+		type_dump(t->t.map.ktype, fp);
121
+		fputs("] ", fp);
122
+		type_dump(t->t.map.vtype, fp);
121
 		break;
123
 		break;
122
 	}
124
 	}
123
 }
125
 }
172
 	}
174
 	}
173
 }
175
 }
174
 
176
 
177
+type_t *type_get_map_of(type_t *ktype, type_t *vtype)
178
+{
179
+	type_t *t;
180
+	size_t i;
181
+
182
+	for (i = 0; i < types.len; i++) {
183
+		t = types.type[i];
184
+		if ((t->ttype == T_MAP)
185
+		    && (t->t.map.ktype == ktype)
186
+		    && (t->t.map.vtype == vtype))
187
+			return t;
188
+	}
189
+
190
+	t = calloc(1, sizeof(*t));
191
+	t->ttype = T_MAP;
192
+	t->t.map.vtype = vtype;
193
+	t->t.map.ktype = ktype;
194
+	type_add(t);
195
+	return t;
196
+}
197
+
175
 int type_equal(type_t *a, type_t *b)
198
 int type_equal(type_t *a, type_t *b)
176
 {
199
 {
177
 	/* TODO */
200
 	/* TODO */
232
 	case T_ARRAY:
255
 	case T_ARRAY:
233
 		t->size = t->t.array.len * t->t.array.type->size;
256
 		t->size = t->t.array.len * t->t.array.type->size;
234
 		break;
257
 		break;
235
-
236
 	case T_MAP:
258
 	case T_MAP:
237
-		/* TODO */
238
-		assert(0);
259
+		/* map fds are s64:s */
260
+		t->size = 8;
239
 		break;
261
 		break;
240
 	}
262
 	}
241
 }
263
 }

+ 1 - 0
type.h

104
 extern type_t t_ull;
104
 extern type_t t_ull;
105
 extern type_t t_ullp;
105
 extern type_t t_ullp;
106
 
106
 
107
+type_t *type_get_map_of(type_t *ktype, type_t *vtype);
107
 
108
 
108
 int type_equal(type_t *a, type_t *b);
109
 int type_equal(type_t *a, type_t *b);
109
 int type_add(type_t *t);
110
 int type_add(type_t *t);