Przeglądaj źródła

quantize type inference

Tobias Waldekranz.com 8 lat temu
rodzic
commit
2a4b0f7444
2 zmienionych plików z 45 dodań i 3 usunięć
  1. 37 3
      global.c
  2. 8 0
      type.h

+ 37 - 3
global.c

@@ -51,10 +51,10 @@ static int global_map_type_infer(const struct func *func, struct node *n)
51 51
 {
52 52
 	struct node *map = n->expr.args;
53 53
 
54
-	if (n->sym->type || !map->sym->type)
54
+	if (!map->sym->type)
55 55
 		return 0;
56 56
 
57
-	assert(map->sym->type->ttype == T_MAP);
57
+	/* TODO validate key against known type */
58 58
 
59 59
 	/* given `m[key]` where m's type is known, infer that the
60 60
 	 * expression's type is equal to m's value type. */
@@ -95,6 +95,9 @@ static int global_assign_type_infer(const struct func *func, struct node *n)
95 95
 {
96 96
 	struct node *lval, *rval;
97 97
 
98
+	if (n->sym->type)
99
+		return 0;
100
+
98 101
 	lval = n->expr.args;
99 102
 	rval = lval->next;
100 103
 
@@ -106,6 +109,9 @@ static int global_assign_type_infer(const struct func *func, struct node *n)
106 109
 		 * infer that a's type must be equal to b's */
107 110
 		lval->sym->type = rval->sym->type;
108 111
 
112
+		/* TODO do we need assignment expressions? */
113
+		n->sym->type = &t_void;
114
+
109 115
 		if (node_is_map(lval))
110 116
 			return global_assign_type_infer_map(lval);
111 117
 
@@ -117,6 +123,7 @@ static int global_assign_type_infer(const struct func *func, struct node *n)
117 123
 
118 124
 	_e("%#N: can't assign %N (type '%T'), to %N (type '%T').\n",
119 125
 	   n, rval, rval->sym->type, lval, lval->sym->type);
126
+
120 127
 	return -EINVAL;
121 128
 }
122 129
 
@@ -139,10 +146,13 @@ static int global_binop_type_infer(const struct func *func, struct node *n)
139 146
 {
140 147
 	struct node *lval, *rval;
141 148
 
149
+	if (n->sym->type)
150
+		return 0;
151
+
142 152
 	lval = n->expr.args;
143 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 156
 		return 0;
147 157
 
148 158
 	if (type_equal(lval->sym->type, rval->sym->type)) {
@@ -154,6 +164,29 @@ static int global_binop_type_infer(const struct func *func, struct node *n)
154 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 190
 /* pid */
158 191
 
159 192
 struct type t_pid = {
@@ -259,6 +292,7 @@ static const struct func global_funcs[] = {
259 292
 	{
260 293
 		.name = "quantize",
261 294
 		.type = &t_1arg_func,
295
+		.type_infer = global_quantize_type_infer,
262 296
 	},
263 297
 	
264 298
 	{ .name = NULL }

+ 8 - 0
type.h

@@ -139,4 +139,12 @@ static inline int type_nargs(struct type *t)
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 150
 #endif	/* _PLY_TYPE_H */