Browse Source

quantize type inference

Tobias Waldekranz.com 8 years ago
parent
commit
2a4b0f7444
2 changed files with 45 additions and 3 deletions
  1. 37 3
      global.c
  2. 8 0
      type.h

+ 37 - 3
global.c

51
 {
51
 {
52
 	struct node *map = n->expr.args;
52
 	struct node *map = n->expr.args;
53
 
53
 
54
-	if (n->sym->type || !map->sym->type)
54
+	if (!map->sym->type)
55
 		return 0;
55
 		return 0;
56
 
56
 
57
-	assert(map->sym->type->ttype == T_MAP);
57
+	/* TODO validate key against known type */
58
 
58
 
59
 	/* given `m[key]` where m's type is known, infer that the
59
 	/* given `m[key]` where m's type is known, infer that the
60
 	 * expression's type is equal to m's value type. */
60
 	 * expression's type is equal to m's value type. */
95
 {
95
 {
96
 	struct node *lval, *rval;
96
 	struct node *lval, *rval;
97
 
97
 
98
+	if (n->sym->type)
99
+		return 0;
100
+
98
 	lval = n->expr.args;
101
 	lval = n->expr.args;
99
 	rval = lval->next;
102
 	rval = lval->next;
100
 
103
 
106
 		 * infer that a's type must be equal to b's */
109
 		 * infer that a's type must be equal to b's */
107
 		lval->sym->type = rval->sym->type;
110
 		lval->sym->type = rval->sym->type;
108
 
111
 
112
+		/* TODO do we need assignment expressions? */
113
+		n->sym->type = &t_void;
114
+
109
 		if (node_is_map(lval))
115
 		if (node_is_map(lval))
110
 			return global_assign_type_infer_map(lval);
116
 			return global_assign_type_infer_map(lval);
111
 
117
 
117
 
123
 
118
 	_e("%#N: can't assign %N (type '%T'), to %N (type '%T').\n",
124
 	_e("%#N: can't assign %N (type '%T'), to %N (type '%T').\n",
119
 	   n, rval, rval->sym->type, lval, lval->sym->type);
125
 	   n, rval, rval->sym->type, lval, lval->sym->type);
126
+
120
 	return -EINVAL;
127
 	return -EINVAL;
121
 }
128
 }
122
 
129
 
139
 {
146
 {
140
 	struct node *lval, *rval;
147
 	struct node *lval, *rval;
141
 
148
 
149
+	if (n->sym->type)
150
+		return 0;
151
+
142
 	lval = n->expr.args;
152
 	lval = n->expr.args;
143
 	rval = lval->next;
153
 	rval = lval->next;
144
 
154
 
145
-	if (n->sym->type || !lval->sym->type || !rval->sym->type)
155
+	if (!lval->sym->type || !rval->sym->type)
146
 		return 0;
156
 		return 0;
147
 
157
 
148
 	if (type_equal(lval->sym->type, rval->sym->type)) {
158
 	if (type_equal(lval->sym->type, rval->sym->type)) {
154
 	return 0;
164
 	return 0;
155
 }
165
 }
156
 
166
 
167
+/* :binop */
168
+
169
+static int global_quantize_type_infer(const struct func *func, struct node *n)
170
+{
171
+	struct node *arg;
172
+	struct type *t;
173
+
174
+	arg = n->expr.args;
175
+
176
+	if (n->sym->type || !arg->sym->type)
177
+		return 0;
178
+
179
+	t = type_base(arg->sym->type);
180
+	if (t->ttype != T_SCALAR) {
181
+		_e("%#N: can't quantize non-scalar value %N (type '%T').\n",
182
+		   n, arg, arg->sym->type);
183
+		return -EINVAL;	
184
+	}
185
+
186
+	n->sym->type = type_array_of(arg->sym->type, type_sizeof(t) * 8);
187
+	return 0;
188
+}
189
+
157
 /* pid */
190
 /* pid */
158
 
191
 
159
 struct type t_pid = {
192
 struct type t_pid = {
259
 	{
292
 	{
260
 		.name = "quantize",
293
 		.name = "quantize",
261
 		.type = &t_1arg_func,
294
 		.type = &t_1arg_func,
295
+		.type_infer = global_quantize_type_infer,
262
 	},
296
 	},
263
 	
297
 	
264
 	{ .name = NULL }
298
 	{ .name = NULL }

+ 8 - 0
type.h

139
 
139
 
140
 }
140
 }
141
 
141
 
142
+static inline struct type *type_base(struct type *t)
143
+{
144
+	while (t->ttype == T_TYPEDEF)
145
+		t = t->tdef.type;
146
+
147
+	return t;
148
+}
149
+
142
 #endif	/* _PLY_TYPE_H */
150
 #endif	/* _PLY_TYPE_H */